one_shot.v 5.09 KB
Newer Older
1 2
From iris.program_logic Require Export weakestpre hoare.
From iris.heap_lang Require Export lang.
Ralf Jung's avatar
Ralf Jung committed
3
From iris.algebra Require Import excl agree csum.
Ralf Jung's avatar
Ralf Jung committed
4
From iris.heap_lang Require Import assert proofmode notation adequacy.
5
From iris.proofmode Require Import tactics.
Ralf Jung's avatar
Ralf Jung committed
6
From iris.heap_lang.lib Require Import par.
7
Set Default Proof Using "Type".
Ralf Jung's avatar
Ralf Jung committed
8 9

Definition one_shot_example : val := λ: <>,
10
  let: "x" := ref NONE in (
Ralf Jung's avatar
Ralf Jung committed
11
  (* tryset *) (λ: "n",
12
    CAS "x" NONE (SOME "n")),
Ralf Jung's avatar
Ralf Jung committed
13
  (* check  *) (λ: <>,
14 15
    let: "y" := !"x" in λ: <>,
    match: "y" with
16 17
      NONE => #()
    | SOME "n" =>
18
       match: !"x" with
19 20
         NONE => assert: #false
       | SOME "m" => assert: "n" = "m"
Ralf Jung's avatar
Ralf Jung committed
21 22 23
       end
    end)).

Ralf Jung's avatar
Ralf Jung committed
24
Definition one_shotR := csumR (exclR unitC) (agreeR ZC).
Robbert Krebbers's avatar
Robbert Krebbers committed
25 26
Definition Pending : one_shotR := Cinl (Excl ()).
Definition Shot (n : Z) : one_shotR := Cinr (to_agree n).
27

28
Class one_shotG Σ := { one_shot_inG :> inG Σ one_shotR }.
29
Definition one_shotΣ : gFunctors := #[GFunctor one_shotR].
30
Instance subG_one_shotΣ {Σ} : subG one_shotΣ Σ  one_shotG Σ.
31
Proof. solve_inG. Qed.
Jacques-Henri Jourdan's avatar
Jacques-Henri Jourdan committed
32

Ralf Jung's avatar
Ralf Jung committed
33
Section proof.
34
Local Set Default Proof Using "Type*".
35
Context `{!heapG Σ, !one_shotG Σ}.
Ralf Jung's avatar
Ralf Jung committed
36

37
Definition one_shot_inv (γ : gname) (l : loc) : iProp Σ :=
38
  (l  NONEV  own γ Pending   n : Z, l  SOMEV #n  own γ (Shot n))%I.
Ralf Jung's avatar
Ralf Jung committed
39

40
Lemma wp_one_shot (Φ : val  iProp Σ) :
41
  ( f1 f2 : val,
Ralf Jung's avatar
Ralf Jung committed
42
    ( n : Z,  WP f1 #n {{ w, w = #true  w = #false }}) 
43
     WP f2 #() {{ g,  WP g #() {{ _, True }} }} - Φ (f1,f2)%V)
Ralf Jung's avatar
Ralf Jung committed
44 45
   WP one_shot_example #() {{ Φ }}.
Proof.
46
  iIntros "Hf /=". pose proof (nroot .@ "N") as N.
Jacques-Henri Jourdan's avatar
Jacques-Henri Jourdan committed
47
  rewrite -wp_fupd. wp_lam. wp_alloc l as "Hl".
48 49
  iMod (own_alloc Pending) as (γ) "Hγ"; first done.
  iMod (inv_alloc N _ (one_shot_inv γ l) with "[Hl Hγ]") as "#HN".
Robbert Krebbers's avatar
Robbert Krebbers committed
50
  { iNext. iLeft. by iSplitL "Hl". }
Jacques-Henri Jourdan's avatar
Jacques-Henri Jourdan committed
51 52
  wp_pures. iModIntro. iApply "Hf"; iSplit.
  - iIntros (n) "!#". wp_lam. wp_pures.
53 54
    iInv N as ">[[Hl Hγ]|H]"; last iDestruct "H" as (m) "[Hl Hγ]".
    + iMod (own_update with "Hγ") as "Hγ".
55
      { by apply cmra_update_exclusive with (y:=Shot n). }
56
      wp_cas_suc. iSplitL; last eauto.
57
      iModIntro. iNext; iRight; iExists n; by iFrame.
58
    + wp_cas_fail. iSplitL; last eauto.
59
      rewrite /one_shot_inv; eauto 10.
60
  - iIntros "!# /=". wp_lam. wp_bind (! _)%E.
61
    iInv N as ">Hγ".
Ralf Jung's avatar
Ralf Jung committed
62 63
    iAssert ( v, l  v  ((v = NONEV  own γ Pending) 
        n : Z, v = SOMEV #n  own γ (Shot n)))%I with "[Hγ]" as "Hv".
64
    { iDestruct "Hγ" as "[[Hl Hγ]|Hl]"; last iDestruct "Hl" as (m) "[Hl Hγ]".
65 66
      + iExists NONEV. iFrame. eauto.
      + iExists (SOMEV #m). iFrame. eauto. }
67
    iDestruct "Hv" as (v) "[Hl Hv]". wp_load.
Ralf Jung's avatar
Ralf Jung committed
68 69
    iAssert (one_shot_inv γ l  (v = NONEV   n : Z,
      v = SOMEV #n  own γ (Shot n)))%I with "[Hl Hv]" as "[Hinv #Hv]".
70
    { iDestruct "Hv" as "[[% ?]|Hv]"; last iDestruct "Hv" as (m) "[% ?]"; subst.
71
      + Show. iSplit. iLeft; by iSplitL "Hl". eauto.
72
      + iSplit. iRight; iExists m; by iSplitL "Hl". eauto. }
73
    iSplitL "Hinv"; first by eauto.
Jacques-Henri Jourdan's avatar
Jacques-Henri Jourdan committed
74 75 76 77
    iModIntro. wp_pures. iIntros "!#". wp_lam.
    iDestruct "Hv" as "[%|Hv]"; last iDestruct "Hv" as (m) "[% Hγ']";
      subst; wp_match; [done|].
    wp_bind (! _)%E.
78
    iInv N as "[[Hl >Hγ]|H]"; last iDestruct "H" as (m') "[Hl Hγ]".
79
    { by iDestruct (own_valid_2 with "Hγ Hγ'") as %?. }
80
    wp_load. Show.
81
    iDestruct (own_valid_2 with "Hγ Hγ'") as %?%agree_op_invL'; subst.
82
    iModIntro. iSplitL "Hl".
83
    { iNext; iRight; by eauto. }
Jacques-Henri Jourdan's avatar
Jacques-Henri Jourdan committed
84
    wp_apply wp_assert. wp_pures. by case_bool_decide.
Ralf Jung's avatar
Ralf Jung committed
85 86
Qed.

87
Lemma ht_one_shot (Φ : val  iProp Σ) :
88
  {{ True }} one_shot_example #()
89
    {{ ff,
Ralf Jung's avatar
Ralf Jung committed
90
      ( n : Z, {{ True }} Fst ff #n {{ w, w = #true  w = #false }}) 
91
      {{ True }} Snd ff #() {{ g, {{ True }} g #() {{ _, True }} }}
Ralf Jung's avatar
Ralf Jung committed
92 93
    }}.
Proof.
94
  iIntros "!# _". iApply wp_one_shot. iIntros (f1 f2) "[#Hf1 #Hf2]"; iSplit.
Jacques-Henri Jourdan's avatar
Jacques-Henri Jourdan committed
95 96
  - iIntros (n) "!# _". wp_apply "Hf1".
  - iIntros "!# _". wp_apply (wp_wand with "Hf2"). by iIntros (v) "#? !# _".
Ralf Jung's avatar
Ralf Jung committed
97 98
Qed.
End proof.
Ralf Jung's avatar
Ralf Jung committed
99 100 101 102 103 104 105 106 107 108

(* Have a client with a closed proof. *)
Definition client : expr :=
  let: "ff" := one_shot_example #() in
  (Fst "ff" #5 ||| let: "check" := Snd "ff" #() in "check" #()).

Section client.
  Context `{!heapG Σ, !one_shotG Σ, !spawnG Σ}.

  Lemma client_safe : WP client {{ _, True }}%I.
109
  Proof using Type*.
Ralf Jung's avatar
Ralf Jung committed
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
    rewrite /client. wp_apply wp_one_shot. iIntros (f1 f2) "[#Hf1 #Hf2]".
    wp_let. wp_apply wp_par.
    - wp_apply "Hf1".
    - wp_proj. wp_bind (f2 _)%E. iApply wp_wand; first by iExact "Hf2".
      iIntros (check) "Hcheck". wp_pures. iApply "Hcheck".
    - auto.
  Qed.
End client.

(** Put together all library functors. *)
Definition clientΣ : gFunctors := #[ heapΣ; one_shotΣ; spawnΣ ].
(** This lemma implicitly shows that these functors are enough to meet
all library assumptions. *)
Lemma client_adequate σ : adequate NotStuck client σ (λ _ _, True).
Proof. apply (heap_adequacy clientΣ)=> ?. apply client_safe. Qed.

(* Since we check the output of the test files, this means
our test suite will fail if we ever accidentally add an axiom
to anything used by this proof. *)
Print Assumptions client_adequate.