Skip to content

Commit

Permalink
wp_while_tailrec_use_functionpost
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelgruetter committed Aug 16, 2023
1 parent 8d21582 commit 6975fa4
Showing 1 changed file with 82 additions and 12 deletions.
94 changes: 82 additions & 12 deletions LiveVerif/src/LiveVerif/LiveRules.v
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ Require Import coqutil.Datatypes.ListSet.
Require Import bedrock2.Syntax bedrock2.Semantics.
Require Import bedrock2.Lift1Prop.
Require Import bedrock2.Map.Separation bedrock2.Map.SeparationLogic bedrock2.Array.
Require Import bedrock2.WeakestPrecondition bedrock2.ProgramLogic bedrock2.Loops.
Require Import bedrock2.WeakestPrecondition bedrock2.ProgramLogic.
Require bedrock2.Loops.
Require Import bedrock2.ZnWords.
Require Import bedrock2.SepLib.
Require Import bedrock2.enable_frame_trick.
Expand Down Expand Up @@ -51,6 +52,9 @@ Section WithParams.
Inductive dexpr{BW: Bitwidth width}(m: mem)(l: locals)(e: expr)(w: word): Prop :=
mk_dexpr(_: WeakestPrecondition.dexpr m l e w).

Lemma invert_dexpr: forall m l e w, dexpr m l e w -> WeakestPrecondition.dexpr m l e w.
Proof. intros. inversion H. assumption. Qed.

Lemma dexpr_literal: forall (m: mem) (l: locals) z,
dexpr m l (expr.literal z) (word.of_Z z).
Proof.
Expand Down Expand Up @@ -730,6 +734,33 @@ Section WithParams.
destruct H; eauto.
Qed.

Lemma wp_while0: forall fs e c t m l (post: _ -> _ -> _ -> Prop) {measure: Type}
(lt: measure -> measure -> Prop)
(inv: measure -> trace -> mem -> locals -> Prop)
(v0: measure),
well_founded lt ->
inv v0 t m l ->
(forall v t m l,
inv v t m l ->
exists b, dexpr m l e b /\
(word.unsigned b <> 0%Z -> wp_cmd fs c t m l (fun t' m l =>
exists v', inv v' t' m l /\ lt v' v)) /\
(word.unsigned b = 0%Z -> post t m l)) ->
wp_cmd fs (cmd.while e c) t m l post.
Proof.
intros * Hwf HInit Hbody.
revert t m l HInit. pattern v0. revert v0.
eapply (well_founded_ind Hwf). intros.
specialize Hbody with (1 := HInit). destruct Hbody as (b & Hb & Ht & Hf).
eapply invert_dexpr in Hb.
eapply WeakestPreconditionProperties.expr_sound in Hb.
destruct Hb as (b' & Hb & ?). subst b'.
destr.destr (Z.eqb (word.unsigned b) 0).
- specialize Hf with (1 := E). eapply exec.while_false; eassumption.
- specialize Ht with (1 := E). eapply exec.while_true; eauto.
cbv beta. intros * (v' & HInv & HLt). eauto.
Qed.

Definition loop_body_marker(P: Prop) := P.

Lemma wp_while {measure : Type} (v0 : measure) (e: expr) (c: cmd) t (m: mem) l fs rest
Expand All @@ -746,18 +777,14 @@ Section WithParams.
True)
: wp_cmd fs (cmd.seq (cmd.while e c) rest) t m l post.
Proof.
eapply wp_seq. eapply wp_while. exists measure, lt, invariant.
split. 1: assumption.
split. 1: eauto.
clear Hpre v0 t m l.
intros v t m l Hinv.
specialize (Hbody v t m l Hinv).
fwd.
inversion Hbody. subst. clear Hbody. inversion H. clear H.
eapply wp_seq. eapply wp_while0. 1,2: eassumption.
intros * Hinv. specialize Hbody with (1 := Hinv).
destruct Hbody as (b & Hbody).
inversion Hbody. subst. clear Hbody.
eexists. split. 1: eassumption.
unfold bool_expr_branches in *. apply proj1 in H1. split.
- intro NE. eapply WeakestPreconditionProperties.complete_cmd.
rewrite word.eqb_ne in H1. 1: eapply H1. intro C. subst v0.
- intro NE.
rewrite word.eqb_ne in H1. 1: eapply H1. intro C. subst v1.
apply NE. apply word.unsigned_of_Z_0.
- intro E. rewrite word.eqb_eq in H1. 1: eapply H1.
eapply word.unsigned_inj. rewrite word.unsigned_of_Z_0. exact E.
Expand Down Expand Up @@ -789,7 +816,7 @@ Section WithParams.
: wp_cmd fs (cmd.seq (cmd.while e c) rest) t0 m0 l0 finalpost.
Proof.
eapply wp_seq. eapply WeakestPreconditionProperties.sound_cmd.
eapply tailrec_localsmap_1ghost with
eapply Loops.tailrec_localsmap_1ghost with
(P := fun v g t m l => pre (g, v, t, m, l))
(Q := fun v g t m l => post (g, v, t, m, l)).
1: eapply Hwf.
Expand All @@ -811,6 +838,49 @@ Section WithParams.
- exact HDone.
Qed.

Lemma wp_while_tailrec_use_functionpost{measure: Type}{Ghost: Type}(v0: measure)(g0: Ghost)
(e: expr) (c: cmd) t0 (m0: mem) l0 fs rest
(pre: Ghost * measure * trace * mem * locals -> Prop) {lt}
{functionpost: Ghost -> measure -> trace -> mem -> locals -> Prop}
(Hwf: well_founded lt)
(* packaging generalized context at entry of loop determines pre: *)
(Hpre: pre (g0, v0, t0, m0, l0))
(Hbody: forall v g t m l,
pre (g, v, t, m, l) ->
exists b, dexpr_bool3 m l e b
(loop_body_marker (wp_cmd fs c t m l
(fun t' m' l' => exists v' g',
pre (g', v', t', m', l') /\
lt v' v /\
(forall t'' m'' l'', functionpost g' v' t'' m'' l'' ->
functionpost g v t'' m'' l''))))
(wp_cmd fs rest t m l (functionpost g v))
True)
: wp_cmd fs (cmd.seq (cmd.while e c) rest) t0 m0 l0 (functionpost g0 v0).
Proof.
eapply wp_seq.
eapply wp_while0 with (inv := fun v t m l =>
exists g, pre (g, v, t, m, l) /\
(forall t' m' l', functionpost g v t' m' l' -> functionpost g0 v0 t' m' l')).
1: exact Hwf.
{ eexists. split. 1: eassumption. intros *. exact id. }
intros * (g & HPre & HPostImpl).
specialize Hbody with (1 := HPre).
destruct Hbody as (b & Hbody).
inversion Hbody. subst. clear Hbody.
unfold bool_expr_branches, loop_body_marker in *. apply proj1 in H1.
eexists. split. 1: eassumption. split.
- intro NE.
rewrite word.eqb_ne in H1.
{ simpl in H1. eapply exec.weaken. 1: eapply H1.
cbv beta. clear -HPostImpl. intros. fwd. eauto 10. }
intro C. subst v1.
apply NE. apply word.unsigned_of_Z_0.
- intro E. eapply exec.weaken. 2: eapply HPostImpl.
rewrite word.eqb_eq in H1. 1: eapply H1.
eapply word.unsigned_inj. rewrite word.unsigned_of_Z_0. exact E.
Qed.

Definition with_again_flag{T: Type}(R: T -> T -> Prop): bool * T -> bool * T -> Prop :=
fun '(again1, x1) '(again2, x2) =>
if again2 then
Expand Down

0 comments on commit 6975fa4

Please sign in to comment.