Skip to Content.
Sympa Menu

coq-club - Re: [Coq-Club] fun <-> forall

coq-club AT inria.fr

Subject: The Coq mailing list

List archive

Re: [Coq-Club] fun <-> forall


Chronological Thread 
  • From: Cyril Cohen <cohen AT crans.org>
  • To: coq-club AT inria.fr, Clément Pit-Claudel <cpitclaudel AT gmail.com>, Burak Ekici <ekcburak AT hotmail.com>
  • Subject: Re: [Coq-Club] fun <-> forall
  • Date: Tue, 31 Oct 2017 11:29:00 +0100
  • Authentication-results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=cohen AT crans.org; spf=Pass smtp.mailfrom=cohen AT crans.org; spf=Pass smtp.helo=postmaster AT redisdead.crans.org
  • Ironport-phdr: 9a23:AlgqSxSxtsFQpDHQ3Gky4O/sKNpsv+yvbD5Q0YIujvd0So/mwa64YReN2/xhgRfzUJnB7Loc0qyN7PCmBDRIyK3CmU5BWaQEbwUCh8QSkl5oK+++Imq/EsTXaTcnFt9JTl5v8iLzG0FUHMHjew+a+SXqvnY6Uy/yPgttJ+nzBpWaz4Huj7jzqNXvZFBDgyP4ardvJj23qx/Qv48Ym88qAaKwzxbPvkxwevgT7mdhOF6em16o7d+x4JVn+jlctvYJ+MtJUKG8dKM9G/gQJik8OmN9yc7qvhiLGQaM7XEBSGwVuhpPHw3M7RW8VZD05HjUrO14jQKLJ8zyBZszWTmkp/NgTx/ljg8MLTc/6yfQkMMm3/ETmw6ouxEqm92cW4qSLvcrO/qFJd4=

Hello,

Using the view mechanism of ssreflect, you can do this:

From Coq Require Import ssreflect ssrfun.

Axiom catC: Type.
Axiom obj: Type -> Type.
Axiom arrow: forall (catC: Type), obj catC -> obj catC -> Type.
Axiom fmap : forall {C: Type} (a b: obj C), arrow C b a -> Type.
Axiom foo : forall {C a b}, arrow C b a -> arrow C b a.

Lemma congf1 {X Y} {f g : forall u : X, Y u} {x} : f = g -> f x = g x.
Proof. by move->. Qed.

Goal ((fun (a b : obj catC) (f : arrow catC b a) => fmap a b (foo f)) =
(fun (a b : obj catC) (f : arrow catC b a) => fmap a b f) -> True).
Proof.
move=> /congf1/congf1/congf1 eq_fmap.
Abort.


Best,

--
Cyril

On 26/10/2017 18:07, Clément Pit-Claudel wrote:
Turning this into a tactic turns out to be surprisingly tricky. Can someone
share a better solution? Here's mine:

Ltac specialize_eq_ind_argument eql x :=
constr:(fun f => ltac:(lazymatch (eval cbv beta in (eql f)) with
| ?l = ?r => exact (l x = r x)
end)).

Ltac quantify_equality eql arrow_type k :=
lazymatch (eval cbv beta in arrow_type) with
| forall (h:?hd), @?tl h =>
let binder := fresh "x" in
constr:(fun (binder: hd) =>
ltac:(let eql_with_hd := specialize_eq_ind_argument eql
binder in
let with_tl := quantify_equality eql_with_hd (tl
binder) k in
exact with_tl))
| _ => k eql
end.

Ltac reverse_functional_extensionality H :=
lazymatch type of H with
| _ = ?g =>
let tg := type of g in
let pr := quantify_equality (fun f0 => f0 = g) tg ltac:(fun eql =>
constr:(eq_ind_r eql eq_refl H)) in
let h' := fresh H in
pose proof pr as h';
cbv beta in h'
end.

And here's an example:

Axiom catC: Type.
Axiom obj: Type -> Type.
Axiom arrow: forall (catC: Type), obj catC -> obj catC -> Type.
Axiom fmap : forall {C: Type} (a b: obj C), arrow C b a -> Type.
Axiom foo : forall {C a b}, arrow C b a -> arrow C b a.

Goal ((fun (a b : obj catC) (f : arrow catC b a) => fmap a b (foo f)) =
(fun (a b : obj catC) (f : arrow catC b a) => fmap a b f) -> True).
Proof.
intros.
reverse_functional_extensionality H.

Clément.

On 2017-10-26 11:11, Burak Ekici wrote:
Hi Clément,

Thanks a lot! That's exactly what I was looking for...

Best,



Burak.



On 26-10-2017 18:08, Clément Pit-Claudel wrote:
On 2017-10-26 10:25, Burak Ekici wrote:
However, could not make it work whatever I did...
Does the following work for you?

pose proof (fun x y z => eq_ind_r (fun f => f x y z = _ x y z) eq_refl
H1c) as H';
cbv beta in H'.

Here's a complete example:

Axiom catC: Type.
Axiom obj: Type -> Type.
Axiom arrow: forall (catC: Type), obj catC -> obj catC -> Type.
Axiom fmap : forall {C: Type} (a b: obj C), arrow C b a -> Type.
Axiom foo : forall {C a b}, arrow C b a -> arrow C b a.

Goal ((fun (a b : obj catC) (f : arrow catC b a) => fmap a b (foo f)) =
(fun (a b : obj catC) (f : arrow catC b a) => fmap a b f) -> True).
Proof.
intros.
pose proof (fun x y z => eq_ind_r (fun f => f x y z = _ x y z) eq_refl H)
as H';
cbv beta in H'.





Archive powered by MHonArc 2.6.18.

Top of Page