Skip to content

Commit 7d51fe4

Browse files
committed
fix handling of bounds in conseq equiv phoare
add tests for conseq equiv phoare
1 parent 3ee0c81 commit 7d51fe4

File tree

2 files changed

+62
-11
lines changed

2 files changed

+62
-11
lines changed

src/phl/ecPhlConseq.ml

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -785,26 +785,35 @@ let t_equivS_conseq_bd side pr po tc =
785785
(* -------------------------------------------------------------------- *)
786786

787787
(*
788-
(forall m1, P1 m1 => exists m2, P m1 m2 /\ P2 m2)
788+
(forall m1, P1 m1 => exists m2, P m1 m2 /\ P2 m2 /\ q m1 = p m2)
789789
(forall m1 m2, Q m1 m2 => Q2 m2 => Q1 m1)
790-
equiv M1 ~ M2 : P ==> Q hoare M2 : P2 ==> Q2.
790+
equiv M1 ~ M2 : P ==> Q phoare M2 : P2 ==> Q2 R p.
791791
-----------------------------------------------
792-
hoare M1 : P1 ==> Q1.
792+
phoare M1 : P1 ==> Q1 R q.
793793
*)
794794

795-
let transitivity_side_cond hyps prml poml pomr p q p2 q2 p1 q1 =
795+
let transitivity_side_cond ?bds hyps prml poml pomr p q p2 q2 p1 q1 =
796796
let env = LDecl.toenv hyps in
797797
let cond1 =
798798
let fv1 = PV.fv env p.mr p.inv in
799799
let fv2 = PV.fv env p2.m p2.inv in
800800
let fv = PV.union fv1 fv2 in
801+
let fv = match bds with
802+
| Some (_, bd2) ->
803+
let fvbd2 = PV.fv env bd2.m bd2.inv in
804+
PV.union fv fvbd2
805+
| None -> fv in
801806
let elts, glob = PV.ntr_elements fv in
802807
let bd, s = generalize_subst env p2.m elts glob in
803808
let s1 = PVM.of_mpv s p.mr in
804809
let s2 = PVM.of_mpv s p2.m in
805-
let concl = f_and (PVM.subst env s1 p.inv) (PVM.subst env s2 p2.inv) in
806-
let p1 = ss_inv_rebind p1 p.ml in
807-
f_forall_mems [prml] (f_imp p1.inv (f_exists bd concl)) in
810+
let concl = {m=p1.m; inv=f_and (PVM.subst env s1 p.inv) (PVM.subst env s2 p2.inv)} in
811+
let concl = match bds with
812+
| Some (bd1, bd2) ->
813+
let sbd = PVM.of_mpv s bd2.m in
814+
map_ss_inv2 f_and concl (map_ss_inv1 (fun bd1 -> f_eq bd1 (PVM.subst env sbd bd2.inv)) bd1)
815+
| None -> concl in
816+
f_forall_mems_ss_inv prml (map_ss_inv2 f_imp p1 (map_ss_inv1 (f_exists bd) concl)) in
808817
let cond2 =
809818
let q1 = ss_inv_generalize_as_left q1 q.ml q.mr in
810819
let q2 = ss_inv_generalize_as_right q2 q.ml q.mr in
@@ -821,14 +830,14 @@ let t_hoareF_conseq_equiv f2 p q p2 q2 tc =
821830
transitivity_side_cond hyps prml poml pomr p q p2 q2 (hf_pr hf1) (hf_po hf1) in
822831
FApi.xmutate1 tc `HoareFConseqEquiv [cond1; cond2; ef; hf2]
823832

824-
let t_bdHoareF_conseq_equiv f2 p q p2 q2 tc =
833+
let t_bdHoareF_conseq_equiv f2 p q p2 q2 bd2 tc =
825834
let env, hyps, _ = FApi.tc1_eflat tc in
826835
let hf1 = tc1_as_bdhoareF tc in
827836
let ef = f_equivF p hf1.bhf_f f2 q in
828-
let hf2 = f_bdHoareF p2 f2 q2 hf1.bhf_cmp (bhf_bd hf1) in
837+
let hf2 = f_bdHoareF p2 f2 q2 hf1.bhf_cmp bd2 in
829838
let (prml, _prmr), (poml, pomr) = Fun.equivF_memenv p.ml p.mr hf1.bhf_f f2 env in
830839
let (cond1, cond2) =
831-
transitivity_side_cond hyps prml poml pomr p q p2 q2 (bhf_pr hf1) (bhf_po hf1) in
840+
transitivity_side_cond ~bds:(bhf_bd hf1, bd2) hyps prml poml pomr p q p2 q2 (bhf_pr hf1) (bhf_po hf1) in
832841
FApi.xmutate1 tc `BdHoareFConseqEquiv [cond1; cond2; ef; hf2]
833842

834843

@@ -1152,7 +1161,7 @@ let rec t_hi_conseq notmod f1 f2 f3 tc =
11521161
let hf2 = pf_as_bdhoareF !!tc f2 in
11531162
FApi.t_seqsub
11541163
(t_bdHoareF_conseq_equiv hf2.bhf_f (ef_pr ef) (ef_po ef)
1155-
(bhf_pr hf2) (bhf_po hf2))
1164+
(bhf_pr hf2) (bhf_po hf2) (bhf_bd hf2))
11561165
[t_id; t_id; t_apply_r nef; t_apply_r nf2] tc
11571166

11581167
(* ------------------------------------------------------------------ *)

tests/conseq_equiv_phoare.ec

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
require import Real Int.
2+
3+
module M = {
4+
var b: bool
5+
6+
proc run() = {
7+
M.b <- false;
8+
}
9+
}.
10+
11+
lemma dep_bound : phoare[M.run : M.b ==> !M.b] = (b2i M.b)%r.
12+
proof. by proc; auto => &hr ->. qed.
13+
14+
equiv triv_equiv : M.run ~ M.run : true ==> ={M.b}.
15+
proof. proc; auto. qed.
16+
17+
lemma bad_bound : phoare[M.run : true ==> !M.b] = (b2i M.b)%r.
18+
proof.
19+
conseq triv_equiv dep_bound => //=.
20+
move => &1.
21+
fail smt().
22+
abort.
23+
24+
lemma dep_bound_conseq :
25+
phoare[M.run : !M.b ==> !M.b] = (1-b2i M.b)%r.
26+
proof.
27+
conseq triv_equiv dep_bound => //=.
28+
move => &1 -> /=.
29+
by exists true => />.
30+
qed.
31+
32+
lemma nodep_bound : phoare[M.run: true ==> true] = 1%r.
33+
proof. proc; auto. qed.
34+
35+
lemma nodep_bound_conseq :
36+
phoare[M.run : !M.b ==> !M.b] = 1%r.
37+
proof.
38+
conseq triv_equiv dep_bound => //=.
39+
move => &1 /> _.
40+
by exists true.
41+
qed.
42+

0 commit comments

Comments
 (0)