Skip to content

Commit 97cc965

Browse files
Gustavo2622strub
authored andcommitted
proc change: support binding fresh local variables
Allow `proc change` to introduce new local memory variables via an optional `[x : ty, ...]` annotation. The replacement statement can then reference these freshly bound variables.
1 parent 7d9a0f5 commit 97cc965

8 files changed

Lines changed: 58 additions & 19 deletions

File tree

src/ecHiTacticals.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ and process1_phl (_ : ttenv) (t : phltactic located) (tc : tcenv1) =
231231
| Prepl_stmt infos -> EcPhlTrans.process_equiv_trans infos
232232
| Pprocrewrite (s, p, f) -> EcPhlRewrite.process_rewrite s p f
233233
| Pprocrewriteat (x, f) -> EcPhlRewrite.process_rewrite_at x f
234-
| Pchangestmt (s, p, c) -> EcPhlRewrite.process_change_stmt s p c
234+
| Pchangestmt (s, b, p, c) -> EcPhlRewrite.process_change_stmt s b p c
235235
| Prwprgm infos -> EcPhlRwPrgm.process_rw_prgm infos
236236
| Phoaresplit -> EcPhlHoare.process_hoaresplit
237237
in

src/ecParser.mly

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3261,11 +3261,11 @@ interleave_info:
32613261
| LOSSLESS
32623262
{ Plossless }
32633263

3264-
| PROC CHANGE side=side? pos=codepos_or_range COLON s=brace(stmt)
3265-
{ Pchangestmt (side, PosOrRange pos, s) }
3264+
| PROC CHANGE side=side? pos=codepos_or_range COLON b=option(bracket(ptybindings)) s=brace(stmt)
3265+
{ Pchangestmt (side, b, PosOrRange pos, s) }
32663266

3267-
| PROC CHANGE side=side? pos=codegap COLON s=brace(stmt)
3268-
{ Pchangestmt (side, Gap pos, s) }
3267+
| PROC CHANGE side=side? pos=codegap COLON b=option(bracket(ptybindings)) s=brace(stmt)
3268+
{ Pchangestmt (side, b, Gap pos, s) }
32693269

32703270
| PROC REWRITE side=side? pos=codepos f=pterm
32713271
{ Pprocrewrite (side, pos, `Rw f) }

src/ecParsetree.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,7 @@ type phltactic =
824824
| Prwprgm of rwprgm
825825
| Pprocrewrite of side option * pcodepos * prrewrite
826826
| Pprocrewriteat of psymbol * ppterm
827-
| Pchangestmt of side option * prange1_or_insert * pstmt
827+
| Pchangestmt of side option * ptybindings option * prange1_or_insert * pstmt
828828
| Phoaresplit
829829

830830
(* Eager *)

src/ecProofTyping.ml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ let process_dformula ?mv hyps pf =
5050
let f = process_xreal ?mv hyps pf in
5151
Double(p,f)
5252

53+
let process_type hyps pty =
54+
let env = LDecl.toenv hyps in
55+
let ue = unienv_of_hyps hyps in
56+
let ty = EcTyping.transty EcTyping.tp_tydecl env ue pty in
57+
58+
if not (EcUnify.UniEnv.closed ue) then
59+
EcTyping.tyerror (EcLocation.loc pty) env EcTyping.FreeTypeVariables;
60+
61+
let ts = Tuni.subst (EcUnify.UniEnv.close ue) in
62+
EcCoreSubst.ty_subst ts ty
63+
5364
let process_exp hyps mode oty e =
5465
let env = LDecl.toenv hyps in
5566
let ue = unienv_of_hyps hyps in

src/ecProofTyping.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ val pf_check_tvi : proofenv -> ty_params -> EcUnify.tvi -> unit
2121
val process_form_opt : ?mv:metavs -> LDecl.hyps -> pformula -> ty option -> form
2222
val process_form : ?mv:metavs -> LDecl.hyps -> pformula -> ty -> form
2323
val process_formula : ?mv:metavs -> LDecl.hyps -> pformula -> form
24+
val process_type : LDecl.hyps -> pty -> ty
2425
val process_exp : LDecl.hyps -> [`InProc|`InOp] -> ty option -> pexpr -> expr
2526
val process_pattern : LDecl.hyps -> pformula -> ptnenv * form
2627

src/phl/ecPhlRewrite.ml

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -236,13 +236,18 @@ let process_rewrite_at
236236
and produce the same values for everything observable afterwards;
237237
- the original program-logic goal with the selected range rewritten. *)
238238
let t_change_stmt
239-
(side : side option)
240-
(pos : EcMatching.Position.codegap_range)
241-
(s : stmt)
242-
(tc : tcenv1)
239+
(side : side option)
240+
(pos : EcMatching.Position.codegap_range)
241+
?(me : memenv option)
242+
(s : stmt)
243+
(tc : tcenv1)
243244
=
244245
let env = FApi.tc1_env tc in
245-
let me, stmt = EcLowPhlGoal.tc1_get_stmt side tc in
246+
247+
let me, stmt =
248+
let metc, stmt = EcLowPhlGoal.tc1_get_stmt side tc in
249+
(odfl metc me, stmt)
250+
in
246251

247252
let zpr, (_,stmt, epilog), _nmr =
248253
EcMatching.Zipper.zipper_and_split_of_cgap_range env pos stmt in
@@ -342,10 +347,12 @@ let t_change_stmt
342347
(* -------------------------------------------------------------------- *)
343348
let process_change_stmt
344349
(side : side option)
350+
(binds : ptybindings option)
345351
(pos : prange1_or_insert)
346352
(s : pstmt)
347353
(tc : tcenv1)
348354
=
355+
let hyps = FApi.tc1_hyps tc in
349356
let env = FApi.tc1_env tc in
350357

351358
begin match side, (FApi.tc1_goal tc).f_node with
@@ -366,14 +373,35 @@ let process_change_stmt
366373

367374
let me, _ = EcLowPhlGoal.tc1_get_stmt side tc in
368375

369-
let pos =
376+
let pos =
370377
let env = EcEnv.Memory.push_active_ss me env in
371378
EcTyping.trans_range1_or_insert ~memory:(fst me) env pos
372379
in
373380

374-
let s = match side with
375-
| Some side -> EcProofTyping.tc1_process_prhl_stmt tc side s
376-
| None -> EcProofTyping.tc1_process_Xhl_stmt tc s
381+
(* Add the new variables *)
382+
let bindings =
383+
binds
384+
|> odfl []
385+
|> List.map (fun (xs, ty) -> List.map (fun x -> (x, ty)) xs)
386+
|> List.flatten
387+
|> List.map (fun (x, ty) ->
388+
let ty = EcProofTyping.process_type hyps ty in
389+
let x = Option.map EcLocation.unloc (EcLocation.unloc x) in
390+
EcAst.{ ov_name = x; ov_type = ty; }
391+
)
392+
in
393+
let me, _ = EcMemory.bindall_fresh bindings me in
394+
395+
(* Process the given statement using the new bound variables *)
396+
let env = EcEnv.Memory.push_active_ss me env in
397+
let s =
398+
let ue = EcProofTyping.unienv_of_hyps hyps in
399+
let s = EcTyping.transstmt env ue s in
400+
401+
assert (EcUnify.UniEnv.closed ue);
402+
403+
let sb = EcCoreSubst.Tuni.subst (EcUnify.UniEnv.close ue) in
404+
EcCoreSubst.s_subst sb s
377405
in
378406

379-
t_change_stmt side pos s tc
407+
t_change_stmt side pos ~me s tc

src/phl/ecPhlRewrite.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ val process_rewrite_rw : side option -> pcodepos -> ppterm -> backward
88
val process_rewrite_simpl : side option -> pcodepos -> backward
99
val process_rewrite : side option -> pcodepos -> prrewrite -> backward
1010
val process_rewrite_at : psymbol -> ppterm -> backward
11-
val process_change_stmt : side option -> prange1_or_insert -> pstmt -> backward
11+
val process_change_stmt : side option -> ptybindings option -> prange1_or_insert -> pstmt -> backward

tests/procchange.ec

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ theory ProcChangeAssignEquiv.
3030
lemma L : equiv[M.f ~ M.f: true ==> true].
3131
proof.
3232
proc.
33-
proc change {1} [1..3] : { x <- 3; }.
34-
33+
proc change {1} [1..3] : [y : int] { y <- 3; x <- y; }.
3534
wp. skip. smt().
3635
abort.
3736
end ProcChangeAssignEquiv.

0 commit comments

Comments
 (0)