Library zoo.iris.algebra.lib.auth_option

Require Import iris.algebra.auth.
Require Import iris.algebra.proofmode_classes.

Require Import zoo.prelude.
Require Export zoo.iris.algebra.base.
Require Import zoo.options.

Definition auth_option {SI : sidx} A :=
  auth (optionUR A).
Definition auth_option۰O {SI : sidx} A :=
  authO (optionUR A).
Definition auth_option۰R {SI : sidx} A :=
  authR (optionUR A).
Definition auth_option۰UR {SI : sidx} A :=
  authUR (optionUR A).

Definition auth_option۰auth {SI : sidx} {A : cmra} dq (a : A) : auth_option۰UR A :=
  {dq} (Some a).
Definition auth_option۰frag {SI : sidx} {A : cmra} (a : A) : auth_option۰UR A :=
   (Some a).

Notation "●O dq a" := (
  auth_option۰auth dq a
)(at level 20,
  dq custom dfrac at level 1,
  format "●O dq a"
).
Notation "◯O a" := (
  auth_option۰frag a
)(at level 20
).

Section cmra.
  Context {SI : sidx}.
  Context {A : cmra}.

  Implicit Type a b : A.

  #[global] Instance auth_option۰authne dq :
    NonExpansive (@auth_option۰auth _ A dq).
  #[global] Instance auth_option۰authproper dq :
    Proper ((≡) ==> (≡)) (@auth_option۰auth _ A dq).
  #[global] Instance auth_option۰fragne :
    NonExpansive (@auth_option۰frag _ A).
  #[global] Instance auth_option۰fragproper :
    Proper ((≡) ==> (≡)) (@auth_option۰frag _ A).

  #[global] Instance auth_option۰authdistinj n :
    Inj2 (=) (≡{n}≡) (≡{n}≡) (@auth_option۰auth _ A).
  #[global] Instance auth_option۰authinj :
    Inj2 (=) (≡) (≡) (@auth_option۰auth _ A).
  #[global] Instance auth_option۰fragdistinj n :
    Inj (≡{n}≡) (≡{n}≡) (@auth_option۰frag _ A).
  #[global] Instance auth_option۰fraginj :
    Inj (≡) (≡) (@auth_option۰frag _ A).

  #[global] Instance auth_option۰ofe_discrete :
    OfeDiscrete A
    OfeDiscrete (auth_option۰O A).
  #[global] Instance auth_option۰authdiscrete dq a :
    Discrete a
    Discrete (O{dq} a).
  #[global] Instance auth_option۰fragdiscrete a :
    Discrete a
    Discrete (O a).
  #[global] Instance auth_option۰cmra_discrete :
    CmraDiscrete A
    CmraDiscrete (auth_option۰R A).

  Lemma auth_option۰authdfracop dq1 dq2 a :
    O{dq1 dq2} a O{dq1} a O{dq2} a.
  #[global] Instance auth_option۰authdfracis_op dq dq1 dq2 a :
    IsOp dq dq1 dq2
    IsOp' (O{dq} a) (O{dq1} a) (O{dq2} a).

  Lemma auth_option۰fragop a b :
    O (a b) = O a O b.
  Lemma auth_option۰fragmono a b :
    a b
    O a O b.
  Lemma auth_option۰fragcore `{!CmraTotal A} a :
    core (O a) = O (core a).
  Lemma auth_optionbothcorediscarded `{!CmraTotal A} a b :
    core (O a O b) O a O (core b).
  Lemma auth_optionbothcorefrac `{!CmraTotal A} q a b :
    core (O{#q} a O b) O (core b).

  #[global] Instance auth_option۰authcore_id a :
    CoreId (O a).
  #[global] Instance auth_option۰fragcore_id a :
    CoreId a
    CoreId (O a).
  #[global] Instance auth_optionbothcore_id a1 a2 :
    CoreId a2
    CoreId (O a1 O a2).
  #[global] Instance auth_option۰fragis_op a b1 b2 :
    IsOp a b1 b2
    IsOp' (O a) (O b1) (O b2).

  Lemma auth_option۰authdfracopinvN n dq1 a1 dq2 a2 :
    ✓{n} (O{dq1} a1 O{dq2} a2)
    a1 ≡{n}≡ a2.
  Lemma auth_option۰authdfracopinv dq1 a1 dq2 a2 :
     (O{dq1} a1 O{dq2} a2)
    a1 a2.
  Lemma auth_option۰authdfracopinvL `{!LeibnizEquiv A} dq1 a1 dq2 a2 :
     (O{dq1} a1 O{dq2} a2)
    a1 = a2.

  Lemma auth_option۰authdfracvalidN n dq a :
    ✓{n} (O{dq} a)
     dq ✓{n} a.
  Lemma auth_option۰authdfracvalid dq a :
     (O{dq} a)
     dq a.
  Lemma auth_option۰authvalidN n a :
    ✓{n} (O a)
    ✓{n} a.
  Lemma auth_option۰authvalid a :
     (O a)
     a.

  Lemma auth_option۰authdfracopvalidN n dq1 a1 dq2 a2 :
    ✓{n} (O{dq1} a1 O{dq2} a2)
     (dq1 dq2) a1 ≡{n}≡ a2 ✓{n} a1.
  Lemma auth_option۰authdfracopvalid dq1 a1 dq2 a2 :
     (O{dq1} a1 O{dq2} a2)
     (dq1 dq2) a1 a2 a1.
  Lemma auth_option۰authopvalidN n a1 a2 :
    ✓{n} (O a1 O a2)
    False.
  Lemma auth_option۰authopvalid a1 a2 :
     (O a1 O a2)
    False.

  Lemma auth_option۰fragvalidN n b :
    ✓{n} (O b)
    ✓{n} b.
  Lemma auth_option۰fragvalidN₁ n b :
    ✓{n} (O b)
    ✓{n} b.
  Lemma auth_option۰fragvalidN₂ n b :
    ✓{n} b
    ✓{n} (O b).
  Lemma auth_option۰fragvalid b :
     (O b)
     b.
  Lemma auth_option۰fragvalid₁ b :
     (O b)
     b.
  Lemma auth_option۰fragvalid₂ b :
     b
     (O b).

  Lemma auth_option۰fragopvalidN n b1 b2 :
    ✓{n} (O b1 O b2)
    ✓{n} (b1 b2).
  Lemma auth_option۰fragopvalidN₁ n b1 b2 :
    ✓{n} (O b1 O b2)
    ✓{n} (b1 b2).
  Lemma auth_option۰fragopvalidN₂ n b1 b2 :
    ✓{n} (b1 b2)
    ✓{n} (O b1 O b2).
  Lemma auth_option۰fragopvalid b1 b2 :
     (O b1 O b2)
     (b1 b2).
  Lemma auth_option۰fragopvalid₁ b1 b2 :
     (O b1 O b2)
     (b1 b2).
  Lemma auth_option۰fragopvalid₂ b1 b2 :
     (b1 b2)
     (O b1 O b2).

  Lemma auth_optionbothdfracvalidN n dq a b :
    ✓{n} (O{dq} a O b)
     dq (a ≡{n}≡ b b ≼{n} a) ✓{n} a.
  Lemma auth_optionbothdfracvalid dq a b :
     (O{dq} a O b)
     dq ( n, a ≡{n}≡ b b ≼{n} a) a.
  Lemma auth_optionbothvalidN n a b :
    ✓{n} (O a O b)
    (a ≡{n}≡ b b ≼{n} a) ✓{n} a.
  Lemma auth_optionbothvalid a b :
     (O a O b)
    ( n, a ≡{n}≡ b b ≼{n} a) a.

  Lemma auth_optionbothdfracvaliddiscrete `{!CmraDiscrete A} dq a b :
     (O{dq} a O b)
     dq (a b b a) a.
  Lemma auth_optionbothvaliddiscrete `{!CmraDiscrete A} a b :
     (O a O b)
    (a b b a) a.

  Lemma auth_option۰authdfracincludedN n dq1 a1 dq2 a2 b :
    O{dq1} a1 ≼{n} O{dq2} a2 O b
    (dq1 dq2 dq1 = dq2) a1 ≡{n}≡ a2.
  Lemma auth_option۰authdfracincluded dq1 a1 dq2 a2 b :
    O{dq1} a1 O{dq2} a2 O b
    (dq1 dq2 dq1 = dq2) a1 a2.
  Lemma auth_option۰authincludedN n a1 a2 b :
    O a1 ≼{n} O a2 O b
    a1 ≡{n}≡ a2.
  Lemma auth_option۰authincluded a1 a2 b :
    O a1 O a2 O b
    a1 a2.

  Lemma auth_option۰fragincludedN n dq a b1 b2 :
    O b1 ≼{n} O{dq} a O b2
    b1 ≡{n}≡ b2 b1 ≼{n} b2.
  Lemma auth_option۰fragincluded dq a b1 b2 :
    O b1 O{dq} a O b2
    b1 b2 b1 b2.

  Lemma auth_optionbothdfracincludedN n dq1 a1 dq2 a2 b1 b2 :
    O{dq1} a1 O b1 ≼{n} O{dq2} a2 O b2
    (dq1 dq2 dq1 = dq2) a1 ≡{n}≡ a2 (b1 ≡{n}≡ b2 b1 ≼{n} b2).
  Lemma auth_optionbothdfracincluded dq1 a1 dq2 a2 b1 b2 :
    O{dq1} a1 O b1 O{dq2} a2 O b2
    (dq1 dq2 dq1 = dq2) a1 a2 (b1 b2 b1 b2).
  Lemma auth_optionbothincludedN n a1 a2 b1 b2 :
    O a1 O b1 ≼{n} O a2 O b2
    a1 ≡{n}≡ a2 (b1 ≡{n}≡ b2 b1 ≼{n} b2).
  Lemma auth_optionbothincluded a1 a2 b1 b2 :
    O a1 O b1 O a2 O b2
    a1 a2 (b1 b2 b1 b2).

  Lemma auth_option۰authpersist dq a :
    O{dq} a ~~> O a.
  Lemma auth_option۰authdfracupdate dq a b `{!CoreId b} :
    a b b a
    O{dq} a ~~> O{dq} a O b.
  Lemma auth_option۰authupdate a b `{!CoreId b} :
    a b b a
    O a ~~> O a O b.
  Lemma auth_optionbothupdate a b a' b' :
    (a, b) ¬l~> (a', b')
    O a O b ~~> O a' O b'.

  Lemma auth_optionlocal_update a b0 b1 a' b0' b1' :
    (b0, b1) ¬l~> (b0', b1')
    a' b0' b0' a'
     a'
    (O a O b0, O a O b1) ¬l~> (O a' O b0', O a' O b1').
End cmra.

#[global] Opaque auth_option۰auth.
#[global] Opaque auth_option۰frag.

Definition auth_option۰URF {SI : sidx} F :=
  authURF $ optionURF F.
#[global] Instance auth_option۰URFcontractive {SI : sidx} F :
  rFunctorContractive F
  urFunctorContractive (auth_option۰URF F).

Definition auth_option۰RF {SI : sidx} F :=
  authRF $ optionURF F.
#[global] Instance auth_option۰RFcontractive {SI : sidx} F :
  rFunctorContractive F
  rFunctorContractive (auth_option۰RF F).