Skip to Content.
Sympa Menu

coq-club - Re: [Coq-Club] Unfolded not cannot be refolded

coq-club AT inria.fr

Subject: The Coq mailing list

List archive

Re: [Coq-Club] Unfolded not cannot be refolded


Chronological Thread 
  • From: ikdc <ikdc AT mit.edu>
  • To: coq-club AT inria.fr, Jason -Zhong Sheng- Hu <fdhzs2010 AT hotmail.com>
  • Subject: Re: [Coq-Club] Unfolded not cannot be refolded
  • Date: Fri, 30 Mar 2018 23:04:40 -0400
  • Authentication-results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=ikdc AT mit.edu; spf=Pass smtp.mailfrom=ikdc AT mit.edu; spf=None smtp.helo=postmaster AT dmz-mailsec-scanner-1.mit.edu
  • Ironport-phdr: 9a23:UpbxhxehWn34zPLWN9LaKQwFlGMj4u6mDksu8pMizoh2WeGdxcu+YR7h7PlgxGXEQZ/co6odzbaO6Oa4ASQp2tWoiDg6aptCVhsI2409vjcLJ4q7M3D9N+PgdCcgHc5PBxdP9nC/NlVJSo6lPwWB6nK94iQPFRrhKAF7Ovr6GpLIj8Swyuu+54Dfbx9HiTahb75+Ngm6oRnMvcQKnIVuLbo8xAHUqXVSYeRWwm1oJVOXnxni48q74YBu/SdNtf8/7sBMSar1cbg2QrxeFzQmLns65Nb3uhnZTAuA/WUTX2MLmRdVGQfF7RX6XpDssivms+d2xSeXMdHqQb0yRD+v6bpgRh31hycdLzM37X/ZisJwgqxYrhyuqRNwzIzIb4+aL/d+YqHQcMkGSWZdUMtcVypMCZ68YYsVCOoBOP5Vr4j+p1QTsRS1GA6hBOLsyjBVmnD7xqg60+U9EQ3cwgMvAs8OvW3Sod7oOqkSVuW1w7PJzTXFd/5W1jb96JTIchA8uv6AR65/cc3UyUQpCgjLjU2QpJT4Mz6WzOgAt3KX4/RgWO61lmIrtRl9riWsy8s2l4XEhYYYxkrH+Cln2oo4K961RUhmatC+CpRQrTuVN45uT8MiXW5ovCE6x6Ubtp6+fSkG0ZEnyATea/yDaIiH/A7sWP+KIThknn1lfrS/iAio8US51+HwTMy00FdWriZfjNbDq20N2wTS6siBVPR94l+s1SuM2gzJ7uxIO144mKrBJ5I83LI8jp8Tvl7CHi/ylkX2lqiWdkA89+ip6OTof6npq4SZN491lgHyKLohldGiAeggKAgBQ3Cb+fig1L3k5UD2XLJKjuQvnqbFtJDaON8Uq7WiAw5V14Yj8wywAy2n0NQeh3kHLUhKdAiJj4jzaBnyJ6XzCu76iFCxmh9qwerHN/vvGNGFDHHYl7GpOIR97EhTgDEzwNZQotp0F/lVLv7zSFSr7IWAJh8+Lwm9wuKhA9J4gNAwQ2WKV66aPKia5V6L6ukHJuiQIoIZpWCueLAe+/fygCphyhcmdq6z0M5PMSHqLrFdO0ycJEHUrJIEGGYOsBA5Sb24jVyeFzNfeiTrBv5u1nQAEIujSLz7aMW1mrXQjiK6Attban0UUgnRQ0etTJ2NXrI3UAzXIsJllWddB7SkWcok3BCqrwLxjqFsJ+zS9zdd7NTm1cQz6uHOx0k/

On 03/28/2018 06:39 PM, Jason -Zhong Sheng- Hu wrote:
Hi all,


Please consider following code:


Goal (forall n : nat, ~ (n >= 0) -> False) -> True.
unfold not. fold not.

This code unfolded not, so the goal becomes


(forall n : nat, (n >= 0 -> False) -> False) -> True


But the next one fold not is not able to refold the not to turn the inner
condition back to ~ (n >= 0).


In general, I tried to write code like this,


intros.
match goal with
| [ _ : forall _, ?T |- _ ] =>
idtac T
end.

following the program above, in my Coq 8.6, it says no matching clause. But I
suspect this error message is bogus, the real error should be Coq wouldn't
allow us to capture a dependent right hand side of implication, due to the
potential misuse of free variables. That probably also explains why fold
cannot undo what unfold has done.


This is especially disturbing, when I do autounfold in *. There are many
lemmas expressed with the presence of not, and if not is unfolded, auto
family does not seem work well with that form anymore. Might I ask how do you
guys handle it?


In general, is there a way to manipulate dependent rhs of implication?


Sincerely Yours,

Jason Hu



(* I found the problem interesting, so I decided to take a stab at it.
* First, I tried using setoid_rewrite. *)

Require Import Coq.Classes.Morphisms.
Require Import Setoid.
Local Existing Instance eq_subrelation | 5.

Goal (forall n : nat, ((n >= 0) -> False) -> False) -> True.
intro.
(* H : forall n : nat, (n >= 0 -> False) -> False *)
assert (forall P : Prop, (P -> False) = ~P) as E by reflexivity.
setoid_rewrite E in H.
(* H : forall n : nat, ~ (n >= 0 -> False) *)
Fail setoid_rewrite E in H. (* why? *)
Abort.

Goal (forall n : nat, ((n >= 0) -> False) -> False) -> True.
intro.
(* H : forall n : nat, (n >= 0 -> False) -> False *)
assert (forall P : Prop, (P -> False) = ~P) as E by reflexivity.
setoid_rewrite E in H at 2.
(* H : forall n : nat, ~ n >= 0 -> False *)
setoid_rewrite E in H.
(* H : forall n : nat, ~ ~ n >= 0 *)
Abort.

(* However, I found that this only worked if it rewrote in a certain order.
* I don't know why the second rewrite fails.
* Hopefully someone can give an explanation or a way to make it work *)

(* Using an idea from Jason Gross in <https://github.com/coq/coq/issues/6243>,
* I managed to write a context match on the body of the forall. *)

Ltac fold_not_under_forall :=
repeat
match goal with
| H : forall n : ?T, @?x n |- _ =>
match x with
| fun n : T => ?b =>
let not_n := fresh in
let b''' :=
constr:(
fun n : T =>
match b with
| not_n =>
ltac:(let b' := (eval cbv delta [not_n] in not_n) in
match b' with
| context C[?P -> False] =>
let b'' := context C[~ P] in
exact b''
end)
end) in
let tH' := eval cbn beta in (forall n : T, b''' n) in
let tH := type of H in
change tH with tH' in H
end
end.

Goal (forall n : nat, ((n >= 0) -> False) -> False) -> True.
intro.
(* H : forall n : nat, (n >= 0 -> False) -> False *)
fold_not_under_forall.
(* H : forall n : nat, ~ ~ n >= 0 *)
Abort.

(* It works, but it's the ugliest Ltac I've ever written.
* Hopefully it can be improved? *)



Archive powered by MHonArc 2.6.18.

Top of Page