@@ -117,6 +117,13 @@ let destr_pr_has pr =
117117 Some (ty_elem, {m;inv= f_f}, f_l)
118118 else None
119119 | _ -> None
120+
121+ let is_eq_w_const_rhs (f : ss_inv ): bool =
122+ try
123+ let _, rhs = destr_eq f.inv in
124+ not (Mid. mem f.m rhs.f_fv)
125+ with DestrError _ -> false
126+
120127(*
121128 lemma mu_has_le ['a 'b] (P : 'a -> 'b -> bool) (d : 'a distr) (s : 'b list) :
122129 mu d (fun a => has (P a) s) <= BRA.big predT (fun b => mu d (fun a => P a b)) s.
@@ -140,7 +147,7 @@ exception FoundPr of form
140147let select_pr on_ev sid f =
141148 match f.f_node with
142149 | Fpr { pr_event = ev } ->
143- if on_ev ev.inv && Mid. set_disjoint f.f_fv sid then raise (FoundPr f)
150+ if on_ev ev && Mid. set_disjoint f.f_fv sid then raise (FoundPr f)
144151 else false
145152 | _ -> false
146153
@@ -222,13 +229,13 @@ let t_pr_rewrite_low (s, (dof: (_ -> _ -> _ -> ss_inv) option)) tc =
222229
223230 let select =
224231 match kind with
225- | `Mu1LeEqMu1 -> select_pr is_eq
226- | `MuDisj | `MuOr -> select_pr is_or
232+ | `Mu1LeEqMu1 -> select_pr is_eq_w_const_rhs
233+ | `MuDisj | `MuOr -> select_pr ( fun inv -> is_or inv.inv)
227234 | `MuEq -> select_pr_cmp (EcPath. p_equal EcCoreLib.CI_Bool. p_eq)
228- | `MuFalse -> select_pr is_false
235+ | `MuFalse -> select_pr ( fun inv -> is_false inv.inv)
229236 | `MuGe0 -> select_pr_ge0
230237 | `MuLe1 -> select_pr_le1
231- | `MuNot -> select_pr is_not
238+ | `MuNot -> select_pr ( fun inv -> is_not inv.inv)
232239 | `MuSplit -> select_pr (fun _ev -> true )
233240 | `MuSub -> select_pr_cmp (EcPath. p_equal EcCoreLib.CI_Real. p_real_le)
234241 | `MuSum -> select_pr (fun _ev -> true )
@@ -250,8 +257,15 @@ let t_pr_rewrite_low (s, (dof: (_ -> _ -> _ -> ss_inv) option)) tc =
250257 let (resv, k) = map_ss_inv_destr2 destr_eq pr.pr_event in
251258 let k_id = EcEnv.LDecl. fresh_id hyps " k" in
252259 let d = (oget dof) tc torw (EcTypes. tdistr k.inv.f_ty) in
253- (* FIXME: Ensure that d.inv does not use d.m *)
254- (* FIXME: Ensure that k.inv does not use k.m *)
260+ (* Check that k and d do not reference the post-execution memory.
261+ Otherwise the rewrite is unsound: the event `res = k` would use
262+ k from the post-state, but `mu1 d k` treats k as a constant. *)
263+ if Mid. mem k.m k.inv.f_fv then
264+ (* This case should already be filtered by selection *)
265+ assert false ;
266+ if Mid. mem d.m d.inv.f_fv then
267+ tc_error !! tc
268+ " Pr-rewrite: the distribution must not depend on memories" ;
255269 (pr_mu1_le_eq_mu1 pr_mem pr_fun pr_args resv k.inv k_id d.inv, 2 )
256270
257271 | (`MuEq | `MuSub as kind ) -> begin
0 commit comments