Skip to content

Commit ad2615b

Browse files
committed
Alias sub-expressions in statements
The tactic `alias $name := $pattern @ $pos` alias the $pattern (subject to matching) in the instruction targetted by $pos using a fresh program variable $name. The tactic does not apply to the expression contained in the condition of a while loop.
1 parent 9771f52 commit ad2615b

File tree

11 files changed

+141
-28
lines changed

11 files changed

+141
-28
lines changed

src/ecCoreModules.ml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,19 @@ and i_get_uninit_read (w : Ssym.t) (i : instr) =
232232
let get_uninit_read (s : stmt) =
233233
snd (s_get_uninit_read Ssym.empty s)
234234

235+
236+
(* -------------------------------------------------------------------- *)
237+
type instr_with_expr = [`Sasgn | `Srnd | `Sif | `Smatch | `Swhile]
238+
239+
let get_expression_of_instruction (i : instr) : (_ * instr_with_expr * _) option =
240+
match i.i_node with
241+
| Sasgn (lv, e) -> Some (e, `Sasgn , (fun e -> i_asgn (lv, e)))
242+
| Srnd (lv, e) -> Some (e, `Srnd , (fun e -> i_rnd (lv, e)))
243+
| Sif (e, s1, s2) -> Some (e, `Sif , (fun e -> i_if (e, s1, s2)))
244+
| Swhile (e, s) -> Some (e, `Swhile, (fun e -> i_while (e, s)))
245+
| Smatch (e, bs) -> Some (e, `Smatch, (fun e -> i_match (e, bs)))
246+
| _ -> None
247+
235248
(* -------------------------------------------------------------------- *)
236249
type 'a use_restr = 'a EcAst.use_restr
237250

src/ecCoreModules.mli

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ val is_assert : instr -> bool
7979
(* -------------------------------------------------------------------- *)
8080
val get_uninit_read : stmt -> Sx.t
8181

82+
(* -------------------------------------------------------------------- *)
83+
type instr_with_expr = [`Sasgn | `Srnd | `Sif | `Smatch | `Swhile]
84+
85+
val get_expression_of_instruction : instr -> (expr * instr_with_expr * (expr -> instr)) option
86+
8287
(* -------------------------------------------------------------------- *)
8388
type funsig = {
8489
fs_name : symbol;

src/ecHiTacticals.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ and process1_phl (_ : ttenv) (t : phltactic located) (tc : tcenv1) =
196196
| Pasgncase info -> EcPhlCodeTx.process_case info
197197
| Palias info -> EcPhlCodeTx.process_alias info
198198
| Pset info -> EcPhlCodeTx.process_set info
199+
| Psetmatch info -> EcPhlCodeTx.process_set_match info
199200
| Pweakmem info -> EcPhlCodeTx.process_weakmem info
200201
| Prnd (side, pos, info) -> EcPhlRnd.process_rnd side pos info
201202
| Prndsem (red, side, pos) -> EcPhlRnd.process_rndsem ~reduce:red side pos

src/ecParser.mly

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3098,6 +3098,9 @@ interleave_info:
30983098
| ALIAS s=side? o=codepos x=lident EQ e=expr
30993099
{ Pset (s, o, false, x,e) }
31003100

3101+
| ALIAS s=side? x=lident CEQ p=sform_h AT o=codepos
3102+
{ Psetmatch (s, o, x, p) }
3103+
31013104
| WEAKMEM s=side? h=loc(ipcore_name) p=param_decl
31023105
{ Pweakmem(s, h, p) }
31033106

src/ecParsetree.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,7 @@ type phltactic =
745745
| Palias of (oside * pcodepos * osymbol_r)
746746
| Pweakmem of (oside * psymbol * fun_params)
747747
| Pset of (oside * pcodepos * bool * psymbol * pexpr)
748+
| Psetmatch of (oside * pcodepos * psymbol * pformula)
748749
| Pconseq of (pcqoptions * (conseq_ppterm option tuple3))
749750
| Pconseqauto of crushmode
750751
| Pconcave of (pformula option tuple2 gppterm * pformula)

src/ecUtils.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,10 @@ module List = struct
467467

468468
include Parallel
469469

470+
(* ------------------------------------------------------------------ *)
471+
let destruct (s : 'a list) =
472+
match s with x :: xs -> (x, xs) | _ -> assert false
473+
470474
(* ------------------------------------------------------------------ *)
471475
let nth_opt (s : 'a list) (i : int) =
472476
try Some (List.nth s i)

src/ecUtils.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ module List : sig
281281
val min : ?cmp:('a -> 'a -> int) -> 'a list -> 'a
282282
val max : ?cmp:('a -> 'a -> int) -> 'a list -> 'a
283283

284+
val destruct : 'a list -> 'a * 'a list
284285
val nth_opt : 'a list -> int -> 'a option
285286
val mbfilter : ('a -> bool) -> 'a list -> 'a list
286287
val fusion : ('a -> 'a -> 'a) -> 'a list -> 'a list -> 'a list

src/phl/ecPhlCodeTx.ml

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
(* -------------------------------------------------------------------- *)
22
open EcUtils
33
open EcParsetree
4+
open EcSymbols
45
open EcAst
56
open EcTypes
67
open EcModules
78
open EcFol
89
open EcEnv
910
open EcPV
11+
open EcMatching
1012

1113
open EcCoreGoal
1214
open EcLowPhlGoal
@@ -136,6 +138,51 @@ let t_set_r side cpos (fresh, id) e tc =
136138
let tr = fun side -> `Set (side, cpos) in
137139
t_code_transform side ~bdhoare:true cpos tr (t_zip (set_stmt (fresh, id) e)) tc
138140

141+
(* -------------------------------------------------------------------- *)
142+
let set_match_stmt (id : symbol) ((ue, mev, ptn) : _ * _ * form) =
143+
fun (pe, hyps) _ me z ->
144+
let i, is = List.destruct z.Zpr.z_tail in
145+
let e, mk =
146+
let e, kind, mk =
147+
get_expression_of_instruction i |> ofdfl (fun () ->
148+
tc_error pe "targetted instruction should contain an expression"
149+
) in
150+
151+
match kind with
152+
| `Sasgn | `Srnd | `Sif | `Smatch -> (e, mk)
153+
| `Swhile -> tc_error pe "while loops not supported"
154+
in
155+
156+
try
157+
let ptev = EcProofTerm.ptenv pe hyps (ue, mev) in
158+
let e = form_of_expr (fst me) e in
159+
let subf, occmode = EcProofTerm.pf_find_occurence_lazy ptev ~ptn e in
160+
161+
assert (EcProofTerm.can_concretize ptev);
162+
163+
let cpos =
164+
EcMatching.FPosition.select_form
165+
~xconv:`AlphaEq ~keyed:occmode.k_keyed
166+
hyps None subf e in
167+
168+
let v = { ov_name = Some id; ov_type = subf.f_ty } in
169+
let (me, id) = EcMemory.bind_fresh v me in
170+
let pv = pv_loc (oget id.ov_name) in
171+
let e = EcMatching.FPosition.map cpos (fun _ -> f_pvar pv (subf.f_ty) (fst me)) e in
172+
173+
let i1 = i_asgn (LvVar (pv, subf.f_ty), expr_of_form (fst me) subf) in
174+
let i2 = mk (expr_of_form (fst me) e) in
175+
176+
(me, { z with z_tail = i1 :: i2 :: is }, [])
177+
178+
with EcProofTerm.FindOccFailure _ ->
179+
tc_error pe "cannot find an occurrence of the pattern"
180+
181+
let t_set_match_r (side : oside) (cpos : Position.codepos) (id : symbol) pattern tc =
182+
let tr = fun side -> `SetMatch (side, cpos) in
183+
t_code_transform side ~bdhoare:true cpos tr
184+
(t_zip (set_match_stmt id pattern)) tc
185+
139186
(* -------------------------------------------------------------------- *)
140187
let cfold_stmt ?(simplify = true) (pf, hyps) (me : memenv) (olen : int option) (zpr : Zpr.zipper) =
141188
let env = LDecl.toenv hyps in
@@ -286,10 +333,11 @@ let t_cfold_r side cpos olen g =
286333
t_code_transform side ~bdhoare:true cpos tr (t_zip cb) g
287334

288335
(* -------------------------------------------------------------------- *)
289-
let t_kill = FApi.t_low3 "code-tx-kill" t_kill_r
290-
let t_alias = FApi.t_low3 "code-tx-alias" t_alias_r
291-
let t_set = FApi.t_low4 "code-tx-set" t_set_r
292-
let t_cfold = FApi.t_low3 "code-tx-cfold" t_cfold_r
336+
let t_kill = FApi.t_low3 "code-tx-kill" t_kill_r
337+
let t_alias = FApi.t_low3 "code-tx-alias" t_alias_r
338+
let t_set = FApi.t_low4 "code-tx-set" t_set_r
339+
let t_set_match = FApi.t_low4 "code-tx-set-match" t_set_match_r
340+
let t_cfold = FApi.t_low3 "code-tx-cfold" t_cfold_r
293341

294342
(* -------------------------------------------------------------------- *)
295343
let process_cfold (side, cpos, olen) tc =
@@ -309,8 +357,18 @@ let process_set (side, cpos, fresh, id, e) tc =
309357
let cpos = EcProofTyping.tc1_process_codepos tc (side, cpos) in
310358
t_set side cpos (fresh, id) e tc
311359

360+
let process_set_match (side, cpos, id, pattern) tc =
361+
let cpos = EcProofTyping.tc1_process_codepos tc (side, cpos) in
362+
let me, _ = tc1_get_stmt side tc in
363+
let hyps = LDecl.push_active me (FApi.tc1_hyps tc) in
364+
let ue = EcProofTyping.unienv_of_hyps hyps in
365+
let ptnmap = ref Mid.empty in
366+
let pattern = EcTyping.trans_pattern (LDecl.toenv hyps) ptnmap ue pattern in
367+
t_set_match side cpos (EcLocation.unloc id)
368+
(ue, EcMatching.MEV.of_idents (Mid.keys !ptnmap) `Form, pattern)
369+
tc
370+
312371
(* -------------------------------------------------------------------- *)
313-
314372
let process_weakmem (side, id, params) tc =
315373
let open EcLocation in
316374
let hyps = FApi.tc1_hyps tc in

src/phl/ecPhlCodeTx.mli

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11
(* -------------------------------------------------------------------- *)
22
open EcParsetree
3-
open EcTypes
3+
open EcSymbols
4+
open EcAst
45
open EcCoreGoal.FApi
56
open EcMatching.Position
7+
open EcMatching
8+
open EcUnify
69

710
(* -------------------------------------------------------------------- *)
8-
val t_kill : oside -> codepos -> int option -> backward
9-
val t_alias : oside -> codepos -> psymbol option -> backward
10-
val t_set : oside -> codepos -> bool * psymbol -> expr -> backward
11-
val t_cfold : oside -> codepos -> int option -> backward
11+
val t_kill : oside -> codepos -> int option -> backward
12+
val t_alias : oside -> codepos -> psymbol option -> backward
13+
val t_set : oside -> codepos -> bool * psymbol -> expr -> backward
14+
val t_set_match : oside -> codepos -> symbol -> unienv * mevmap * form -> backward
15+
val t_cfold : oside -> codepos -> int option -> backward
1216

1317
(* -------------------------------------------------------------------- *)
14-
val process_kill : oside * pcodepos * int option -> backward
15-
val process_alias : oside * pcodepos * psymbol option -> backward
16-
val process_set : oside * pcodepos * bool * psymbol * pexpr -> backward
17-
val process_cfold : oside * pcodepos * int option -> backward
18-
val process_case : oside * pcodepos -> backward
18+
val process_kill : oside * pcodepos * int option -> backward
19+
val process_alias : oside * pcodepos * psymbol option -> backward
20+
val process_set : oside * pcodepos * bool * psymbol * pexpr -> backward
21+
val process_set_match : oside * pcodepos * psymbol * pformula -> backward
22+
val process_cfold : oside * pcodepos * int option -> backward
23+
val process_case : oside * pcodepos -> backward
1924

2025
(* -------------------------------------------------------------------- *)
2126
val process_weakmem : (oside * psymbol * fun_params) -> backward

src/phl/ecPhlRewrite.ml

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,6 @@ open EcEnv
66
open EcModules
77
open EcFol
88

9-
(* -------------------------------------------------------------------- *)
10-
let get_expression_of_instruction (i : instr) =
11-
match i.i_node with
12-
| Sasgn (lv, e) -> Some (e, (fun e -> i_asgn (lv, e)))
13-
| Srnd (lv, e) -> Some (e, (fun e -> i_rnd (lv, e)))
14-
| Sif (e, s1, s2) -> Some (e, (fun e -> i_if (e, s1, s2)))
15-
| Swhile (e, s) -> Some (e, (fun e -> i_while (e, s)))
16-
| Smatch (e, bs) -> Some (e, (fun e -> i_match (e, bs)))
17-
| _ -> None
18-
199
(* -------------------------------------------------------------------- *)
2010
let t_change
2111
(side : side option)
@@ -26,12 +16,11 @@ let t_change
2616
let hyps, concl = FApi.tc1_flat tc in
2717

2818
let change (m : memenv) (i : instr) =
29-
let e, mk =
19+
let e, _, mk =
3020
EcUtils.ofdfl
3121
(fun () ->
3222
tc_error !!tc
33-
"targeted instruction should be \
34-
an assignment or random sampling")
23+
"targetted instruction should contain an expression")
3524
(get_expression_of_instruction i)
3625
in
3726

0 commit comments

Comments
 (0)