Library zoo_saturn.queue_mpsc_3

Require Import zoo.prelude.
Require Import zoo.common.countable.
Require Import zoo.common.list.
Require Import zoo.iris.base_logic.lib.twins.
Require Import zoo.iris.base_logic.lib.oneshot.
Require Import zoo.base.
Require Import zoo_std.option.
Require Export zoo_saturn.queue_mpsc_3__code.
Require Import zoo_saturn.queue_mpsc_3__types.
Require Import zoo.options.

Implicit Type b closed : bool.
Implicit Type l : location.
Implicit Type v t : val.
Implicit Type vs front back : list val.
Implicit Type ws : option (list val).

Class QueueMpsc3G Σ `{zoo۰G : !ZooG Σ} :=
  { #[local] queue_mpsc_3۰G۰twins۰G :: TwinsG Σ (leibnizO (list val))
  ; #[local] queue_mpsc_3۰G۰lstate۰G :: OneshotG Σ () ()
  }.

Definition queue_mpsc_3۰Σ :=
  #[twins۰Σ (leibnizO (list val))
  ; oneshot۰Σ () ()
  ].
#[global] Instance subGqueue_mpsc_3۰Σ Σ `{zoo۰G : !ZooG Σ} :
  subG queue_mpsc_3۰Σ Σ
  QueueMpsc3G Σ.

Section queue_mpsc_3۰G.
  Context `{queue_mpsc_3۰G : QueueMpsc3G Σ}.

  Record metadata :=
    { metadata۰model : gname
    ; metadata۰front : gname
    ; metadata۰lstate : gname
    }.
  Implicit Type γ : metadata.

  #[local] Instance metadataeq_dec : EqDecision metadata :=
    ltac:(solve_decision).
  #[local] Instance metadatacountable :
    Countable metadata.

  #[local] Definition model₁' γ_model vs :=
    twins۰twin₁ γ_model (DfracOwn 1) vs.
  #[local] Definition model₁ γ vs :=
    model₁' γ.(metadata۰model) vs.
  #[local] Definition model₂' γ_model vs :=
    twins۰twin₂ γ_model vs.
  #[local] Definition model₂ γ vs :=
    model₂' γ.(metadata۰model) vs.

  #[local] Definition front₁' γ_front front :=
    twins۰twin₁ γ_front (DfracOwn 1) front.
  #[local] Definition front₁ γ front :=
    front₁' γ.(metadata۰front) front.
  #[local] Definition front₂' γ_model front :=
    twins۰twin₂ γ_model front.
  #[local] Definition front₂ γ front :=
    front₂' γ.(metadata۰front) front.

  #[local] Definition lstate۰open₁' γ_lstate :=
    oneshot۰pending γ_lstate (DfracOwn (1/2)) ().
  #[local] Definition lstate۰open₁ γ :=
    lstate۰open₁' γ.(metadata۰lstate).
  #[local] Definition lstate۰open₂' γ_lstate :=
    oneshot۰pending γ_lstate (DfracOwn (1/2)) ().
  #[local] Definition lstate۰open₂ γ :=
    lstate۰open₂' γ.(metadata۰lstate).
  #[local] Definition lstate۰closed γ :=
    oneshot۰shot γ.(metadata۰lstate) ().

  #[local] Definition inv۰inner l γ : iProp Σ :=
     front v_back,
    front₂ γ front
    l.[back] v_back
    ( ( lstate۰open₂ γ
           back,
          v_back = list۰to_clist_open back
          model₂ γ (front ++ reverse back)
      ) (
        lstate۰closed γ
        v_back = §clist٠Closed%V
      )
    ).
  #[local] Instance : CustomIpat "inv۰inner" :=
    " ( %front{} & %v_back & >Hfront₂ & >Hl_back & [(>Hopen₂ & %back{} & >-> & >Hmodel₂{_{suff}}) | (>Hclosed{_{suff}} & >->)] ) ".
  Definition queue_mpsc_3۰inv t ι : iProp Σ :=
     l γ,
    t = #l
    l γ
    inv ι (inv۰inner l γ).
  #[local] Instance : CustomIpat "inv" :=
    " ( %l & %γ & -> & #Hmeta & #Hinv ) ".

  Definition queue_mpsc_3۰model t vs : iProp Σ :=
     l γ,
    t = #l
    l γ
    model₁ γ vs.
  #[local] Instance : CustomIpat "model" :=
    " ( %l{;_} & %γ{;_} & %Heq{} & Hmeta_{} & Hmodel₁{_{}} ) ".

  Definition queue_mpsc_3۰consumer t ws : iProp Σ :=
     l γ v_front front,
    t = #l
    l γ
    l.[front] v_front
    front₁ γ front
    match ws with
    | None
        v_front = list۰to_clist_open front
        lstate۰open₁ γ
    | Some ws
        ws = front
        v_front = list۰to_clist_closed front
        lstate۰closed γ
        model₂ γ front
    end.
  #[local] Instance : CustomIpat "consumer" :=
    " ( %l_ & %γ_ & %v_front & %front & %Heq & Hmeta_ & Hl_front & Hfront₁ & {{open}(-> & Hopen₁);{closed}(-> & -> & Hclosed & Hmodel₂);Hlstate} ) ".

  Definition queue_mpsc_3۰closed t : iProp Σ :=
     l γ,
    t = #l
    l γ
    lstate۰closed γ.
  #[local] Instance : CustomIpat "closed" :=
    " ( %l_ & %γ_ & %Heq & Hmeta_ & Hclosed ) ".

  #[global] Instance queue_mpsc_3۰modeltimeless t vs :
    Timeless (queue_mpsc_3۰model t vs).
  #[global] Instance queue_mpsc_3۰consumertimeless t ws :
    Timeless (queue_mpsc_3۰consumer t ws ).

  #[global] Instance queue_mpsc_3۰invpersistent t ι :
    Persistent (queue_mpsc_3۰inv t ι).
  #[global] Instance queue_mpsc_3۰closedpersistent t :
    Persistent (queue_mpsc_3۰closed t).

  #[local] Lemma modelalloc :
     |==>
       γ_model,
      model₁' γ_model []
      model₂' γ_model [].
  #[local] Lemma model₁exclusive γ vs1 vs2 :
    model₁ γ vs1 -∗
    model₁ γ vs2 -∗
    False.
  #[local] Lemma modelagree γ vs1 vs2 :
    model₁ γ vs1 -∗
    model₂ γ vs2 -∗
    vs1 = vs2.
  #[local] Lemma modelupdate {γ vs1 vs2} vs :
    model₁ γ vs1 -∗
    model₂ γ vs2 ==∗
      model₁ γ vs
      model₂ γ vs.

  #[local] Lemma frontalloc :
     |==>
       γ_front,
      front₁' γ_front []
      front₂' γ_front [].
  #[local] Lemma frontagree γ front1 front2 :
    front₁ γ front1 -∗
    front₂ γ front2 -∗
    front1 = front2.
  #[local] Lemma frontupdate {γ front1 front2} front :
    front₁ γ front1 -∗
    front₂ γ front2 ==∗
      front₁ γ front
      front₂ γ front.

  #[local] Lemma lstatealloc :
     |==>
       γ_lstate,
      lstate۰open₁' γ_lstate
      lstate۰open₂' γ_lstate.
  #[local] Lemma lstateopen₁closed γ :
    lstate۰open₁ γ -∗
    lstate۰closed γ -∗
    False.
  #[local] Lemma lstateopen₂closed γ :
    lstate۰open₂ γ -∗
    lstate۰closed γ -∗
    False.
  #[local] Lemma lstateupdate γ :
    lstate۰open₁ γ -∗
    lstate۰open₂ γ ==∗
    lstate۰closed γ.

  Lemma queue_mpsc_3۰modelexclusive t vs1 vs2 :
    queue_mpsc_3۰model t vs1 -∗
    queue_mpsc_3۰model t vs2 -∗
    False.

  Lemma queue_mpsc_3۰consumerexclusive t ws1 ws2 :
    queue_mpsc_3۰consumer t ws1 -∗
    queue_mpsc_3۰consumer t ws2 -∗
    False.
  Lemma queue_mpsc_3consumerclosed t vs :
    queue_mpsc_3۰consumer t (Some vs)
    queue_mpsc_3۰closed t.

  Lemma queue_mpsc_3٠createspec ι :
    {{{
      True
    }}}
      queue_mpsc_3٠create ()
    {{{
      t
    , RET t;
      queue_mpsc_3۰inv t ι
      queue_mpsc_3۰model t []
      queue_mpsc_3۰consumer t None
    }}}.

  Lemma queue_mpsc_3٠is_emptyspecopen t ι :
    <<<
      queue_mpsc_3۰inv t ι
      queue_mpsc_3۰consumer t None
    | ∀∀ vs,
      queue_mpsc_3۰model t vs
    >>>
      queue_mpsc_3٠is_empty t @ ι
    <<<
      queue_mpsc_3۰model t vs
    | RET #(bool_decide (vs = []%list));
      queue_mpsc_3۰consumer t None
    >>>.
  Lemma queue_mpsc_3٠is_emptyspecclosed t ι vs :
    {{{
      queue_mpsc_3۰inv t ι
      queue_mpsc_3۰consumer t (Some vs)
    }}}
      queue_mpsc_3٠is_empty t
    {{{
      RET #(bool_decide (vs = []%list));
      queue_mpsc_3۰consumer t (Some vs)
    }}}.

  Lemma queue_mpsc_3٠push_frontspecopen t ι v :
    <<<
      queue_mpsc_3۰inv t ι
      queue_mpsc_3۰consumer t None
    | ∀∀ vs,
      queue_mpsc_3۰model t vs
    >>>
      queue_mpsc_3٠push_front t v @ ι
    <<<
      queue_mpsc_3۰model t (v :: vs)
    | RET false;
      queue_mpsc_3۰consumer t None
    >>>.
  Lemma queue_mpsc_3٠push_frontspecclosed t ι vs v :
    <<<
      queue_mpsc_3۰inv t ι
      queue_mpsc_3۰consumer t (Some vs)
    | ∀∀ vs',
      queue_mpsc_3۰model t vs'
    >>>
      queue_mpsc_3٠push_front t v @ ι
    <<<
      ∃∃ b,
      b = bool_decide (vs = [])
      vs' = vs
      queue_mpsc_3۰model t (if b then [] else v :: vs)
    | RET #b;
      queue_mpsc_3۰consumer t (Some $ if b then [] else v :: vs)
    >>>.

  Lemma queue_mpsc_3٠push_backspecopen closed t ι v :
    <<<
      queue_mpsc_3۰inv t ι
    | ∀∀ vs,
      queue_mpsc_3۰model t vs
    >>>
      queue_mpsc_3٠push_back t v @ ι
    <<<
      ∃∃ closed,
      if closed then
        queue_mpsc_3۰model t vs
      else
        queue_mpsc_3۰model t (vs ++ [v])
    | RET #closed;
      if closed then
        queue_mpsc_3۰closed t
      else
        True
    >>>.
  Lemma queue_mpsc_3٠push_backspecclosed closed t ι v :
    {{{
      queue_mpsc_3۰inv t ι
      queue_mpsc_3۰closed t
    }}}
      queue_mpsc_3٠push_back t v
    {{{
      RET true;
      True
    }}}.

  Lemma queue_mpsc_3٠popspecopen t ι :
    <<<
      queue_mpsc_3۰inv t ι
      queue_mpsc_3۰consumer t None
    | ∀∀ vs,
      queue_mpsc_3۰model t vs
    >>>
      queue_mpsc_3٠pop t @ ι
    <<<
      queue_mpsc_3۰model t (tail vs)
    | RET head vs;
      queue_mpsc_3۰consumer t None
    >>>.
  Lemma queue_mpsc_3٠popspecclosed t ι vs :
    <<<
      queue_mpsc_3۰inv t ι
      queue_mpsc_3۰consumer t (Some vs)
    | ∀∀ vs',
      queue_mpsc_3۰model t vs'
    >>>
      queue_mpsc_3٠pop t @ ι
    <<<
      vs' = vs
      queue_mpsc_3۰model t (tail vs)
    | RET head vs;
      queue_mpsc_3۰consumer t (Some $ tail vs)
    >>>.

  Lemma queue_mpsc_3٠closespecopen t ι :
    <<<
      queue_mpsc_3۰inv t ι
      queue_mpsc_3۰consumer t None
    | ∀∀ vs,
      queue_mpsc_3۰model t vs
    >>>
      queue_mpsc_3٠close t @ ι
    <<<
      queue_mpsc_3۰model t vs
    | RET false;
      queue_mpsc_3۰consumer t (Some vs)
    >>>.
  Lemma queue_mpsc_3٠closespecclosed t ι vs :
    {{{
      queue_mpsc_3۰inv t ι
      queue_mpsc_3۰consumer t (Some vs)
    }}}
      queue_mpsc_3٠close t
    {{{
      RET true;
      queue_mpsc_3۰consumer t (Some vs)
    }}}.
End queue_mpsc_3۰G.

Require zoo_saturn.queue_mpsc_3__opaque.

#[global] Opaque queue_mpsc_3۰inv.
#[global] Opaque queue_mpsc_3۰model.
#[global] Opaque queue_mpsc_3۰consumer.
#[global] Opaque queue_mpsc_3۰closed.