coq-club AT inria.fr
Subject: The Coq mailing list
List archive
- From: "jonikelee AT gmail.com" <jonikelee AT gmail.com>
- To: Tej Chajed <tchajed AT mit.edu>
- Cc: coq-club AT inria.fr
- Subject: Re: [Coq-Club] help calling ltac1 function from ltac2
- Date: Sun, 16 Aug 2020 14:00:19 -0400
- Authentication-results: mail2-smtp-roc.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:ZoURbxMJN9h5e/1a1P8l6mtUPXoX/o7sNwtQ0KIMzox0K/z6p8bcNUDSrc9gkEXOFd2Cra4d1ayP6/mrADVRqb+681k6OKRWUBEEjchE1ycBO+WiTXPBEfjxciYhF95DXlI2t1uyMExSBdqsLwaK+i764jEdAAjwOhRoLerpBIHSk9631+ev8JHPfglEnjWwba5zIRmssAndqtQajYR/JqoszhbCv2dFdflRyW50P1yYggzy5t23/J5t8iRQv+wu+stdWqjkfKo2UKJVAi0+P286+MPkux/DTRCS5nQHSWUZjgBIAwne4x7kWJr6rzb3ufB82CmeOs32UKw0VDG/5KplVBPklCEKPCMi/WrJlsJ/kr5UoBO5pxx+3YHUZp2VNOFjda/ZZN8WWHZNUtpUWyFHH4iybZYAD/AZMOhWr4fzuUYAoxi8CgmiA+3gxSNHiHDt0K0myuQsCx3K0RY8E94QtnnfsdX7NL0VUeCw1KTEwzfDb/RQ2Tf864jHbBQhru+SUr9rfsrRzFMgFwLBjlmKtYPlODaV2uoQuGWc7epgUuSvi28kqw5vpjig2Nkjh5LGhoIQ0F/E9CF5zJwpKt2/TU52eNipG4ZfuC+GLYV5WN8iQ312tyYgzL0LoYK3cDQOxZg5xxDSdeGKfpSU7h79SOudPCp1inJkdb+/mRq/8Uatx/DzWMSq0VtGsihInsXQunwQ2BLe5cuKRPR780y81ziP0AXT5ftFIUAyjafbJJshzaQxlpoXq0jMAij2mEDugK+WdkQk4vOo5/7nYrXhqJ6RMZJ/hALmMqk2hMCzHeA1PhINUmWb4+iwyqPv8VPjTLlXjPA7kLHVvI7bKMgHu6K0BhJZ34I/5Bu6ADqr0cgUkWUCIV5YZh6HgY3kNEvSL//kE/uyhlqsnyxlx/DIO7DhDIvCI3nfn7rkf7tx9UBRxxA1wNtC/ZxbEKsBL+j2WkLptNzXEBs5MwuszubiEtp914ceVXuWAq+aLa/eqFGI6v8tLuSOfoMVtzH9K/8q5/7qk3A1g0MSfa6s3ZcPaXC4GOppI1mBbHbyntsMFX0Gswk+QeDwllGOTyBfa2yvU68+5Dw3EIemAp3CRoCpjryBxiC7HphOa2BEDVCMF3bod4aaVPcIdi2dPNRskjMBVbe7So8h0QuiuxP9y7piNubU4DEXtYr/1Nhp4O3ejQ099TttD8iEz26NS3x0kXgTSj8t3KF/pFR9xU2Z3ah5hfxYD91T6OlTXgc0L56Ph9B9Xuz/WErqft6LRVruFsmtATgzQ94Zxt4SJUtxBoPxoArE2n/gAbgTlr+GAJE52q3Z1nn1Yc16zjyOgKsmiVglT89COEWpg6d+807YAIufwBbRrLqjaalJhH2Fz2yE12fb+RgACFcsA5WAZmgWYw7tlfq8/lnLFub8BrEuMw8HwsmHePMTO4/ZyG5eTfKmA+zwJme4mmO+HxGNn+reY4/jemFb1yLYWhFdzlIjuE2ePA17PR+P5mLTCDs0SwDqakLotPB98Ta1FxBriQ6NaEJl2vy+/RtH3fE=
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+.