Commit cfb00b3e authored by Robbert Krebbers's avatar Robbert Krebbers

CMRAs with partial cores.

Based on an idea and WIP commits of J-H. Jourdan: the core of a CMRA
A is now a partial function A → option A.

TODO: define sum CMRA
TODO: remove one shot CMRA and define it in terms of sum
parent 4195e15c
......@@ -60,7 +60,7 @@ Program Instance agree_op : Op (agree A) := λ x y,
{| agree_car := x;
agree_is_valid n := agree_is_valid x n agree_is_valid y n x {n} y |}.
Next Obligation. naive_solver eauto using agree_valid_S, dist_S. Qed.
Instance agree_core : Core (agree A) := id.
Instance agree_pcore : PCore (agree A) := Some.
Instance: Comm () (@op (agree A) _).
Proof. intros x y; split; [naive_solver|by intros n (?&?&Hxy); apply Hxy]. Qed.
......@@ -106,11 +106,11 @@ Qed.
Definition agree_cmra_mixin : CMRAMixin (agree A).
Proof.
split; try (apply _ || done).
apply cmra_total_mixin; try apply _ || by eauto.
- intros n x [? Hx]; split; [by apply agree_valid_S|intros n' ?].
rewrite -(Hx n'); last auto.
symmetry; apply dist_le with n; try apply Hx; auto.
- intros x; apply agree_idemp.
- intros x. apply agree_idemp.
- by intros n x y [(?&?&?) ?].
- intros n x y1 y2 Hval Hx; exists (x,x); simpl; split.
+ by rewrite agree_idemp.
......@@ -119,8 +119,10 @@ Qed.
Canonical Structure agreeR : cmraT :=
CMRAT (agree A) agree_cofe_mixin agree_cmra_mixin.
Global Instance agree_total : CMRATotal agreeR.
Proof. rewrite /CMRATotal; eauto. Qed.
Global Instance agree_persistent (x : agree A) : Persistent x.
Proof. done. Qed.
Proof. by constructor. Qed.
Program Definition to_agree (x : A) : agree A :=
{| agree_car n := x; agree_is_valid n := True |}.
......
......@@ -3,18 +3,18 @@ From iris.algebra Require Import upred.
Local Arguments valid _ _ !_ /.
Local Arguments validN _ _ _ !_ /.
Record auth (A : Type) : Type := Auth { authoritative : excl A ; own : A }.
Record auth (A : Type) := Auth { authoritative : option (excl A); own : A }.
Add Printing Constructor auth.
Arguments Auth {_} _ _.
Arguments authoritative {_} _.
Arguments own {_} _.
Notation "◯ a" := (Auth ExclUnit a) (at level 20).
Notation "● a" := (Auth (Excl a) ) (at level 20).
Notation "◯ a" := (Auth None a) (at level 20).
Notation "● a" := (Auth (Excl' a) ) (at level 20).
(* COFE *)
Section cofe.
Context {A : cofeT}.
Implicit Types a : excl A.
Implicit Types a : option (excl A).
Implicit Types b : A.
Implicit Types x y : auth A.
......@@ -72,20 +72,20 @@ Implicit Types x y : auth A.
Instance auth_valid : Valid (auth A) := λ x,
match authoritative x with
| Excl a => ( n, own x {n} a) a
| ExclUnit => own x
| ExclBot => False
| Excl' a => ( n, own x {n} a) a
| None => own x
| ExclBot' => False
end.
Global Arguments auth_valid !_ /.
Instance auth_validN : ValidN (auth A) := λ n x,
match authoritative x with
| Excl a => own x {n} a {n} a
| ExclUnit => {n} own x
| ExclBot => False
| Excl' a => own x {n} a {n} a
| None => {n} own x
| ExclBot' => False
end.
Global Arguments auth_validN _ !_ /.
Instance auth_core : Core (auth A) := λ x,
Auth (core (authoritative x)) (core (own x)).
Instance auth_pcore : PCore (auth A) := λ x,
Some (Auth (core (authoritative x)) (core (own x))).
Instance auth_op : Op (auth A) := λ x y,
Auth (authoritative x authoritative y) (own x own y).
......@@ -96,20 +96,21 @@ Proof.
intros [[z1 Hz1] [z2 Hz2]]; exists (Auth z1 z2); split; auto.
Qed.
Lemma authoritative_validN n (x : auth A) : {n} x {n} authoritative x.
Proof. by destruct x as [[]]. Qed.
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.
Proof. destruct x as [[[]|]]; naive_solver eauto using cmra_validN_includedN. Qed.
Lemma auth_cmra_mixin : CMRAMixin (auth A).
Proof.
split.
apply cmra_total_mixin.
- eauto.
- 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.
- intros [[] ?]; rewrite /= ?cmra_included_includedN ?cmra_valid_validN;
- intros n [x a] [y b] [Hx Ha]; simpl in *.
destruct Hx as [?? Hx|]; first destruct Hx; intros ?; cofe_subst; auto.
- intros [[[?|]|] ?]; rewrite /= ?cmra_included_includedN ?cmra_valid_validN;
naive_solver eauto using O.
- intros n [[] ?] ?; naive_solver eauto using cmra_includedN_S, cmra_validN_S.
- 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_core_l.
......@@ -118,7 +119,7 @@ Proof.
by split; simpl; apply cmra_core_preserving.
- assert ( n (a b1 b2 : A), b1 b2 {n} a b1 {n} a).
{ intros n a b1 b2 <-; apply cmra_includedN_l. }
intros n [[a1| |] b1] [[a2| |] b2];
intros n [[[a1|]|] b1] [[[a2|]|] b2];
naive_solver eauto using cmra_validN_op_l, cmra_validN_includedN.
- intros n x y1 y2 ? [??]; simpl in *.
destruct (cmra_extend n (authoritative x) (authoritative y1)
......@@ -127,12 +128,12 @@ Proof.
as (b&?&?&?); auto using own_validN.
by exists (Auth (ea.1) (b.1), Auth (ea.2) (b.2)).
Qed.
Canonical Structure authR :=
CMRAT (auth A) auth_cofe_mixin auth_cmra_mixin.
Canonical Structure authR := CMRAT (auth A) auth_cofe_mixin auth_cmra_mixin.
Global Instance auth_cmra_discrete : CMRADiscrete A CMRADiscrete authR.
Proof.
split; first apply _.
intros [[] ?]; rewrite /= /cmra_valid /cmra_validN /=; auto.
intros [[[?|]|] ?]; rewrite /= /cmra_valid /cmra_validN /=; auto.
- setoid_rewrite <-cmra_discrete_included_iff.
rewrite -cmra_discrete_valid_iff. tauto.
- by rewrite -cmra_discrete_valid_iff.
......@@ -145,6 +146,7 @@ Proof.
- apply (@ucmra_unit_valid A).
- by intros x; constructor; rewrite /= left_id.
- apply _.
- do 2 constructor; simpl; apply (persistent_core _).
Qed.
Canonical Structure authUR :=
UCMRAT (auth A) auth_cofe_mixin auth_cmra_mixin auth_ucmra_mixin.
......@@ -155,22 +157,23 @@ Lemma auth_equivI {M} (x y : auth A) :
Proof. by uPred.unseal. Qed.
Lemma auth_validI {M} (x : auth A) :
( x) (match authoritative x with
| Excl a => ( b, a own x b) a
| ExclUnit => own x
| ExclBot => False
| Excl' a => ( b, a own x b) a
| None => own x
| ExclBot' => False
end : uPred M).
Proof. uPred.unseal. by destruct x as [[]]. Qed.
Proof. uPred.unseal. by destruct x as [[[]|]]. Qed.
Lemma auth_frag_op a b : (a b) a b.
Proof. done. Qed.
Lemma auth_both_op a b : Auth (Excl a) b a b.
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' :
( n af, {n} a a {n} a' af b {n} b' af {n} b)
a a' ~~> b b'.
Proof.
move=> Hab n [[?| |] bf1] // =>-[[bf2 Ha] ?]; do 2 red; simpl in *.
intros Hab; apply cmra_total_update.
move=> 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].
......@@ -209,25 +212,29 @@ Arguments authUR : clear implicits.
(* Functor *)
Definition auth_map {A B} (f : A B) (x : auth A) : auth B :=
Auth (excl_map f (authoritative x)) (f (own x)).
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.
Proof. by destruct x as [[[]|]]. 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.
Proof. by destruct x as [[[]|]]. 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 :
Proof.
constructor; simpl; auto.
apply option_fmap_setoid_ext=> a; by apply excl_map_ext.
Qed.
Instance auth_map_ne {A B : cofeT} n :
Proper ((dist n ==> dist n) ==> dist n ==> dist n) (@auth_map A B).
Proof.
intros f g Hf [??] [??] [??]; split; [by apply excl_map_cmra_ne|by apply Hf].
intros f g Hf [??] [??] [??]; split; simpl in *; [|by apply Hf].
apply option_fmap_ne; [|done]=> x y ?; by apply excl_map_ne.
Qed.
Instance auth_map_cmra_monotone {A B : ucmraT} (f : A B) :
CMRAMonotone f CMRAMonotone (auth_map f).
Proof.
split; try apply _.
- intros n [[a| |] b]; rewrite /= /cmra_validN /=; try
- intros n [[[a|]|] b]; rewrite /= /cmra_validN /=; try
naive_solver eauto using includedN_preserving, validN_preserving.
- by intros [x a] [y b]; rewrite !auth_included /=;
intros [??]; split; simpl; apply: included_preserving.
......@@ -235,7 +242,7 @@ Qed.
Definition authC_map {A B} (f : A -n> B) : authC A -n> authC B :=
CofeMor (auth_map f).
Lemma authC_map_ne A B n : Proper (dist n ==> dist n) (@authC_map A B).
Proof. intros f f' Hf [[a| |] b]; repeat constructor; apply Hf. Qed.
Proof. intros f f' Hf [[[a|]|] b]; repeat constructor; apply Hf. Qed.
Program Definition authURF (F : urFunctor) : urFunctor := {|
urFunctor_car A B := authUR (urFunctor_car F A B);
......
From iris.algebra Require Export cofe.
Class Core (A : Type) := core : A A.
Instance: Params (@core) 2.
Class PCore (A : Type) := pcore : A option A.
Instance: Params (@pcore) 2.
Class Op (A : Type) := op : A A A.
Instance: Params (@op) 2.
......@@ -29,10 +29,11 @@ Notation "x ≼{ n } y" := (includedN n x y)
Instance: Params (@includedN) 4.
Hint Extern 0 (_ {_} _) => reflexivity.
Record CMRAMixin A `{Dist A, Equiv A, Core A, Op A, Valid A, ValidN A} := {
Record CMRAMixin A `{Dist A, Equiv A, PCore A, Op A, Valid A, ValidN A} := {
(* setoids *)
mixin_cmra_op_ne n (x : A) : Proper (dist n ==> dist n) (op x);
mixin_cmra_core_ne n : Proper (dist n ==> dist n) core;
mixin_cmra_pcore_ne n x y cx :
x {n} y pcore x = Some cx cy, pcore y = Some cy cx {n} cy;
mixin_cmra_validN_ne n : Proper (dist n ==> impl) (validN n);
(* valid *)
mixin_cmra_valid_validN x : x n, {n} x;
......@@ -40,9 +41,10 @@ Record CMRAMixin A `{Dist A, Equiv A, Core A, Op A, Valid A, ValidN A} := {
(* monoid *)
mixin_cmra_assoc : Assoc () ();
mixin_cmra_comm : Comm () ();
mixin_cmra_core_l x : core x x x;
mixin_cmra_core_idemp x : core (core x) core x;
mixin_cmra_core_preserving x y : x y core x core y;
mixin_cmra_pcore_l x cx : pcore x = Some cx cx x x;
mixin_cmra_pcore_idemp x cx : pcore x = Some cx pcore cx Some cx;
mixin_cmra_pcore_preserving x y cx :
x y pcore x = Some cx cy, pcore y = Some cy cx cy;
mixin_cmra_validN_op_l n x y : {n} (x y) {n} x;
mixin_cmra_extend n x y1 y2 :
{n} x x {n} y1 y2
......@@ -55,7 +57,7 @@ Structure cmraT := CMRAT {
cmra_equiv : Equiv cmra_car;
cmra_dist : Dist cmra_car;
cmra_compl : Compl cmra_car;
cmra_core : Core cmra_car;
cmra_pcore : PCore cmra_car;
cmra_op : Op cmra_car;
cmra_valid : Valid cmra_car;
cmra_validN : ValidN cmra_car;
......@@ -67,14 +69,14 @@ Arguments cmra_car : simpl never.
Arguments cmra_equiv : simpl never.
Arguments cmra_dist : simpl never.
Arguments cmra_compl : simpl never.
Arguments cmra_core : simpl never.
Arguments cmra_pcore : simpl never.
Arguments cmra_op : simpl never.
Arguments cmra_valid : simpl never.
Arguments cmra_validN : simpl never.
Arguments cmra_cofe_mixin : simpl never.
Arguments cmra_mixin : simpl never.
Add Printing Constructor cmraT.
Existing Instances cmra_core cmra_op cmra_valid cmra_validN.
Existing Instances cmra_pcore cmra_op cmra_valid cmra_validN.
Coercion cmra_cofeC (A : cmraT) : cofeT := CofeT A (cmra_cofe_mixin A).
Canonical Structure cmra_cofeC.
......@@ -84,8 +86,9 @@ Section cmra_mixin.
Implicit Types x y : A.
Global Instance cmra_op_ne n (x : A) : Proper (dist n ==> dist n) (op x).
Proof. apply (mixin_cmra_op_ne _ (cmra_mixin A)). Qed.
Global Instance cmra_core_ne n : Proper (dist n ==> dist n) (@core A _).
Proof. apply (mixin_cmra_core_ne _ (cmra_mixin A)). Qed.
Lemma cmra_pcore_ne n x y cx :
x {n} y pcore x = Some cx cy, pcore y = Some cy cx {n} cy.
Proof. apply (mixin_cmra_pcore_ne _ (cmra_mixin A)). Qed.
Global Instance cmra_validN_ne n : Proper (dist n ==> impl) (@validN A _ n).
Proof. apply (mixin_cmra_validN_ne _ (cmra_mixin A)). Qed.
Lemma cmra_valid_validN x : x n, {n} x.
......@@ -96,12 +99,13 @@ Section cmra_mixin.
Proof. apply (mixin_cmra_assoc _ (cmra_mixin A)). Qed.
Global Instance cmra_comm : Comm () (@op A _).
Proof. apply (mixin_cmra_comm _ (cmra_mixin A)). Qed.
Lemma cmra_core_l x : core x x x.
Proof. apply (mixin_cmra_core_l _ (cmra_mixin A)). Qed.
Lemma cmra_core_idemp x : core (core x) core x.
Proof. apply (mixin_cmra_core_idemp _ (cmra_mixin A)). Qed.
Lemma cmra_core_preserving x y : x y core x core y.
Proof. apply (mixin_cmra_core_preserving _ (cmra_mixin A)). Qed.
Lemma cmra_pcore_l x cx : pcore x = Some cx cx x x.
Proof. apply (mixin_cmra_pcore_l _ (cmra_mixin A)). Qed.
Lemma cmra_pcore_idemp x cx : pcore x = Some cx pcore cx Some cx.
Proof. apply (mixin_cmra_pcore_idemp _ (cmra_mixin A)). Qed.
Lemma cmra_pcore_preserving x y cx :
x y pcore x = Some cx cy, pcore y = Some cy cx cy.
Proof. apply (mixin_cmra_pcore_preserving _ (cmra_mixin A)). Qed.
Lemma cmra_validN_op_l n x y : {n} (x y) {n} x.
Proof. apply (mixin_cmra_validN_op_l _ (cmra_mixin A)). Qed.
Lemma cmra_extend n x y1 y2 :
......@@ -110,13 +114,33 @@ Section cmra_mixin.
Proof. apply (mixin_cmra_extend _ (cmra_mixin A)). Qed.
End cmra_mixin.
Definition opM {A : cmraT} (x : A) (my : option A) :=
match my with Some y => x y | None => x end.
Infix "⋅?" := opM (at level 50, left associativity) : C_scope.
(** * Persistent elements *)
Class Persistent {A : cmraT} (x : A) := persistent : pcore x Some x.
Arguments persistent {_} _ {_}.
(** * CMRAs whose core is total *)
(** The function [core] may return a dummy when used on CMRAs without total
core. *)
Class CMRATotal (A : cmraT) := cmra_total (x : A) : is_Some (pcore x).
Class Core (A : Type) := core : A A.
Instance: Params (@core) 2.
Instance core' `{PCore A} : Core A := λ x, from_option id x (pcore x).
Arguments core' _ _ _ /.
(** * CMRAs with a unit element *)
(** We use the notation ∅ because for most instances (maps, sets, etc) the
`empty' element is the unit. *)
Record UCMRAMixin A `{Dist A, Equiv A, Op A, Valid A, Empty A} := {
Record UCMRAMixin A `{Dist A, Equiv A, PCore A, Op A, Valid A, Empty A} := {
mixin_ucmra_unit_valid : ;
mixin_ucmra_unit_left_id : LeftId () ();
mixin_ucmra_unit_timeless : Timeless
mixin_ucmra_unit_timeless : Timeless ;
mixin_ucmra_pcore_unit : pcore Some
}.
Structure ucmraT := UCMRAT {
......@@ -124,7 +148,7 @@ Structure ucmraT := UCMRAT {
ucmra_equiv : Equiv ucmra_car;
ucmra_dist : Dist ucmra_car;
ucmra_compl : Compl ucmra_car;
ucmra_core : Core ucmra_car;
ucmra_pcore : PCore ucmra_car;
ucmra_op : Op ucmra_car;
ucmra_valid : Valid ucmra_car;
ucmra_validN : ValidN ucmra_car;
......@@ -138,7 +162,7 @@ Arguments ucmra_car : simpl never.
Arguments ucmra_equiv : simpl never.
Arguments ucmra_dist : simpl never.
Arguments ucmra_compl : simpl never.
Arguments ucmra_core : simpl never.
Arguments ucmra_pcore : simpl never.
Arguments ucmra_op : simpl never.
Arguments ucmra_valid : simpl never.
Arguments ucmra_validN : simpl never.
......@@ -163,12 +187,10 @@ Section ucmra_mixin.
Proof. apply (mixin_ucmra_unit_left_id _ (ucmra_mixin A)). Qed.
Global Instance ucmra_unit_timeless : Timeless ( : A).
Proof. apply (mixin_ucmra_unit_timeless _ (ucmra_mixin A)). Qed.
Lemma ucmra_pcore_unit : pcore (:A) Some .
Proof. apply (mixin_ucmra_pcore_unit _ (ucmra_mixin A)). Qed.
End ucmra_mixin.
(** * Persistent elements *)
Class Persistent {A : cmraT} (x : A) := persistent : core x x.
Arguments persistent {_} _ {_}.
(** * Discrete CMRAs *)
Class CMRADiscrete (A : cmraT) := {
cmra_discrete :> Discrete A;
......@@ -194,12 +216,13 @@ Class LocalUpdate {A : cmraT} (Lv : A → Prop) (L : A → A) := {
Arguments local_updateN {_ _} _ {_} _ _ _ _ _.
(** * Frame preserving updates *)
Definition cmra_updateP {A : cmraT} (x : A) (P : A Prop) := n z,
{n} (x z) y, P y {n} (y z).
Definition cmra_updateP {A : cmraT} (x : A) (P : A Prop) := n mz,
{n} (x ? mz) y, P y {n} (y ? mz).
Instance: Params (@cmra_updateP) 1.
Infix "~~>:" := cmra_updateP (at level 70).
Definition cmra_update {A : cmraT} (x y : A) := n z,
{n} (x z) {n} (y z).
Definition cmra_update {A : cmraT} (x y : A) := n mz,
{n} (x ? mz) {n} (y ? mz).
Infix "~~>" := cmra_update (at level 70).
Instance: Params (@cmra_update) 1.
......@@ -210,13 +233,24 @@ Implicit Types x y z : A.
Implicit Types xs ys zs : list A.
(** ** Setoids *)
Global Instance cmra_core_proper : Proper (() ==> ()) (@core A _).
Proof. apply (ne_proper _). Qed.
Global Instance cmra_op_ne' n : Proper (dist n ==> dist n ==> dist n) (@op A _).
Global Instance cmra_pcore_ne' n : Proper (dist n ==> dist n) (@pcore A _).
Proof.
intros x y Hxy. destruct (pcore x) as [cx|] eqn:?.
{ destruct (cmra_pcore_ne n x y cx) as (cy&->&->); auto. }
destruct (pcore y) as [cy|] eqn:?; auto.
destruct (cmra_pcore_ne n y x cy) as (cx&?&->); simplify_eq/=; auto.
Qed.
Lemma cmra_pcore_proper x y cx :
x y pcore x = Some cx cy, pcore y = Some cy cx cy.
Proof.
intros x1 x2 Hx y1 y2 Hy.
by rewrite Hy (comm _ x1) Hx (comm _ y2).
intros. destruct (cmra_pcore_ne 0 x y cx) as (cy&?&?); auto.
exists cy; split; [done|apply equiv_dist=> n].
destruct (cmra_pcore_ne n x y cx) as (cy'&?&?); naive_solver.
Qed.
Global Instance cmra_pcore_proper' : Proper (() ==> ()) (@pcore A _).
Proof. apply (ne_proper _). Qed.
Global Instance cmra_op_ne' n : Proper (dist n ==> dist n ==> dist n) (@op A _).
Proof. intros x1 x2 Hx y1 y2 Hy. by rewrite Hy (comm _ x1) Hx (comm _ y2). Qed.
Global Instance ra_op_proper' : Proper (() ==> () ==> ()) (@op A _).
Proof. apply (ne_proper_2 _). Qed.
Global Instance cmra_validN_ne' : Proper (dist n ==> iff) (@validN A _ n) | 1.
......@@ -247,18 +281,26 @@ Proof.
intros x x' Hx y y' Hy.
by split; intros [z ?]; exists z; [rewrite -Hx -Hy|rewrite Hx Hy].
Qed.
Global Instance cmra_update_proper :
Proper (() ==> () ==> iff) (@cmra_update A).
Proof.
intros x1 x2 Hx y1 y2 Hy; split=>? n z; [rewrite -Hx -Hy|rewrite Hx Hy]; auto.
Qed.
Global Instance cmra_opM_ne n : Proper (dist n ==> dist n ==> dist n) (@opM A).
Proof. destruct 2; by cofe_subst. Qed.
Global Instance cmra_opM_proper : Proper (() ==> () ==> ()) (@opM A).
Proof. destruct 2; by setoid_subst. Qed.
Global Instance cmra_updateP_proper :
Proper (() ==> pointwise_relation _ iff ==> iff) (@cmra_updateP A).
Proof.
intros x1 x2 Hx P1 P2 HP; split=>Hup n z;
[rewrite -Hx; setoid_rewrite <-HP|rewrite Hx; setoid_rewrite HP]; auto.
rewrite /pointwise_relation /cmra_updateP=> x x' Hx P P' HP;
split=> ? n mz; setoid_subst; naive_solver.
Qed.
Global Instance cmra_update_proper :
Proper (() ==> () ==> iff) (@cmra_update A).
Proof.
rewrite /cmra_update=> x x' Hx y y' Hy; split=> ? n mz ?; setoid_subst; auto.
Qed.
(** ** Op *)
Lemma cmra_opM_assoc x y mz : (x y) ? mz x (y ? mz).
Proof. destruct mz; by rewrite /= -?assoc. Qed.
(** ** Validity *)
Lemma cmra_validN_le n n' x : {n} x n' n {n'} x.
Proof. induction 2; eauto using cmra_validN_S. Qed.
......@@ -270,33 +312,37 @@ Lemma cmra_valid_op_r x y : ✓ (x ⋅ y) → ✓ y.
Proof. rewrite !cmra_valid_validN; eauto using cmra_validN_op_r. Qed.
(** ** Core *)
Lemma cmra_core_r x : x core x x.
Proof. by rewrite (comm _ x) cmra_core_l. Qed.
Lemma cmra_core_core x : core x core x core x.
Proof. by rewrite -{2}(cmra_core_idemp x) cmra_core_r. Qed.
Lemma cmra_core_validN n x : {n} x {n} core x.
Proof. rewrite -{1}(cmra_core_l x); apply cmra_validN_op_l. Qed.
Lemma cmra_core_valid x : x core x.
Proof. rewrite -{1}(cmra_core_l x); apply cmra_valid_op_l. Qed.
Global Instance cmra_core_persistent x : Persistent (core x).
Proof. apply cmra_core_idemp. Qed.
Lemma cmra_pcore_l' x cx : pcore x Some cx cx x x.
Proof. intros (cx'&?&->)%equiv_Some_inv_r'. by apply cmra_pcore_l. Qed.
Lemma cmra_pcore_r x cx : pcore x = Some cx x cx x.
Proof. intros. rewrite comm. by apply cmra_pcore_l. Qed.
Lemma cmra_pcore_r' x cx : pcore x Some cx x cx x.
Proof. intros (cx'&?&->)%equiv_Some_inv_r'. by apply cmra_pcore_r. Qed.
Lemma cmra_pcore_idemp' x cx : pcore x Some cx pcore cx Some cx.
Proof. intros (cx'&?&->)%equiv_Some_inv_r'. eauto using cmra_pcore_idemp. Qed.
Lemma cmra_pcore_pcore x cx : pcore x = Some cx cx cx cx.
Proof. eauto using cmra_pcore_r', cmra_pcore_idemp. Qed.
Lemma cmra_pcore_pcore' x cx : pcore x Some cx cx cx cx.
Proof. eauto using cmra_pcore_r', cmra_pcore_idemp'. Qed.
Lemma cmra_pcore_validN n x cx : {n} x pcore x = Some cx {n} cx.
Proof.
intros Hvx Hx%cmra_pcore_l. move: Hvx; rewrite -Hx. apply cmra_validN_op_l.
Qed.
Lemma cmra_pcore_valid x cx : x pcore x = Some cx cx.
Proof.
intros Hv Hx%cmra_pcore_l. move: Hv; rewrite -Hx. apply cmra_valid_op_l.
Qed.
(** ** Order *)
Lemma cmra_included_includedN n x y : x y x {n} y.
Proof. intros [z ->]. by exists z. Qed.
Global Instance cmra_includedN_preorder n : PreOrder (@includedN A _ _ n).
Global Instance cmra_includedN_trans n : Transitive (@includedN A _ _ n).
Proof.
split.
- by intros x; exists (core x); rewrite cmra_core_r.
- intros x y z [z1 Hy] [z2 Hz]; exists (z1 z2).
by rewrite assoc -Hy -Hz.
intros x y z [z1 Hy] [z2 Hz]; exists (z1 z2). by rewrite assoc -Hy -Hz.
Qed.
Global Instance cmra_included_preorder: PreOrder (@included A _ _).
Global Instance cmra_included_trans: Transitive (@included A _ _).
Proof.
split.
- by intros x; exists (core x); rewrite cmra_core_r.
- intros x y z [z1 Hy] [z2 Hz]; exists (z1 z2).
by rewrite assoc -Hy -Hz.
intros x y z [z1 Hy] [z2 Hz]; exists (z1 z2). by rewrite assoc -Hy -Hz.
Qed.
Lemma cmra_validN_includedN n x y : {n} y x {n} y {n} x.
Proof. intros Hyv [z ?]; cofe_subst y; eauto using cmra_validN_op_l. Qed.
......@@ -317,13 +363,26 @@ Proof. rewrite (comm op); apply cmra_includedN_l. Qed.
Lemma cmra_included_r x y : y x y.
Proof. rewrite (comm op); apply cmra_included_l. Qed.
Lemma cmra_core_preservingN n x y : x {n} y core x {n} core y.
Lemma cmra_pcore_preserving' x y cx :
x y pcore x Some cx cy, pcore y = Some cy cx cy.
Proof.
intros ? (cx'&?&Hcx)%equiv_Some_inv_r'.
destruct (cmra_pcore_preserving x y cx') as (cy&->&?); auto.
exists cy; by rewrite Hcx.
Qed.
Lemma cmra_pcore_preservingN' n x y cx :
x {n} y pcore x {n} Some cx cy, pcore y = Some cy cx {n} cy.
Proof.
intros [z ->].
apply cmra_included_includedN, cmra_core_preserving, cmra_included_l.
intros [z Hy] (cx'&?&Hcx)%dist_Some_inv_r'.
destruct (cmra_pcore_preserving x (x z) cx')
as (cy&Hxy&?); auto using cmra_included_l.
assert (pcore y {n} Some cy) as (cy'&?&Hcy')%dist_Some_inv_r'.
{ by rewrite Hy Hxy. }