clutch.foxtrot.examples.nodet_example
From clutch.foxtrot Require Import foxtrot nodet diverge.
Definition prog : expr :=
let: "n" := nodet #() in
if: rand "n"=#0
then diverge #()
else #().
Lemma prog_refines_unit :
∅ ⊨ prog ≤ctx≤ #() : TUnit.
Proof.
apply (refines_sound foxtrotRΣ).
iIntros (??).
unfold_rel.
iIntros (K j) "Hspec".
rewrite /prog.
wp_apply (wp_nodet); first done.
iIntros (?) "_".
wp_pures.
wp_apply wp_rand; first done.
iIntros.
wp_pures.
case_bool_decide.
- wp_pures. wp_apply (wp_diverge); first done.
by iIntros.
- wp_pure. by iFrame.
Qed.
Lemma unit_refines_prog :
∅ ⊨ #() ≤ctx≤ prog : TUnit.
Proof.
apply (refines_sound foxtrotRΣ).
iIntros (??).
unfold_rel.
iIntros (K j) "Hspec".
rewrite /prog.
iMod (pupd_epsilon_err) as "(%ε & %Hpos &Herr)".
apply archimed_cor1 in Hpos as (N&Hineq&Hpos').
assert (/(S N)< ε)%R as Hineq'.
{ etrans; last exact.
apply Rinv_0_lt_contravar.
- by apply lt_0_INR.
- apply lt_INR. lia.
}
iDestruct (ec_weaken with "[$]") as "Herr".
{ split; last (left; apply Hineq').
rewrite -Rdiv_1_l.
apply Rdiv_INR_ge_0.
}
tp_bind j (nodet #()).
iMod (tp_nodet _ _ _ N with "[$]") as "Hspec".
Local Opaque INR.
simpl.
tp_pures j.
tp_bind j (rand _)%E.
iMod (tp_rand_r_err _ _ _ _ _ 0 with "[$][Herr]") as "(%&%&%&Hspec)".
{ iApply ec_eq; last done.
by rewrite S_INR plus_INR.
}
simpl.
tp_pures j.
- solve_vals_compare_safe.
- rewrite bool_decide_eq_false_2; last first.
{ intros ?. simplify_eq. lia. }
tp_pures j.
wp_pures.
by iFrame.
Qed.
Lemma prog_eq_unit :
∅ ⊨ prog =ctx= #() : TUnit.
Proof.
split; [apply prog_refines_unit|apply unit_refines_prog].
Qed.
Definition prog : expr :=
let: "n" := nodet #() in
if: rand "n"=#0
then diverge #()
else #().
Lemma prog_refines_unit :
∅ ⊨ prog ≤ctx≤ #() : TUnit.
Proof.
apply (refines_sound foxtrotRΣ).
iIntros (??).
unfold_rel.
iIntros (K j) "Hspec".
rewrite /prog.
wp_apply (wp_nodet); first done.
iIntros (?) "_".
wp_pures.
wp_apply wp_rand; first done.
iIntros.
wp_pures.
case_bool_decide.
- wp_pures. wp_apply (wp_diverge); first done.
by iIntros.
- wp_pure. by iFrame.
Qed.
Lemma unit_refines_prog :
∅ ⊨ #() ≤ctx≤ prog : TUnit.
Proof.
apply (refines_sound foxtrotRΣ).
iIntros (??).
unfold_rel.
iIntros (K j) "Hspec".
rewrite /prog.
iMod (pupd_epsilon_err) as "(%ε & %Hpos &Herr)".
apply archimed_cor1 in Hpos as (N&Hineq&Hpos').
assert (/(S N)< ε)%R as Hineq'.
{ etrans; last exact.
apply Rinv_0_lt_contravar.
- by apply lt_0_INR.
- apply lt_INR. lia.
}
iDestruct (ec_weaken with "[$]") as "Herr".
{ split; last (left; apply Hineq').
rewrite -Rdiv_1_l.
apply Rdiv_INR_ge_0.
}
tp_bind j (nodet #()).
iMod (tp_nodet _ _ _ N with "[$]") as "Hspec".
Local Opaque INR.
simpl.
tp_pures j.
tp_bind j (rand _)%E.
iMod (tp_rand_r_err _ _ _ _ _ 0 with "[$][Herr]") as "(%&%&%&Hspec)".
{ iApply ec_eq; last done.
by rewrite S_INR plus_INR.
}
simpl.
tp_pures j.
- solve_vals_compare_safe.
- rewrite bool_decide_eq_false_2; last first.
{ intros ?. simplify_eq. lia. }
tp_pures j.
wp_pures.
by iFrame.
Qed.
Lemma prog_eq_unit :
∅ ⊨ prog =ctx= #() : TUnit.
Proof.
split; [apply prog_refines_unit|apply unit_refines_prog].
Qed.