Library zoo_saturn.stack_mpmc_2

Require Import zoo.prelude.
Require Import zoo.iris.base_logic.lib.twins.
Require Import zoo.base.
Require Import zoo_std.option.
Require Export zoo_saturn.stack_mpmc_2__code.
Require Import zoo_saturn.stack_mpmc_2__types.
Require Import zoo.options.

Implicit Type l : location.
Implicit Type v t : val.
Implicit Type ws : list val.

Class StackMpmc2G Σ `{zoo۰G : !ZooG Σ} :=
  { #[local] stack_mpmc_2۰G۰model۰G :: TwinsG Σ (leibnizO (option $ list val))
  }.

Definition stack_mpmc_2۰Σ :=
  #[twins۰Σ (leibnizO (option $ list val))
  ].
#[global] Instance subGstack_mpmc_2۰Σ Σ `{zoo۰G : !ZooG Σ} :
  subG stack_mpmc_2۰Σ Σ
  StackMpmc2G Σ.

Section zoo۰G.
  Context `{stack_mpmc_2۰G : StackMpmc2G Σ}.

  #[local] Definition metadata :=
    gname.
  Implicit Type γ : metadata.

  #[local] Definition model₁ γ vs :=
    twins۰twin₁ γ (if vs is None then DfracDiscarded else DfracOwn 1) vs.
  #[local] Definition model₂ γ vs :=
    twins۰twin₂ γ vs.

  #[local] Definition inv۰inner l γ : iProp Σ :=
     vs,
    l ↦ᵣ from_option (clist۰to_val list۰to_clist_open) §clist٠Closed vs
    model₂ γ vs.
  #[local] Instance : CustomIpat "inv۰inner" :=
    " ( %vs & Hl & Hmodel₂ ) ".
  Definition stack_mpmc_2۰inv t ι : iProp Σ :=
     l γ,
    t = #l
    l γ
    inv ι (inv۰inner l γ).
  #[local] Instance : CustomIpat "inv" :=
    " ( %l & %γ & -> & #Hmeta & #Hinv ) ".

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

  Definition stack_mpmc_2۰closed t :=
    stack_mpmc_2۰model t None.

  #[global] Instance stack_mpmc_2۰modeltimeless t vs :
    Timeless (stack_mpmc_2۰model t vs).

  #[global] Instance stack_mpmc_2۰invpersistent t ι :
    Persistent (stack_mpmc_2۰inv t ι).
  #[global] Instance stack_mpmc_2۰modelpersistent t :
    Persistent (stack_mpmc_2۰model t None).

  #[local] Lemma modelalloc :
     |==>
       γ,
      model₁ γ (Some [])
      model₂ γ (Some []).
  #[local] Lemma model₁exclusive γ vs1 vs2 :
    model₁ γ (Some vs1) -∗
    model₁ γ vs2 -∗
    False.
  #[local] Lemma modelagree γ vs1 vs2 :
    model₁ γ vs1 -∗
    model₂ γ vs2 -∗
    vs1 = vs2.
  #[local] Lemma modelupdate {γ ws1 ws2} ws :
    model₁ γ (Some ws1) -∗
    model₂ γ (Some ws2) ==∗
      model₁ γ (Some ws)
      model₂ γ (Some ws).
  #[local] Lemma modelclose γ ws1 ws2 :
    model₁ γ (Some ws1) -∗
    model₂ γ (Some ws2) ==∗
      model₁ γ None
      model₂ γ None.

  Lemma stack_mpmc_2۰modelexclusive t vs1 vs2 :
    stack_mpmc_2۰model t (Some vs1) -∗
    stack_mpmc_2۰model t vs2 -∗
    False.

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

  Lemma stack_mpmc_2٠pushspec t ι v :
    <<<
      stack_mpmc_2۰inv t ι
    | ∀∀ vs,
      stack_mpmc_2۰model t vs
    >>>
      stack_mpmc_2٠push t v @ ι
    <<<
      stack_mpmc_2۰model t (cons v <$> vs)
    | RET #(bool_decide (vs = None));
      £ 1
    >>>.
  Lemma stack_mpmc_2٠pushspecclosed t ι v :
    {{{
      stack_mpmc_2۰inv t ι
      stack_mpmc_2۰closed t
    }}}
      stack_mpmc_2٠push t v
    {{{
      RET true;
      True
    }}}.

  Lemma stack_mpmc_2٠popspec t ι :
    <<<
      stack_mpmc_2۰inv t ι
    | ∀∀ vs,
      stack_mpmc_2۰model t vs
    >>>
      stack_mpmc_2٠pop t @ ι
    <<<
      stack_mpmc_2۰model t (tail <$> vs)
    | RET default Anything (option۰to_optional head <$> vs);
      £ 1
    >>>.
  Lemma stack_mpmc_2٠popspecclosed t ι v :
    {{{
      stack_mpmc_2۰inv t ι
      stack_mpmc_2۰closed t
    }}}
      stack_mpmc_2٠pop t
    {{{
      RET §optional٠Anything;
      True
    }}}.

  Lemma stack_mpmc_2٠is_closedspec t ι :
    <<<
      stack_mpmc_2۰inv t ι
    | ∀∀ vs,
      stack_mpmc_2۰model t vs
    >>>
      stack_mpmc_2٠is_closed t @ ι
    <<<
      stack_mpmc_2۰model t vs
    | RET #(bool_decide (vs = None));
      £ 1
    >>>.
  Lemma stack_mpmc_2٠is_closedspecclosed t ι :
    {{{
      stack_mpmc_2۰inv t ι
      stack_mpmc_2۰closed t
    }}}
      stack_mpmc_2٠is_closed t
    {{{
      RET true;
      True
    }}}.

  Lemma stack_mpmc_2٠closespec t ι :
    <<<
      stack_mpmc_2۰inv t ι
    | ∀∀ vs,
      stack_mpmc_2۰model t vs
    >>>
      stack_mpmc_2٠close t @ ι
    <<<
      stack_mpmc_2۰model t None
    | RET from_option list۰to_clist_open Closed vs;
      £ 1
    >>>.
  Lemma stack_mpmc_2٠closedspecclosed t ι v :
    {{{
      stack_mpmc_2۰inv t ι
      stack_mpmc_2۰closed t
    }}}
      stack_mpmc_2٠close t
    {{{
      RET §clist٠Closed;
      True
    }}}.
End zoo۰G.

Require zoo_saturn.stack_mpmc_2__opaque.

#[global] Opaque stack_mpmc_2۰inv.
#[global] Opaque stack_mpmc_2۰model.