clutch.foxtrot.lib.or
From clutch.foxtrot Require Import foxtrot nodet.
Definition or (e1 e2:expr) :expr :=
if: nodet #()= #0
then e1
else e2.
Section proof.
Local Set Default Proof Using "Type*".
Context `{!foxtrotGS Σ}.
Lemma wp_or e1 e2 Φ:
{{{ WP e1 {{ Φ }} ∧ WP e2 {{ Φ }} }}}
or e1 e2
{{{ (v:val), RET (v); Φ v}}}.
Proof.
rewrite /or.
iIntros (ψ) "H Hψ".
wp_pures.
wp_apply (wp_nodet); first done.
iIntros (?) "_".
wp_pures.
case_bool_decide; wp_pure.
- iDestruct "H" as "[H _]".
by wp_apply (wp_wand with "[$]").
- iDestruct "H" as "[_ H]".
by wp_apply (wp_wand with "[$]").
Qed.
End proof.
Section proof'.
Context `{!foxtrotGS Σ}.
Lemma tp_or j K E (b:bool) e1 e2:
j ⤇ fill K (or e1 e2) -∗
pupd E E
(if b then j ⤇ fill K e1 else j ⤇ fill K e2
).
Proof.
rewrite /or.
iIntros "Hspec".
tp_bind j (nodet #())%E.
destruct b.
- iMod (tp_nodet _ _ _ 0 with "[$]").
simpl.
tp_pures j; last done.
solve_vals_compare_safe.
- iMod (tp_nodet _ _ _ 1 with "[$]").
simpl.
tp_pures j; last done.
solve_vals_compare_safe.
Qed.
End proof'.
Definition or (e1 e2:expr) :expr :=
if: nodet #()= #0
then e1
else e2.
Section proof.
Local Set Default Proof Using "Type*".
Context `{!foxtrotGS Σ}.
Lemma wp_or e1 e2 Φ:
{{{ WP e1 {{ Φ }} ∧ WP e2 {{ Φ }} }}}
or e1 e2
{{{ (v:val), RET (v); Φ v}}}.
Proof.
rewrite /or.
iIntros (ψ) "H Hψ".
wp_pures.
wp_apply (wp_nodet); first done.
iIntros (?) "_".
wp_pures.
case_bool_decide; wp_pure.
- iDestruct "H" as "[H _]".
by wp_apply (wp_wand with "[$]").
- iDestruct "H" as "[_ H]".
by wp_apply (wp_wand with "[$]").
Qed.
End proof.
Section proof'.
Context `{!foxtrotGS Σ}.
Lemma tp_or j K E (b:bool) e1 e2:
j ⤇ fill K (or e1 e2) -∗
pupd E E
(if b then j ⤇ fill K e1 else j ⤇ fill K e2
).
Proof.
rewrite /or.
iIntros "Hspec".
tp_bind j (nodet #())%E.
destruct b.
- iMod (tp_nodet _ _ _ 0 with "[$]").
simpl.
tp_pures j; last done.
solve_vals_compare_safe.
- iMod (tp_nodet _ _ _ 1 with "[$]").
simpl.
tp_pures j; last done.
solve_vals_compare_safe.
Qed.
End proof'.