@@ -92,7 +92,15 @@ let symb_eval_stateful_app (g: env) (ctxt: slprop) (t: term) : T.Tac R.term =
9292 let rwr = RU. deep_compress rwr in // TODO: maybe this fails on uvars...
9393 rwr
9494
95- let rec symb_eval_subterms ( g : env ) ( ctxt : ctxt ) ( t : R. term ) : T. Tac (bool & R. term ) =
95+ noeq type ctxt' = {
96+ ctxt : ctxt ;
97+ in_old : in_old :bool { in_old ==> Some ? ctxt . ctxt_old };
98+ }
99+
100+ let cur_ctxt c =
101+ if c . in_old then Some ?. v c . ctxt . ctxt_old else c . ctxt . ctxt_now
102+
103+ let rec symb_eval_subterms ( g : env ) ( ctxt : ctxt' ) ( t : R. term ) : T. Tac (bool & R. term ) =
96104 match R. inspect_ln t with
97105 | R. Tv_Abs b body ->
98106 debug g ( fun _ -> [ text " symb eval subterms abs 0" ; pp t ]);
@@ -145,7 +153,7 @@ let rec symb_eval_subterms (g:env) (ctxt: ctxt) (t:R.term) : T.Tac (bool & R.ter
145153 match is_stateful_application g t with
146154 | Some _ ->
147155 let t = RU. mk_app_flat head args ( T. range_of_term t ) in
148- let t' = symb_eval_stateful_app g ctxt . ctxt_now t in
156+ let t' = symb_eval_stateful_app g ( cur_ctxt ctxt ) t in
149157 true , t'
150158 | None ->
151159 if changed then
@@ -159,28 +167,23 @@ let rec symb_eval_subterms (g:env) (ctxt: ctxt) (t:R.term) : T.Tac (bool & R.ter
159167 | R. Tv_FVar fv , [ t , _ ] ->
160168 if R. inspect_fv fv = old_lid then
161169 // let t = RU.mk_app_flat head args (T.range_of_term t) in
162- match is_stateful_application g t , ctxt . ctxt_old with
163- | _ , None ->
170+ if not ( Some ? ctxt . ctxt . ctxt_old ) then
164171 T. fail_doc_at [
165172 text " 'old' can only be used in postconditions" ;
166173 ] r
167- | None , _ ->
168- T. fail_doc_at [
169- text " 'old' needs to be applied to a stateful computation, not:" ;
170- pp t ;
171- ] r
172- | Some _ , Some ctxt_old ->
173- let head , args = T. collect_app_ln t in
174- let g , changed , args = symb_eval_subterms_args g ctxt args in
175- let t = RU. mk_app_flat head args ( T. range_of_term t ) in
176- let t' = symb_eval_stateful_app g ctxt_old t in
177- true , t'
174+ else (
175+ ( if ctxt . in_old then
176+ warn_doc g r [
177+ text " 'old' only needs to be specified once" ;
178+ ]);
179+ symb_eval_subterms g { ctxt with in_old = true } t
180+ )
178181 else
179182 fallback ()
180183 | _ ->
181184 fallback ()
182185
183- and symb_eval_subterms_args ( g : env ) ( ctxt : ctxt ) ( args : list T. argv )
186+ and symb_eval_subterms_args ( g : env ) ( ctxt : ctxt' ) ( args : list T. argv )
184187: T. Tac ( env & bool & list T. argv )
185188= T. fold_right
186189 ( fun ( arg , q ) ( g , changed , args ) ->
@@ -219,7 +222,8 @@ let run_elim (g: env) (ctxt: slprop) : T.Tac (env & list nvar & slprop) =
219222 g' , xs , list_as_slprop ctxt
220223
221224(* Adds add to the ctxt in a way that the prover will prefer it when ambiguous. *)
222- let push_ctxt ctxt add = { ctxt with ctxt_now = tm_star add ctxt . ctxt_now }
225+ let push_ctxt ( ctxt : ctxt' ) add =
226+ { ctxt with ctxt = { ctxt . ctxt with ctxt_now = tm_star add ctxt . ctxt . ctxt_now } }
223227
224228let un_uinst ( t : term ) : R. term_view =
225229 match R. inspect_ln t with
@@ -282,7 +286,7 @@ let tc_term_phase1_with_type_twice g t ty =
282286let or_emp ( t : option slprop ) : slprop =
283287 match t with Some t -> t | None -> tm_emp
284288
285- let rec purify_spec_core ( g : env ) ( ctxt : ctxt ) ( ts : list slprop ) : T. Tac ( option slprop ) =
289+ let rec purify_spec_core ( g : env ) ( ctxt : ctxt' ) ( ts : list slprop ) : T. Tac ( option slprop ) =
286290 match ts with
287291 | [] -> None
288292 | t :: ts ->
@@ -336,7 +340,7 @@ let rec purify_spec_core (g: env) (ctxt: ctxt) (ts: list slprop) : T.Tac (option
336340 let t = T. norm_term_env ( elab_env g ) steps t in
337341 extrude g ctxt [ t ] ts
338342
339- and extrude ( g : env ) ( ctxt : ctxt ) ( todo : list slprop ) ( ts : list slprop ) : T. Tac ( option slprop ) =
343+ and extrude ( g : env ) ( ctxt : ctxt' ) ( todo : list slprop ) ( ts : list slprop ) : T. Tac ( option slprop ) =
340344 match todo with
341345 | [] -> purify_spec_core g ctxt ts
342346 | t :: todo ->
@@ -386,12 +390,14 @@ let run_elim_ctxt (g: env) (ctxt: ctxt) =
386390
387391let purify_term ( g : env ) ( ctxt : ctxt ) ( t : term ) : T. Tac term =
388392 let g' , xs , ctxt = run_elim_ctxt g ctxt in
393+ let ctxt = { ctxt ; in_old = false } in
389394 let _ , t = symb_eval_subterms g ctxt t in
390395 t
391396
392397let purify_spec ( g : env ) ( ctxt : ctxt ) ( t0 : slprop ) : T. Tac slprop =
393398 let t = t0 in
394399 let g' , xs , ctxt = run_elim_ctxt g ctxt in
400+ let ctxt = { ctxt ; in_old = false } in
395401 let t = purify_spec_core g' ctxt [ t ] |> or_emp in
396402 // TODO: check that xs is not free in t
397403 // If we call phase1 TC only once, then the universe instantiation in
0 commit comments