coq-club AT inria.fr
Subject: The Coq mailing list
List archive
- From: "jonikelee AT gmail.com" <jonikelee AT gmail.com>
- To: Jason Gross <jasongross9 AT gmail.com>
- Cc: coq-club AT inria.fr, Tej Chajed <tchajed AT mit.edu>
- Subject: Re: [Coq-Club] help calling ltac1 function from ltac2
- Date: Sun, 16 Aug 2020 15:33:41 -0400
- Authentication-results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=jonikelee AT gmail.com; spf=Pass smtp.mailfrom=jonikelee AT gmail.com; spf=None smtp.helo=postmaster AT mail-qk1-f177.google.com
- Ironport-phdr: 9a23:rJOM/xfdPOM0kHZFrYKX4/cqlGMj4u6mDksu8pMizoh2WeGdxc26ZRON2/xhgRfzUJnB7Loc0qyK6v6mADRZqs/a6DgrS99lb1c9k8IYnggtUoauKHbQC7rUVRE8B9lIT1R//nu2YgB/Ecf6YEDO8DXptWZBUhrwOhBoKevrB4Xck9q41/yo+53Ufg5EmCexbal9IRmrrAjdrNQajZd/Jqo+1xfErGdEcPlKyG11Il6egwzy7dqq8p559CRQtfMh98peXqj/Yq81U79WAik4Pm4s/MHkugXNQgWJ5nsHT2UZiQFIDBTf7BH7RZj+rC33vfdg1SaAPM32Sbc0WSm+76puVRTlhjsLOyI//WrKkcF7kr5Vrwy9qBx+247UYZ+aNPxifqPGYNgWQXNNUttNWyBdB4+xaZYEAegcMuZCt4TzqVsAowWjCwevBuzvxDhGiXDq0qM1yOkhDQPL0RY8E98UrHjYstP4P7oSX+Cvy6nIyC3OY/1U2Tf67ojIcxMhru+IXb1ub8Xc0kYvFwbfgVWRrYzpJS+a1uMIs2SV8uFtUuCvi2khqwFwoTig2MMshZfXiY8OxVDE8D92wIcxJdGiVEF7ZtukHYJWuiqHOIR4XtksTHt0uCYm1LIGo5i7cTAUxJkjwxPSZfyKf5WG7B/+VeucPzh2iXNrdr+wmRq/81atxvHzWMWq0ltHsDdJnsfMu30DyxHd5NSLR/tj8kqh3zuEyg7d6uZBIU8ulKrbLYYswrE1lpUJsETDGjX6l1nxjK+Tbkkk+uip6/z8Yrn8pp+cMIF1hwfjOaotgsyyGfo0PhQKUmSB+umx1Kfv8VPnTLlUlPE6j6vUvZLCKcgFp6O1HxJZ34M+5xu7Ezir1dsVkHgbIF5ZfR+LkpblO1/LLf/iEfiwn0qgnTJlx//dML3hDJDALnbdn7rgYblw7kxRxBQ9wN9F4Z9fF6sPL+jpWkDrsdzVFh85PBKww+bgENh905kRWWOLAqOAKaPSskKE6vshI+WRZoIYuizxK/ci5/7pgn85nUEScbO10psQbXC0BvVmI0OHbnrwmtoND3sGsw4kQOHpiFCOSyBfa2isU64m+z02CoCrAZ/GRo+3gbyB2Cm7HodRZmBDEl2ME3Dod4OFW/cPdi2SJtFunSIfWLiuTo8uzxCutAvgx7V7KerU/zUUtYj/29ht++3TiRYy+CRoAMSaymGBVn17nmcVRzAtx61/ukx8ylKb0adimfBYFNpT5+lIUgggL5LcwfZ6WJjOXVfjd8yOTh6JWNK9GnllTNsqxNkBeUFmAISKgRXK3i7sCLgQwe+lHpsxp+je2H7wJMt5xnvu26wojl1gScxKfyXyhKl59gveA4PEu0qcnqeuM68b2Xiepy+40WOSsRQAA0ZLWqLfUCVaPxOO9Imr1gb5V7arTI8fHE5BxMqFcPUYb9ToiRBfR66mNo2BPCS+nGC/ARvOzbSJPtKzJzctmR7FAU1BqDg9uG6cPFFnVCikqmPaSjdpEAC3OhK+waxFsHq+C3QM4USPZkxl2aCy/0dM1/OZQvIXmLkDvXV4pg==
On Sun, 16 Aug 2020 14:09:38 -0400
Jason Gross <jasongross9 AT gmail.com> wrote:
> > But, why doesn't this work?:
>
> The problem is that you are throwing away the applied tactic without
> running it. You have two options:
> 1. Make your thunk immediate, e.g., by replacing `ltac:(fun i =>
> idtac i)` with `ltac:(fun i => match goal with _ => idtac i end)`
> 2. Run the tactic in the continuation of Ltac1.apply by replacing
> `(fun _ => ())` with `Ltac1.run`
Thanks, Jason. I didn't notice that the lazymatch in Tej's tac_constr
function was serving that purpose as well.
Control.hyp is indeed the ident->constr mechanism needed for this to
work - so no need to gang up on PMP just yet.
The resulting hypotheses iterator also needs a Control.enter to be
fully compatible with the Ltac1 version it replaces. As hoped, it is
significantly faster than any Ltac1-only mechanisms I've tried.
>
> On Sun, Aug 16, 2020 at 2:01 PM jonikelee AT gmail.com
> <jonikelee AT gmail.com> wrote:
>
> > On Sat, 15 Aug 2020 21:39:11 -0500
> > Tej Chajed <tchajed AT mit.edu> wrote:
> >
> > > Here's a solution (perhaps more complicated than you were
> > > expecting):
> >
> > I guess I shouldn't be embarassed that I didn't figure this one out
> > on my own. ;)
> >
> > But, why doesn't this work?:
> >
> > From Ltac2 Require Import Ltac2.
> >
> > Ltac2 hyploop (tac : constr -> unit) :=
> > let hypconstrs := List.map (fun (id, _, _) => Control.hyp id)
> > (Control.hyps ()) in
> > let rec loop hs :=
> > match hs with
> > | h :: hs => tac h; loop hs
> > | _ => ()
> > end in loop hypconstrs.
> >
> > Ltac allhyps_fast tac :=
> > let hyploop' :=
> > ltac2:(t |-
> > let tac2 (i: constr) := Ltac1.apply t [Ltac1.of_constr i]
> > (fun _ => ()) in
> > hyploop tac2) in
> > hyploop' tac.
> >
> > Set Default Proof Mode "Classic".
> >
> > Goal nat -> bool -> nat.
> > Proof.
> > intros x y.
> > allhyps_fast ltac:(fun i => idtac i).
> > Abort.
> >
> > Even staying entirely within Ltac2, if there no way more
> > straightforward than this ident_to_constr kludge cast to get
> > hypotheses as constrs instead of idents, that seems like a
> > significant shortcoming of Ltac2 having nothing to do with the
> > Ltac1/Ltac2 interface.
> >
> >
> > >
> > > Note a significant part of the nastiness comes from not having
> > > Ltac1.of_ident, please complain to Pierre-Marie Pedrot that this
> > > is a useful feature and workarounds for it are horrendous.
> > > Otherwise the complications are somewhat necessary due to a bunch
> > > of higher-order stuff that has to back and forth between the two
> > > languages.
> > >
> > > From Ltac2 Require Import Ltac2.
> > >
> > > Ltac2 hyploop (tac : ident -> unit) :=
> > > let rec loop hs :=
> > > match hs with
> > > | h3 :: hs => match h3 with
> > > | (h, _, _) => tac h; loop hs
> > > end
> > > | _ => ()
> > > end in loop (Control.hyps ()).
> > >
> > > (* ident_to_constr is a helper to serialize an identifier as a
> > > constr of type [unit -> unit], which uses the ident as the binder
> > > *) Ltac2 ident_to_constr (i:ident) :=
> > > constr:(ltac2:(clear; intros $i; exact tt) : unit -> unit).
> > >
> > > Ltac allhyps_fast tac :=
> > > (* tac can't be called from Ltac2 because we can't convert an
> > > ident to an Ltac1 dynamically typed value (the type Ltac1.t in
> > > Ltac2); instead, we will call a variant that expects its argument
> > > as the binder of a constr *) let tac_constr i_constr :=
> > > lazymatch i_constr with
> > > | fun i => _ => tac i
> > > end in
> > > (* at the outermost level, we're constructing hyploop using the
> > > ltac1-to-ltac2 FFI which allows passing an argument so we can pass
> > > tac (as [tac_constr]) to it *)
> > > let hyploop :=
> > > ltac2:(t |- (* t is passed as an Ltac1 opaque object of type
> > > [Ltac1.t]. Remember that it's an Ltac1 tactic that takes a constr
> > > and returns nothing. *)
> > > (* we now convert the ident hyploop will pass us to an
> > > Ltac1 dynamically-typed bundle... *)
> > > let ident_to_arg (i: ident) := Ltac1.of_constr
> > > (ident_to_constr i) in (* And finally construct the higher-order
> > > argument to hyploop using [Ltac1.apply], the most general way to
> > > call an Ltac1 function. The third argument is a CPS tactic to use
> > > the result, but these tactics passed to hyploop (thankfully)
> > > don't return anything. *) let tac (i: ident) := Ltac1.apply t
> > > [ident_to_arg i] (fun _ => ()) in hyploop tac) in
> > > hyploop tac_constr.
> > >
> > > Set Default Proof Mode "Classic".
> > >
> > > Goal nat -> bool -> nat.
> > > Proof.
> > > intros x y.
> > > allhyps_fast ltac:(fun i => let P := type of i in idtac i ":"
> > > P). (* prints x : nat and y : bool, as expected *)
> > > Abort.
> > >
> > > On Sat, Aug 15, 2020 at 8:12 PM jonikelee AT gmail.com
> > > jonikelee AT gmail.com <http://mailto:jonikelee AT gmail.com> wrote:
> > >
> > >
> > > > I have the following Ltac2 function to iterate over hypotheses:
> > > >
> > > > Ltac2 hyploop (tac : ident -> unit) :=
> > > > let rec loop hs :=
> > > > match hs with
> > > > | h3 :: hs => match h3 with
> > > > | (h, _, _) => tac h; loop hs
> > > > end
> > > > | _ => ()
> > > > end in loop (Control.hyps ()).
> > > >
> > > > How do I call hyploop from Ltac1, passing in an Ltac1 function
> > > > for the tac argument?
> > > >
> > > > Ltac allhyps_fast tac :=
> > > > ltac2:(hyploop ltac1:(????)).
> > > >
> > > >
> >
> >
- [Coq-Club] help calling ltac1 function from ltac2, jonikelee AT gmail.com, 08/16/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, Tej Chajed, 08/16/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, Jim Fehrle, 08/16/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, jonikelee AT gmail.com, 08/16/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, Jason Gross, 08/16/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, jonikelee AT gmail.com, 08/16/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, Jim Fehrle, 08/16/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, jonikelee AT gmail.com, 08/17/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, jonikelee AT gmail.com, 08/18/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, Jason Gross, 08/18/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, jonikelee AT gmail.com, 08/18/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, jonikelee AT gmail.com, 08/17/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, Jim Fehrle, 08/16/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, jonikelee AT gmail.com, 08/16/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, Jason Gross, 08/16/2020
- Re: [Coq-Club] help calling ltac1 function from ltac2, Tej Chajed, 08/16/2020
Archive powered by MHonArc 2.6.19+.