Skip to content

Commit c71ef7b

Browse files
committed
when renaming, give precedence to recent context entries over old ones
1 parent 35b0393 commit c71ef7b

File tree

2 files changed

+52
-23
lines changed

2 files changed

+52
-23
lines changed

src/coq_elpi_HOAS.ml

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ let in_coq_fresh ~id_only =
399399
let mk_fresh dbl =
400400
Id.of_string_soft
401401
(Printf.sprintf "elpi_ctx_entry_%d_" dbl) in
402-
fun ~depth dbl name ~coq_ctx:{names}->
402+
fun ~depth dbl name ~names ->
403403
match in_coq_name ~depth name with
404404
| Name.Anonymous when id_only -> Name.Name (mk_fresh dbl)
405405
| Name.Anonymous as x -> x
@@ -409,11 +409,11 @@ fun ~depth dbl name ~coq_ctx:{names}->
409409
let in_coq_annot ~depth t = Context.make_annot (in_coq_name ~depth t) Sorts.Relevant
410410

411411
let in_coq_fresh_annot_name ~depth ~coq_ctx dbl t =
412-
Context.make_annot (in_coq_fresh ~id_only:false ~depth ~coq_ctx dbl t) Sorts.Relevant
412+
Context.make_annot (in_coq_fresh ~id_only:false ~depth ~names:coq_ctx.names dbl t) Sorts.Relevant
413413

414-
let in_coq_fresh_annot_id ~depth ~coq_ctx dbl t =
414+
let in_coq_fresh_annot_id ~depth ~names dbl t =
415415
let get_name = function Name.Name x -> x | Name.Anonymous -> assert false in
416-
Context.make_annot (in_coq_fresh ~id_only:true ~depth ~coq_ctx dbl t |> get_name) Sorts.Relevant
416+
Context.make_annot (in_coq_fresh ~id_only:true ~depth ~names dbl t |> get_name) Sorts.Relevant
417417

418418
let unspec2opt = function Elpi.Builtin.Given x -> Some x | Elpi.Builtin.Unspec -> None
419419
let opt2unspec = function Some x -> Elpi.Builtin.Given x | None -> Elpi.Builtin.Unspec
@@ -1716,40 +1716,53 @@ let is_global_or_pglobal ~depth t =
17161716
let rec of_elpi_ctx ~calldepth syntactic_constraints depth dbl2ctx state initial_coq_ctx =
17171717

17181718
let aux coq_ctx depth state t =
1719-
lp2constr ~calldepth syntactic_constraints coq_ctx ~depth state t in
1720-
1721-
let of_elpi_ctx_entry dbl coq_ctx ~depth e state =
1719+
lp2constr ~calldepth syntactic_constraints coq_ctx ~depth state t
1720+
in
1721+
let of_elpi_ctx_entry id dbl coq_ctx ~depth e state =
17221722
match e with
1723-
| `Decl(name,ty) ->
1724-
debug Pp.(fun () -> str "decl name: " ++ str(pp2string (P.term depth) name));
1723+
| `Decl(name_hint,ty) ->
1724+
debug Pp.(fun () -> str "decl name (hint/actual): " ++ str(pp2string (P.term depth) name_hint) ++ spc () ++ Id.print (Context.binder_name id));
17251725
debug Pp.(fun () -> str "decl ty: " ++ str(pp2string (P.term depth) ty));
1726-
let id = in_coq_fresh_annot_id ~depth ~coq_ctx dbl name in
17271726
let state, ty, gls = aux coq_ctx depth state ty in
17281727
state, Context.Named.Declaration.LocalAssum(id,ty), gls
1729-
| `Def(name,ty,bo) ->
1730-
debug Pp.(fun () -> str "def name: " ++ str(pp2string (P.term depth) name));
1728+
| `Def(name_hint,ty,bo) ->
1729+
debug Pp.(fun () -> str "def name (hint/actual): " ++ str(pp2string (P.term depth) name_hint) ++ spc () ++ Id.print (Context.binder_name id));
17311730
debug Pp.(fun () -> str "def ty: " ++ str(pp2string (P.term depth) ty));
17321731
debug Pp.(fun () -> str "def bo: " ++ str(pp2string (P.term depth) bo));
1733-
let id = in_coq_fresh_annot_id ~depth ~coq_ctx dbl name in
17341732
let state, ty, gl1 = aux coq_ctx depth state ty in
17351733
let state, bo, gl2 = aux coq_ctx depth state bo in
17361734
state, Context.Named.Declaration.LocalDef(id,bo,ty), gl1 @ gl2
17371735
in
1738-
1739-
let rec ctx_entries coq_ctx state gls i =
1740-
if i = depth then state, coq_ctx, List.(concat (rev gls))
1736+
let of_elpi_ctx_entry_name dbl names ~depth e =
1737+
match e with
1738+
| `Decl(name_hint,_) -> in_coq_fresh_annot_id ~depth ~names dbl name_hint
1739+
| `Def(name_hint,_,_) -> in_coq_fresh_annot_id ~depth ~names dbl name_hint
1740+
in
1741+
let rec build_ctx_entry coq_ctx state gls = function
1742+
| [] -> state, coq_ctx, List.(concat (rev gls))
1743+
| (i,id,d,e) :: rest ->
1744+
debug Pp.(fun () -> str "<<< context entry for DBL "++ int i ++ str" at depth" ++ int d);
1745+
let state, e, gl1 = of_elpi_ctx_entry id i coq_ctx ~depth:d e state in
1746+
debug Pp.(fun () -> str "<<< context entry for DBL "++ int i ++ str" at depth" ++ int d);
1747+
let coq_ctx = push_coq_ctx_proof i e coq_ctx in
1748+
build_ctx_entry coq_ctx state (gl1 :: gls) rest
1749+
in
1750+
(* we go from the bottom (most recent addition) to the top in order to
1751+
give precedence to the name recently introduced *)
1752+
let rec ctx_entries_names names i =
1753+
if i < 0 then []
17411754
else (* context entry for the i-th variable *)
17421755
if not (Int.Map.mem i dbl2ctx)
1743-
then ctx_entries coq_ctx state gls (i+1)
1756+
then ctx_entries_names names (i - 1)
17441757
else
17451758
let d, e = Int.Map.find i dbl2ctx in
1746-
debug Pp.(fun () -> str "<<< context entry for DBL "++ int i ++ str" at depth" ++ int d);
1747-
let state, e, gl1 = of_elpi_ctx_entry i coq_ctx ~depth:d e state in
1748-
debug Pp.(fun () -> str "context entry >>>");
1749-
let coq_ctx = push_coq_ctx_proof i e coq_ctx in
1750-
ctx_entries coq_ctx state (gl1 :: gls) (i+1)
1759+
let id = of_elpi_ctx_entry_name i names ~depth:d e in
1760+
let names = Id.Set.add (Context.binder_name id) names in
1761+
(i,id,d,e) :: ctx_entries_names names (i - 1)
17511762
in
1752-
ctx_entries initial_coq_ctx state [] 0
1763+
ctx_entries_names Id.Set.empty (depth-1) |>
1764+
List.rev |> (* we need to readback the context from top to bottom *)
1765+
build_ctx_entry initial_coq_ctx state []
17531766

17541767
(* ***************************************************************** *)
17551768
(* <-- depth --> *)

tests/test_tactic.v

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
From elpi Require Import elpi.
22

3+
Elpi Tactic double_open.
4+
Elpi Accumulate lp:{{
5+
solve (goal _Ctx _Trigger Type _Proof [] as G) GL :-
6+
@no-tc! => refine {{ id _ }} G [G2],
7+
coq.ltac.open (refine {{ id _ }}) G2 GL,
8+
coq.say G2.
9+
}}.
10+
Elpi Typecheck.
11+
12+
Lemma foo (P : Prop) :
13+
P -> P.
14+
Proof.
15+
elpi double_open.
16+
match goal with |- P -> P => idtac end. (* no renaming *)
17+
Abort.
18+
319
Elpi Command foo.
420
Elpi Print foo.
521
Elpi Tactic foobar.

0 commit comments

Comments
 (0)