Library zoo.iris.base_logic.lib.ghost_var

Require Import iris.algebra.lib.dfrac_agree.

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

Class GhostVarG Σ F :=
  { #[local] ghost_var۰G۰inG :: inG Σ (dfrac_agreeR $ oFunctor_apply F $ iPropO Σ)
  }.

Definition ghost_var۰Σ F `{!oFunctorContractive F} :=
  #[GFunctor (dfrac_agreeRF F)
  ].
#[global] Instance subGghost_var۰Σ Σ F `{!oFunctorContractive F} :
  subG (ghost_var۰Σ F) Σ
  GhostVarG Σ F.

Section ghost_var۰G.
  Context `{ghost_var۰G : !GhostVarG Σ F}.

  Definition ghost_var γ dq a :=
    own γ (to_dfrac_agree dq a).

  #[global] Instance ghost_varnonexpansive γ dq :
    NonExpansive (ghost_var γ dq).
  #[global] Instance ghost_varproper γ dq :
    Proper ((≡) ==> (≡)) (ghost_var γ dq).

  #[global] Instance ghost_vartimeless γ dq a :
    Discrete a
    Timeless (ghost_var γ dq a).

  #[global] Instance ghost_varpersistent γ a :
    Persistent (ghost_var γ DfracDiscarded a).

  #[global] Instance ghost_varfractional γ a :
    Fractional (λ q, ghost_var γ (DfracOwn q) a).
  #[global] Instance ghost_varas_fractional γ a q :
    AsFractional (ghost_var γ (DfracOwn q) a) (λ q, ghost_var γ (DfracOwn q) a) q.

  Lemma ghost_varalloc a :
     |==>
       γ,
      ghost_var γ (DfracOwn 1) a.
  Lemma ghost_varalloccofinite (γs : gset gname) a :
     |==>
       γ,
      γ γs
      ghost_var γ (DfracOwn 1) a.

  Lemma ghost_varvalid γ dq a :
    ghost_var γ dq a
     dq.
  Lemma ghost_varcombine γ dq1 a1 dq2 a2 :
    ghost_var γ dq1 a1 -∗
    ghost_var γ dq2 a2 -∗
      a1 a2
      ghost_var γ (dq1 dq2) a1.
  Lemma ghost_varvalidー2 γ dq1 a1 dq2 a2 :
    ghost_var γ dq1 a1 -∗
    ghost_var γ dq2 a2 -∗
       (dq1 dq2)
      a1 a2.
  Lemma ghost_varagree γ dq1 a1 dq2 a2 :
    ghost_var γ dq1 a1 -∗
    ghost_var γ dq2 a2 -∗
    a1 a2.
  Lemma ghost_vardfracne γ1 dq1 a1 γ2 dq2 a2 :
    ¬ (dq1 dq2)
    ghost_var γ1 dq1 a1 -∗
    ghost_var γ2 dq2 a2 -∗
    γ1 γ2.
  Lemma ghost_varne γ1 a1 γ2 dq2 a2 :
    ghost_var γ1 (DfracOwn 1) a1 -∗
    ghost_var γ2 dq2 a2 -∗
    γ1 γ2.
  Lemma ghost_varexclusive γ a1 dq2 a2 :
    ghost_var γ (DfracOwn 1) a1 -∗
    ghost_var γ dq2 a2 -∗
    False.
  Lemma ghost_varpersist γ dq a :
    ghost_var γ dq a |==>
    ghost_var γ DfracDiscarded a.
  Section discrete.
    Context `{!OfeDiscrete $ oFunctor_apply F $ iPropO Σ}.
    Lemma ghost_varcombinediscrete γ dq1 a1 dq2 a2 :
      ghost_var γ dq1 a1 -∗
      ghost_var γ dq2 a2 -∗
        a1 a2
        ghost_var γ (dq1 dq2) a1.
    Lemma ghost_varvalidー2ーdiscrete γ dq1 a1 dq2 a2 :
      ghost_var γ dq1 a1 -∗
      ghost_var γ dq2 a2 -∗
         (dq1 dq2)
        a1 a2.
    Lemma ghost_varagreediscrete γ dq1 a1 dq2 a2 :
      ghost_var γ dq1 a1 -∗
      ghost_var γ dq2 a2 -∗
      a1 a2.
    Section leibniz_equiv.
      Context `{!LeibnizEquiv $ oFunctor_apply F $ iPropO Σ}.
      Lemma ghost_varcombineL γ dq1 a1 dq2 a2 :
        ghost_var γ dq1 a1 -∗
        ghost_var γ dq2 a2 -∗
          a1 = a2
          ghost_var γ (dq1 dq2) a1.
      Lemma ghost_varvalidー2ーL γ dq1 a1 dq2 a2 :
        ghost_var γ dq1 a1 -∗
        ghost_var γ dq2 a2 -∗
           (dq1 dq2)
          a1 = a2.
      Lemma ghost_varagreeL γ dq1 a1 dq2 a2 :
        ghost_var γ dq1 a1 -∗
        ghost_var γ dq2 a2 -∗
        a1 = a2.
    End leibniz_equiv.
  End discrete.

  Lemma ghost_varupdate {γ a} a' :
    ghost_var γ (DfracOwn 1) a |==>
    ghost_var γ (DfracOwn 1) a'.
End ghost_var۰G.

#[global] Opaque ghost_var.