Skip to content

Commit 2ee3660

Browse files
authored
Adapt to rocq-prover/rocq#20566 (Ltac2 rec doesn't produce a wrapper lambda) (#30)
Fix #29
2 parents 2428c8e + 653b621 commit 2ee3660

File tree

7 files changed

+68
-47
lines changed

7 files changed

+68
-47
lines changed

src/tac2compile.ml

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ type nontac_expr =
259259
| PrjV of nontac_expr * int (* non-mutable projection *)
260260
| Prim of ml_tactic_name
261261
| ValLetNoRec of (Name.t * nontac_expr) list * nontac_expr
262+
| ValLetRec of (Id.t * (Name.t list * tac_expr)) list * nontac_expr
262263

263264
(** evaluates to a valexpr tactic *)
264265
and tac_expr_head =
@@ -450,11 +451,11 @@ let rec is_nontac = function
450451
| GTacPrj (typ, sube, i) ->
451452
not (is_mutable_proj typ i) && is_nontac sube
452453

453-
| GTacLet (false, bnd, e) ->
454+
| GTacLet (_, bnd, e) ->
454455
List.for_all (fun (_, e) -> is_nontac e) bnd
455456
&& is_nontac e
456457

457-
| GTacApp _ | GTacLet (true, _, _) | GTacCse _
458+
| GTacApp _ | GTacCse _
458459
| GTacSet _ | GTacWth _ | GTacFullMatch _
459460
| GTacExt _
460461
-> false
@@ -495,6 +496,12 @@ let rec nontac_expr env ((cnt, nonvals) as acc) e = match e with
495496
acc, Ref (LocalKn ("Tac2compiledPrim."^ml.mltac_tactic, info))
496497
end
497498

499+
| GTacLet (true, bnd, sube) when is_nontac e ->
500+
let envbnd, lets = letrec_bnd env bnd in
501+
let acc', sube = nontac_expr envbnd acc sube in
502+
assert (acc' == acc);
503+
acc, ValLetRec (lets, sube)
504+
498505
| GTacLet (false, bnd, sube) when is_nontac e ->
499506
let envbnd, nas' = push_env push_user_names (List.map fst bnd) Valexpr env in
500507
let bnd = List.map2 (fun (_, e) na' ->
@@ -544,36 +551,16 @@ and tac_expr env e =
544551
let acc, args = List.fold_left_map (nontac_expr env) acc args in
545552
acc, App (h, args)
546553

547-
| GTacLet (true, lets, e) ->
548-
let lets = lets |> List.filter_map (fun (na, e) ->
549-
match e with
550-
| GTacFun (bnd, e) ->
551-
begin match na with
552-
| Anonymous ->
553-
(* "let rec _ := ..." seems good for nothing, just a syntax curiosity
554-
lambda abstraction can't have effects so just drop it *)
555-
None
556-
| Name na ->
557-
Some (na, (bnd, e))
558-
end
559-
| _ -> assert false)
560-
in
561-
let env, nas' =
562-
List.fold_left_map (fun env (na, (bnd, _)) ->
563-
push_env push_user_id na (Function {arity=List.length bnd}) env)
564-
env lets
565-
in
566-
let lets = List.map2 (fun (_, (bnd, e)) na' ->
567-
let env, bnd = push_env push_user_names bnd Valexpr env in
568-
let e = tac_expr env e in
569-
(na', (bnd, e)))
570-
lets
571-
nas'
572-
in
573-
let e = tac_expr env e in
574-
acc, LetRec (lets, e)
554+
| GTacLet (true, lets, sube) ->
555+
if is_nontac e then
556+
let acc', e = nontac_expr env acc e in
557+
assert (acc == acc');
558+
acc, Return e
559+
else
560+
let env, lets = letrec_bnd env lets in
561+
let sube = tac_expr env sube in
562+
acc, LetRec (lets, sube)
575563

576-
(* XXX detect when a let can be nontac_expr *)
577564
| GTacLet (false, bnd, sube) ->
578565
if is_nontac e then
579566
let acc', e = nontac_expr env acc e in
@@ -650,6 +637,34 @@ and tac_expr env e =
650637
{ spilled_exprs = nonvals;
651638
head_expr = e; }
652639

640+
and letrec_bnd env lets =
641+
let lets = lets |> List.filter_map (fun (na, e) ->
642+
match e with
643+
| GTacFun (bnd, e) ->
644+
begin match na with
645+
| Anonymous ->
646+
(* "let rec _ := ..." seems good for nothing, just a syntax curiosity
647+
lambda abstraction can't have effects so just drop it *)
648+
None
649+
| Name na ->
650+
Some (na, (bnd, e))
651+
end
652+
| _ -> assert false)
653+
in
654+
let env, nas' =
655+
List.fold_left_map (fun env (na, (bnd, _)) ->
656+
push_env push_user_id na (Function {arity=List.length bnd}) env)
657+
env lets
658+
in
659+
let lets = List.map2 (fun (_, (bnd, e)) na' ->
660+
let env, bnd = push_env push_user_names bnd Valexpr env in
661+
let e = tac_expr env e in
662+
(na', (bnd, e)))
663+
lets
664+
nas'
665+
in
666+
env, lets
667+
653668
let nontac_expr env state acc e =
654669
let state = ref state in
655670
let acc, e = nontac_expr {env;state} acc e in
@@ -799,7 +814,16 @@ let rec pp_nontac_expr = function
799814
str "in" ++ spc() ++
800815
pp_nontac_expr e ++
801816
str ")")
802-
817+
| ValLetRec (lets, e) ->
818+
let pr_one_let (na, (bnd, e)) =
819+
hov 1 (Id.print na ++ pp_binders bnd ++ str " =") ++ spc () ++
820+
pp_expr e ++ spc()
821+
in
822+
surround
823+
(hv 0
824+
(str "let rec " ++ prlist_with_sep (fun () -> str "and ") pr_one_let lets ++
825+
str "in" ++ spc()) ++
826+
pp_nontac_expr e)
803827

804828
(* produce a ocaml term of type valexpr tactic *)
805829
and pp_expr e =

src/tac2compiledPrim.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ open Proofview.Notations
1616

1717
let core_prefix path n = KerName.make path (Label.of_id (Id.of_string_soft n))
1818

19-
let coq_core n = core_prefix Tac2env.coq_prefix n
19+
let coq_core n = core_prefix Tac2env.rocq_prefix n
2020

2121
let err_outofbounds =
2222
Tac2interp.LtacError (coq_core "Out_of_bounds", [||])

tests/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ submake: Makefile.coq
55
$(MAKE) $(MAKE_OPTS) -f Makefile.coq $(MAKECMDGOALS)
66

77
Makefile.coq: _CoqProject
8-
$(COQBIN)coq_makefile -f $< -o $@
8+
$(COQBIN)coq_makefile -f $< -o $@ $(wildcard *.v)
99

1010
%:: submake ;
1111

tests/_CoqProject

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,6 @@
33

44
-R . Test
55

6-
tac2compile_test.v
7-
bug_10107.v
8-
minibench.v
9-
compiler_bug_4.v
10-
compiler_bug_6.v
11-
compiler_bug_14.v
12-
compiler_bug_16.v
13-
compiler_bug_17.v
14-
compiler_bug_24.v
15-
166
-I src
177

188
src/META.compiler-bugs

tests/bug_10107.v

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Ltac2 rec iter tac ls :=
1717

1818
Ltac2 rec find (id : ident) (term : constr) :=
1919
match Constr.Unsafe.kind term with
20-
| Constr.Unsafe.Cast c cst ty => find id c; find id ty
20+
| Constr.Unsafe.Cast c _cst ty => find id c; find id ty
2121
| Constr.Unsafe.App f xs => find id f; Array.iter (find id) xs
2222
| _ => ()
2323
end.
@@ -32,6 +32,6 @@ Goal True.
3232
do 5 pose c).
3333
Time let v := Control.hyps () in
3434
let i := @x in
35-
iter (fun (h, body, ty) => find i ty; match body with Some b => find i b | None => () end) v.
35+
iter (fun (_h, body, ty) => find i ty; match body with Some b => find i b | None => () end) v.
3636
(* Finished transaction in 0.75 secs *)
3737
Abort.

tests/compiler_bug_29.v

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Require Import Ltac2.Ltac2.
2+
Require Import Ltac2Compiler.Ltac2Compiler.
3+
4+
Ltac2 foo := let rec foo () := foo () in foo.
5+
6+
Ltac2 Compile foo.
7+
(* Error: Anomaly "File "src/tac2compile.ml", line 662, characters 2-8: Assertion failed." *)

tests/tac2compile_test.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ Module MatchGoal.
189189

190190
Ltac2 check () :=
191191
lazy_match! goal with
192-
| [ h1 : context c1 [ ?t1 ] , h2 := context c2 [ Nat.add ?v2 ] , h3 : context c3 [ ?t2 ] |- _ ] =>
192+
| [ _h1 : context c1 [ ?t1 ] , _h2 := context c2 [ Nat.add ?v2 ] , _h3 : context c3 [ ?t2 ] |- _ ] =>
193193
check_constr t1 'bool;
194194
check_constr v2 '0;
195195
check_constr t2 'bool;

0 commit comments

Comments
 (0)