Library zoo.iris.base_logic.lib.twins

Require Import zoo.prelude.
Require Import zoo.iris.algebra.lib.twins.
Require Export zoo.iris.base_logic.lib.base.
Require Import zoo.iris.base_logic.algebra.twins.
Require Import zoo.iris.diaframe.
Require Import zoo.options.

Class TwinsG Σ F :=
  { #[local] twins۰G۰inG :: inG Σ (twins۰R $ oFunctor_apply F $ iPropO Σ)
  }.

Definition twins۰Σ F `{!oFunctorContractive F} :=
  #[GFunctor (twins۰RF F)
  ].
#[global] Instance subGtwins۰Σ Σ F `{!oFunctorContractive F} :
  subG (twins۰Σ F) Σ
  TwinsG Σ F.

Section twins۰G.
  Context `{twins۰G : !TwinsG Σ F}.

  Definition twins۰twin₁ γ dq a :=
    own γ (twins۰twin₁ dq a).
  Definition twins۰twin₂ γ a :=
    own γ (twins۰twin₂ a).

  #[global] Instance twins۰twin₁proper γ dq :
    Proper ((≡) ==> (≡)) (twins۰twin₁ γ dq).
  #[global] Instance twins۰twin₂proper γ :
    Proper ((≡) ==> (≡)) (twins۰twin₂ γ).

  #[global] Instance twins۰twin₁timeless γ dq a :
    Discrete a
    Timeless (twins۰twin₁ γ dq a).
  #[global] Instance twins۰twin₂timeless γ a :
    Discrete a
    Timeless (twins۰twin₂ γ a).

  #[global] Instance twins۰twin₁persistent γ a :
    Persistent (twins۰twin₁ γ DfracDiscarded a).

  #[global] Instance twins۰twin₁fractional γ a :
    Fractional (λ q, twins۰twin₁ γ (DfracOwn q) a).
  #[global] Instance twins۰twin₁as_fractional γ q a :
    AsFractional (twins۰twin₁ γ (DfracOwn q) a) (λ q, twins۰twin₁ γ (DfracOwn q) a) q.

  Lemma twinsalloc a b :
    a b
     |==>
       γ,
      twins۰twin₁ γ (DfracOwn 1) a
      twins۰twin₂ γ b.
  Lemma twinsalloc' a :
     |==>
       γ,
      twins۰twin₁ γ (DfracOwn 1) a twins۰twin₂ γ a.

  Lemma twins۰twin₁valid γ dq a :
    twins۰twin₁ γ dq a
     dq.
  Lemma twins۰twin₁combine γ dq1 a1 dq2 a2 :
    twins۰twin₁ γ dq1 a1 -∗
    twins۰twin₁ γ dq2 a2 -∗
      a1 a2
      twins۰twin₁ γ (dq1 dq2) a1.
  Lemma twins۰twin₁validー2 γ dq1 a1 dq2 a2 :
    twins۰twin₁ γ dq1 a1 -∗
    twins۰twin₁ γ dq2 a2 -∗
       (dq1 dq2)
      a1 a2.
  Lemma twins۰twin₁agree γ dq1 a1 dq2 a2 :
    twins۰twin₁ γ dq1 a1 -∗
    twins۰twin₁ γ dq2 a2 -∗
    a1 a2.
  Lemma twins۰twin₁dfracne γ1 dq1 a1 γ2 dq2 a2 :
    ¬ (dq1 dq2)
    twins۰twin₁ γ1 dq1 a1 -∗
    twins۰twin₁ γ2 dq2 a2 -∗
    γ1 γ2.
  Lemma twins۰twin₁ne γ1 a1 γ2 dq2 a2 :
    twins۰twin₁ γ1 (DfracOwn 1) a1 -∗
    twins۰twin₁ γ2 dq2 a2 -∗
    γ1 γ2.
  Lemma twins۰twin₁exclusive γ a1 dq2 a2 :
    twins۰twin₁ γ (DfracOwn 1) a1 -∗
    twins۰twin₁ γ dq2 a2 -∗
    False.
  Lemma twins۰twin₁persist γ dq a :
    twins۰twin₁ γ dq a |==>
    twins۰twin₁ γ DfracDiscarded a.

  Lemma twins۰twin₂exclusive γ a1 a2 :
    twins۰twin₂ γ a1 -∗
    twins۰twin₂ γ a2 -∗
    False.

  Lemma twinsagree γ dq a b :
    twins۰twin₁ γ dq a -∗
    twins۰twin₂ γ b -∗
    a b.

  Section ofe_discrete.
    Context `{!OfeDiscrete $ oFunctor_apply F $ iPropO Σ}.

    Lemma twins۰twin₁combinediscrete γ dq1 a1 dq2 a2 :
      twins۰twin₁ γ dq1 a1 -∗
      twins۰twin₁ γ dq2 a2 -∗
        a1 a2
        twins۰twin₁ γ (dq1 dq2) a1.
    Lemma twins۰twin₁validー2ーdiscrete γ dq1 a1 dq2 a2 :
      twins۰twin₁ γ dq1 a1 -∗
      twins۰twin₁ γ dq2 a2 -∗
         (dq1 dq2)
        a1 a2.
    Lemma twins۰twin₁agreediscrete γ dq1 a1 dq2 a2 :
      twins۰twin₁ γ dq1 a1 -∗
      twins۰twin₁ γ dq2 a2 -∗
      a1 a2.

    Lemma twinsagreediscrete γ dq a b :
      twins۰twin₁ γ dq a -∗
      twins۰twin₂ γ b -∗
      a b.

    Section leibniz_equiv.
      Context `{!LeibnizEquiv $ oFunctor_apply F $ iPropO Σ}.

      Lemma twins۰twin₁combineL γ dq1 a1 dq2 a2 :
        twins۰twin₁ γ dq1 a1 -∗
        twins۰twin₁ γ dq2 a2 -∗
          a1 = a2
          twins۰twin₁ γ (dq1 dq2) a1.
      Lemma twins۰twin₁validー2ーL γ dq1 a1 dq2 a2 :
        twins۰twin₁ γ dq1 a1 -∗
        twins۰twin₁ γ dq2 a2 -∗
           (dq1 dq2)
          a1 = a2.
      Lemma twins۰twin₁agreeL γ dq1 a1 dq2 a2 :
        twins۰twin₁ γ dq1 a1 -∗
        twins۰twin₁ γ dq2 a2 -∗
        a1 = a2.

      Lemma twinsagreeL γ dq a b :
        twins۰twin₁ γ dq a -∗
        twins۰twin₂ γ b -∗
        a = b.
    End leibniz_equiv.
  End ofe_discrete.

  Lemma twinsupdateequivI {γ a1 b1} a2 b2 :
    twins۰twin₁ γ (DfracOwn 1) a1 -∗
    twins۰twin₂ γ b1 -∗
    a2 b2 ==∗
      twins۰twin₁ γ (DfracOwn 1) a2
      twins۰twin₂ γ b2.
  Lemma twinsupdateequiv {γ a1 b1} a2 b2 :
    a2 b2
    twins۰twin₁ γ (DfracOwn 1) a1 -∗
    twins۰twin₂ γ b1 ==∗
      twins۰twin₁ γ (DfracOwn 1) a2
      twins۰twin₂ γ b2.
  Lemma twinsupdate {γ a b} a' :
    twins۰twin₁ γ (DfracOwn 1) a -∗
    twins۰twin₂ γ b ==∗
      twins۰twin₁ γ (DfracOwn 1) a'
      twins۰twin₂ γ a'.
End twins۰G.

#[global] Opaque twins۰twin₁.
#[global] Opaque twins۰twin₂.