Skip to content

Commit 2795594

Browse files
Gustavo2622strub
authored andcommitted
PR: Feature: Proc change
1 parent bfbe7f3 commit 2795594

File tree

13 files changed

+294
-24
lines changed

13 files changed

+294
-24
lines changed

src/ecHiTacticals.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,9 @@ and process1_phl (_ : ttenv) (t : phltactic located) (tc : tcenv1) =
230230
| Pauto -> EcPhlAuto.t_auto ~conv:`Conv
231231
| Plossless -> EcPhlHiAuto.t_lossless
232232
| Prepl_stmt infos -> EcPhlTrans.process_equiv_trans infos
233-
| Pprocchange (s, p, f) -> EcPhlRewrite.process_change s p f
234233
| Pprocrewrite (s, p, f) -> EcPhlRewrite.process_rewrite s p f
234+
| Pchangestmt (s, p, c) -> EcPhlRewrite.process_change_stmt s p c
235+
| Prwprgm infos -> EcPhlRwPrgm.process_rw_prgm infos
235236
in
236237

237238
try tx tc

src/ecLexer.mll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@
9797
"clear" , CLEAR ; (* KW: tactic *)
9898
"wlog" , WLOG ; (* KW: tactic *)
9999

100+
"idassign" , IDASSIGN ; (* KW: tactic *)
101+
100102
(* Auto tactics *)
101103
"apply" , APPLY ; (* KW: tactic *)
102104
"rewrite" , REWRITE ; (* KW: tactic *)

src/ecPV.ml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ module PVM = struct
205205
end
206206

207207
(* -------------------------------------------------------------------- *)
208-
209208
module PV = struct
210209

211210
type t =
@@ -413,6 +412,10 @@ module PV = struct
413412
{ s_pv = Mnpv.set_diff fv1.s_pv fv2.s_pv;
414413
s_gl = Sm.diff fv1.s_gl fv2.s_gl }
415414

415+
let inter fv1 fv2 =
416+
{ s_pv = Mnpv.inter (fun _ _ t2 -> Some t2) fv1.s_pv fv2.s_pv;
417+
s_gl = Sm.inter fv1.s_gl fv2.s_gl }
418+
416419
let interdep env fv1 fv2 =
417420
let test_pv pv _ =
418421
Mnpv.mem pv fv2.s_pv ||

src/ecPV.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ module PV : sig
9595
val remove : env -> prog_var -> t -> t
9696
val union : t -> t -> t
9797
val diff : t -> t -> t
98+
val inter : t -> t -> t
9899
val subset : t -> t -> bool
99100

100101
val interdep : env -> t -> t -> t

src/ecParser.mly

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@
466466
%token HAVE
467467
%token HINT
468468
%token HOARE
469+
%token IDASSIGN
469470
%token IDTAC
470471
%token IF
471472
%token IFF
@@ -3193,15 +3194,20 @@ interleave_info:
31933194
| LOSSLESS
31943195
{ Plossless }
31953196

3196-
| PROC CHANGE side=side? pos=codepos COLON f=sexpr
3197-
{ Pprocchange (side, pos, f) }
3197+
| PROC CHANGE side=side? pos=loc(codepos) offset=codeoffset1 COLON s=brace(stmt)
3198+
{ if not (List.is_empty (fst (unloc pos))) then
3199+
parse_error (loc pos) (Some "only top-level positions are supported");
3200+
Pchangestmt (side, (snd (unloc pos), offset), s) }
31983201

31993202
| PROC REWRITE side=side? pos=codepos f=pterm
32003203
{ Pprocrewrite (side, pos, `Rw f) }
32013204

32023205
| PROC REWRITE side=side? pos=codepos SLASHEQ
32033206
{ Pprocrewrite (side, pos, `Simpl) }
32043207

3208+
| IDASSIGN o=codepos x=lvalue_var
3209+
{ Prwprgm (`IdAssign (o, x)) }
3210+
32053211
bdhoare_split:
32063212
| b1=sform b2=sform b3=sform?
32073213
{ BDH_split_bop (b1,b2,b3) }

src/ecParsetree.ml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -770,8 +770,10 @@ type phltactic =
770770
| Prw_equiv of rw_eqv_info
771771
| Psymmetry
772772
| Pbdhoare_split of bdh_split
773-
| Pprocchange of side option * pcodepos * pexpr
773+
| Pchangestmt of side option * (pcodepos1 * pcodeoffset1) * pstmt
774774
| Pprocrewrite of side option * pcodepos * prrewrite
775+
| Prwprgm of rwprgm
776+
775777

776778
(* Eager *)
777779
| Peager_seq of (eager_info * pcodepos1 pair * pformula)
@@ -789,6 +791,10 @@ type phltactic =
789791
| Pauto
790792
| Plossless
791793

794+
and rwprgm = [
795+
| `IdAssign of pcodepos * pqsymbol
796+
]
797+
792798
(* -------------------------------------------------------------------- *)
793799
type include_exclude = [ `Include | `Exclude ]
794800
type pdbmap1 = {

src/ecProofTyping.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ let tc1_process_prhl_stmt ?map tc side c =
143143
tc1_process_stmt hyps tc ?map c
144144

145145
let tc1_process_Xhl_stmt ?map tc c =
146-
let concl = FApi.tc1_goal tc in
146+
let concl = FApi.tc1_goal tc in
147147
let m = match concl.f_node with FbdHoareS {bhs_m=m} | FhoareS {hs_m=m} -> m | _ -> assert false in
148148
let hyps = FApi.tc1_hyps tc in
149149
let hyps = LDecl.push_active_ss m hyps in

src/ecTyping.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3665,6 +3665,11 @@ and trans_codepos_range ?(memory : memory option) (env : EcEnv.env) ((cps, cpe)
36653665
and trans_dcodepos1 ?(memory : memory option) (env : EcEnv.env) (p : pcodepos1 doption) : codepos1 doption =
36663666
DOption.map (trans_codepos1 ?memory env) p
36673667

3668+
and trans_codeoffset1 ?(memory: memory option) (env : EcEnv.env) (o : pcodeoffset1) : codeoffset1 =
3669+
match o with
3670+
| `ByOffset i -> `ByOffset i
3671+
| `ByPosition p -> `ByPosition (trans_codepos1 ?memory env p)
3672+
36683673
(* -------------------------------------------------------------------- *)
36693674
let get_instances (tvi, bty) env =
36703675
let inst = List.pmap

src/ecTyping.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ val trans_codepos_range : ?memory:EcMemory.memory -> env -> pcodepos_range -> co
230230
val trans_codepos1 : ?memory:EcMemory.memory -> env -> pcodepos1 -> codepos1
231231
val trans_codepos : ?memory:EcMemory.memory -> env -> pcodepos -> codepos
232232
val trans_dcodepos1 : ?memory:EcMemory.memory -> env -> pcodepos1 doption -> codepos1 doption
233+
val trans_codeoffset1 : ?memory:EcMemory.memory -> env -> pcodeoffset1 -> codeoffset1
233234

234235
(* -------------------------------------------------------------------- *)
235236
type ptnmap = ty EcIdent.Mid.t ref

src/phl/ecPhlRewrite.ml

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ open EcCoreGoal
55
open EcEnv
66
open EcModules
77
open EcFol
8+
open Batteries
89

910
(* -------------------------------------------------------------------- *)
1011
let t_change
@@ -112,7 +113,7 @@ let process_rewrite_rw
112113
let data, e =
113114
EcUtils.ofdfl
114115
(fun () -> tc_error !!tc "cannot find a pattern to rewrite")
115-
(List.find_map try1 pts) in
116+
(List.find_map_opt try1 pts) in
116117

117118
(m, data), expr_of_ss_inv e
118119
in
@@ -167,3 +168,111 @@ let process_rewrite
167168
match rw with
168169
| `Rw rw -> process_rewrite_rw side pos rw tc
169170
| `Simpl -> process_rewrite_simpl side pos tc
171+
172+
(* -------------------------------------------------------------------- *)
173+
let t_change_stmt
174+
(side : side option)
175+
(hd, stmt, tl : instr list * instr list * instr list)
176+
(s : stmt)
177+
(tc : tcenv1)
178+
=
179+
let env = FApi.tc1_env tc in
180+
let me, _ = EcLowPhlGoal.tc1_get_stmt side tc in
181+
182+
let pvs = EcPV.is_write env (stmt @ s.s_node) in
183+
let pvs, globs = EcPV.PV.elements pvs in
184+
185+
let pre_pvs, pre_globs = EcPV.PV.elements @@ EcPV.PV.inter
186+
(EcPV.is_read env stmt)
187+
(EcPV.is_read env s.s_node)
188+
in
189+
190+
let mleft = EcIdent.create "1" in (* FIXME: PR: is this how we want to do this? *)
191+
let mright = EcIdent.create "2" in
192+
193+
let eq =
194+
List.map
195+
(fun (pv, ty) -> f_eq (f_pvar pv ty mleft).inv (f_pvar pv ty mright).inv)
196+
pvs
197+
@
198+
List.map
199+
(fun mp -> f_eqglob mp mleft mp mright)
200+
globs in
201+
202+
let pre_eq =
203+
List.map
204+
(fun (pv, ty) -> f_eq (f_pvar pv ty mleft).inv (f_pvar pv ty mright).inv)
205+
pre_pvs
206+
@
207+
List.map
208+
(fun mp -> f_eqglob mp mleft mp mright)
209+
pre_globs
210+
in
211+
212+
let goal1 =
213+
f_equivS
214+
(snd me) (snd me)
215+
{ml=mleft; mr=mright; inv=f_ands pre_eq}
216+
(EcAst.stmt stmt) s
217+
{ml=mleft; mr=mright; inv=f_ands eq}
218+
in
219+
220+
let goal2 =
221+
EcLowPhlGoal.hl_set_stmt
222+
side (FApi.tc1_goal tc)
223+
(EcAst.stmt (List.flatten [hd; s.s_node; tl])) in
224+
225+
FApi.xmutate1 tc `ProcChangeStmt [goal1; goal2]
226+
227+
(* -------------------------------------------------------------------- *)
228+
let process_change_stmt
229+
(side : side option)
230+
((p, o) : pcodepos1 * pcodeoffset1)
231+
(s : pstmt)
232+
(tc : tcenv1)
233+
=
234+
let env = FApi.tc1_env tc in
235+
236+
begin match side, (FApi.tc1_goal tc).f_node with
237+
| _, FhoareF _
238+
| _, FeHoareF _
239+
| _, FequivF _
240+
| _, FbdHoareF _ -> tc_error !!tc "Expecting goal with inlined program code"
241+
| Some _, FhoareS _
242+
| Some _, FeHoareS _
243+
| Some _, FbdHoareS _-> tc_error !!tc "Tactic should not receive side for non-relational goal"
244+
| None, FequivS _ -> tc_error !!tc "Tactic requires side selector for relational goal"
245+
| None, FhoareS _
246+
| None, FeHoareS _
247+
| None, FbdHoareS _
248+
| Some _ , FequivS _ -> ()
249+
| _ -> tc_error !!tc "Wrong goal shape, expecting hoare or equiv goal with inlined code"
250+
end;
251+
252+
let me, stmt = EcLowPhlGoal.tc1_get_stmt side tc in
253+
254+
let p, o =
255+
let env = EcEnv.Memory.push_active_ss me env in
256+
let pos = EcTyping.trans_codepos1 ~memory:(fst me) env p in
257+
let off = EcTyping.trans_codeoffset1 ~memory:(fst me) env o in
258+
let off = EcMatching.Position.resolve_offset ~base:pos ~offset:off in
259+
260+
let start = EcMatching.Zipper.offset_of_position env pos stmt in
261+
let end_ = EcMatching.Zipper.offset_of_position env off stmt in
262+
263+
if (end_ < start) then
264+
tc_error !!tc "end position cannot be before start position";
265+
266+
(start - 1, end_ - start)
267+
in
268+
269+
let stmt = stmt.s_node in
270+
let hd, stmt = List.takedrop p stmt in
271+
let stmt, tl = List.takedrop o stmt in
272+
273+
let s = match side with
274+
| Some side -> EcProofTyping.tc1_process_prhl_stmt tc side s
275+
| None -> EcProofTyping.tc1_process_Xhl_stmt tc s
276+
in
277+
278+
t_change_stmt side (hd, stmt, tl) s tc

0 commit comments

Comments
 (0)