|
| 1 | +(* |
| 2 | + Examples demonstrating programming and reasoning with the PRNG effect. |
| 3 | + Randomized algorithms and their partial correctness. |
| 4 | + *) |
| 5 | +From gitrees Require Import gitree program_logic. |
| 6 | +From gitrees.effects Require Import prng store. |
| 7 | +From gitrees.lib Require Import while. |
| 8 | + |
| 9 | +Section prng_examples. |
| 10 | + Context {sz : nat} (rs : gReifiers NotCtxDep sz). |
| 11 | + Context `{!subReifier reify_store rs}. |
| 12 | + Context `{!subReifier reify_prng rs}. |
| 13 | + Notation F := (gReifiers_ops rs). |
| 14 | + Context {R} `{!Cofe R}. |
| 15 | + Context `{!SubOfe natO R, !SubOfe unitO R, !SubOfe locO R}. |
| 16 | + Notation IT := (IT F R). |
| 17 | + Notation ITV := (ITV F R). |
| 18 | + |
| 19 | + Context `{!gitreeGS_gen rs R Σ}. |
| 20 | + Context `{!heapG rs R Σ} `{prngG Σ}. |
| 21 | + Notation iProp := (iProp Σ). |
| 22 | + |
| 23 | + Notation wp_new := (wp_new rs). |
| 24 | + Notation wp_seed := (wp_seed rs). |
| 25 | + Notation wp_gen := (wp_gen rs). |
| 26 | + Notation wp_alloc := (wp_alloc rs). |
| 27 | + Notation wp_read := (wp_read rs). |
| 28 | + Notation wp_write := (wp_write rs). |
| 29 | + Notation wp_bind := (wp_bind rs). |
| 30 | + |
| 31 | + Definition neg_bool : IT -> IT := NATOP Nat.sub (Ret 1). |
| 32 | + |
| 33 | + Definition las_vegas_ITF (sd : nat) (init : nat) (test : IT) : IT := |
| 34 | + PRNG_NEW $ λne r, |
| 35 | + ALLOC (Ret init) $ λne s, |
| 36 | + SEQ (PRNG_SEED r sd) $ |
| 37 | + SEQ (WHILE |
| 38 | + (neg_bool (test ⊙ (READ s))) |
| 39 | + (LET (PRNG_GEN r) (WRITE s))) $ |
| 40 | + READ s. |
| 41 | + |
| 42 | + Lemma wp_las_vegas_ITF (f : nat -> bool) (fIT : IT) (sd : nat) (init : nat) : |
| 43 | + heap_ctx rs |
| 44 | + -∗ prng_ctx rs |
| 45 | + -∗ □ (∀ n, WP@{rs} fIT ⊙ (Ret n) {{ β, β ≡ RetV (if f n then 1 else 0) }}) |
| 46 | + -∗ WP@{rs} las_vegas_ITF sd init fIT {{ β, ∃ n, β ≡ RetV n ∧ f n ≡ true }}. |
| 47 | + Proof with (try solve_proper). |
| 48 | + (* preamble *) |
| 49 | + rewrite /las_vegas_ITF. |
| 50 | + iIntros "#Hheap #Hprng #Hf". |
| 51 | + iApply (wp_new with "Hprng")... |
| 52 | + iIntros "!>!> %r #Hr /=". |
| 53 | + iApply (wp_alloc with "Hheap")... |
| 54 | + iIntros "!>!> %s Hl /=". |
| 55 | + iApply wp_seq... |
| 56 | + iApply (wp_seed with "Hprng Hr"). |
| 57 | + iIntros "!>!> _ /=". |
| 58 | + (* repeated retry *) |
| 59 | + iApply (wp_bind (SEQCtx _) _)... |
| 60 | + iLöb as "IH" forall (init). |
| 61 | + rewrite {2}(WHILE_eq _ _). |
| 62 | + iApply (wp_bind (IFSCtx _ _) _)... |
| 63 | + iApply (wp_bind neg_bool _)... |
| 64 | + iApply (wp_bind (AppRSCtx fIT) _)... |
| 65 | + iApply (wp_read with "Hheap Hl"). |
| 66 | + iIntros "!>!> Hl /=". |
| 67 | + iApply wp_val; iModIntro. |
| 68 | + iPoseProof ("Hf" $! init) as "Hf0". |
| 69 | + rewrite /AppRSCtx IT_of_V_Ret. |
| 70 | + iApply (wp_wand with "Hf0"). |
| 71 | + iIntros "%v Hv !>". |
| 72 | + iRewrite "Hv". |
| 73 | + rewrite /IFSCtx IT_of_V_Ret. |
| 74 | + destruct (f init) eqn:Hdec; |
| 75 | + rewrite /neg_bool NATOP_Ret /=; |
| 76 | + iApply wp_val; iModIntro; |
| 77 | + rewrite IT_of_V_Ret. |
| 78 | + - rewrite IF_False; last lia. |
| 79 | + iApply wp_val; iModIntro. |
| 80 | + rewrite /SEQCtx IT_of_V_Ret SEQ_Val. |
| 81 | + iApply (wp_read with "Hheap Hl"). |
| 82 | + iIntros "!>!> _". |
| 83 | + iApply wp_val; iModIntro. |
| 84 | + by iExists init. |
| 85 | + - rewrite IF_True; last lia. |
| 86 | + iApply (wp_bind (SEQCtx _) _)... |
| 87 | + iApply wp_let... |
| 88 | + iApply (wp_gen with "Hprng Hr"). |
| 89 | + iIntros "!>!> _ %n". |
| 90 | + iApply (wp_write with "Hheap Hl"). |
| 91 | + iIntros "!>!> Hl". |
| 92 | + rewrite /SEQCtx !IT_of_V_Ret SEQ_Val. |
| 93 | + iApply wp_tick. |
| 94 | + iIntros "!> _". |
| 95 | + iApply ("IH" $! n with "Hl"). |
| 96 | + Qed. |
| 97 | +End prng_examples. |
0 commit comments