11(* -------------------------------------------------------------------- *)
22open EcUtils
33open EcParsetree
4+ open EcSymbols
45open EcAst
56open EcTypes
67open EcModules
78open EcFol
89open EcEnv
910open EcPV
11+ open EcMatching
1012
1113open EcCoreGoal
1214open 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(* -------------------------------------------------------------------- *)
140187let 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(* -------------------------------------------------------------------- *)
295343let 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-
314372let process_weakmem (side , id , params ) tc =
315373 let open EcLocation in
316374 let hyps = FApi. tc1_hyps tc in
0 commit comments