@@ -5,6 +5,7 @@ open EcCoreGoal
55open EcEnv
66open EcModules
77open EcFol
8+ open Batteries
89
910(* -------------------------------------------------------------------- *)
1011let 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