Skip to content

Commit 8bf255f

Browse files
authored
Merge pull request #482 from FStarLang/gebner_purify_rw
Support purification inside rewrite and unfold.
2 parents 647594b + ae50550 commit 8bf255f

12 files changed

+56
-12
lines changed

src/checker/Pulse.Checker.AssertWithBinders.fst

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module Pulse.Checker.AssertWithBinders
1919
open Pulse.Syntax
2020
open Pulse.Typing
2121
open Pulse.Checker.Base
22+
open Pulse.Checker.ImpureSpec
2223
open Pulse.Elaborate.Pure
2324
open Pulse.Typing.Env
2425

@@ -263,7 +264,7 @@ let rec as_subst (p : list (term & term))
263264

264265

265266

266-
let rewrite_all (is_source:bool) (g:env) (p: list (term & term)) (t:term) tac_opt : T.Tac (term & term) =
267+
let rewrite_all (is_source:bool) (g:env) (p: list (term & term)) (t:term) pre elaborated tac_opt : T.Tac (term & term) =
267268
(* We only use the rewrites_to substitution if there is no tactic attached to the
268269
rewrite. Otherwise, tactics may become brittle as the goal is changed unexpectedly
269270
by other things in the context. See tests/Match.fst. *)
@@ -274,7 +275,10 @@ let rewrite_all (is_source:bool) (g:env) (p: list (term & term)) (t:term) tac_op
274275
let t = dfst <| Pulse.Checker.Prover.normalize_slprop g t use_rwr in
275276
t
276277
in
278+
let maybe_purify t = if elaborated then t else purify_term g {ctxt_now=pre;ctxt_old=None} t in
277279
let elab_pair (lhs rhs : R.term) : T.Tac (R.term & R.term) =
280+
let lhs = maybe_purify lhs in
281+
let rhs = maybe_purify rhs in
278282
let lhs, lhs_typ = Pulse.Checker.Pure.instantiate_term_implicits g lhs None true in
279283
let rhs, rhs_typ = Pulse.Checker.Pure.instantiate_term_implicits g rhs (Some lhs_typ) true in
280284
let lhs = norm lhs in
@@ -303,7 +307,7 @@ let check_renaming
303307
})
304308
: T.Tac st_term
305309
= let Tm_ProofHintWithBinders ht = st.term in
306-
let { hint_type=RENAME { pairs; goal; tac_opt }; binders=bs; t=body } = ht in
310+
let { hint_type=RENAME { pairs; goal; tac_opt; elaborated }; binders=bs; t=body } = ht in
307311
match bs, goal with
308312
| _::_, None ->
309313
//if there are binders, we must have a goal
@@ -323,7 +327,7 @@ let check_renaming
323327

324328
| [], None ->
325329
// if there is no goal, take the goal to be the full current pre
326-
let lhs, rhs = rewrite_all (T.unseal st.source) g pairs pre tac_opt in
330+
let lhs, rhs = rewrite_all (T.unseal st.source) g pairs pre pre elaborated tac_opt in
327331
let t = { st with term = Tm_Rewrite { t1 = lhs; t2 = rhs; tac_opt; elaborated = true };
328332
source = Sealed.seal false; } in
329333
{ st with
@@ -333,7 +337,7 @@ let check_renaming
333337

334338
| [], Some goal -> (
335339
let goal, _ = PC.instantiate_term_implicits g goal None false in
336-
let lhs, rhs = rewrite_all (T.unseal st.source) g pairs goal tac_opt in
340+
let lhs, rhs = rewrite_all (T.unseal st.source) g pairs goal pre elaborated tac_opt in
337341
let t = { st with term = Tm_Rewrite { t1 = lhs; t2 = rhs; tac_opt; elaborated = true };
338342
source = Sealed.seal false; } in
339343
{ st with term = Tm_Bind { binder = as_binder tm_unit; head = t; body };
@@ -486,6 +490,7 @@ let check
486490

487491
check_unfoldable g v;
488492

493+
let v_opened = purify_term g { ctxt_now = pre; ctxt_old = None } v_opened in
489494
let v_opened, t_rem = PC.instantiate_term_implicits (push_env g uvs) v_opened None false in
490495

491496
let uvs, v_opened =

src/checker/Pulse.Checker.If.fst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ let check
7777
let t =
7878
mk_term (Tm_ProofHintWithBinders {
7979
binders = [];
80-
hint_type = RENAME { pairs = [(b, eq_v)]; goal=None; tac_opt=None; };
80+
hint_type = RENAME { pairs = [(b, eq_v)]; goal=None; tac_opt=None; elaborated=true };
8181
t = br;
8282
}) br.range
8383
in

src/checker/Pulse.Checker.ImpureSpec.fst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ open Pulse.Readback
3030
open Pulse.Syntax.Naming
3131
open Pulse.Reflection.Util
3232
open Pulse.PP
33-
open Pulse.Checker.Prover.Substs
3433
open Pulse.Show
3534

3635
let old_lid = Pulse.Reflection.Util.mk_pulse_lib_core_lid "old"
@@ -433,6 +432,11 @@ let run_elim_ctxt (g: env) (ctxt: ctxt) =
433432
g, ys, Some old in
434433
g, xs @ ys, { ctxt_old = old; ctxt_now = now }
435434

435+
let purify_term (g: env) (ctxt: ctxt) (t: term) : T.Tac term =
436+
let g', xs, ctxt = run_elim_ctxt g ctxt in
437+
let _, t = symb_eval_subterms g ctxt t in
438+
t
439+
436440
let purify_spec (g: env) (ctxt: ctxt) (t0: slprop) : T.Tac slprop =
437441
let t = t0 in
438442
let g', xs, ctxt = run_elim_ctxt g ctxt in

src/checker/Pulse.Checker.ImpureSpec.fsti

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ noeq type ctxt = {
2525
ctxt_old: option slprop;
2626
}
2727

28+
val purify_term (g: env) (ctxt: ctxt) (t: term) : T.Tac term
29+
2830
val purify_spec (g: env) (ctxt: ctxt) (t: slprop) :
2931
T.Tac slprop
3032

src/checker/Pulse.Checker.Match.fst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,8 @@ let check_branch
286286
binders = [];
287287
hint_type = RENAME { pairs = [(sc, elab_p_tm)];
288288
goal = None;
289-
tac_opt = Some Pulse.Reflection.Util.match_rewrite_tac_tm; };
289+
tac_opt = Some Pulse.Reflection.Util.match_rewrite_tac_tm;
290+
elaborated = true };
290291
t = e; })
291292
e.range
292293
in

src/checker/Pulse.Checker.Rewrite.fst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ open Pulse.Typing
2121
open Pulse.Checker.Pure
2222
open Pulse.Checker.Base
2323
open Pulse.Checker.Prover
24+
open Pulse.Checker.ImpureSpec
2425
open Pulse.PP
2526
module T = FStar.Tactics.V2
2627
module R = FStar.Reflection.V2
@@ -118,6 +119,12 @@ let check
118119

119120
let g = push_context "check_rewrite" t.range g in
120121
let Tm_Rewrite {t1=p; t2=q; tac_opt; elaborated} = t.term in
122+
let p, q =
123+
if elaborated then
124+
p, q
125+
else
126+
let ctxt = { ctxt_now = pre; ctxt_old = None } in
127+
purify_term g ctxt p, purify_term g ctxt q in
121128
let (| p, p_typing |), (| q, q_typing |) =
122129
check_slprop g p, check_slprop g q in
123130

src/checker/Pulse.Syntax.Base.fst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,11 @@ let eq_hint_type (ht1 ht2:proof_hint_type)
150150
| UNFOLD { names=ns1; p=p1}, UNFOLD { names=ns2; p=p2 } ->
151151
eq_opt (eq_list (fun n1 n2 -> n1 = n2)) ns1 ns2 &&
152152
eq_tm p1 p2
153-
| RENAME { pairs=ps1; goal=p1; tac_opt=t1 }, RENAME { pairs=ps2; goal=p2; tac_opt=t2 } ->
153+
| RENAME { pairs=ps1; goal=p1; tac_opt=t1; elaborated=e1 }, RENAME { pairs=ps2; goal=p2; tac_opt=t2; elaborated=e2 } ->
154154
eq_list (fun (x1, y1) (x2, y2) -> eq_tm x1 x2 && eq_tm y1 y2) ps1 ps2 &&
155155
eq_opt eq_tm p1 p2 &&
156-
eq_tm_opt t1 t2
156+
eq_tm_opt t1 t2 &&
157+
e1 = e2
157158
| REWRITE { t1; t2; tac_opt; elaborated=e1 }, REWRITE { t1=s1; t2=s2; tac_opt=tac_opt2; elaborated=e2 } ->
158159
eq_tm t1 s1 &&
159160
eq_tm t2 s2 &&

src/checker/Pulse.Syntax.Base.fsti

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ type proof_hint_type =
179179
pairs:list (term & term);
180180
goal: option term;
181181
tac_opt : option term; (* optional tactic *)
182+
elaborated: bool; (* internally created by the checker, don't purify *)
182183
}
183184
| REWRITE {
184185
t1:slprop;

src/checker/Pulse.Syntax.Builder.fst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ let tm_assert_with_binders bs p t = Tm_ProofHintWithBinders { hint_type=ASSERT {
6060
let mk_assert_hint_type p = ASSERT { p; elaborated=false }
6161
let mk_unfold_hint_type names p = UNFOLD { names; p }
6262
let mk_fold_hint_type names p = FOLD { names; p }
63-
let mk_rename_hint_type pairs goal tac_opt = RENAME { pairs; goal; tac_opt=map_opt tac_opt thunk }
63+
let mk_rename_hint_type pairs goal tac_opt = RENAME { pairs; goal; tac_opt=map_opt tac_opt thunk; elaborated=false }
6464
let mk_rewrite_hint_type t1 t2 tac_opt = REWRITE { t1; t2; tac_opt=map_opt tac_opt thunk; elaborated=false }
6565
let mk_fn_defn id isrec us bs comp meas body : decl' = FnDefn { id; isrec; us; bs; comp; meas; body }
6666
let mk_fn_decl id us bs comp : decl' = FnDecl { id; us; bs; comp; }

src/checker/Pulse.Syntax.Naming.fsti

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,10 +470,11 @@ let subst_proof_hint (ht:proof_hint_type) (ss:subst)
470470
| ASSERT { p; elaborated } -> ASSERT { p=subst_term p ss; elaborated }
471471
| UNFOLD { names; p } -> UNFOLD {names; p=subst_term p ss}
472472
| FOLD { names; p } -> FOLD { names; p=subst_term p ss }
473-
| RENAME { pairs; goal; tac_opt } ->
473+
| RENAME { pairs; goal; tac_opt; elaborated } ->
474474
RENAME { pairs=subst_term_pairs pairs ss;
475475
goal=subst_term_opt goal ss;
476476
tac_opt=subst_term_opt tac_opt ss;
477+
elaborated;
477478
}
478479
| REWRITE { t1; t2; tac_opt; elaborated } ->
479480
REWRITE { t1=subst_term t1 ss;

0 commit comments

Comments
 (0)