Skip to content
Snippets Groups Projects
auth.v 9.66 KiB
Newer Older
From algebra Require Export excl.
From algebra Require Import functor upred.
Robbert Krebbers's avatar
Robbert Krebbers committed
Local Arguments validN _ _ _ !_ /.
Robbert Krebbers's avatar
Robbert Krebbers committed

Record auth (A : Type) : Type := Auth { authoritative : excl A ; own : A }.
Add Printing Constructor auth.
Robbert Krebbers's avatar
Robbert Krebbers committed
Arguments Auth {_} _ _.
Arguments authoritative {_} _.
Robbert Krebbers's avatar
Robbert Krebbers committed
Arguments own {_} _.
Notation "◯ a" := (Auth ExclUnit a) (at level 20).
Notation "● a" := (Auth (Excl a) ) (at level 20).
Robbert Krebbers's avatar
Robbert Krebbers committed

Robbert Krebbers's avatar
Robbert Krebbers committed
(* COFE *)
Section cofe.
Context {A : cofeT}.
Implicit Types a b : A.
Implicit Types x y : auth A.

Instance auth_equiv : Equiv (auth A) := λ x y,
  authoritative x  authoritative y  own x  own y.
Instance auth_dist : Dist (auth A) := λ n x y,
  authoritative x {n} authoritative y  own x {n} own y.
Robbert Krebbers's avatar
Robbert Krebbers committed

Global Instance Auth_ne : Proper (dist n ==> dist n ==> dist n) (@Auth A).
Robbert Krebbers's avatar
Robbert Krebbers committed
Proof. by split. Qed.
Global Instance Auth_proper : Proper (() ==> () ==> ()) (@Auth A).
Proof. by split. Qed.
Global Instance authoritative_ne: Proper (dist n ==> dist n) (@authoritative A).
Robbert Krebbers's avatar
Robbert Krebbers committed
Proof. by destruct 1. Qed.
Global Instance authoritative_proper : Proper (() ==> ()) (@authoritative A).
Proof. by destruct 1. Qed.
Global Instance own_ne : Proper (dist n ==> dist n) (@own A).
Robbert Krebbers's avatar
Robbert Krebbers committed
Proof. by destruct 1. Qed.
Global Instance own_proper : Proper (() ==> ()) (@own A).
Proof. by destruct 1. Qed.
Robbert Krebbers's avatar
Robbert Krebbers committed

Instance auth_compl : Compl (auth A) := λ c,
Robbert Krebbers's avatar
Robbert Krebbers committed
  Auth (compl (chain_map authoritative c)) (compl (chain_map own c)).
Definition auth_cofe_mixin : CofeMixin (auth A).
Robbert Krebbers's avatar
Robbert Krebbers committed
Proof.
  split.
  - intros x y; unfold dist, auth_dist, equiv, auth_equiv.
Robbert Krebbers's avatar
Robbert Krebbers committed
    rewrite !equiv_dist; naive_solver.
  - intros n; split.
Robbert Krebbers's avatar
Robbert Krebbers committed
    + by intros ?; split.
    + by intros ?? [??]; split; symmetry.
    + intros ??? [??] [??]; split; etrans; eauto.
  - by intros ? [??] [??] [??]; split; apply dist_S.
  - intros n c; split. apply (conv_compl n (chain_map authoritative c)).
    apply (conv_compl n (chain_map own c)).
Robbert Krebbers's avatar
Robbert Krebbers committed
Qed.
Canonical Structure authC := CofeT auth_cofe_mixin.
Global Instance auth_timeless (x : auth A) :
  Timeless (authoritative x)  Timeless (own x)  Timeless x.
Proof. by intros ?? [??] [??]; split; simpl in *; apply (timeless _). Qed.
Global Instance auth_leibniz : LeibnizEquiv A  LeibnizEquiv (auth A).
Proof. by intros ? [??] [??] [??]; f_equal/=; apply leibniz_equiv. Qed.
End cofe.

Arguments authC : clear implicits.
Robbert Krebbers's avatar
Robbert Krebbers committed

(* CMRA *)
Section cmra.
Context {A : cmraT}.
Implicit Types a b : A.
Implicit Types x y : auth A.

Global Instance auth_empty `{Empty A} : Empty (auth A) := Auth  ∅.
Instance auth_validN : ValidN (auth A) := λ n x,
Robbert Krebbers's avatar
Robbert Krebbers committed
  match authoritative x with
  | Excl a => own x {n} a  {n} a
  | ExclUnit => {n} own x
Robbert Krebbers's avatar
Robbert Krebbers committed
  end.
Global Arguments auth_validN _ !_ /.
Instance auth_unit : Unit (auth A) := λ x,
  Auth (unit (authoritative x)) (unit (own x)).
Instance auth_op : Op (auth A) := λ x y,
  Auth (authoritative x  authoritative y) (own x  own y).
Instance auth_minus : Minus (auth A) := λ x y,
  Auth (authoritative x  authoritative y) (own x  own y).
Lemma auth_included (x y : auth A) :
  x  y  authoritative x  authoritative y  own x  own y.
Proof.
  split; [intros [[z1 z2] Hz]; split; [exists z1|exists z2]; apply Hz|].
  intros [[z1 Hz1] [z2 Hz2]]; exists (Auth z1 z2); split; auto.
Qed.
Lemma auth_includedN n (x y : auth A) :
Robbert Krebbers's avatar
Robbert Krebbers committed
  x {n} y  authoritative x {n} authoritative y  own x {n} own y.
Proof.
  split; [intros [[z1 z2] Hz]; split; [exists z1|exists z2]; apply Hz|].
  intros [[z1 Hz1] [z2 Hz2]]; exists (Auth z1 z2); split; auto.
Qed.
Lemma authoritative_validN n (x : auth A) : {n} x  {n} authoritative x.
Robbert Krebbers's avatar
Robbert Krebbers committed
Proof. by destruct x as [[]]. Qed.
Lemma own_validN n (x : auth A) : {n} x  {n} own x.
Proof. destruct x as [[]]; naive_solver eauto using cmra_validN_includedN. Qed.

Definition auth_cmra_mixin : CMRAMixin (auth A).
Robbert Krebbers's avatar
Robbert Krebbers committed
Proof.
  split.
  - by intros n x y1 y2 [Hy Hy']; split; simpl; rewrite ?Hy ?Hy'.
  - by intros n y1 y2 [Hy Hy']; split; simpl; rewrite ?Hy ?Hy'.
  - intros n [x a] [y b] [Hx Ha]; simpl in *;
      destruct Hx; intros ?; cofe_subst; auto.
  - by intros n x1 x2 [Hx Hx'] y1 y2 [Hy Hy'];
      split; simpl; rewrite ?Hy ?Hy' ?Hx ?Hx'.
  - intros n [[] ?] ?; naive_solver eauto using cmra_includedN_S, cmra_validN_S.
  - by split; simpl; rewrite assoc.
  - by split; simpl; rewrite comm.
  - by split; simpl; rewrite ?cmra_unit_l.
  - by split; simpl; rewrite ?cmra_unit_idemp.
  - intros n ??; rewrite! auth_includedN; intros [??].
    by split; simpl; apply cmra_unit_preservingN.
  - assert ( n (a b1 b2 : A), b1  b2 {n} a  b1 {n} a).
    { intros n a b1 b2 <-; apply cmra_includedN_l. }
Robbert Krebbers's avatar
Robbert Krebbers committed
   intros n [[a1| |] b1] [[a2| |] b2];
     naive_solver eauto using cmra_validN_op_l, cmra_validN_includedN.
  - by intros n ??; rewrite auth_includedN;
Robbert Krebbers's avatar
Robbert Krebbers committed
      intros [??]; split; simpl; apply cmra_op_minus.
Qed.
Definition auth_cmra_extend_mixin : CMRAExtendMixin (auth A).
Robbert Krebbers's avatar
Robbert Krebbers committed
Proof.
  intros n x y1 y2 ? [??]; simpl in *.
  destruct (cmra_extend_op n (authoritative x) (authoritative y1)
    (authoritative y2)) as (ea&?&?&?); auto using authoritative_validN.
Robbert Krebbers's avatar
Robbert Krebbers committed
  destruct (cmra_extend_op n (own x) (own y1) (own y2))
    as (b&?&?&?); auto using own_validN.
  by exists (Auth (ea.1) (b.1), Auth (ea.2) (b.2)).
Robbert Krebbers's avatar
Robbert Krebbers committed
Qed.
Canonical Structure authRA : cmraT :=
  CMRAT auth_cofe_mixin auth_cmra_mixin auth_cmra_extend_mixin.
(** Internalized properties *)
Lemma auth_equivI {M} (x y : auth A) :
  (x  y)%I  (authoritative x  authoritative y  own x  own y : uPred M)%I.
Proof. done. Qed.
Lemma auth_validI {M} (x : auth A) :
  ( x)%I  (match authoritative x with
             | Excl a => ( b, a  own x  b)   a
             | ExclUnit =>  own x
             | ExclBot => False
             end : uPred M)%I.
Proof. by destruct x as [[]]. Qed.

(** The notations ◯ and ● only work for CMRAs with an empty element. So, in
what follows, we assume we have an empty element. *)
Context `{Empty A, !CMRAIdentity A}.

Global Instance auth_cmra_identity : CMRAIdentity authRA.
Robbert Krebbers's avatar
Robbert Krebbers committed
Proof.
  split; simpl.
  - by apply (@cmra_empty_valid A _).
  - by intros x; constructor; rewrite /= left_id.
  - apply _.
Robbert Krebbers's avatar
Robbert Krebbers committed
Qed.
Lemma auth_frag_op a b :  (a  b)   a   b.
Robbert Krebbers's avatar
Robbert Krebbers committed
Proof. done. Qed.
Lemma auth_both_op a b : Auth (Excl a) b   a   b.
Proof. by rewrite /op /auth_op /= left_id. Qed.

Lemma auth_update a a' b b' :
Ralf Jung's avatar
Ralf Jung committed
  ( n af, {n} a  a {n} a'  af  b {n} b'  af  {n} b) 
   a   a' ~~>  b   b'.
  move=> Hab n [[?| |] bf1] // =>-[[bf2 Ha] ?]; do 2 red; simpl in *.
  destruct (Hab n (bf1  bf2)) as [Ha' ?]; auto.
  { by rewrite Ha left_id assoc. }
  split; [by rewrite Ha' left_id assoc; apply cmra_includedN_l|done].
Lemma auth_local_update L `{!LocalUpdate Lv L} a a' :
   a'   a ~~>  L a'   L a.
Ralf Jung's avatar
Ralf Jung committed
  intros. apply auth_update=>n af ? EQ; split; last done.
  by rewrite EQ (local_updateN L) // -EQ.

Lemma auth_update_op_l a a' b :
   (b  a)   a   a' ~~>  (b  a)   (b  a').
Proof. by intros; apply (auth_local_update _). Qed.
Lemma auth_update_op_r a a' b :
   (a  b)   a   a' ~~>  (a  b)   (a'  b).
Proof. rewrite -!(comm _ b); apply auth_update_op_l. Qed.
Ralf Jung's avatar
Ralf Jung committed
(* This does not seem to follow from auth_local_update.
   The trouble is that given ✓ (L a ⋅ a'), Lv a
Ralf Jung's avatar
Ralf Jung committed
   we need ✓ (a ⋅ a'). I think this should hold for every local update,
   but adding an extra axiom to local updates just for this is silly. *)
Lemma auth_local_update_l L `{!LocalUpdate Lv L} a a' :
  Lv a   (L a  a') 
   (a  a')   a ~~>  (L a  a')   L a.
Ralf Jung's avatar
Ralf Jung committed
Proof.
  intros. apply auth_update=>n af ? EQ; split; last done.
  by rewrite -(local_updateN L) // EQ -(local_updateN L) // -EQ.
Ralf Jung's avatar
Ralf Jung committed
Qed.

End cmra.

Arguments authRA : clear implicits.
Robbert Krebbers's avatar
Robbert Krebbers committed

(* Functor *)
Definition auth_map {A B} (f : A  B) (x : auth A) : auth B :=
  Auth (excl_map f (authoritative x)) (f (own x)).
Lemma auth_map_id {A} (x : auth A) : auth_map id x = x.
Proof. by destruct x; rewrite /auth_map excl_map_id. Qed.
Lemma auth_map_compose {A B C} (f : A  B) (g : B  C) (x : auth A) :
  auth_map (g  f) x = auth_map g (auth_map f x).
Proof. by destruct x; rewrite /auth_map excl_map_compose. Qed.
Lemma auth_map_ext {A B : cofeT} (f g : A  B) x :
  ( x, f x  g x)  auth_map f x  auth_map g x.
Proof. constructor; simpl; auto using excl_map_ext. Qed.
Instance auth_map_cmra_ne {A B : cofeT} n :
  Proper ((dist n ==> dist n) ==> dist n ==> dist n) (@auth_map A B).
Robbert Krebbers's avatar
Robbert Krebbers committed
Proof.
  intros f g Hf [??] [??] [??]; split; [by apply excl_map_cmra_ne|by apply Hf].
Robbert Krebbers's avatar
Robbert Krebbers committed
Qed.
Instance auth_map_cmra_monotone {A B : cmraT} (f : A  B) :
  ( n, Proper (dist n ==> dist n) f) 
  CMRAMonotone f  CMRAMonotone (auth_map f).
Robbert Krebbers's avatar
Robbert Krebbers committed
Proof.
  split.
  - by intros n [x a] [y b]; rewrite !auth_includedN /=;
      intros [??]; split; simpl; apply: includedN_preserving.
  - intros n [[a| |] b]; rewrite /= /cmra_validN;
Robbert Krebbers's avatar
Robbert Krebbers committed
      naive_solver eauto using @includedN_preserving, @validN_preserving.
Qed.
Definition authC_map {A B} (f : A -n> B) : authC A -n> authC B :=
Lemma authC_map_ne A B n : Proper (dist n ==> dist n) (@authC_map A B).
Robbert Krebbers's avatar
Robbert Krebbers committed
Proof. intros f f' Hf [[a| |] b]; repeat constructor; apply Hf. Qed.

Program Definition authF (Σ : iFunctor) : iFunctor := {|
  ifunctor_car := authRA  Σ; ifunctor_map A B := authC_map  ifunctor_map Σ
|}.
Next Obligation.
  by intros Σ A B n f g Hfg; apply authC_map_ne, ifunctor_map_ne.
Qed.
Next Obligation.
  intros Σ A x. rewrite /= -{2}(auth_map_id x).
  apply auth_map_ext=>y; apply ifunctor_map_id.
Qed.
Next Obligation.
  intros Σ A B C f g x. rewrite /= -auth_map_compose.
  apply auth_map_ext=>y; apply ifunctor_map_compose.
Qed.