Library zoo_std.waiter_mpsc

Require Import zoo.prelude.
Require Import zoo.common.countable.
Require Import zoo.iris.base_logic.lib.oneshot.
Require Import zoo.iris.base_logic.lib.excl.
Require Import zoo.base.
Require Export zoo_std.waiter_mpsc__code.
Require Import zoo_std.waiter_mpsc__types.
Require Import zoo.options.

Implicit Type b : bool.
Implicit Type 𝑡 : location.

Class WaiterMpscG Σ `{zoo۰G : !ZooG Σ} :=
  { #[local] waiter_mpsc۰G۰mutex۰G :: MutexG Σ
  ; #[local] waiter_mpsc۰G۰lstate۰G :: OneshotG Σ unit unit
  ; #[local] waiter_mpsc۰G۰consumer۰G :: ExclG Σ unitO
  }.

Definition waiter_mpsc۰Σ :=
  #[mutex۰Σ
  ; oneshot۰Σ unit unit
  ; excl۰Σ unitO
  ].
#[global] Instance subGwaiter_mpsc۰Σ Σ `{zoo۰G : !ZooG Σ} :
  subG waiter_mpsc۰Σ Σ
  WaiterMpscG Σ .

Section waiter_mpsc۰G.
  Context `{waiter_mpsc۰G : WaiterMpscG Σ}.

  Record metadata :=
    { metadata۰mutex : val
    ; metadata۰condition : val
    ; metadata۰lstate : gname
    ; metadata۰consumer : gname
    }.
  Implicit Type γ : metadata.

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

  #[local] Definition inv۰inner 𝑡 γ P : iProp Σ :=
     b,
    𝑡.[flag] #b
    if b then
      oneshot۰shot γ.(metadata۰lstate) ()
      (P excl γ.(metadata۰consumer) ())
    else
      oneshot۰pending γ.(metadata۰lstate) (DfracOwn 1) ().
  Definition waiter_mpsc۰inv t P : iProp Σ :=
     𝑡 γ,
    t = #𝑡
    𝑡 γ
    𝑡.[mutex] γ.(metadata۰mutex)
    mutex۰inv γ.(metadata۰mutex) True
    𝑡.[condition] γ.(metadata۰condition)
    condition۰inv γ.(metadata۰condition)
    inv nroot (inv۰inner 𝑡 γ P).

  Definition waiter_mpsc۰consumer t : iProp Σ :=
     𝑡 γ,
    t = #𝑡
    𝑡 γ
    excl γ.(metadata۰consumer) ().

  Definition waiter_mpsc۰notified t : iProp Σ :=
     𝑡 γ,
    t = #𝑡
    𝑡 γ
    oneshot۰shot γ.(metadata۰lstate) ().

  #[global] Instance waiter_mpsc۰invcontractive t :
    Contractive (waiter_mpsc۰inv t).
  #[global] Instance waiter_mpsc۰invne t :
    NonExpansive (waiter_mpsc۰inv t).
  #[global] Instance waiter_mpsc۰invproper t :
    Proper ((≡) ==> (≡)) (waiter_mpsc۰inv t).

  #[global] Instance waiter_mpsc۰consumertimeless t :
    Timeless (waiter_mpsc۰consumer t).
  #[global] Instance waiter_mpsc۰notifiedtimeless t :
    Timeless (waiter_mpsc۰notified t).

  #[global] Instance waiter_mpsc۰invpersistent t P :
    Persistent (waiter_mpsc۰inv t P).
  #[global] Instance waiter_mpsc۰notifiedpersistent t :
    Persistent (waiter_mpsc۰notified t).

  Lemma waiter_mpsc۰consumerexclusive t :
    waiter_mpsc۰consumer t -∗
    waiter_mpsc۰consumer t -∗
    False.

  Lemma waiter_mpsc٠createspec P :
    {{{
      True
    }}}
      waiter_mpsc٠create ()
    {{{
      t
    , RET t;
      waiter_mpsc۰inv t P
      waiter_mpsc۰consumer t
    }}}.

  Lemma waiter_mpsc٠notifyspec t P :
    {{{
      waiter_mpsc۰inv t P
      P
    }}}
      waiter_mpsc٠notify t
    {{{
      b
    , RET #b;
      waiter_mpsc۰notified t
    }}}.

  Lemma waiter_mpsc٠try_waitspec t P :
    {{{
      waiter_mpsc۰inv t P
      waiter_mpsc۰consumer t
    }}}
      waiter_mpsc٠try_wait t
    {{{
      b
    , RET #b;
      if b then
        P
      else
        waiter_mpsc۰consumer t
    }}}.
  Lemma waiter_mpsc٠try_waitspecnotified t P :
    {{{
      waiter_mpsc۰inv t P
      waiter_mpsc۰consumer t
      waiter_mpsc۰notified t
    }}}
      waiter_mpsc٠try_wait t
    {{{
      RET true;
      P
    }}}.

  Lemma waiter_mpsc٠waitspec t P :
    {{{
      waiter_mpsc۰inv t P
      waiter_mpsc۰consumer t
    }}}
      waiter_mpsc٠wait t
    {{{
      RET ();
      P
    }}}.
End waiter_mpsc۰G.

Require zoo_std.waiter_mpsc__opaque.

#[global] Opaque waiter_mpsc۰inv.
#[global] Opaque waiter_mpsc۰consumer.
#[global] Opaque waiter_mpsc۰notified.