Guarantees by Construction (Mechanization)

Jules Jacobs

From dlfactris.session_logic Require Export sessions.

Module Imp.
  Definition fork_chan : val := λ: "f",                                          (* https://apndx.org/pub/thesis/thesis.pdf#nameddest=c323fd08 *)
    Alloc $ Ses.fork_chan (λ: "c2", "f" (Alloc "c2")).

  Definition recv : val := λ: "c",
    let: '("v","r") := Ses.recv !"c" in
    "c" <- "r";; "v".

  Definition send : val := λ: "c" "v",
    "c" <- Ses.send (!"c") "v".

  Definition close : val := λ: "c",
    Ses.close !"c";; Free "c".

  Definition wait : val := λ: "c",
    Ses.wait !"c";; Free  "c".

  Notation prot := Ses.prot.
  Notation dual := Ses.dual.
  Notation end_prot := Ses.end_prot.
  Notation msg_prot := Ses.msg_prot.
  Notation subprot := Ses.subprot.

  Definition own_chan (c : val) (p : aMiniProt) : aProp :=
    ∃ (l : loc) ch, ⌜⌜ c = #l ⌝⌝ ∗ l ↦ ch ∗ Ses.own_chan ch p.

  Module Import notations.
    Notation "p ⊑ q" := (subprot p q) : bi_scope.
    Notation "c ↣ p" := (own_chan c p) : bi_scope.
  End notations.

  Notation subprot_refl := Ses.subprot_refl.
  Notation subprot_trans := Ses.subprot_trans.
  Notation subprot_dual := Ses.subprot_dual.

  Global Instance own_chan_contractive ch : Contractive (own_chan ch).
  Proof. solve_contractive. Qed.
  Global Instance own_chan_ne ch : NonExpansive (own_chan ch).
  Proof. solve_proper. Qed.
  Global Instance own_chan_proper ch : Proper ((≡) ==> (≡)) (own_chan ch).
  Proof. solve_proper. Qed.

  Lemma own_chan_subprot c p1 p2 : c ↣ p1 -∗ ▷ (p1 ⊑ p2) -∗ c ↣ p2.
  Proof.
    iIntros "(%l & %ch & -> & Hl & Hch) Hsp". iExists l, ch.
    iSplit; [done|]. iFrame. by iApply (Ses.own_chan_subprot with "Hch").
  Qed.

  Lemma wp_fork_chan p (f : val) :                                               (* https://apndx.org/pub/thesis/thesis.pdf#nameddest=061b08c7 *)
    ▷ (∀ c, c ↣ dual p -∗ WP f c {{ _, emp }}) -∗
    WP fork_chan f {{ c, c ↣ p }}.
  Proof.
    iIntros "Hf". wp_rec!. iApply (Ses.wp_fork_chan with "[Hf]").
    { iIntros "!>" (c) "Hc". wp_alloc l as "Hl". iApply "Hf".
      iExists l, c. by iFrame. }
    iIntros "!>" (c) "Hc". wp_alloc l as "Hl". iExists l, c. by iFrame.
  Qed.

  Lemma wp_recv {A} c (v : A → val) (P : A → aProp) (p : A → aMiniProt) :
    c ↣ msg_prot ARecv v P p -∗
    WP recv c {{ w, ∃ x, ⌜⌜ w = v x ⌝⌝ ∗ c ↣ p x ∗ P x }}.
  Proof.
    iIntros "(%l & %ch & -> & Hl & Hch)". wp_rec!. wp_load.
    iApply (Ses.wp_recv with "Hch"); iIntros "!>" (ch' x) "[Hch' HP]".
    wp_store!. iExists x. iSplit; [done|]. iFrame. iExists l, ch'. by iFrame.
  Qed.

  Lemma wp_send {A} c (v : A → val) (P : A → aProp) (p : A → aMiniProt) x :
    c ↣ msg_prot ASend v P p -∗ P x -∗
    WP send c (v x) {{ v, ⌜⌜ v = #() ⌝⌝ ∗ c ↣ p x }}.
  Proof.
    iIntros "(%l & %ch & -> & Hl & Hch) HP". wp_rec!. wp_load.
    iApply (Ses.wp_send with "Hch HP"); iIntros "!>" (ch') "Hch'".
    wp_store. iSplit; [done|]. iExists l, ch'. by iFrame.
  Qed.

  Lemma wp_wait c P :
    c ↣ end_prot ARecv P -∗ WP wait c {{ v, ⌜⌜ v = #() ⌝⌝ ∗ P }}.
  Proof.
    iIntros "(%l & %ch & -> & Hl & Hch)". wp_rec!. wp_load.
    iApply (Ses.wp_wait with "Hch"); iIntros "!> HP". wp_free. by iFrame.
  Qed.

  Lemma wp_close c P :
    c ↣ end_prot ASend P -∗ P -∗ WP close c {{ v, ⌜⌜ v = #() ⌝⌝ }}.
  Proof.
    iIntros "(%l & %ch & -> & Hl & Hch) HP". wp_rec!. wp_load.
    iApply (Ses.wp_close with "Hch HP"); iNext. by wp_free.
  Qed.

  Global Opaque fork_chan recv send close wait.
  Global Opaque own_chan.
End Imp.