Skip to Content.
Sympa Menu

coq-club - Re: [Coq-Club] Matching function applications in second-order patterns

coq-club AT inria.fr

Subject: The Coq mailing list

List archive

Re: [Coq-Club] Matching function applications in second-order patterns


Chronological Thread 
  • From: James Wilcox <wilcoxjay AT gmail.com>
  • To: coq-club AT inria.fr
  • Subject: Re: [Coq-Club] Matching function applications in second-order patterns
  • Date: Sat, 14 May 2016 09:43:47 -0700
  • Authentication-results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=wilcoxjay AT gmail.com; spf=Pass smtp.mailfrom=wilcoxjay AT gmail.com; spf=None smtp.helo=postmaster AT mail-qg0-f52.google.com
  • Ironport-phdr: 9a23:yEyf3hMTgkT8OtkcLhYl6mtUPXoX/o7sNwtQ0KIMzox0KP/8rarrMEGX3/hxlliBBdydsKIVzbCN+Pm4AiQp2tWojjMrSNR0TRgLiMEbzUQLIfWuLgnFFsPsdDEwB89YVVVorDmROElRH9viNRWJ+iXhpQAbFhi3DwdpPOO9QteU1JTmkbrpsMSLOE1hv3mUX/BbFF2OtwLft80b08NJC50a7V/3mEZOYPlc3mhyJFiezF7W78a0+4N/oWwL46pyv50IbaKvdKMhCLdcET4OMmYv5cStuwOQYxGI4y4+W2AbiVJ3AgzO6wGyCojwtiD9puh0yQGVOMT3SfY/XjH0vPQjcwPhlCpSb21xy2rQkMEl1K8=

Thanks, that seems to work! 

My mental model was that the ?F would not even match if it referred to the bound variable, but I guess that's just not how it works. 

Thanks again!

James

On Sat, May 14, 2016 at 9:17 AM, Guillaume Melquiond <guillaume.melquiond AT inria.fr> wrote:
On 14/05/2016 16:23, James Wilcox wrote:
> I am trying to use second-order ltac patterns to implement a reflection
> tactic that can recurse under binders, roughly following the strategy
> outlined in the CPDT chapter on reflection. I can't figure out how to
> write a second-order pattern that matches a function application.
>
> For example, I would expect to be able to write something like
>
> Ltac reflect x :=
> match eval simpl in x with
> (* other cases here *)
> | fun (y : ?T) => (@?F y) (@?A y) => (* ... *)
> end.
>
> Coq accepts this definition syntactically, but whenever the case
> matches, it complains "Only bound indices allowed in second order
> pattern matching."
>
> The closest I can get to something like this working is to disallow
> references to bound variables in the left hand side of the application,
> as follows:
>
>  fun (y : ?T) => ?F (@?A y) => (* ... *)
>
> This works as long as the tactic never encounters a function application
> that applies an _expression_ that refers to bound variables, but this is
> not as general as I'd like.
>
> Does anyone know if there is a way to do this? I've included a complete
> but simple example showing the issue below.
>
> James
>
>
> Example:
>
> The goal is to write a tactic that annotates every function application
> with the function apply, defined as:
>
> Definition apply {A B} (f : A -> B) (x : A) : B := f x.
>
> A version of the desired tactic with the limitations mentioned above is:
>
> Ltac refl' x :=
>   lazymatch eval simpl in x with
>   | fun x => snd (@?B x) => let r := refl' B in constr:(fun z => snd (r z))
>   | fun x => fst (@?B x) => let r := refl' B in constr:(fun z => fst (r z))
>   | fun (x : ?T) => x => constr:(fun (z : T) => z)
>   | fun (y : ?T) (z : ?U) => @?B y z =>
>     let r := refl' (fun (p : T * U) => B (fst p) (snd p)) in
>     constr:(fun (y : T) (z : U) => r (y, z))
>   | fun (y : ?T) => ?F (@?A y) => let r1 := refl' (fun _ : T => F) in
>                               let r2 := refl' A in
>                               constr:(fun y : T => @apply _ _ (r1 y) (r2 y))
>   | fun (_ : ?T) => ?B => constr:(fun (_ : T) => B)
>   end.
>
> (* simple driver tactic to print the simplified term constructed by refl' *)
> Ltac refl x :=
>   let r := refl' (fun _ : unit => x) in
>   let r' := eval simpl in (r tt) in
>   idtac r'.
>
> For example, it is able to handle the following simple case:
>
> Goal False.
> refl (fun (x : nat) (f : nat -> nat) => S x).
> (* prints: (fun (x : nat) (_ : nat -> nat) => apply S x) *)
>
> But of course it doesn't work if the _expression_ being applied refers to
> bound variables:
>
> Goal False.
> refl (fun (x : nat) (f : nat -> nat) => f x).
> (* Error: Ltac variable F depends on pattern variable name y
>    which is not bound in current context. *)
>
> Is it possible to implement a version of refl' which handles this case?

I am still not sure whether it is a bug or a feature, but you are
allowed to reuse "y" there. In other words, instead of calling "refl'
(fun _ : T => F)", call "refl' (fun y : T => F)". That way, any
occurrence of "y" still in "F" will get rebound.

Best regards,

Guillaume




Archive powered by MHonArc 2.6.18.

Top of Page