diff --git a/algebra/agree.v b/algebra/agree.v index ecc0bd9758028e8fab806b46a3e96f514da1e2b5..320b7ae1e4847aeebf5cb7fac55ed63745a91672 100644 --- a/algebra/agree.v +++ b/algebra/agree.v @@ -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 |}. diff --git a/algebra/auth.v b/algebra/auth.v index 21012546f19d09688633053919d7b962861d460b..4ae474849c058fc5b5975fa7b1bb07bb4b280f8a 100644 --- a/algebra/auth.v +++ b/algebra/auth.v @@ -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); diff --git a/algebra/cmra.v b/algebra/cmra.v index e15086715cfcf1c1b2dc2be8d963aa205229b94c..fe76e9cbb9a91bf7f1750da556fb924eab21d579 100644 --- a/algebra/cmra.v +++ b/algebra/cmra.v @@ -1,7 +1,7 @@ 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. } + exists cy'; split; first done. + rewrite Hcx -Hcy'; auto using cmra_included_includedN. Qed. -Lemma cmra_included_core x : core x ≼ x. -Proof. by exists x; rewrite cmra_core_l. Qed. +Lemma cmra_included_pcore x cx : pcore x = Some cx → cx ≼ x. +Proof. exists x. by rewrite cmra_pcore_l. Qed. Lemma cmra_preservingN_l n x y z : x ≼{n} y → z ⋅ x ≼{n} z ⋅ y. Proof. by intros [z1 Hz1]; exists z1; rewrite Hz1 (assoc op). Qed. Lemma cmra_preserving_l x y z : x ≼ y → z ⋅ x ≼ z ⋅ y. @@ -340,6 +399,74 @@ Proof. by rewrite Hx1 Hx2. Qed. +(** ** Total core *) +Section total_core. + Context `{CMRATotal A}. + + Lemma cmra_core_l x : core x ⋅ x ≡ x. + Proof. + destruct (cmra_total x) as [cx Hcx]. by rewrite /core /= Hcx cmra_pcore_l. + Qed. + Lemma cmra_core_idemp x : core (core x) ≡ core x. + Proof. + destruct (cmra_total x) as [cx Hcx]. by rewrite /core /= Hcx cmra_pcore_idemp. + Qed. + Lemma cmra_core_preserving x y : x ≼ y → core x ≼ core y. + Proof. + intros; destruct (cmra_total x) as [cx Hcx]. + destruct (cmra_pcore_preserving x y cx) as (cy&Hcy&?); auto. + by rewrite /core /= Hcx Hcy. + Qed. + + Global Instance cmra_core_ne n : Proper (dist n ==> dist n) (@core A _). + Proof. + intros x y Hxy. destruct (cmra_total x) as [cx Hcx]. + by rewrite /core /= -Hxy Hcx. + Qed. + Global Instance cmra_core_proper : Proper ((≡) ==> (≡)) (@core A _). + Proof. apply (ne_proper _). Qed. + + 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. + + Lemma persistent_total x : Persistent x ↔ core x ≡ x. + Proof. + split; [intros; by rewrite /core /= (persistent x)|]. + rewrite /Persistent /core /=. + destruct (cmra_total x) as [? ->]. by constructor. + Qed. + Lemma persistent_core x `{!Persistent x} : core x ≡ x. + Proof. by apply persistent_total. Qed. + + Global Instance cmra_core_persistent x : Persistent (core x). + Proof. + destruct (cmra_total x) as [cx Hcx]. + rewrite /Persistent /core /= Hcx /=. eauto using cmra_pcore_idemp. + Qed. + + Lemma cmra_included_core x : core x ≼ x. + Proof. by exists x; rewrite cmra_core_l. Qed. + Global Instance cmra_includedN_preorder n : PreOrder (@includedN A _ _ n). + Proof. + split; [|apply _]. by intros x; exists (core x); rewrite cmra_core_r. + Qed. + Global Instance cmra_included_preorder : PreOrder (@included A _ _). + Proof. + split; [|apply _]. by intros x; exists (core x); rewrite cmra_core_r. + Qed. + Lemma cmra_core_preservingN n x y : x ≼{n} y → core x ≼{n} core y. + Proof. + intros [z ->]. + apply cmra_included_includedN, cmra_core_preserving, cmra_included_l. + Qed. +End total_core. + (** ** Timeless *) Lemma cmra_timeless_included_l x y : Timeless x → ✓{0} y → x ≼{0} y → x ≼ y. Proof. @@ -369,12 +496,6 @@ Proof. split; first by apply cmra_included_includedN. intros [z ->%(timeless_iff _ _)]; eauto using cmra_included_l. Qed. -Lemma cmra_discrete_updateP `{CMRADiscrete A} (x : A) (P : A → Prop) : - (∀ z, ✓ (x ⋅ z) → ∃ y, P y ∧ ✓ (y ⋅ z)) → x ~~>: P. -Proof. intros ? n. by setoid_rewrite <-cmra_discrete_valid_iff. Qed. -Lemma cmra_discrete_update `{CMRADiscrete A} (x y : A) : - (∀ z, ✓ (x ⋅ z) → ✓ (y ⋅ z)) → x ~~> y. -Proof. intros ? n. by setoid_rewrite <-cmra_discrete_valid_iff. Qed. (** ** Local updates *) Global Instance local_update_proper Lv (L : A → A) : @@ -394,74 +515,143 @@ Global Instance local_update_id : LocalUpdate (λ _, True) (@id A). Proof. split; auto with typeclass_instances. Qed. (** ** Updates *) -Global Instance cmra_update_preorder : PreOrder (@cmra_update A). -Proof. split. by intros x y. intros x y y' ?? z ?; naive_solver. Qed. Lemma cmra_update_updateP x y : x ~~> y ↔ x ~~>: (y =). -Proof. - split. - - by intros Hx z ?; exists y; split; [done|apply (Hx z)]. - - by intros Hx n z ?; destruct (Hx n z) as (?&<-&?). -Qed. +Proof. split=> Hup n z ?; eauto. destruct (Hup n z) as (?&<-&?); auto. Qed. Lemma cmra_updateP_id (P : A → Prop) x : P x → x ~~>: P. -Proof. by intros ? n z ?; exists x. Qed. +Proof. intros ? n mz ?; eauto. Qed. Lemma cmra_updateP_compose (P Q : A → Prop) x : x ~~>: P → (∀ y, P y → y ~~>: Q) → x ~~>: Q. -Proof. - intros Hx Hy n z ?. destruct (Hx n z) as (y&?&?); auto. by apply (Hy y). -Qed. +Proof. intros Hx Hy n mz ?. destruct (Hx n mz) as (y&?&?); naive_solver. Qed. Lemma cmra_updateP_compose_l (Q : A → Prop) x y : x ~~> y → y ~~>: Q → x ~~>: Q. Proof. rewrite cmra_update_updateP. - intros; apply cmra_updateP_compose with (y =); intros; subst; auto. + intros; apply cmra_updateP_compose with (y =); naive_solver. Qed. -Lemma cmra_updateP_weaken (P Q : A → Prop) x : x ~~>: P → (∀ y, P y → Q y) → x ~~>: Q. +Lemma cmra_updateP_weaken (P Q : A → Prop) x : + x ~~>: P → (∀ y, P y → Q y) → x ~~>: Q. Proof. eauto using cmra_updateP_compose, cmra_updateP_id. Qed. +Global Instance cmra_update_preorder : PreOrder (@cmra_update A). +Proof. + split. + - intros x. by apply cmra_update_updateP, cmra_updateP_id. + - intros x y z. rewrite !cmra_update_updateP. + eauto using cmra_updateP_compose with subst. +Qed. Lemma cmra_updateP_op (P1 P2 Q : A → Prop) x1 x2 : - x1 ~~>: P1 → x2 ~~>: P2 → (∀ y1 y2, P1 y1 → P2 y2 → Q (y1 ⋅ y2)) → x1 ⋅ x2 ~~>: Q. + x1 ~~>: P1 → x2 ~~>: P2 → (∀ y1 y2, P1 y1 → P2 y2 → Q (y1 ⋅ y2)) → + x1 ⋅ x2 ~~>: Q. Proof. - intros Hx1 Hx2 Hy n z ?. - destruct (Hx1 n (x2 ⋅ z)) as (y1&?&?); first by rewrite assoc. - destruct (Hx2 n (y1 ⋅ z)) as (y2&?&?); - first by rewrite assoc (comm _ x2) -assoc. - exists (y1 ⋅ y2); split; last rewrite (comm _ y1) -assoc; auto. + intros Hx1 Hx2 Hy n mz ?. + destruct (Hx1 n (Some (x2 ⋅? mz))) as (y1&?&?). + { by rewrite /= -cmra_opM_assoc. } + destruct (Hx2 n (Some (y1 ⋅? mz))) as (y2&?&?). + { by rewrite /= -cmra_opM_assoc (comm _ x2) cmra_opM_assoc. } + exists (y1 ⋅ y2); split; last rewrite (comm _ y1) cmra_opM_assoc; auto. Qed. Lemma cmra_updateP_op' (P1 P2 : A → Prop) x1 x2 : - x1 ~~>: P1 → x2 ~~>: P2 → x1 ⋅ x2 ~~>: λ y, ∃ y1 y2, y = y1 ⋅ y2 ∧ P1 y1 ∧ P2 y2. + x1 ~~>: P1 → x2 ~~>: P2 → + x1 ⋅ x2 ~~>: λ y, ∃ y1 y2, y = y1 ⋅ y2 ∧ P1 y1 ∧ P2 y2. Proof. eauto 10 using cmra_updateP_op. Qed. Lemma cmra_update_op x1 x2 y1 y2 : x1 ~~> y1 → x2 ~~> y2 → x1 ⋅ x2 ~~> y1 ⋅ y2. Proof. rewrite !cmra_update_updateP; eauto using cmra_updateP_op with congruence. Qed. -Lemma cmra_update_id x : x ~~> x. -Proof. intro. auto. Qed. + +Section total_updates. + Context `{CMRATotal A}. + + Lemma cmra_total_updateP x (P : A → Prop) : + x ~~>: P ↔ ∀ n z, ✓{n} (x ⋅ z) → ∃ y, P y ∧ ✓{n} (y ⋅ z). + Proof. + split=> Hup; [intros n z; apply (Hup n (Some z))|]. + intros n [z|] ?; simpl; [by apply Hup|]. + destruct (Hup n (core x)) as (y&?&?); first by rewrite cmra_core_r. + eauto using cmra_validN_op_l. + Qed. + Lemma cmra_total_update x y : x ~~> y ↔ ∀ n z, ✓{n} (x ⋅ z) → ✓{n} (y ⋅ z). + Proof. rewrite cmra_update_updateP cmra_total_updateP. naive_solver. Qed. + + Context `{CMRADiscrete A}. + + Lemma cmra_discrete_updateP (x : A) (P : A → Prop) : + x ~~>: P ↔ ∀ z, ✓ (x ⋅ z) → ∃ y, P y ∧ ✓ (y ⋅ z). + Proof. + rewrite cmra_total_updateP; setoid_rewrite <-cmra_discrete_valid_iff. + naive_solver eauto using 0. + Qed. + Lemma cmra_discrete_update `{CMRADiscrete A} (x y : A) : + x ~~> y ↔ ∀ z, ✓ (x ⋅ z) → ✓ (y ⋅ z). + Proof. + rewrite cmra_total_update; setoid_rewrite <-cmra_discrete_valid_iff. + naive_solver eauto using 0. + Qed. +End total_updates. End cmra. (** * Properties about CMRAs with a unit element **) Section ucmra. -Context {A : ucmraT}. -Implicit Types x y z : A. + Context {A : ucmraT}. + Implicit Types x y z : A. + + Global Instance ucmra_unit_inhabited : Inhabited A := populate ∅. + + Lemma ucmra_unit_validN n : ✓{n} (∅:A). + Proof. apply cmra_valid_validN, ucmra_unit_valid. Qed. + Lemma ucmra_unit_leastN n x : ∅ ≼{n} x. + Proof. by exists x; rewrite left_id. Qed. + Lemma ucmra_unit_least x : ∅ ≼ x. + Proof. by exists x; rewrite left_id. Qed. + Global Instance ucmra_unit_right_id : RightId (≡) ∅ (@op A _). + Proof. by intros x; rewrite (comm op) left_id. Qed. + Global Instance ucmra_unit_persistent : Persistent (∅:A). + Proof. apply ucmra_pcore_unit. Qed. + + Global Instance cmra_unit_total : CMRATotal A. + Proof. + intros x. destruct (cmra_pcore_preserving' ∅ x ∅) as (cx&->&?); + eauto using ucmra_unit_least, (persistent ∅). + Qed. -Global Instance ucmra_unit_inhabited : Inhabited A := populate ∅. - -Lemma ucmra_unit_validN n : ✓{n} (∅:A). -Proof. apply cmra_valid_validN, ucmra_unit_valid. Qed. -Lemma ucmra_unit_leastN n x : ∅ ≼{n} x. -Proof. by exists x; rewrite left_id. Qed. -Lemma ucmra_unit_least x : ∅ ≼ x. -Proof. by exists x; rewrite left_id. Qed. -Global Instance ucmra_unit_right_id : RightId (≡) ∅ (@op A _). -Proof. by intros x; rewrite (comm op) left_id. Qed. -Global Instance ucmra_unit_persistent : Persistent (∅:A). -Proof. by rewrite /Persistent -{2}(cmra_core_l ∅) right_id. Qed. -Lemma ucmra_core_unit : core (∅:A) ≡ ∅. -Proof. by rewrite -{2}(cmra_core_l ∅) right_id. Qed. - -Lemma ucmra_update_unit x : x ~~> ∅. -Proof. intros n z; rewrite left_id; apply cmra_validN_op_r. Qed. -Lemma ucmra_update_unit_alt y : ∅ ~~> y ↔ ∀ x, x ~~> y. -Proof. split; [intros; trans ∅|]; auto using ucmra_update_unit. Qed. + Lemma ucmra_update_unit x : x ~~> ∅. + Proof. + apply cmra_total_update=> n z. rewrite left_id; apply cmra_validN_op_r. + Qed. + Lemma ucmra_update_unit_alt y : ∅ ~~> y ↔ ∀ x, x ~~> y. + Proof. split; [intros; trans ∅|]; auto using ucmra_update_unit. Qed. End ucmra. +Hint Immediate cmra_unit_total. + +(** * Constructing a CMRA with total core *) +Section cmra_total. + Context A `{Dist A, Equiv A, PCore A, Op A, Valid A, ValidN A}. + Context (total : ∀ x, is_Some (pcore x)). + Context (op_ne : ∀ n (x : A), Proper (dist n ==> dist n) (op x)). + Context (core_ne : ∀ n, Proper (dist n ==> dist n) (@core A _)). + Context (validN_ne : ∀ n, Proper (dist n ==> impl) (@validN A _ n)). + Context (valid_validN : ∀ (x : A), ✓ x ↔ ∀ n, ✓{n} x). + Context (validN_S : ∀ n (x : A), ✓{S n} x → ✓{n} x). + Context (op_assoc : Assoc (≡) (@op A _)). + Context (op_comm : Comm (≡) (@op A _)). + Context (core_l : ∀ x : A, core x ⋅ x ≡ x). + Context (core_idemp : ∀ x : A, core (core x) ≡ core x). + Context (core_preserving : ∀ x y : A, x ≼ y → core x ≼ core y). + Context (validN_op_l : ∀ n (x y : A), ✓{n} (x ⋅ y) → ✓{n} x). + Context (extend : ∀ n (x y1 y2 : A), + ✓{n} x → x ≡{n}≡ y1 ⋅ y2 → + { z | x ≡ z.1 ⋅ z.2 ∧ z.1 ≡{n}≡ y1 ∧ z.2 ≡{n}≡ y2 }). + Lemma cmra_total_mixin : CMRAMixin A. + Proof. + split; auto. + - intros n x y ? Hcx%core_ne Hx; move: Hcx. rewrite /core /= Hx /=. + case (total y)=> [cy ->]; eauto. + - intros x cx Hcx. move: (core_l x). by rewrite /core /= Hcx. + - intros x cx Hcx. move: (core_idemp x). rewrite /core /= Hcx /=. + case (total cx)=>[ccx ->]; by constructor. + - intros x y cx Hxy%core_preserving Hx. move: Hxy. + rewrite /core /= Hx /=. case (total y)=> [cy ->]; eauto. + Qed. +End cmra_total. (** * Properties about monotone functions *) Instance cmra_monotone_id {A : cmraT} : CMRAMonotone (@id A). @@ -579,22 +769,24 @@ End cmra_transport. (** * Instances *) (** ** Discrete CMRA *) -Record RAMixin A `{Equiv A, Core A, Op A, Valid A} := { +Record RAMixin A `{Equiv A, PCore A, Op A, Valid A} := { (* setoids *) - ra_op_ne (x : A) : Proper ((≡) ==> (≡)) (op x); - ra_core_ne : Proper ((≡) ==> (≡)) core; - ra_validN_ne : Proper ((≡) ==> impl) valid; + ra_op_proper (x : A) : Proper ((≡) ==> (≡)) (op x); + ra_core_proper x y cx : + x ≡ y → pcore x = Some cx → ∃ cy, pcore y = Some cy ∧ cx ≡ cy; + ra_validN_proper : Proper ((≡) ==> impl) valid; (* monoid *) ra_assoc : Assoc (≡) (⋅); ra_comm : Comm (≡) (⋅); - ra_core_l x : core x ⋅ x ≡ x; - ra_core_idemp x : core (core x) ≡ core x; - ra_core_preserving x y : x ≼ y → core x ≼ core y; + ra_pcore_l x cx : pcore x = Some cx → cx ⋅ x ≡ x; + ra_pcore_idemp x cx : pcore x = Some cx → pcore cx ≡ Some cx; + ra_pcore_preserving x y cx : + x ≼ y → pcore x = Some cx → ∃ cy, pcore y = Some cy ∧ cx ≼ cy; ra_valid_op_l x y : ✓ (x ⋅ y) → ✓ x }. Section discrete. - Context `{Equiv A, Core A, Op A, Valid A, @Equivalence A (≡)}. + Context `{Equiv A, PCore A, Op A, Valid A, @Equivalence A (≡)}. Context (ra_mix : RAMixin A). Existing Instances discrete_dist discrete_compl. @@ -612,19 +804,43 @@ Notation discreteR A ra_mix := Notation discreteLeibnizR A ra_mix := (CMRAT A (@discrete_cofe_mixin _ equivL _) (discrete_cmra_mixin ra_mix)). -Global Instance discrete_cmra_discrete `{Equiv A, Core A, Op A, Valid A, +Global Instance discrete_cmra_discrete `{Equiv A, PCore A, Op A, Valid A, @Equivalence A (≡)} (ra_mix : RAMixin A) : CMRADiscrete (discreteR A ra_mix). Proof. split. apply _. done. Qed. +Section ra_total. + Context A `{Equiv A, PCore A, Op A, Valid A}. + Context (total : ∀ x, is_Some (pcore x)). + Context (op_proper : ∀ (x : A), Proper ((≡) ==> (≡)) (op x)). + Context (core_proper: Proper ((≡) ==> (≡)) (@core A _)). + Context (valid_proper : Proper ((≡) ==> impl) (@valid A _)). + Context (op_assoc : Assoc (≡) (@op A _)). + Context (op_comm : Comm (≡) (@op A _)). + Context (core_l : ∀ x : A, core x ⋅ x ≡ x). + Context (core_idemp : ∀ x : A, core (core x) ≡ core x). + Context (core_preserving : ∀ x y : A, x ≼ y → core x ≼ core y). + Context (valid_op_l : ∀ x y : A, ✓ (x ⋅ y) → ✓ x). + Lemma ra_total_mixin : RAMixin A. + Proof. + split; auto. + - intros x y ? Hcx%core_proper Hx; move: Hcx. rewrite /core /= Hx /=. + case (total y)=> [cy ->]; eauto. + - intros x cx Hcx. move: (core_l x). by rewrite /core /= Hcx. + - intros x cx Hcx. move: (core_idemp x). rewrite /core /= Hcx /=. + case (total cx)=>[ccx ->]; by constructor. + - intros x y cx Hxy%core_preserving Hx. move: Hxy. + rewrite /core /= Hx /=. case (total y)=> [cy ->]; eauto. + Qed. +End ra_total. + (** ** CMRA for the unit type *) Section unit. Instance unit_valid : Valid () := λ x, True. Instance unit_validN : ValidN () := λ n x, True. - Instance unit_core : Core () := λ x, x. + Instance unit_pcore : PCore () := λ x, Some x. Instance unit_op : Op () := λ x y, (). - Lemma unit_cmra_mixin : CMRAMixin (). - Proof. by split; last exists ((),()). Qed. + Proof. apply cmra_total_mixin; try done. eauto. by exists ((),()). Qed. Canonical Structure unitR : cmraT := CMRAT () unit_cofe_mixin unit_cmra_mixin. Instance unit_empty : Empty () := (). @@ -636,17 +852,34 @@ Section unit. Global Instance unit_cmra_discrete : CMRADiscrete unitR. Proof. done. Qed. Global Instance unit_persistent (x : ()) : Persistent x. - Proof. done. Qed. + Proof. by constructor. Qed. End unit. (** ** Product *) Section prod. Context {A B : cmraT}. + Local Arguments pcore _ _ !_ /. + Local Arguments cmra_pcore _ !_/. + Instance prod_op : Op (A * B) := λ x y, (x.1 ⋅ y.1, x.2 ⋅ y.2). - Instance prod_core : Core (A * B) := λ x, (core (x.1), core (x.2)). + Instance prod_pcore : PCore (A * B) := λ x, + c1 ↠pcore (x.1); c2 ↠pcore (x.2); Some (c1, c2). + Arguments prod_pcore !_ /. Instance prod_valid : Valid (A * B) := λ x, ✓ x.1 ∧ ✓ x.2. Instance prod_validN : ValidN (A * B) := λ n x, ✓{n} x.1 ∧ ✓{n} x.2. + Lemma prod_pcore_Some (x cx : A * B) : + pcore x = Some cx ↔ pcore (x.1) = Some (cx.1) ∧ pcore (x.2) = Some (cx.2). + Proof. destruct x, cx; by intuition simplify_option_eq. Qed. + Lemma prod_pcore_Some' (x cx : A * B) : + pcore x ≡ Some cx ↔ pcore (x.1) ≡ Some (cx.1) ∧ pcore (x.2) ≡ Some (cx.2). + Proof. + split; [by intros (cx'&[-> ->]%prod_pcore_Some&->)%equiv_Some_inv_r'|]. + rewrite {3}/pcore /prod_pcore. (* TODO: use setoid rewrite *) + intros [Hx1 Hx2]; inversion_clear Hx1; simpl; inversion_clear Hx2. + by constructor. + Qed. + Lemma prod_included (x y : A * B) : x ≼ y ↔ x.1 ≼ y.1 ∧ x.2 ≼ y.2. Proof. split; [intros [z Hz]; split; [exists (z.1)|exists (z.2)]; apply Hz|]. @@ -662,7 +895,10 @@ Section prod. Proof. split; try apply _. - by intros n x y1 y2 [Hy1 Hy2]; split; rewrite /= ?Hy1 ?Hy2. - - by intros n y1 y2 [Hy1 Hy2]; split; rewrite /= ?Hy1 ?Hy2. + - intros n x y cx; setoid_rewrite prod_pcore_Some=> -[??] [??]. + destruct (cmra_pcore_ne n (x.1) (y.1) (cx.1)) as (z1&->&?); auto. + destruct (cmra_pcore_ne n (x.2) (y.2) (cx.2)) as (z2&->&?); auto. + exists (z1,z2); repeat constructor; auto. - by intros n y1 y2 [Hy1 Hy2] [??]; split; rewrite /= -?Hy1 -?Hy2. - intros x; split. + intros [??] n; split; by apply cmra_valid_validN. @@ -670,10 +906,14 @@ Section prod. - by intros n x [??]; split; apply cmra_validN_S. - by split; rewrite /= assoc. - by split; rewrite /= comm. - - by split; rewrite /= cmra_core_l. - - by split; rewrite /= cmra_core_idemp. - - intros x y; rewrite !prod_included. - by intros [??]; split; apply cmra_core_preserving. + - intros x y [??]%prod_pcore_Some; + constructor; simpl; eauto using cmra_pcore_l. + - intros x y; rewrite prod_pcore_Some prod_pcore_Some'. + naive_solver eauto using cmra_pcore_idemp. + - intros x y cx; rewrite prod_included prod_pcore_Some=> -[??] [??]. + destruct (cmra_pcore_preserving (x.1) (y.1) (cx.1)) as (z1&?&?); auto. + destruct (cmra_pcore_preserving (x.2) (y.2) (cx.2)) as (z2&?&?); auto. + exists (z1,z2). by rewrite prod_included prod_pcore_Some. - intros n x y [??]; split; simpl in *; eauto using cmra_validN_op_l. - intros n x y1 y2 [??] [??]; simpl in *. destruct (cmra_extend n (x.1) (y1.1) (y2.1)) as (z1&?&?&?); auto. @@ -683,26 +923,36 @@ Section prod. Canonical Structure prodR := CMRAT (A * B) prod_cofe_mixin prod_cmra_mixin. + Global Instance prod_cmra_total : CMRATotal A → CMRATotal B → CMRATotal prodR. + Proof. + intros H1 H2 [a b]. destruct (H1 a) as [ca ?], (H2 b) as [cb ?]. + exists (ca,cb); by simplify_option_eq. + Qed. + Global Instance prod_cmra_discrete : CMRADiscrete A → CMRADiscrete B → CMRADiscrete prodR. Proof. split. apply _. by intros ? []; split; apply cmra_discrete_valid. Qed. Global Instance pair_persistent x y : Persistent x → Persistent y → Persistent (x,y). - Proof. by split. Qed. + Proof. by rewrite /Persistent prod_pcore_Some'. Qed. - Lemma prod_update x y : x.1 ~~> y.1 → x.2 ~~> y.2 → x ~~> y. - Proof. intros ?? n z [??]; split; simpl in *; auto. Qed. Lemma prod_updateP P1 P2 (Q : A * B → Prop) x : x.1 ~~>: P1 → x.2 ~~>: P2 → (∀ a b, P1 a → P2 b → Q (a,b)) → x ~~>: Q. Proof. - intros Hx1 Hx2 HP n z [??]; simpl in *. - destruct (Hx1 n (z.1)) as (a&?&?), (Hx2 n (z.2)) as (b&?&?); auto. - exists (a,b); repeat split; auto. + intros Hx1 Hx2 HP n mz [??]; simpl in *. + destruct (Hx1 n (fst <$> mz)) as (a&?&?); first by destruct mz. + destruct (Hx2 n (snd <$> mz)) as (b&?&?); first by destruct mz. + exists (a,b); repeat split; destruct mz; auto. Qed. Lemma prod_updateP' P1 P2 x : x.1 ~~>: P1 → x.2 ~~>: P2 → x ~~>: λ y, P1 (y.1) ∧ P2 (y.2). Proof. eauto using prod_updateP. Qed. + Lemma prod_update x y : x.1 ~~> y.1 → x.2 ~~> y.2 → x ~~> y. + Proof. + rewrite !cmra_update_updateP. + destruct x, y; eauto using prod_updateP with subst. + Qed. Global Instance prod_local_update (LA : A → A) `{!LocalUpdate LvA LA} (LB : B → B) `{!LocalUpdate LvB LB} : @@ -727,6 +977,7 @@ Section prod_unit. - split; apply ucmra_unit_valid. - by split; rewrite /=left_id. - by intros ? [??]; split; apply (timeless _). + - rewrite prod_pcore_Some'; split; apply (persistent _). Qed. Canonical Structure prodUR := UCMRAT (A * B) prod_cofe_mixin prod_cmra_mixin prod_ucmra_mixin. @@ -793,21 +1044,24 @@ Qed. (** ** CMRA for the option type *) Section option. Context {A : cmraT}. + Local Arguments core _ _ !_ /. + Local Arguments pcore _ _ !_ /. Instance option_valid : Valid (option A) := λ mx, match mx with Some x => ✓ x | None => True end. Instance option_validN : ValidN (option A) := λ n mx, match mx with Some x => ✓{n} x | None => True end. - Instance option_empty : Empty (option A) := None. - - Instance option_core : Core (option A) := fmap core. + Instance option_pcore : PCore (option A) := λ mx, Some (mx ≫= pcore). + Arguments option_pcore !_ /. Instance option_op : Op (option A) := union_with (λ x y, Some (x ⋅ y)). Definition Some_valid a : ✓ Some a ↔ ✓ a := reflexivity _. Definition Some_op a b : Some (a ⋅ b) = Some a ⋅ Some b := eq_refl. + Lemma Some_core `{CMRATotal A} a : Some (core a) = core (Some a). + Proof. rewrite /core /=. by destruct (cmra_total a) as [? ->]. Qed. Lemma option_included (mx my : option A) : - mx ≼ my ↔ mx = None ∨ ∃ x y, mx = Some x ∧ my = Some y ∧ x ≼ y. + mx ≼ my ↔ mx = None ∨ ∃ x y, mx = Some x ∧ my = Some y ∧ (x ≼ y ∨ x ≡ y). Proof. split. - intros [mz Hmz]. @@ -815,24 +1069,33 @@ Section option. destruct my as [y|]; [exists x, y|destruct mz; inversion_clear Hmz]. destruct mz as [z|]; inversion_clear Hmz; split_and?; auto; setoid_subst; eauto using cmra_included_l. - - intros [->|(x&y&->&->&z&Hz)]; try (by exists my; destruct my; constructor). - by exists (Some z); constructor. + - intros [->|(x&y&->&->&[[z Hz]|Hz])]. + + exists my. by destruct my. + + exists (Some z); by constructor. + + exists None; by constructor. Qed. Lemma option_cmra_mixin : CMRAMixin (option A). Proof. - split. + apply cmra_total_mixin. + - eauto. - by intros n [x|]; destruct 1; constructor; cofe_subst. - - by destruct 1; constructor; cofe_subst. + - destruct 1; by cofe_subst. - by destruct 1; rewrite /validN /option_validN //=; cofe_subst. - intros [x|]; [apply cmra_valid_validN|done]. - intros n [x|]; unfold validN, option_validN; eauto using cmra_validN_S. - intros [x|] [y|] [z|]; constructor; rewrite ?assoc; auto. - intros [x|] [y|]; constructor; rewrite 1?comm; auto. - - by intros [x|]; constructor; rewrite cmra_core_l. - - by intros [x|]; constructor; rewrite cmra_core_idemp. - - intros mx my; rewrite !option_included ;intros [->|(x&y&->&->&?)]; auto. - right; exists (core x), (core y); eauto using cmra_core_preserving. + - intros [x|]; simpl; auto. + destruct (pcore x) as [cx|] eqn:?; constructor; eauto using cmra_pcore_l. + - intros [x|]; simpl; auto. + destruct (pcore x) as [cx|] eqn:?; simpl; eauto using cmra_pcore_idemp. + - intros mx my; setoid_rewrite option_included. + intros [->|(x&y&->&->&[?|?])]; simpl; eauto. + + destruct (pcore x) as [cx|] eqn:?; eauto. + destruct (cmra_pcore_preserving x y cx) as (?&?&?); eauto 10. + + destruct (pcore x) as [cx|] eqn:?; eauto. + destruct (cmra_pcore_proper x y cx) as (?&?&?); eauto 10. - intros n [x|] [y|]; rewrite /validN /option_validN /=; eauto using cmra_validN_op_l. - intros n mx my1 my2. @@ -851,8 +1114,9 @@ Section option. Global Instance option_cmra_discrete : CMRADiscrete A → CMRADiscrete optionR. Proof. split; [apply _|]. by intros [x|]; [apply (cmra_discrete_valid x)|]. Qed. + Instance option_empty : Empty (option A) := None. Lemma option_ucmra_mixin : UCMRAMixin optionR. - Proof. split. done. by intros []. by inversion_clear 1. Qed. + Proof. split. done. by intros []. by inversion_clear 1. done. Qed. Canonical Structure optionUR := UCMRAT (option A) option_cofe_mixin option_cmra_mixin option_ucmra_mixin. @@ -872,16 +1136,16 @@ Section option. Proof. by constructor. Qed. Global Instance option_persistent (mx : option A) : (∀ x : A, Persistent x) → Persistent mx. - Proof. intros. destruct mx. apply _. constructor. Qed. + Proof. intros. destruct mx; apply _. Qed. (** Updates *) Lemma option_updateP (P : A → Prop) (Q : option A → Prop) x : x ~~>: P → (∀ y, P y → Q (Some y)) → Some x ~~>: Q. Proof. - intros Hx Hy n [y|] ?. - { destruct (Hx n y) as (y'&?&?); auto. exists (Some y'); auto. } - destruct (Hx n (core x)) as (y'&?&?); rewrite ?cmra_core_r; auto. - by exists (Some y'); split; [auto|apply cmra_validN_op_l with (core x)]. + intros Hx Hy; apply cmra_total_updateP=> n [y|] ?. + { destruct (Hx n (Some y)) as (y'&?&?); auto. exists (Some y'); auto. } + destruct (Hx n None) as (y'&?&?); rewrite ?cmra_core_r; auto. + by exists (Some y'); auto. Qed. Lemma option_updateP' (P : A → Prop) x : x ~~>: P → Some x ~~>: from_option P False. @@ -901,7 +1165,8 @@ Proof. split; first apply _. - intros n [x|] ?; rewrite /cmra_validN //=. by apply (validN_preserving f). - intros mx my; rewrite !option_included. - intros [->|(x&y&->&->&?)]; simpl; eauto 10 using @included_preserving. + intros [->|(x&y&->&->&[?|Hxy])]; simpl; eauto 10 using @included_preserving. + right; exists (f x), (f y). by rewrite {4}Hxy; eauto. Qed. Program Definition optionURF (F : rFunctor) : urFunctor := {| urFunctor_car A B := optionUR (rFunctor_car F A B); diff --git a/algebra/cofe.v b/algebra/cofe.v index 6ef5c1332e68716257ff3f93b34556a1999724be..dcfaa63558459411457966b8a864ed7f2640dee6 100644 --- a/algebra/cofe.v +++ b/algebra/cofe.v @@ -88,6 +88,8 @@ Section cofe_mixin. Proof. apply (mixin_conv_compl _ (cofe_mixin A)). Qed. End cofe_mixin. +Hint Extern 1 (_ ≡{_}≡ _) => apply equiv_dist; assumption. + (** Discrete COFEs and Timeless elements *) (* TODO: On paper, We called these "discrete elements". I think that makes more sense. *) @@ -151,8 +153,7 @@ Section cofe. Qed. Lemma timeless_iff n (x : A) `{!Timeless x} y : x ≡ y ↔ x ≡{n}≡ y. Proof. - split; intros; [by apply equiv_dist|]. - apply (timeless _), dist_le with n; auto with lia. + split; intros; auto. apply (timeless _), dist_le with n; auto with lia. Qed. End cofe. @@ -569,6 +570,9 @@ Section option. Proof. destruct 1; split; eauto. Qed. Global Instance Some_dist_inj : Inj (dist n) (dist n) (@Some A). Proof. by inversion_clear 1. Qed. + Global Instance from_option_ne {B} (R : relation B) (f : A → B) n : + Proper (dist n ==> R) f → Proper (R ==> dist n ==> R) (from_option f). + Proof. destruct 3; simpl; auto. Qed. Global Instance None_timeless : Timeless (@None A). Proof. inversion_clear 1; constructor. Qed. @@ -592,14 +596,9 @@ End option. Typeclasses Opaque option_dist. Arguments optionC : clear implicits. -Instance from_option_ne {A B : cofeT} (f : A → B) n : - Proper (dist n ==> dist n) f → - Proper (dist n ==> dist n ==> dist n) (from_option f). -Proof. destruct 3; simpl; auto. Qed. - -Instance option_fmap_ne {A B : cofeT} (f : A → B) n: - Proper (dist n ==> dist n) f → Proper (dist n==>dist n) (fmap (M:=option) f). -Proof. by intros Hf; destruct 1; constructor; apply Hf. Qed. +Instance option_fmap_ne {A B : cofeT} n: + Proper ((dist n ==> dist n) ==> dist n ==> dist n) (@fmap option _ A B). +Proof. intros f f' Hf ?? []; constructor; auto. Qed. Definition optionC_map {A B} (f : A -n> B) : optionC A -n> optionC B := CofeMor (fmap f : optionC A → optionC B). Instance optionC_map_ne A B n : Proper (dist n ==> dist n) (@optionC_map A B). diff --git a/algebra/dec_agree.v b/algebra/dec_agree.v index 07352633a70f500e7d48caf421a33381fe4d97b4..4fe1fba88d68a5b696726e114b874695636790be 100644 --- a/algebra/dec_agree.v +++ b/algebra/dec_agree.v @@ -2,7 +2,7 @@ From iris.algebra Require Export cmra. Local Arguments validN _ _ _ !_ /. Local Arguments valid _ _ !_ /. Local Arguments op _ _ _ !_ /. -Local Arguments core _ _ !_ /. +Local Arguments pcore _ _ !_ /. (* This is isomorphic to option, but has a very different RA structure. *) Inductive dec_agree (A : Type) : Type := @@ -26,19 +26,19 @@ Instance dec_agree_op : Op (dec_agree A) := λ x y, | DecAgree a, DecAgree b => if decide (a = b) then DecAgree a else DecAgreeBot | _, _ => DecAgreeBot end. -Instance dec_agree_core : Core (dec_agree A) := id. +Instance dec_agree_pcore : PCore (dec_agree A) := Some. Definition dec_agree_ra_mixin : RAMixin (dec_agree A). Proof. split. - apply _. - - apply _. + - intros x y cx ? [=<-]; eauto. - apply _. - intros [?|] [?|] [?|]; by repeat (simplify_eq/= || case_match). - intros [?|] [?|]; by repeat (simplify_eq/= || case_match). + - intros [?|] ? [=<-]; by repeat (simplify_eq/= || case_match). - intros [?|]; by repeat (simplify_eq/= || case_match). - - intros [?|]; by repeat (simplify_eq/= || case_match). - - by intros [?|] [?|] ?. + - intros [?|] [?|] ?? [=<-]; eauto. - by intros [?|] [?|] ?. Qed. @@ -47,7 +47,7 @@ Canonical Structure dec_agreeR : cmraT := (* Some properties of this CMRA *) Global Instance dec_agree_persistent (x : dec_agreeR) : Persistent x. -Proof. done. Qed. +Proof. by constructor. Qed. Lemma dec_agree_ne a b : a ≠b → DecAgree a ⋅ DecAgree b = DecAgreeBot. Proof. intros. by rewrite /= decide_False. Qed. diff --git a/algebra/dra.v b/algebra/dra.v index 6d2e9c893d5213475856f921e0a61b39b42259d2..e4e46c1eb91ebc494acd342ca42b8170b4415c70 100644 --- a/algebra/dra.v +++ b/algebra/dra.v @@ -142,8 +142,8 @@ Hint Immediate dra_disjoint_move_l dra_disjoint_move_r. Lemma validity_valid_car_valid z : ✓ z → ✓ validity_car z. Proof. apply validity_prf. Qed. Hint Resolve validity_valid_car_valid. -Program Instance validity_core : Core (validity A) := λ x, - Validity (core (validity_car x)) (✓ x) _. +Program Instance validity_pcore : PCore (validity A) := λ x, + Some (Validity (core (validity_car x)) (✓ x) _). Solve Obligations with naive_solver eauto using dra_core_valid. Program Instance validity_op : Op (validity A) := λ x y, Validity (validity_car x ⋅ validity_car y) @@ -152,7 +152,7 @@ Solve Obligations with naive_solver eauto using dra_op_valid. Definition validity_ra_mixin : RAMixin (validity A). Proof. - split. + apply ra_total_mixin; first eauto. - intros ??? [? Heq]; split; simpl; [|by intros (?&?&?); rewrite Heq]. split; intros (?&?&?); split_and!; first [rewrite ?Heq; tauto|rewrite -?Heq; tauto|tauto]. @@ -176,6 +176,9 @@ Qed. Canonical Structure validityR : cmraT := discreteR (validity A) validity_ra_mixin. +Global Instance validity_cmra_total : CMRATotal validityR. +Proof. rewrite /CMRATotal; eauto. Qed. + Lemma validity_update x y : (∀ c, ✓ x → ✓ c → validity_car x ⊥ c → ✓ y ∧ validity_car y ⊥ c) → x ~~> y. Proof. diff --git a/algebra/excl.v b/algebra/excl.v index 994f9ab9f45cdd7564e8b4041271fd9baed6b1b4..5e83c0e59a44fa3aa049249d3be553ea23cd5699 100644 --- a/algebra/excl.v +++ b/algebra/excl.v @@ -5,11 +5,13 @@ Local Arguments valid _ _ !_ /. Inductive excl (A : Type) := | Excl : A → excl A - | ExclUnit : excl A | ExclBot : excl A. Arguments Excl {_} _. -Arguments ExclUnit {_}. Arguments ExclBot {_}. + +Notation Excl' x := (Some (Excl x)). +Notation ExclBot' := (Some ExclBot). + Instance maybe_Excl {A} : Maybe (@Excl A) := λ x, match x with Excl a => Some a | _ => None end. @@ -21,12 +23,10 @@ Implicit Types x y : excl A. (* Cofe *) Inductive excl_equiv : Equiv (excl A) := | Excl_equiv a b : a ≡ b → Excl a ≡ Excl b - | ExclUnit_equiv : ExclUnit ≡ ExclUnit | ExclBot_equiv : ExclBot ≡ ExclBot. Existing Instance excl_equiv. Inductive excl_dist : Dist (excl A) := | Excl_dist a b n : a ≡{n}≡ b → Excl a ≡{n}≡ Excl b - | ExclUnit_dist n : ExclUnit ≡{n}≡ ExclUnit | ExclBot_dist n : ExclBot ≡{n}≡ ExclBot. Existing Instance excl_dist. @@ -67,43 +67,31 @@ Proof. by destruct 2; f_equal; apply leibniz_equiv. Qed. Global Instance Excl_timeless a : Timeless a → Timeless (Excl a). Proof. by inversion_clear 2; constructor; apply (timeless _). Qed. -Global Instance ExclUnit_timeless : Timeless (@ExclUnit A). -Proof. by inversion_clear 1; constructor. Qed. Global Instance ExclBot_timeless : Timeless (@ExclBot A). Proof. by inversion_clear 1; constructor. Qed. (* CMRA *) Instance excl_valid : Valid (excl A) := λ x, - match x with Excl _ | ExclUnit => True | ExclBot => False end. + match x with Excl _ => True | ExclBot => False end. Instance excl_validN : ValidN (excl A) := λ n x, - match x with Excl _ | ExclUnit => True | ExclBot => False end. -Instance excl_core : Core (excl A) := λ _, ExclUnit. -Instance excl_op : Op (excl A) := λ x y, - match x, y with - | Excl a, ExclUnit | ExclUnit, Excl a => Excl a - | ExclUnit, ExclUnit => ExclUnit - | _, _=> ExclBot - end. + match x with Excl _ => True | ExclBot => False end. +Instance excl_pcore : PCore (excl A) := λ _, None. +Instance excl_op : Op (excl A) := λ x y, ExclBot. Lemma excl_cmra_mixin : CMRAMixin (excl A). Proof. - split. + split; try discriminate. - by intros n []; destruct 1; constructor. - - constructor. - by destruct 1; intros ?. - intros x; split. done. by move=> /(_ 0). - - intros n [?| |]; simpl; auto with lia. - - by intros [?| |] [?| |] [?| |]; constructor. - - by intros [?| |] [?| |]; constructor. - - by intros [?| |]; constructor. - - constructor. - - by intros [?| |] [?| |]; exists ExclUnit. - - by intros n [?| |] [?| |]. + - intros n [?|]; simpl; auto with lia. + - by intros [?|] [?|] [?|]; constructor. + - by intros [?|] [?|]; constructor. + - by intros n [?|] [?|]. - intros n x y1 y2 ? Hx. by exists match y1, y2 with | Excl a1, Excl a2 => (Excl a1, Excl a2) | ExclBot, _ => (ExclBot, y2) | _, ExclBot => (y1, ExclBot) - | ExclUnit, _ => (ExclUnit, x) | _, ExclUnit => (x, ExclUnit) end; destruct y1, y2; inversion_clear Hx; repeat constructor. Qed. Canonical Structure exclR := @@ -112,57 +100,49 @@ Canonical Structure exclR := Global Instance excl_cmra_discrete : Discrete A → CMRADiscrete exclR. Proof. split. apply _. by intros []. Qed. -Instance excl_empty : Empty (excl A) := ExclUnit. -Lemma excl_ucmra_mixin : UCMRAMixin (excl A). -Proof. split. done. by intros []. apply _. Qed. -Canonical Structure exclUR := - UCMRAT (excl A) excl_cofe_mixin excl_cmra_mixin excl_ucmra_mixin. - -Lemma excl_validN_inv_l n x a : ✓{n} (Excl a ⋅ x) → x = ∅. -Proof. by destruct x. Qed. -Lemma excl_validN_inv_r n x a : ✓{n} (x ⋅ Excl a) → x = ∅. -Proof. by destruct x. Qed. -Lemma Excl_includedN n a x : ✓{n} x → Excl a ≼{n} x ↔ x ≡{n}≡ Excl a. -Proof. - intros Hvalid; split; [|by intros ->]. - intros [z ?]; cofe_subst. by rewrite (excl_validN_inv_l n z a). -Qed. - (** Internalized properties *) Lemma excl_equivI {M} (x y : excl A) : (x ≡ y) ⊣⊢ (match x, y with | Excl a, Excl b => a ≡ b - | ExclUnit, ExclUnit | ExclBot, ExclBot => True + | ExclBot, ExclBot => True | _, _ => False end : uPred M). Proof. uPred.unseal. do 2 split. by destruct 1. by destruct x, y; try constructor. Qed. Lemma excl_validI {M} (x : excl A) : - (✓ x) ⊣⊢ (if x is ExclBot then False else True : uPred M). + ✓ x ⊣⊢ (if x is ExclBot then False else True : uPred M). Proof. uPred.unseal. by destruct x. Qed. (** ** Local updates *) Global Instance excl_local_update y : LocalUpdate (λ x, if x is Excl _ then ✓ y else False) (λ _, y). -Proof. split. apply _. by destruct y; intros n [a| |] [b'| |]. Qed. +Proof. split. apply _. by destruct y; intros n [a|] [b'|]. Qed. (** Updates *) Lemma excl_update a y : ✓ y → Excl a ~~> y. -Proof. destruct y; by intros ?? [?| |]. Qed. +Proof. destruct y=> ? n [z|]; eauto. Qed. Lemma excl_updateP (P : excl A → Prop) a y : ✓ y → P y → Excl a ~~>: P. -Proof. intros ?? n z ?; exists y. by destruct y, z as [?| |]. Qed. +Proof. destruct y=> ?? n [z|]; eauto. Qed. + +(** Option excl *) +Lemma excl_validN_inv_l n mx a : ✓{n} (Excl' a ⋅ mx) → mx = None. +Proof. by destruct mx. Qed. +Lemma excl_validN_inv_r n mx a : ✓{n} (mx ⋅ Excl' a) → mx = None. +Proof. by destruct mx. Qed. +Lemma Excl_includedN n a mx : ✓{n} mx → Excl' a ≼{n} mx ↔ mx ≡{n}≡ Excl' a. +Proof. + intros Hvalid; split; [|by intros ->]. + intros [z ?]; cofe_subst. by rewrite (excl_validN_inv_l n z a). +Qed. End excl. Arguments exclC : clear implicits. Arguments exclR : clear implicits. -Arguments exclUR : clear implicits. (* Functor *) Definition excl_map {A B} (f : A → B) (x : excl A) : excl B := - match x with - | Excl a => Excl (f a) | ExclUnit => ExclUnit | ExclBot => ExclBot - end. + match x with Excl a => Excl (f a) | ExclBot => ExclBot end. Lemma excl_map_id {A} (x : excl A) : excl_map id x = x. Proof. by destruct x. Qed. Lemma excl_map_compose {A B C} (f : A → B) (g : B → C) (x : excl A) : @@ -171,14 +151,14 @@ Proof. by destruct x. Qed. Lemma excl_map_ext {A B : cofeT} (f g : A → B) x : (∀ x, f x ≡ g x) → excl_map f x ≡ excl_map g x. Proof. by destruct x; constructor. Qed. -Instance excl_map_cmra_ne {A B : cofeT} n : +Instance excl_map_ne {A B : cofeT} n : Proper ((dist n ==> dist n) ==> dist n ==> dist n) (@excl_map A B). Proof. by intros f f' Hf; destruct 1; constructor; apply Hf. Qed. Instance excl_map_cmra_monotone {A B : cofeT} (f : A → B) : (∀ n, Proper (dist n ==> dist n) f) → CMRAMonotone (excl_map f). Proof. split; try apply _. - - by intros n [a| |]. + - by intros n [a|]. - intros x y [z Hy]; exists (excl_map f z); apply equiv_dist=> n. move: Hy=> /equiv_dist /(_ n) ->; by destruct x, z. Qed. @@ -187,9 +167,9 @@ Definition exclC_map {A B} (f : A -n> B) : exclC A -n> exclC B := Instance exclC_map_ne A B n : Proper (dist n ==> dist n) (@exclC_map A B). Proof. by intros f f' Hf []; constructor; apply Hf. Qed. -Program Definition exclURF (F : cFunctor) : urFunctor := {| - urFunctor_car A B := (exclUR (cFunctor_car F A B) : ucmraT); - urFunctor_map A1 A2 B1 B2 fg := exclC_map (cFunctor_map F fg) +Program Definition exclRF (F : cFunctor) : rFunctor := {| + rFunctor_car A B := (exclR (cFunctor_car F A B)); + rFunctor_map A1 A2 B1 B2 fg := exclC_map (cFunctor_map F fg) |}. Next Obligation. intros F A1 A2 B1 B2 n x1 x2 ??. by apply exclC_map_ne, cFunctor_ne. @@ -203,8 +183,8 @@ Next Obligation. apply excl_map_ext=>y; apply cFunctor_compose. Qed. -Instance exclURF_contractive F : - cFunctorContractive F → urFunctorContractive (exclURF F). +Instance exclRF_contractive F : + cFunctorContractive F → rFunctorContractive (exclRF F). Proof. intros A1 A2 B1 B2 n x1 x2 ??. by apply exclC_map_ne, cFunctor_contractive. Qed. diff --git a/algebra/frac.v b/algebra/frac.v index e4f7897d268a17804ad717698fbf942a2d1a7a6b..6581ce2534a0d5926a2290f0089c4f73d6b00860 100644 --- a/algebra/frac.v +++ b/algebra/frac.v @@ -1,15 +1,15 @@ From Coq.QArith Require Import Qcanon. From iris.algebra Require Export cmra. From iris.algebra Require Import upred. +Local Arguments op _ _ !_ !_ /. Local Arguments validN _ _ _ !_ /. Local Arguments valid _ _ !_ /. -Inductive frac {A : Type} := - | Frac : Qp → A → frac - | FracUnit : frac. -Arguments frac _ : clear implicits. -Instance maybe_Frac {A} : Maybe2 (@Frac A) := λ x, - match x with Frac q a => Some (q,a) | _ => None end. +Inductive frac A := Frac { frac_perm : Qp ; frac_car : A }. +Add Printing Constructor frac. +Arguments Frac {_} _ _. +Arguments frac_perm {_} _. +Arguments frac_car {_} _. Instance: Params (@Frac) 2. Section cofe. @@ -18,37 +18,37 @@ Implicit Types a b : A. Implicit Types x y : frac A. (* Cofe *) -Inductive frac_equiv : Equiv (frac A) := - | Frac_equiv q1 q2 a b : q1 = q2 → a ≡ b → Frac q1 a ≡ Frac q2 b - | FracUnit_equiv : FracUnit ≡ FracUnit. -Existing Instance frac_equiv. -Inductive frac_dist : Dist (frac A) := - | Frac_dist q1 q2 a b n : q1 = q2 → a ≡{n}≡ b → Frac q1 a ≡{n}≡ Frac q2 b - | FracUnit_dist n : FracUnit ≡{n}≡ FracUnit. -Existing Instance frac_dist. +Instance frac_equiv : Equiv (frac A) := λ x y, + frac_perm x = frac_perm y ∧ frac_car x ≡ frac_car y. +Instance frac_dist : Dist (frac A) := λ n x y, + frac_perm x = frac_perm y ∧ frac_car x ≡{n}≡ frac_car y. Global Instance Frac_ne q n : Proper (dist n ==> dist n) (@Frac A q). Proof. by constructor. Qed. Global Instance Frac_proper q : Proper ((≡) ==> (≡)) (@Frac A q). Proof. by constructor. Qed. Global Instance Frac_inj : Inj2 (=) (≡) (≡) (@Frac A). -Proof. by inversion_clear 1. Qed. +Proof. by destruct 1. Qed. Global Instance Frac_dist_inj n : Inj2 (=) (dist n) (dist n) (@Frac A). -Proof. by inversion_clear 1. Qed. - -Program Definition frac_chain (c : chain (frac A)) (q : Qp) (a : A) - (H : maybe2 Frac (c 0) = Some (q,a)) : chain A := - {| chain_car n := match c n return _ with Frac _ b => b | _ => a end |}. +Proof. by destruct 1. Qed. + +Global Instance frac_perm_ne n : Proper (dist n ==> (=)) (@frac_perm A). +Proof. by destruct 1. Qed. +Global Instance frac_car_ne n : Proper (dist n ==> dist n) (@frac_car A). +Proof. by destruct 1. Qed. +Global Instance frac_perm_proper : Proper ((≡) ==> (=)) (@frac_perm A). +Proof. by destruct 1. Qed. +Global Instance frac_car_proper : Proper ((≡) ==> (≡)) (@frac_car A). +Proof. by destruct 1. Qed. + +Program Definition frac_chain (c : chain (frac A)) : chain A := + {| chain_car n := match c n return _ with Frac _ b => b end |}. Next Obligation. - intros c q a ? n i ?; simpl. - destruct (c 0) eqn:?; simplify_eq/=. + intros c n i ?; simpl. destruct (c 0) eqn:?; simplify_eq/=. by feed inversion (chain_cauchy c n i). Qed. Instance frac_compl : Compl (frac A) := λ c, - match Some_dec (maybe2 Frac (c 0)) with - | inleft (exist (q,a) H) => Frac q (compl (frac_chain c q a H)) - | inright _ => c 0 - end. + Frac (frac_perm (c 0)) (compl (frac_chain c)). Definition frac_cofe_mixin : CofeMixin (frac A). Proof. split. @@ -57,40 +57,29 @@ Proof. + intros Hxy; feed inversion (Hxy 0); subst; constructor; try done. apply equiv_dist=> n; by feed inversion (Hxy n). - intros n; split. - + by intros [q a|]; constructor. + + by intros [q a]; constructor. + by destruct 1; constructor. + destruct 1; inversion_clear 1; constructor; etrans; eauto. - by inversion_clear 1; constructor; done || apply dist_S. - - intros n c; unfold compl, frac_compl. - destruct (Some_dec (maybe2 Frac (c 0))) as [[[q a] Hx]|]. - { assert (c 0 = Frac q a) by (by destruct (c 0); simplify_eq/=). - assert (∃ b, c n = Frac q b) as [y Hy]. - { feed inversion (chain_cauchy c 0 n); - eauto with lia congruence f_equal. } - rewrite Hy; constructor; auto. - by rewrite (conv_compl n (frac_chain c q a Hx)) /= Hy. } - feed inversion (chain_cauchy c 0 n); first lia; - constructor; destruct (c 0); simplify_eq/=. + - intros n c; constructor; simpl. + + destruct (chain_cauchy c 0 n); auto with lia. + + apply (conv_compl n (frac_chain c)). Qed. Canonical Structure fracC : cofeT := CofeT (frac A) frac_cofe_mixin. Global Instance frac_discrete : Discrete A → Discrete fracC. Proof. by inversion_clear 2; constructor; done || apply (timeless _). Qed. Global Instance frac_leibniz : LeibnizEquiv A → LeibnizEquiv (frac A). -Proof. by destruct 2; f_equal; done || apply leibniz_equiv. Qed. +Proof. intros ? [??] [??] [??]; f_equal; done || by apply leibniz_equiv. Qed. Global Instance Frac_timeless q (a : A) : Timeless a → Timeless (Frac q a). Proof. by inversion_clear 2; constructor; done || apply (timeless _). Qed. -Global Instance FracUnit_timeless : Timeless (@FracUnit A). -Proof. by inversion_clear 1; constructor. Qed. End cofe. Arguments fracC : clear implicits. (* Functor on COFEs *) Definition frac_map {A B} (f : A → B) (x : frac A) : frac B := - match x with - | Frac q a => Frac q (f a) | FracUnit => FracUnit - end. + match x with Frac q a => Frac q (f a) end. Instance: Params (@frac_map) 2. Lemma frac_map_id {A} (x : frac A) : frac_map id x = x. @@ -100,10 +89,10 @@ Lemma frac_map_compose {A B C} (f : A → B) (g : B → C) (x : frac A) : Proof. by destruct x. Qed. Lemma frac_map_ext {A B : cofeT} (f g : A → B) x : (∀ x, f x ≡ g x) → frac_map f x ≡ frac_map g x. -Proof. by destruct x; constructor. Qed. +Proof. destruct x; constructor; simpl; auto. Qed. Instance frac_map_cmra_ne {A B : cofeT} n : Proper ((dist n ==> dist n) ==> dist n ==> dist n) (@frac_map A B). -Proof. intros f f' Hf; destruct 1; constructor; by try apply Hf. Qed. +Proof. intros f f' Hf [??] [??] [??]; constructor; by try apply Hf. Qed. Definition fracC_map {A B} (f : A -n> B) : fracC A -n> fracC B := CofeMor (frac_map f). Instance fracC_map_ne A B n : Proper (dist n ==> dist n) (@fracC_map A B). @@ -114,131 +103,103 @@ Context {A : cmraT}. Implicit Types a b : A. Implicit Types x y : frac A. -(* CMRA *) Instance frac_valid : Valid (frac A) := λ x, - match x with Frac q a => (q ≤ 1)%Qc ∧ ✓ a | FracUnit => True end. + (frac_perm x ≤ 1)%Qc ∧ ✓ frac_car x. +Global Arguments frac_valid !_/. Instance frac_validN : ValidN (frac A) := λ n x, - match x with Frac q a => (q ≤ 1)%Qc ∧ ✓{n} a | FracUnit => True end. -Instance frac_core : Core (frac A) := λ _, FracUnit. + (frac_perm x ≤ 1)%Qc ∧ ✓{n} frac_car x. +Global Arguments frac_validN _ !_/. +Instance frac_pcore : PCore (frac A) := λ _, None. Instance frac_op : Op (frac A) := λ x y, - match x, y with - | Frac q1 a, Frac q2 b => Frac (q1 + q2) (a ⋅ b) - | Frac q a, FracUnit | FracUnit, Frac q a => Frac q a - | FracUnit, FracUnit => FracUnit - end. + Frac (frac_perm x + frac_perm y) (frac_car x ⋅ frac_car y). +Global Arguments frac_op !_ !_ /. Lemma Frac_op q1 q2 a b : Frac q1 a ⋅ Frac q2 b = Frac (q1 + q2) (a ⋅ b). Proof. done. Qed. Definition frac_cmra_mixin : CMRAMixin (frac A). Proof. - split. - - intros n []; destruct 1; constructor; by cofe_subst. - - constructor. - - do 2 destruct 1; split; by cofe_subst. - - intros [q a|]; rewrite /= ?cmra_valid_validN; naive_solver eauto using O. - - intros n [q a|]; destruct 1; split; auto using cmra_validN_S. - - intros [q1 a1|] [q2 a2|] [q3 a3|]; constructor; by rewrite ?assoc. - - intros [q1 a1|] [q2 a2|]; constructor; by rewrite 1?comm ?[(q1+_)%Qp]comm. - - intros []; by constructor. - - done. - - by exists FracUnit. - - intros n [q1 a1|] [q2 a2|]; destruct 1; split; eauto using cmra_validN_op_l. + split; try discriminate. + - intros n [??] [??] [??] [??]; constructor; by cofe_subst. + - intros ? [??] [??] [??] [??]; split; by cofe_subst. + - intros [??]; rewrite /= ?cmra_valid_validN; naive_solver eauto using O. + - intros n [q a]; destruct 1; split; auto using cmra_validN_S. + - intros [q1 a1] [q2 a2] [q3 a3]; constructor; by rewrite /= ?assoc. + - intros [q1 a1] [q2 a2]; constructor; by rewrite /= 1?comm ?[(q1+_)%Qp]comm. + - intros n [q1 a1] [q2 a2]; destruct 1; split; eauto using cmra_validN_op_l. trans (q1 + q2)%Qp; simpl; last done. rewrite -{1}(Qcplus_0_r q1) -Qcplus_le_mono_l; auto using Qclt_le_weak. - - intros n [q a|] y1 y2 Hx Hx'; last first. - { by exists (FracUnit, FracUnit); destruct y1, y2; inversion_clear Hx'. } - destruct Hx, y1 as [q1 b1|], y2 as [q2 b2|]. - + apply (inj2 Frac) in Hx'; destruct Hx' as [-> ?]. - destruct (cmra_extend n a b1 b2) as ([z1 z2]&?&?&?); auto. - exists (Frac q1 z1,Frac q2 z2); by repeat constructor. - + exists (Frac q a, FracUnit); inversion_clear Hx'; by repeat constructor. - + exists (FracUnit, Frac q a); inversion_clear Hx'; by repeat constructor. - + exfalso; inversion_clear Hx'. + - intros n [q a] y1 y2 Hx Hx'. + destruct Hx, y1 as [q1 b1], y2 as [q2 b2]. + apply (inj2 Frac) in Hx'; destruct Hx' as [-> ?]. + destruct (cmra_extend n a b1 b2) as ([z1 z2]&?&?&?); auto. + exists (Frac q1 z1,Frac q2 z2); by repeat constructor. Qed. -Canonical Structure fracR := - CMRAT (frac A) frac_cofe_mixin frac_cmra_mixin. +Canonical Structure fracR := CMRAT (frac A) frac_cofe_mixin frac_cmra_mixin. Global Instance frac_cmra_discrete : CMRADiscrete A → CMRADiscrete fracR. Proof. split; first apply _. - intros [q a|]; destruct 1; split; auto using cmra_discrete_valid. + intros [q a]; destruct 1; split; auto using cmra_discrete_valid. Qed. -Instance frac_empty : Empty (frac A) := FracUnit. -Definition frac_ucmra_mixin : UCMRAMixin (frac A). -Proof. split. done. by intros []. apply _. Qed. -Canonical Structure fracUR := - UCMRAT (frac A) frac_cofe_mixin frac_cmra_mixin frac_ucmra_mixin. - -Lemma frac_validN_inv_l n y a : ✓{n} (Frac 1 a ⋅ y) → y = ∅. +Lemma frac_validN_inv_l n x y : ✓{n} (x ⋅ y) → frac_perm x ≠1%Qp. Proof. - destruct y as [q b|]; [|done]=> -[Hq ?]; destruct (Qcle_not_lt _ _ Hq). - by rewrite -{1}(Qcplus_0_r 1) -Qcplus_lt_mono_l. + intros [Hq _] Hx; simpl in *; destruct (Qcle_not_lt _ _ Hq). + by rewrite Hx -{1}(Qcplus_0_r 1) -Qcplus_lt_mono_l. Qed. -Lemma frac_valid_inv_l y a : ✓ (Frac 1 a ⋅ y) → y = ∅. -Proof. intros. by apply frac_validN_inv_l with 0 a, cmra_valid_validN. Qed. +Lemma frac_valid_inv_l x y : ✓ (x ⋅ y) → frac_perm x ≠1%Qp. +Proof. intros. by apply frac_validN_inv_l with 0 y, cmra_valid_validN. Qed. (** Internalized properties *) Lemma frac_equivI {M} (x y : frac A) : - (x ≡ y) ⊣⊢ (match x, y with - | Frac q1 a, Frac q2 b => q1 = q2 ∧ a ≡ b - | FracUnit, FracUnit => True - | _, _ => False - end : uPred M). -Proof. - uPred.unseal; do 2 split; first by destruct 1. - by destruct x, y; destruct 1; try constructor. -Qed. + (x ≡ y) ⊣⊢ (frac_perm x = frac_perm y ∧ frac_car x ≡ frac_car y : uPred M). +Proof. by uPred.unseal. Qed. Lemma frac_validI {M} (x : frac A) : - (✓ x) ⊣⊢ (if x is Frac q a then ■(q ≤ 1)%Qc ∧ ✓ a else True : uPred M). -Proof. uPred.unseal. by destruct x. Qed. + ✓ x ⊣⊢ (■(frac_perm x ≤ 1)%Qc ∧ ✓ frac_car x : uPred M). +Proof. by uPred.unseal. Qed. (** ** Local updates *) Global Instance frac_local_update_full p a : - LocalUpdate (λ x, if x is Frac q _ then q = 1%Qp else False) (λ _, Frac p a). -Proof. - split; first by intros ???. - by intros n [q b|] y; [|done]=> -> /frac_validN_inv_l ->. -Qed. + LocalUpdate (λ x, frac_perm x = 1%Qp) (λ _, Frac p a). +Proof. split; first by intros ???. by intros n x y ? ?%frac_validN_inv_l. Qed. Global Instance frac_local_update `{!LocalUpdate Lv L} : - LocalUpdate (λ x, if x is Frac _ a then Lv a else False) (frac_map L). + LocalUpdate (λ x, Lv (frac_car x)) (frac_map L). Proof. - split; first apply _. intros n [p a|] [q b|]; simpl; try done. + split; first apply _. intros n [p a] [q b]; simpl. intros ? [??]; constructor; [done|by apply (local_updateN L)]. Qed. (** Updates *) Lemma frac_update_full (a1 a2 : A) : ✓ a2 → Frac 1 a1 ~~> Frac 1 a2. Proof. - move=> ? n y /frac_validN_inv_l ->. split. done. by apply cmra_valid_validN. + move=> ? n [y|]; last (intros; by apply cmra_valid_validN). + by intros ?%frac_validN_inv_l. Qed. Lemma frac_update (a1 a2 : A) p : a1 ~~> a2 → Frac p a1 ~~> Frac p a2. Proof. - intros Ha n [q b|] [??]; split; auto. - apply cmra_validN_op_l with (core a1), Ha. by rewrite cmra_core_r. + intros Ha n mz [??]; split; first by destruct mz. + pose proof (Ha n (frac_car <$> mz)); destruct mz; naive_solver. Qed. End cmra. Arguments fracR : clear implicits. -Arguments fracUR : clear implicits. (* Functor *) Instance frac_map_cmra_monotone {A B : cmraT} (f : A → B) : CMRAMonotone f → CMRAMonotone (frac_map f). Proof. split; try apply _. - - intros n [p a|]; destruct 1; split; auto using validN_preserving. - - intros [q1 a1|] [q2 a2|] [[q3 a3|] Hx]; - inversion Hx; setoid_subst; try apply: ucmra_unit_least; auto. + - intros n [p a]; destruct 1; split; simpl in *; auto using validN_preserving. + - intros [q1 a1] [q2 a2] [[q3 a3] [??]]; setoid_subst. destruct (included_preserving f a1 (a1 ⋅ a3)) as [b ?]. { by apply cmra_included_l. } by exists (Frac q3 b); constructor. Qed. -Program Definition fracURF (F : rFunctor) : urFunctor := {| - urFunctor_car A B := fracUR (rFunctor_car F A B); - urFunctor_map A1 A2 B1 B2 fg := fracC_map (rFunctor_map F fg) +Program Definition fracRF (F : rFunctor) : rFunctor := {| + rFunctor_car A B := fracR (rFunctor_car F A B); + rFunctor_map A1 A2 B1 B2 fg := fracC_map (rFunctor_map F fg) |}. Next Obligation. by intros F A1 A2 B1 B2 n f g Hfg; apply fracC_map_ne, rFunctor_ne. @@ -252,8 +213,8 @@ Next Obligation. apply frac_map_ext=>y; apply rFunctor_compose. Qed. -Instance fracURF_contractive F : - rFunctorContractive F → urFunctorContractive (fracURF F). +Instance fracRF_contractive F : + rFunctorContractive F → rFunctorContractive (fracRF F). Proof. by intros ? A1 A2 B1 B2 n f g Hfg; apply fracC_map_ne, rFunctor_contractive. Qed. diff --git a/algebra/gmap.v b/algebra/gmap.v index f209cf09c39d3435dc9867ca54d12842c533b38e..accb4f183b04d48e4a955a7f81279b348ace4ada 100644 --- a/algebra/gmap.v +++ b/algebra/gmap.v @@ -93,14 +93,14 @@ Context `{Countable K} {A : cmraT}. Implicit Types m : gmap K A. Instance gmap_op : Op (gmap K A) := merge op. -Instance gmap_core : Core (gmap K A) := fmap core. +Instance gmap_pcore : PCore (gmap K A) := λ m, Some (omap pcore m). Instance gmap_valid : Valid (gmap K A) := λ m, ∀ i, ✓ (m !! i). Instance gmap_validN : ValidN (gmap K A) := λ n m, ∀ i, ✓{n} (m !! i). Lemma lookup_op m1 m2 i : (m1 ⋅ m2) !! i = m1 !! i ⋅ m2 !! i. Proof. by apply lookup_merge. Qed. Lemma lookup_core m i : core m !! i = core (m !! i). -Proof. by apply lookup_fmap. Qed. +Proof. by apply lookup_omap. Qed. Lemma lookup_included (m1 m2 : gmap K A) : m1 ≼ m2 ↔ ∀ i, m1 !! i ≼ m2 !! i. Proof. @@ -120,20 +120,21 @@ Qed. Lemma gmap_cmra_mixin : CMRAMixin (gmap K A). Proof. - split. - - by intros n m1 m2 m3 Hm i; rewrite !lookup_op (Hm i). - - by intros n m1 m2 Hm i; rewrite !lookup_core (Hm i). - - by intros n m1 m2 Hm ? i; rewrite -(Hm i). + apply cmra_total_mixin. + - eauto. + - intros n m1 m2 m3 Hm i; by rewrite !lookup_op (Hm i). + - intros n m1 m2 Hm i; by rewrite !lookup_core (Hm i). + - intros n m1 m2 Hm ? i; by rewrite -(Hm i). - intros m; split. + by intros ? n i; apply cmra_valid_validN. + intros Hm i; apply cmra_valid_validN=> n; apply Hm. - intros n m Hm i; apply cmra_validN_S, Hm. - by intros m1 m2 m3 i; rewrite !lookup_op assoc. - by intros m1 m2 i; rewrite !lookup_op comm. - - by intros m i; rewrite lookup_op !lookup_core cmra_core_l. - - by intros m i; rewrite !lookup_core cmra_core_idemp. - - intros x y; rewrite !lookup_included; intros Hm i. - by rewrite !lookup_core; apply cmra_core_preserving. + - intros m i. by rewrite lookup_op lookup_core cmra_core_l. + - intros m i. by rewrite !lookup_core cmra_core_idemp. + - intros m1 m2; rewrite !lookup_included=> Hm i. + rewrite !lookup_core. by apply cmra_core_preserving. - intros n m1 m2 Hm i; apply cmra_validN_op_l with (m2 !! i). by rewrite -lookup_op. - intros n m m1 m2 Hm Hm12. @@ -164,6 +165,7 @@ Proof. - by intros i; rewrite lookup_empty. - by intros m i; rewrite /= lookup_op lookup_empty (left_id_L None _). - apply gmap_empty_timeless. + - constructor=> i. by rewrite lookup_omap lookup_empty. Qed. Canonical Structure gmapUR := UCMRAT (gmap K A) gmap_cofe_mixin gmap_cmra_mixin gmap_ucmra_mixin. @@ -201,42 +203,51 @@ Lemma singleton_valid i x : ✓ ({[ i := x ]} : gmap K A) ↔ ✓ x. Proof. rewrite !cmra_valid_validN. by setoid_rewrite singleton_validN. Qed. Lemma insert_singleton_opN n m i x : - m !! i = None ∨ m !! i ≡{n}≡ Some (core x) → <[i:=x]> m ≡{n}≡ {[ i := x ]} ⋅ m. + m !! i = None → <[i:=x]> m ≡{n}≡ {[ i := x ]} ⋅ m. Proof. - intros Hi j; destruct (decide (i = j)) as [->|]; - [|by rewrite lookup_op lookup_insert_ne // lookup_singleton_ne // left_id]. - rewrite lookup_op lookup_insert lookup_singleton. - by destruct Hi as [->| ->]; constructor; rewrite ?cmra_core_r. + intros Hi j; destruct (decide (i = j)) as [->|]. + - by rewrite lookup_op lookup_insert lookup_singleton Hi right_id. + - by rewrite lookup_op lookup_insert_ne // lookup_singleton_ne // left_id. Qed. -Lemma insert_singleton_op m i x : - m !! i = None ∨ m !! i ≡ Some (core x) → <[i:=x]> m ≡ {[ i := x ]} ⋅ m. +Lemma insert_singleton_op m i x : m !! i = None → <[i:=x]> m ≡ {[ i := x ]} ⋅ m. Proof. rewrite !equiv_dist; naive_solver eauto using insert_singleton_opN. Qed. -Lemma core_singleton (i : K) (x : A) : - core ({[ i := x ]} : gmap K A) = {[ i := core x ]}. -Proof. apply map_fmap_singleton. Qed. +Lemma core_singleton (i : K) (x : A) cx : + pcore x = Some cx → core ({[ i := x ]} : gmap K A) = {[ i := cx ]}. +Proof. apply omap_singleton. Qed. +Lemma core_singleton' (i : K) (x : A) cx : + pcore x ≡ Some cx → core ({[ i := x ]} : gmap K A) ≡ {[ i := cx ]}. +Proof. + intros (cx'&?&->)%equiv_Some_inv_r'. by rewrite (core_singleton _ _ cx'). +Qed. Lemma op_singleton (i : K) (x y : A) : {[ i := x ]} ⋅ {[ i := y ]} = ({[ i := x ⋅ y ]} : gmap K A). Proof. by apply (merge_singleton _ _ _ x y). Qed. Global Instance gmap_persistent m : (∀ x : A, Persistent x) → Persistent m. -Proof. intros ? i. by rewrite lookup_core persistent. Qed. +Proof. + intros; apply persistent_total=> i. + rewrite lookup_core. apply (persistent_core _). +Qed. Global Instance gmap_singleton_persistent i (x : A) : Persistent x → Persistent {[ i := x ]}. -Proof. intros. by rewrite /Persistent core_singleton persistent. Qed. +Proof. intros. by apply persistent_total, core_singleton'. Qed. Lemma singleton_includedN n m i x : - {[ i := x ]} ≼{n} m ↔ ∃ y, m !! i ≡{n}≡ Some y ∧ x ≼{n} y. + {[ i := x ]} ≼{n} m ↔ ∃ y, m !! i ≡{n}≡ Some y ∧ (x ≼{n} y ∨ x ≡{n}≡ y). Proof. split. - move=> [m' /(_ i)]; rewrite lookup_op lookup_singleton. case (m' !! i)=> [y|]=> Hm. + exists (x ⋅ y); eauto using cmra_includedN_l. - + by exists x. - - intros (y&Hi&[z ?]). - exists (<[i:=z]>m)=> j; destruct (decide (i = j)) as [->|]. - + rewrite Hi lookup_op lookup_singleton lookup_insert. by constructor. - + by rewrite lookup_op lookup_singleton_ne // lookup_insert_ne // left_id. + + exists x; eauto. + - intros (y&Hi&[[z ?]| ->]). + + exists (<[i:=z]>m)=> j; destruct (decide (i = j)) as [->|]. + * rewrite Hi lookup_op lookup_singleton lookup_insert. by constructor. + * by rewrite lookup_op lookup_singleton_ne // lookup_insert_ne // left_id. + + exists (delete i m)=> j; destruct (decide (i = j)) as [->|]. + * by rewrite Hi lookup_op lookup_singleton lookup_delete. + * by rewrite lookup_op lookup_singleton_ne // lookup_delete_ne // left_id. Qed. Lemma dom_op m1 m2 : dom (gset K) (m1 ⋅ m2) ≡ dom _ m1 ∪ dom _ m2. Proof. @@ -248,8 +259,8 @@ Qed. Lemma insert_updateP (P : A → Prop) (Q : gmap K A → Prop) m i x : x ~~>: P → (∀ y, P y → Q (<[i:=y]>m)) → <[i:=x]>m ~~>: Q. Proof. - intros Hx%option_updateP' HP n mf Hm. - destruct (Hx n (mf !! i)) as ([y|]&?&?); try done. + intros Hx%option_updateP' HP; apply cmra_total_updateP=> n mf Hm. + destruct (Hx n (Some (mf !! i))) as ([y|]&?&?); try done. { by generalize (Hm i); rewrite lookup_op; simplify_map_eq. } exists (<[i:=y]> m); split; first by auto. intros j; move: (Hm j)=>{Hm}; rewrite !lookup_op=>Hm. @@ -275,14 +286,15 @@ Context `{Fresh K (gset K), !FreshSpec K (gset K)}. Lemma updateP_alloc_strong (Q : gmap K A → Prop) (I : gset K) m x : ✓ x → (∀ i, m !! i = None → i ∉ I → Q (<[i:=x]>m)) → m ~~>: Q. Proof. - intros ? HQ n mf Hm. set (i := fresh (I ∪ dom (gset K) (m ⋅ mf))). + intros ? HQ. apply cmra_total_updateP. + intros n mf Hm. set (i := fresh (I ∪ dom (gset K) (m ⋅ mf))). assert (i ∉ I ∧ i ∉ dom (gset K) m ∧ i ∉ dom (gset K) mf) as [?[??]]. { rewrite -not_elem_of_union -dom_op -not_elem_of_union; apply is_fresh. } exists (<[i:=x]>m); split. { by apply HQ; last done; apply not_elem_of_dom. } - rewrite insert_singleton_opN; last by left; apply not_elem_of_dom. + rewrite insert_singleton_opN; last by apply not_elem_of_dom. rewrite -assoc -insert_singleton_opN; - last by left; apply not_elem_of_dom; rewrite dom_op not_elem_of_union. + last by apply not_elem_of_dom; rewrite dom_op not_elem_of_union. by apply insert_validN; [apply cmra_valid_validN|]. Qed. Lemma updateP_alloc (Q : gmap K A → Prop) m x : @@ -299,15 +311,15 @@ Lemma singleton_updateP_unit (P : A → Prop) (Q : gmap K A → Prop) u i : ✓ u → LeftId (≡) u (⋅) → u ~~>: P → (∀ y, P y → Q {[ i := y ]}) → ∅ ~~>: Q. Proof. - intros ?? Hx HQ n gf Hg. - destruct (Hx n (from_option id u (gf !! i))) as (y&?&Hy). + intros ?? Hx HQ. apply cmra_total_updateP=> n gf Hg. + destruct (Hx n (gf !! i)) as (y&?&Hy). { move:(Hg i). rewrite !left_id. - case _: (gf !! i); simpl; first done. intros; by apply cmra_valid_validN. } + case _: (gf !! i)=>[x|]; rewrite /= ?left_id //. + intros; by apply cmra_valid_validN. } exists {[ i := y ]}; split; first by auto. intros i'; destruct (decide (i' = i)) as [->|]. - rewrite lookup_op lookup_singleton. - move:Hy; case _: (gf !! i); first done. - by rewrite /= (comm _ y) left_id right_id. + move:Hy; case _: (gf !! i)=>[x|]; rewrite /= ?right_id //. - move:(Hg i'). by rewrite !lookup_op lookup_singleton_ne // !left_id. Qed. Lemma singleton_updateP_unit' (P: A → Prop) u i : diff --git a/algebra/iprod.v b/algebra/iprod.v index 111b7d47eb4ec48fe7a34a87595c4e229087e81b..ecb2ac1cae3587fab8ede88576105c9b122b72b6 100644 --- a/algebra/iprod.v +++ b/algebra/iprod.v @@ -85,7 +85,7 @@ Section iprod_cmra. Implicit Types f g : iprod B. Instance iprod_op : Op (iprod B) := λ f g x, f x ⋅ g x. - Instance iprod_core : Core (iprod B) := λ f x, core (f x). + Instance iprod_pcore : PCore (iprod B) := λ f, Some (λ x, core (f x)). Instance iprod_valid : Valid (iprod B) := λ f, ∀ x, ✓ f x. Instance iprod_validN : ValidN (iprod B) := λ n f, ∀ x, ✓{n} f x. @@ -100,7 +100,8 @@ Section iprod_cmra. Lemma iprod_cmra_mixin : CMRAMixin (iprod B). Proof. - split. + apply cmra_total_mixin. + - eauto. - by intros n f1 f2 f3 Hf x; rewrite iprod_lookup_op (Hf x). - by intros n f1 f2 Hf x; rewrite iprod_lookup_core (Hf x). - by intros n f1 f2 Hf ? x; rewrite -(Hf x). @@ -132,6 +133,7 @@ Section iprod_cmra. - intros x; apply ucmra_unit_valid. - by intros f x; rewrite iprod_lookup_op left_id. - intros f Hf x. by apply: timeless. + - constructor=> x. apply persistent_core, _. Qed. Canonical Structure iprodUR := UCMRAT (iprod B) iprod_cofe_mixin iprod_cmra_mixin iprod_ucmra_mixin. @@ -147,7 +149,8 @@ Section iprod_cmra. y1 ~~>: P → (∀ y2, P y2 → Q (iprod_insert x y2 g)) → iprod_insert x y1 g ~~>: Q. Proof. - intros Hy1 HP n gf Hg. destruct (Hy1 n (gf x)) as (y2&?&?). + intros Hy1 HP; apply cmra_total_updateP. + intros n gf Hg. destruct (Hy1 n (Some (gf x))) as (y2&?&?). { move: (Hg x). by rewrite iprod_lookup_op iprod_lookup_insert. } exists (iprod_insert x y2 g); split; [auto|]. intros x'; destruct (decide (x' = x)) as [->|]; @@ -205,12 +208,12 @@ Section iprod_singleton. Proof. move=>x'; destruct (decide (x = x')) as [->|]; by rewrite iprod_lookup_core ?iprod_lookup_singleton - ?iprod_lookup_singleton_ne // (persistent ∅). + ?iprod_lookup_singleton_ne // (persistent_core ∅). Qed. Global Instance iprod_singleton_persistent x (y : B x) : Persistent y → Persistent (iprod_singleton x y). - Proof. intros. rewrite /Persistent iprod_core_singleton. by f_equiv. Qed. + Proof. by rewrite !persistent_total iprod_core_singleton=> ->. Qed. Lemma iprod_op_singleton (x : A) (y1 y2 : B x) : iprod_singleton x y1 ⋅ iprod_singleton x y2 ≡ iprod_singleton x (y1 ⋅ y2). @@ -235,7 +238,8 @@ Section iprod_singleton. Lemma iprod_singleton_updateP_empty x (P : B x → Prop) (Q : iprod B → Prop) : ∅ ~~>: P → (∀ y2, P y2 → Q (iprod_singleton x y2)) → ∅ ~~>: Q. Proof. - intros Hx HQ n gf Hg. destruct (Hx n (gf x)) as (y2&?&?); first apply Hg. + intros Hx HQ; apply cmra_total_updateP. + intros n gf Hg. destruct (Hx n (Some (gf x))) as (y2&?&?); first apply Hg. exists (iprod_singleton x y2); split; [by apply HQ|]. intros x'; destruct (decide (x' = x)) as [->|]. - by rewrite iprod_lookup_op iprod_lookup_singleton. diff --git a/algebra/list.v b/algebra/list.v index eafa5210e18f6fcf989adafd867888464eb421b8..17f9b32ff847c601cde5be2484cf6fa9468e26be 100644 --- a/algebra/list.v +++ b/algebra/list.v @@ -124,7 +124,7 @@ Section cmra. | _, [] => l1 | x :: l1, y :: l2 => x ⋅ y :: l1 ⋅ l2 end. - Instance list_core : Core (list A) := fmap core. + Instance list_pcore : PCore (list A) := λ l, Some (core <$> l). Instance list_valid : Valid (list A) := Forall (λ x, ✓ x). Instance list_validN : ValidN (list A) := λ n, Forall (λ x, ✓{n} x). @@ -147,7 +147,10 @@ Section cmra. by rewrite /= ?left_id_L ?right_id_L. Qed. Lemma list_lookup_core l i : core l !! i = core (l !! i). - Proof. revert i; induction l; intros [|i]; simpl; auto. Qed. + Proof. + rewrite /core /= list_lookup_fmap. + destruct (l !! i); by rewrite /= ?Some_core. + Qed. Lemma list_lookup_included l1 l2 : l1 ≼ l2 ↔ ∀ i, l1 !! i ≼ l2 !! i. Proof. @@ -165,10 +168,11 @@ Section cmra. Definition list_cmra_mixin : CMRAMixin (list A). Proof. - split. + apply cmra_total_mixin. + - eauto. - intros n l l1 l2; rewrite !list_dist_lookup=> Hl i. by rewrite !list_lookup_op Hl. - - apply _. + - intros n l1 l2 Hl; by rewrite /core /= Hl. - intros n l1 l2; rewrite !list_dist_lookup !list_lookup_validN=> Hl ? i. by rewrite -Hl. - intros l. rewrite list_lookup_valid. setoid_rewrite list_lookup_validN. @@ -196,8 +200,7 @@ Section cmra. [inversion_clear Hl; inversion_clear Hl'; auto ..|]; simplify_eq/=. exists (y1' :: l1', y2' :: l2'); repeat constructor; auto. Qed. - Canonical Structure listR := - CMRAT (list A) list_cofe_mixin list_cmra_mixin. + Canonical Structure listR := CMRAT (list A) list_cofe_mixin list_cmra_mixin. Global Instance empty_list : Empty (list A) := []. Definition list_ucmra_mixin : UCMRAMixin (list A). @@ -206,6 +209,7 @@ Section cmra. - constructor. - by intros l. - by inversion_clear 1. + - by constructor. Qed. Canonical Structure listUR := UCMRAT (list A) list_cofe_mixin list_cmra_mixin list_ucmra_mixin. @@ -218,8 +222,8 @@ Section cmra. Global Instance list_persistent l : (∀ x : A, Persistent x) → Persistent l. Proof. - intros ?; apply list_equiv_lookup=> i. - by rewrite list_lookup_core (persistent (l !! i)). + intros ?; constructor; apply list_equiv_lookup=> i. + by rewrite list_lookup_core (persistent_core (l !! i)). Qed. (** Internalized properties *) @@ -294,8 +298,8 @@ Section properties. Lemma list_core_singletonM i (x : A) : core {[ i := x ]} ≡ {[ i := core x ]}. Proof. - rewrite /singletonM /list_singletonM /=. - induction i; constructor; auto using ucmra_core_unit. + rewrite /singletonM /list_singletonM. + by rewrite {1}/core /= fmap_app fmap_replicate (persistent_core ∅). Qed. Lemma list_op_singletonM i (x y : A) : {[ i := x ]} ⋅ {[ i := y ]} ≡ {[ i := x ⋅ y ]}. @@ -305,19 +309,19 @@ Section properties. Qed. Lemma list_alter_singletonM f i x : alter f i {[i := x]} = {[i := f x]}. Proof. - rewrite /singletonM /list_singletonM /=. - induction i; f_equal/=; auto. + rewrite /singletonM /list_singletonM /=. induction i; f_equal/=; auto. Qed. Global Instance list_singleton_persistent i (x : A) : Persistent x → Persistent {[ i := x ]}. - Proof. intros. by rewrite /Persistent list_core_singletonM persistent. Qed. + Proof. by rewrite !persistent_total list_core_singletonM=> ->. Qed. (* Update *) Lemma list_update_updateP (P : A → Prop) (Q : list A → Prop) l1 x l2 : x ~~>: P → (∀ y, P y → Q (l1 ++ y :: l2)) → l1 ++ x :: l2 ~~>: Q. Proof. - intros Hx%option_updateP' HP n mf; rewrite list_lookup_validN=> Hm. - destruct (Hx n (mf !! length l1)) as ([y|]&H1&H2); simpl in *; try done. + intros Hx%option_updateP' HP. + apply cmra_total_updateP=> n mf; rewrite list_lookup_validN=> Hm. + destruct (Hx n (Some (mf !! length l1))) as ([y|]&H1&H2); simpl in *; try done. { move: (Hm (length l1)). by rewrite list_lookup_op list_lookup_middle. } exists (l1 ++ y :: l2); split; auto. apply list_lookup_validN=> i. diff --git a/algebra/one_shot.v b/algebra/one_shot.v index b156f57e6deca9cf2e252fecf858f6d857de2828..5c3f6f6a0c510d7e25261f902a2d71eb9c849bb0 100644 --- a/algebra/one_shot.v +++ b/algebra/one_shot.v @@ -1,17 +1,21 @@ From iris.algebra Require Export cmra. From iris.algebra Require Import upred. +Local Arguments pcore _ _ !_ /. +Local Arguments cmra_pcore _ !_ /. Local Arguments validN _ _ _ !_ /. Local Arguments valid _ _ !_ /. Local Arguments cmra_validN _ _ !_ /. Local Arguments cmra_valid _ !_ /. (* TODO: Really, we should have sums, and then this should be just "excl unit + A". *) -Inductive one_shot {A : Type} := - | OneShotPending : one_shot - | Shot : A → one_shot - | OneShotUnit : one_shot - | OneShotBot : one_shot. -Arguments one_shot _ : clear implicits. +Inductive one_shot (A : Type) := + | OneShotPending : one_shot A + | Shot : A → one_shot A + | OneShotBot : one_shot A. +Arguments OneShotPending {_}. +Arguments Shot {_} _. +Arguments OneShotBot {_}. + Instance maybe_Shot {A} : Maybe (@Shot A) := λ x, match x with Shot a => Some a | _ => None end. Instance: Params (@Shot) 1. @@ -25,13 +29,11 @@ Implicit Types x y : one_shot A. Inductive one_shot_equiv : Equiv (one_shot A) := | OneShotPending_equiv : OneShotPending ≡ OneShotPending | OneShot_equiv a b : a ≡ b → Shot a ≡ Shot b - | OneShotUnit_equiv : OneShotUnit ≡ OneShotUnit | OneShotBot_equiv : OneShotBot ≡ OneShotBot. Existing Instance one_shot_equiv. Inductive one_shot_dist : Dist (one_shot A) := | OneShotPending_dist n : OneShotPending ≡{n}≡ OneShotPending | OneShot_dist n a b : a ≡{n}≡ b → Shot a ≡{n}≡ Shot b - | OneShotUnit_dist n : OneShotUnit ≡{n}≡ OneShotUnit | OneShotBot_dist n : OneShotBot ≡{n}≡ OneShotBot. Existing Instance one_shot_dist. @@ -57,7 +59,7 @@ Proof. + intros Hxy; feed inversion (Hxy 0); subst; constructor; try done. apply equiv_dist=> n; by feed inversion (Hxy n). - intros n; split. - + by intros [|a| |]; constructor. + + by intros [|a|]; constructor. + by destruct 1; constructor. + destruct 1; inversion_clear 1; constructor; etrans; eauto. - by inversion_clear 1; constructor; done || apply dist_S. @@ -73,8 +75,6 @@ Proof. by destruct 2; f_equal; done || apply leibniz_equiv. Qed. Global Instance Shot_timeless (a : A) : Timeless a → Timeless (Shot a). Proof. by inversion_clear 2; constructor; done || apply (timeless _). Qed. -Global Instance OneShotUnit_timeless : Timeless (@OneShotUnit A). -Proof. by inversion_clear 1; constructor. Qed. End cofe. Arguments one_shotC : clear implicits. @@ -84,7 +84,6 @@ Definition one_shot_map {A B} (f : A → B) (x : one_shot A) : one_shot B := match x with | OneShotPending => OneShotPending | Shot a => Shot (f a) - | OneShotUnit => OneShotUnit | OneShotBot => OneShotBot end. Instance: Params (@one_shot_map) 2. @@ -115,106 +114,91 @@ Instance one_shot_valid : Valid (one_shot A) := λ x, match x with | OneShotPending => True | Shot a => ✓ a - | OneShotUnit => True | OneShotBot => False end. Instance one_shot_validN : ValidN (one_shot A) := λ n x, match x with | OneShotPending => True | Shot a => ✓{n} a - | OneShotUnit => True | OneShotBot => False end. -Instance one_shot_core : Core (one_shot A) := λ x, +Instance one_shot_pcore : PCore (one_shot A) := λ x, match x with - | Shot a => Shot (core a) - | OneShotBot => OneShotBot - | _ => OneShotUnit + | OneShotPending => None + | Shot a => Shot <$> pcore a + | OneShotBot => Some OneShotBot end. Instance one_shot_op : Op (one_shot A) := λ x y, match x, y with | Shot a, Shot b => Shot (a ⋅ b) - | Shot a, OneShotUnit | OneShotUnit, Shot a => Shot a - | OneShotUnit, OneShotPending | OneShotPending, OneShotUnit => OneShotPending - | OneShotUnit, OneShotUnit => OneShotUnit | _, _ => OneShotBot end. Lemma Shot_op a b : Shot a ⋅ Shot b = Shot (a ⋅ b). Proof. done. Qed. -Lemma Shot_core a : core (Shot a) = Shot (core a). -Proof. done. Qed. -Lemma Shot_incl a b : Shot a ≼ Shot b ↔ a ≼ b. +Lemma one_shot_included x y : + x ≼ y ↔ y = OneShotBot ∨ ∃ a b, x = Shot a ∧ y = Shot b ∧ a ≼ b. Proof. - split; intros [c H]. - - destruct c; inversion_clear H; first by eexists. - by rewrite (_ : b ≡ a). - - exists (Shot c). constructor. done. -Qed. + split. + - intros [z Hy]; destruct x as [|a|], z as [|b|]; inversion_clear Hy; auto. + right; eexists _, _; split_and!; eauto. + setoid_subst; eauto using cmra_included_l. + - intros [->|(a&b&->&->&c&?)]. + + destruct x; exists OneShotBot; constructor. + + exists (Shot c); by constructor. +Qed. Lemma one_shot_cmra_mixin : CMRAMixin (one_shot A). Proof. split. - intros n []; destruct 1; constructor; by cofe_subst. - - intros ? [|a| |] [|b| |] H; inversion_clear H; constructor; by f_equiv. - - intros ? [|a| |] [|b| |] H; inversion_clear H; cofe_subst; done. - - intros [|a| |]; rewrite /= ?cmra_valid_validN; naive_solver eauto using O. - - intros n [|a| |]; simpl; auto using cmra_validN_S. - - intros [|a1| |] [|a2| |] [|a3| |]; constructor; by rewrite ?assoc. - - intros [|a1| |] [|a2| |]; constructor; by rewrite 1?comm. - - intros [|a| |]; constructor; []. exact: cmra_core_l. - - intros [|a| |]; constructor; []. exact: cmra_core_idemp. - - intros [|a1| |] [|a2| |]; simpl; - try solve [ by exists OneShotUnit; constructor - | by exists OneShotBot; constructor - | by intros [[|a3| |] H]; inversion_clear H ]. - + intros H%Shot_incl. apply Shot_incl, cmra_core_preserving. done. - + intros _. exists (Shot (core a2)). by constructor. - - intros n [|a1| |] [|a2| |]; simpl; eauto using cmra_validN_op_l; done. - - intros n [|a| |] y1 y2 Hx Hx'; last 2 first. - + by exists (OneShotUnit, OneShotUnit); destruct y1, y2; inversion_clear Hx'. + - intros ???? [n|n a b Hab|n] [=]; subst; eauto. + destruct (pcore a) as [ca|] eqn:?; simplify_option_eq. + destruct (cmra_pcore_ne n a b ca) as (cb&->&?); auto. + exists (Shot cb); by repeat constructor. + - intros ? [|a|] [|b|] H; inversion_clear H; cofe_subst; done. + - intros [|a|]; rewrite /= ?cmra_valid_validN; naive_solver eauto using O. + - intros n [|a|]; simpl; auto using cmra_validN_S. + - intros [|a1|] [|a2|] [|a3|]; constructor; by rewrite ?assoc. + - intros [|a1|] [|a2|]; constructor; by rewrite 1?comm. + - intros [|a|] ? [=]; subst; auto. + destruct (pcore a) as [ca|] eqn:?; simplify_option_eq. + constructor; eauto using cmra_pcore_l. + - intros [|a|] ? [=]; subst; auto. + destruct (pcore a) as [ca|] eqn:?; simplify_option_eq. + feed inversion (cmra_pcore_idemp a ca); repeat constructor; auto. + - intros x y ? [->|(a&b&->&->&?)]%one_shot_included [=]. + { exists OneShotBot. rewrite one_shot_included; eauto. } + destruct (pcore a) as [ca|] eqn:?; simplify_option_eq. + destruct (cmra_pcore_preserving a b ca) as (cb&->&?); auto. + exists (Shot cb). rewrite one_shot_included; eauto 10. + - intros n [|a1|] [|a2|]; simpl; eauto using cmra_validN_op_l; done. + - intros n [|a|] y1 y2 Hx Hx'. + + destruct y1, y2; exfalso; by inversion_clear Hx'. + + destruct y1 as [|b1|], y2 as [|b2|]; try (exfalso; by inversion_clear Hx'). + apply (inj Shot) in Hx'. + destruct (cmra_extend n a b1 b2) as ([z1 z2]&?&?&?); auto. + exists (Shot z1, Shot z2). by repeat constructor. + by exists (OneShotBot, OneShotBot); destruct y1, y2; inversion_clear Hx'. - + destruct y1, y2; try (exfalso; by inversion_clear Hx'). - * by exists (OneShotPending, OneShotUnit). - * by exists (OneShotUnit, OneShotPending). - + destruct y1 as [|b1 | |], y2 as [|b2| |]; try (exfalso; by inversion_clear Hx'). - * apply (inj Shot) in Hx'. - destruct (cmra_extend n a b1 b2) as ([z1 z2]&?&?&?); auto. - exists (Shot z1, Shot z2). by repeat constructor. - * exists (Shot a, OneShotUnit). inversion_clear Hx'. by repeat constructor. - * exists (OneShotUnit, Shot a). inversion_clear Hx'. by repeat constructor. Qed. Canonical Structure one_shotR := CMRAT (one_shot A) one_shot_cofe_mixin one_shot_cmra_mixin. + Global Instance one_shot_cmra_discrete : CMRADiscrete A → CMRADiscrete one_shotR. Proof. split; first apply _. - intros [|a| |]; simpl; auto using cmra_discrete_valid. + intros [|a|]; simpl; auto using cmra_discrete_valid. Qed. -Instance one_shot_empty : Empty (one_shot A) := OneShotUnit. -Lemma one_shot_ucmra_mixin : UCMRAMixin (one_shot A). -Proof. split. done. by intros []. apply _. Qed. -Canonical Structure one_shotUR := - UCMRAT (one_shot A) one_shot_cofe_mixin one_shot_cmra_mixin one_shot_ucmra_mixin. - Global Instance Shot_persistent a : Persistent a → Persistent (Shot a). -Proof. by constructor. Qed. - -Lemma one_shot_validN_inv_l n y : ✓{n} (OneShotPending ⋅ y) → y = ∅. -Proof. by destruct y; inversion_clear 1. Qed. -Lemma one_shot_valid_inv_l y : ✓ (OneShotPending ⋅ y) → y = ∅. -Proof. intros. by apply one_shot_validN_inv_l with 0, cmra_valid_validN. Qed. -Lemma one_shot_bot_largest y : y ≼ OneShotBot. -Proof. destruct y; exists OneShotBot; constructor. Qed. +Proof. rewrite /Persistent /=. inversion_clear 1; by repeat constructor. Qed. (** Internalized properties *) Lemma one_shot_equivI {M} (x y : one_shot A) : (x ≡ y) ⊣⊢ (match x, y with | OneShotPending, OneShotPending => True | Shot a, Shot b => a ≡ b - | OneShotUnit, OneShotUnit => True | OneShotBot, OneShotBot => True | _, _ => False end : uPred M). @@ -232,45 +216,35 @@ Proof. uPred.unseal. by destruct x. Qed. (** Updates *) Lemma one_shot_update_shoot (a : A) : ✓ a → OneShotPending ~~> Shot a. -Proof. - move=> ? n y /one_shot_validN_inv_l ->. by apply cmra_valid_validN. -Qed. +Proof. move=> ? n [y|] //= ?. by apply cmra_valid_validN. Qed. Lemma one_shot_update (a1 a2 : A) : a1 ~~> a2 → Shot a1 ~~> Shot a2. Proof. - intros Ha n [|b| |] ?; simpl; auto. - apply cmra_validN_op_l with (core a1), Ha. by rewrite cmra_core_r. + intros Ha n [[|b|]|] ?; simpl in *; auto. + - by apply (Ha n (Some b)). + - by apply (Ha n None). Qed. Lemma one_shot_updateP (P : A → Prop) (Q : one_shot A → Prop) a : a ~~>: P → (∀ b, P b → Q (Shot b)) → Shot a ~~>: Q. Proof. - intros Hx HP n mf Hm. destruct mf as [|b| |]; try by destruct Hm. - - destruct (Hx n b) as (c&?&?); try done. - exists (Shot c). auto. - - destruct (Hx n (core a)) as (c&?&?); try done. - { by rewrite cmra_core_r. } - exists (Shot c). split; simpl; eauto using cmra_validN_op_l. + intros Hx HP n mf Hm. destruct mf as [[|b|]|]; try by destruct Hm. + - destruct (Hx n (Some b)) as (c&?&?); naive_solver. + - destruct (Hx n None) as (c&?&?); naive_solver eauto using cmra_validN_op_l. Qed. Lemma one_shot_updateP' (P : A → Prop) a : a ~~>: P → Shot a ~~>: λ m', ∃ b, m' = Shot b ∧ P b. Proof. eauto using one_shot_updateP. Qed. - End cmra. Arguments one_shotR : clear implicits. -Arguments one_shotUR : clear implicits. (* Functor *) Instance one_shot_map_cmra_monotone {A B : cmraT} (f : A → B) : CMRAMonotone f → CMRAMonotone (one_shot_map f). Proof. split; try apply _. - - intros n [|a| |]; simpl; auto using validN_preserving. - - intros [|a1| |] [|a2| |] [[|a3| |] Hx]; - inversion Hx; setoid_subst; try apply: ucmra_unit_least; - try apply one_shot_bot_largest; auto; []. - destruct (included_preserving f a1 (a1 ⋅ a3)) as [b ?]. - { by apply cmra_included_l. } - by exists (Shot b); constructor. + - intros n [|a|]; simpl; auto using validN_preserving. + - intros x y; rewrite !one_shot_included. + intros [->|(a&b&->&->&?)]; simpl; eauto 10 using included_preserving. Qed. Program Definition one_shotRF (F : rFunctor) : rFunctor := {| @@ -294,25 +268,3 @@ Instance one_shotRF_contractive F : Proof. by intros ? A1 A2 B1 B2 n f g Hfg; apply one_shotC_map_ne, rFunctor_contractive. Qed. - -Program Definition one_shotURF (F : rFunctor) : urFunctor := {| - urFunctor_car A B := one_shotUR (rFunctor_car F A B); - urFunctor_map A1 A2 B1 B2 fg := one_shotC_map (rFunctor_map F fg) -|}. -Next Obligation. - by intros F A1 A2 B1 B2 n f g Hfg; apply one_shotC_map_ne, rFunctor_ne. -Qed. -Next Obligation. - intros F A B x. rewrite /= -{2}(one_shot_map_id x). - apply one_shot_map_ext=>y; apply rFunctor_id. -Qed. -Next Obligation. - intros F A1 A2 A3 B1 B2 B3 f g f' g' x. rewrite /= -one_shot_map_compose. - apply one_shot_map_ext=>y; apply rFunctor_compose. -Qed. - -Instance one_shotURF_contractive F : - rFunctorContractive F → urFunctorContractive (one_shotURF F). -Proof. - by intros ? A1 A2 B1 B2 n f g Hfg; apply one_shotC_map_ne, rFunctor_contractive. -Qed. diff --git a/algebra/upred.v b/algebra/upred.v index 3a46637b316c00c6aa2bc3fddab074324206278c..0a72da7b07a5f0c63b8aebaa0117409a61a7bd42 100644 --- a/algebra/upred.v +++ b/algebra/upred.v @@ -215,8 +215,10 @@ Definition uPred_wand_eq : Program Definition uPred_always_def {M} (P : uPred M) : uPred M := {| uPred_holds n x := P n (core x) |}. -Next Obligation. naive_solver eauto using uPred_mono, cmra_core_preservingN. Qed. -Next Obligation. naive_solver eauto using uPred_closed, cmra_core_validN. Qed. +Next Obligation. + intros M; naive_solver eauto using uPred_mono, @cmra_core_preservingN. +Qed. +Next Obligation. naive_solver eauto using uPred_closed, @cmra_core_validN. Qed. Definition uPred_always_aux : { x | x = @uPred_always_def }. by eexists. Qed. Definition uPred_always {M} := proj1_sig uPred_always_aux M. Definition uPred_always_eq : @@ -431,7 +433,7 @@ Global Instance later_proper : Global Instance always_ne n : Proper (dist n ==> dist n) (@uPred_always M). Proof. intros P1 P2 HP. - unseal; split=> n' x; split; apply HP; eauto using cmra_core_validN. + unseal; split=> n' x; split; apply HP; eauto using @cmra_core_validN. Qed. Global Instance always_proper : Proper ((⊣⊢) ==> (⊣⊢)) (@uPred_always M) := ne_proper _. @@ -856,11 +858,11 @@ Proof. by unseal. Qed. Lemma always_elim P : □ P ⊢ P. Proof. unseal; split=> n x ? /=. - eauto using uPred_mono, cmra_included_core, cmra_included_includedN. + eauto using uPred_mono, @cmra_included_core, cmra_included_includedN. Qed. Lemma always_intro' P Q : □ P ⊢ Q → □ P ⊢ □ Q. Proof. - unseal=> HPQ; split=> n x ??; apply HPQ; simpl; auto using cmra_core_validN. + unseal=> HPQ; split=> n x ??; apply HPQ; simpl; auto using @cmra_core_validN. by rewrite cmra_core_idemp. Qed. Lemma always_and P Q : □ (P ∧ Q) ⊣⊢ (□ P ∧ □ Q). @@ -1023,7 +1025,7 @@ Qed. Lemma always_ownM (a : M) : Persistent a → □ uPred_ownM a ⊣⊢ uPred_ownM a. Proof. split=> n x /=; split; [by apply always_elim|unseal; intros Hx]; simpl. - rewrite -(persistent a). by apply cmra_core_preservingN. + rewrite -(persistent_core a). by apply cmra_core_preservingN. Qed. Lemma ownM_something : True ⊢ ∃ a, uPred_ownM a. Proof. unseal; split=> n x ??. by exists x; simpl. Qed. diff --git a/heap_lang/heap.v b/heap_lang/heap.v index 9a2cac7a9ea7ecdb26123b249dddfdaa4009c05c..c1e2c2a7afa9486704806c12aecbf3079a6c7a60 100644 --- a/heap_lang/heap.v +++ b/heap_lang/heap.v @@ -19,8 +19,7 @@ Class heapG Σ := HeapG { Definition heapGF : gFunctor := authGF heapUR. Definition to_heap : state → heapUR := fmap (λ v, Frac 1 (DecAgree v)). -Definition of_heap : heapUR → state := - omap (mbind (maybe DecAgree ∘ snd) ∘ maybe2 Frac). +Definition of_heap : heapUR → state := omap (maybe DecAgree ∘ frac_car). Section definitions. Context `{i : heapG Σ}. @@ -70,7 +69,7 @@ Section heap. intros Hv. apply map_eq=> l'; destruct (decide (l' = l)) as [->|]. - move: (Hv l). rewrite /of_heap lookup_insert lookup_omap (lookup_op _ h) lookup_singleton. - case _:(h !! l)=>[[q' [v'|]|]|] //=; last by move=> [??]. + case _:(h !! l)=>[[q' [v'|]]|] //=; last by move=> [??]. move=> [? /dec_agree_op_inv [->]]. by rewrite dec_agree_idemp. - rewrite /of_heap lookup_insert_ne // !lookup_omap. by rewrite (lookup_op _ h) lookup_singleton_ne // left_id_L. @@ -79,10 +78,10 @@ Section heap. to_heap (<[l:=v]> σ) = <[l:=Frac 1 (DecAgree v)]> (to_heap σ). Proof. by rewrite /to_heap -fmap_insert. Qed. Lemma of_heap_None h l : - ✓ h → of_heap h !! l = None → h !! l = None ∨ h !! l ≡ Some FracUnit. + ✓ h → of_heap h !! l = None → h !! l = None. Proof. move=> /(_ l). rewrite /of_heap lookup_omap. - by case: (h !! l)=> [[q [v|]|]|] //=; destruct 1; auto. + by case: (h !! l)=> [[q [v|]]|] //=; destruct 1; auto. Qed. Lemma heap_store_valid l h v1 v2 : ✓ ({[l := Frac 1 (DecAgree v1)]} ⋅ h) → @@ -90,7 +89,7 @@ Section heap. Proof. intros Hv l'; move: (Hv l'). destruct (decide (l' = l)) as [->|]. - rewrite !lookup_op !lookup_singleton. - case: (h !! l)=>[x|]; [|done]=> /frac_valid_inv_l=>-> //. + by case: (h !! l)=> [x|] // /frac_valid_inv_l. - by rewrite !lookup_op !lookup_singleton_ne. Qed. Hint Resolve heap_store_valid. diff --git a/program_logic/adequacy.v b/program_logic/adequacy.v index dbc1f76f3795904f1b8420844ccf14a8ef0de06c..f5eab2f097c041d58c0345a7bc959454b6b7cfbc 100644 --- a/program_logic/adequacy.v +++ b/program_logic/adequacy.v @@ -75,9 +75,9 @@ Lemma wp_adequacy_own Φ e1 t2 σ1 m σ2 : ∃ rs2 Φs', wptp 2 t2 (Φ :: Φs') rs2 ∧ wsat 2 ⊤ σ2 (big_op rs2). Proof. intros Hv ? [k ?]%rtc_nsteps. - eapply wp_adequacy_steps with (r1 := (Res ∅ (Excl σ1) m)); eauto; [|]. + eapply wp_adequacy_steps with (r1 := (Res ∅ (Excl' σ1) m)); eauto; [|]. { by rewrite Nat.add_comm; apply wsat_init, cmra_valid_validN. } - uPred.unseal; exists (Res ∅ (Excl σ1) ∅), (Res ∅ ∅ m); split_and?. + uPred.unseal; exists (Res ∅ (Excl' σ1) ∅), (Res ∅ ∅ m); split_and?. - by rewrite Res_op ?left_id ?right_id. - rewrite /ownP; uPred.unseal; rewrite /uPred_holds //=. - by apply ownG_spec. diff --git a/program_logic/auth.v b/program_logic/auth.v index e1c79a43679613ac3b26b54219c7ed11ce3821c9..0cdf20cab6db26f3bf9ea7a760672773ad34ee5b 100644 --- a/program_logic/auth.v +++ b/program_logic/auth.v @@ -58,7 +58,7 @@ Section auth. ▷ φ a ⊢ (|={E}=> ∃ γ, auth_ctx γ N φ ∧ auth_own γ a). Proof. iIntros {??} "Hφ". rewrite /auth_own /auth_ctx. - iPvs (own_alloc (Auth (Excl a) a)) as {γ} "Hγ"; first done. + iPvs (own_alloc (Auth (Excl' a) a)) as {γ} "Hγ"; first done. iRevert "Hγ"; rewrite auth_both_op; iIntros "[Hγ Hγ']". iPvs (inv_alloc N _ (auth_inv γ φ) with "[-Hγ']"); first done. { iNext. iExists a. by iFrame "Hφ". } diff --git a/program_logic/model.v b/program_logic/model.v index 5daecb065756b8523bebc17246e0b9507ea485a1..55cdb0ac6f870c12c7e3614ab91ac8afc1e19c41 100644 --- a/program_logic/model.v +++ b/program_logic/model.v @@ -19,7 +19,7 @@ Definition iGst (Λ : language) (Σ : iFunctor) : ucmraT := Σ (iPreProp Λ Σ). Definition iRes Λ Σ := res Λ (laterC (iPreProp Λ Σ)) (iGst Λ Σ). Definition iResUR Λ Σ := resUR Λ (laterC (iPreProp Λ Σ)) (iGst Λ Σ). Definition iWld Λ Σ := gmap positive (agree (laterC (iPreProp Λ Σ))). -Definition iPst Λ := excl (state Λ). +Definition iPst Λ := option (excl (state Λ)). Definition iProp (Λ : language) (Σ : iFunctor) : cofeT := uPredC (iResUR Λ Σ). Parameter iProp_unfold: ∀ {Λ Σ}, iProp Λ Σ -n> iPreProp Λ Σ. @@ -40,7 +40,7 @@ Definition iGst (Λ : language) (Σ : iFunctor) : ucmraT := Σ (iPreProp Λ Σ). Definition iRes Λ Σ := res Λ (laterC (iPreProp Λ Σ)) (iGst Λ Σ). Definition iResUR Λ Σ := resUR Λ (laterC (iPreProp Λ Σ)) (iGst Λ Σ). Definition iWld Λ Σ := gmap positive (agree (laterC (iPreProp Λ Σ))). -Definition iPst Λ := excl (state Λ). +Definition iPst Λ := option (excl (state Λ)). Definition iProp (Λ : language) (Σ : iFunctor) : cofeT := uPredC (iResUR Λ Σ). Definition iProp_unfold {Λ Σ} : iProp Λ Σ -n> iPreProp Λ Σ := diff --git a/program_logic/ownership.v b/program_logic/ownership.v index 3127a5b2b15e97817a9e67d012237d774db758fd..88368a6cf5ec4529a8225f835008e65fa469271d 100644 --- a/program_logic/ownership.v +++ b/program_logic/ownership.v @@ -3,7 +3,7 @@ From iris.program_logic Require Export model. Definition ownI {Λ Σ} (i : positive) (P : iProp Λ Σ) : iProp Λ Σ := uPred_ownM (Res {[ i := to_agree (Next (iProp_unfold P)) ]} ∅ ∅). Arguments ownI {_ _} _ _%I. -Definition ownP {Λ Σ} (σ: state Λ) : iProp Λ Σ := uPred_ownM (Res ∅ (Excl σ) ∅). +Definition ownP {Λ Σ} (σ: state Λ) : iProp Λ Σ := uPred_ownM (Res ∅ (Excl' σ) ∅). Definition ownG {Λ Σ} (m: iGst Λ Σ) : iProp Λ Σ := uPred_ownM (Res ∅ ∅ m). Instance: Params (@ownI) 3. Instance: Params (@ownP) 2. @@ -64,11 +64,12 @@ Proof. intros (?&?&?). rewrite /ownI; uPred.unseal. rewrite /uPred_holds/=res_includedN/= singleton_includedN; split. - intros [(P'&Hi&HP) _]; rewrite Hi. - constructor; symmetry; apply agree_valid_includedN; last done. - by apply lookup_validN_Some with (wld r) i. + constructor; symmetry; apply agree_valid_includedN. + + by apply lookup_validN_Some with (wld r) i. + + by destruct HP as [?| ->]. - intros ?; split_and?; try apply ucmra_unit_leastN; eauto. Qed. -Lemma ownP_spec n r σ : ✓{n} r → (ownP σ) n r ↔ pst r ≡ Excl σ. +Lemma ownP_spec n r σ : ✓{n} r → (ownP σ) n r ↔ pst r ≡ Excl' σ. Proof. intros (?&?&?). rewrite /ownP; uPred.unseal. rewrite /uPred_holds /= res_includedN /= Excl_includedN //. diff --git a/program_logic/resources.v b/program_logic/resources.v index d03e671f5510b225c37c6355c56f4b0f5ec9b1a5..0304c1bc0c554953fbe4e84d533a52b5a3cf416b 100644 --- a/program_logic/resources.v +++ b/program_logic/resources.v @@ -4,7 +4,7 @@ From iris.program_logic Require Export language. Record res (Λ : language) (A : cofeT) (M : cmraT) := Res { wld : gmapR positive (agreeR A); - pst : exclR (stateC Λ); + pst : optionR (exclR (stateC Λ)); gst : M; }. Add Printing Constructor res. @@ -73,8 +73,8 @@ Proof. destruct 3; constructor; by apply (timeless _). Qed. Instance res_op : Op (res Λ A M) := λ r1 r2, Res (wld r1 ⋅ wld r2) (pst r1 ⋅ pst r2) (gst r1 ⋅ gst r2). -Instance res_core : Core (res Λ A M) := λ r, - Res (core (wld r)) (core (pst r)) (core (gst r)). +Instance res_pcore : PCore (res Λ A M) := λ r, + Some $ Res (core (wld r)) (core (pst r)) (core (gst r)). Instance res_valid : Valid (res Λ A M) := λ r, ✓ wld r ∧ ✓ pst r ∧ ✓ gst r. Instance res_validN : ValidN (res Λ A M) := λ n r, ✓{n} wld r ∧ ✓{n} pst r ∧ ✓{n} gst r. @@ -95,7 +95,8 @@ Proof. Qed. Definition res_cmra_mixin : CMRAMixin (res Λ A M). Proof. - split. + apply cmra_total_mixin. + - eauto. - by intros n x [???] ? [???]; constructor; cofe_subst. - by intros n [???] ? [???]; constructor; cofe_subst. - by intros n [???] ? [???] (?&?&?); split_and!; cofe_subst. @@ -117,8 +118,7 @@ Proof. (cmra_extend n (gst r) (gst r1) (gst r2)) as ([m m']&?&?&?); auto. by exists (Res w σ m, Res w' σ' m'). Qed. -Canonical Structure resR := - CMRAT (res Λ A M) res_cofe_mixin res_cmra_mixin. +Canonical Structure resR := CMRAT (res Λ A M) res_cofe_mixin res_cmra_mixin. Instance res_empty : Empty (res Λ A M) := Res ∅ ∅ ∅. Definition res_ucmra_mixin : UCMRAMixin (res Λ A M). @@ -127,12 +127,13 @@ Proof. - split_and!; apply ucmra_unit_valid. - by split; rewrite /= left_id. - apply _. + - do 2 constructor; simpl; apply (persistent_core _). Qed. Canonical Structure resUR := UCMRAT (res Λ A M) res_cofe_mixin res_cmra_mixin res_ucmra_mixin. Definition update_pst (σ : state Λ) (r : res Λ A M) : res Λ A M := - Res (wld r) (Excl σ) (gst r). + Res (wld r) (Excl' σ) (gst r). Definition update_gst (m : M) (r : res Λ A M) : res Λ A M := Res (wld r) (pst r) m. @@ -158,7 +159,7 @@ Proof. rewrite (comm _ r1) (comm _ (wld r1)); apply lookup_wld_op_l. Qed. Global Instance Res_timeless eσ m : Timeless m → Timeless (@Res Λ A M ∅ eσ m). Proof. by intros ? ? [???]; constructor; apply (timeless _). Qed. Global Instance Res_persistent w m: Persistent m → Persistent (@Res Λ A M w ∅ m). -Proof. constructor; apply (persistent _). Qed. +Proof. do 2 constructor; apply (persistent_core _). Qed. (** Internalized properties *) Lemma res_equivI {M'} r1 r2 : diff --git a/program_logic/wsat.v b/program_logic/wsat.v index 84fb2cde34707659ad42dc27af629784e12090b3..650238ddd5f910f70db52d1ad6c6e925b097d6a4 100644 --- a/program_logic/wsat.v +++ b/program_logic/wsat.v @@ -9,7 +9,7 @@ Local Hint Extern 1 (✓{_} wld _) => apply wld_validN. Record wsat_pre {Λ Σ} (n : nat) (E : coPset) (σ : state Λ) (rs : gmap positive (iRes Λ Σ)) (r : iRes Λ Σ) := { wsat_pre_valid : ✓{S n} r; - wsat_pre_state : pst r ≡ Excl σ; + wsat_pre_state : pst r ≡ Excl' σ; wsat_pre_dom i : is_Some (rs !! i) → i ∈ E ∧ is_Some (wld r !! i); wsat_pre_wld i P : i ∈ E → @@ -70,7 +70,7 @@ Proof. destruct n; first done. intros _ [rs ?]; eapply cmra_validN_op_l, wsat_pre_valid; eauto. Qed. -Lemma wsat_init k E σ m : ✓{S k} m → wsat (S k) E σ (Res ∅ (Excl σ) m). +Lemma wsat_init k E σ m : ✓{S k} m → wsat (S k) E σ (Res ∅ (Excl' σ) m). Proof. intros Hv. exists ∅; constructor; auto. - rewrite big_opM_empty right_id. @@ -114,7 +114,7 @@ Proof. exists r'; rewrite lookup_insert_ne; naive_solver. Qed. Lemma wsat_update_pst n E σ1 σ1' r rf : - pst r ≡{S n}≡ Excl σ1 → wsat (S n) E σ1' (r ⋅ rf) → + pst r ≡{S n}≡ Excl' σ1 → wsat (S n) E σ1' (r ⋅ rf) → σ1' = σ1 ∧ ∀ σ2, wsat (S n) E σ2 (update_pst σ2 r ⋅ rf). Proof. intros Hpst_r [rs [(?&?&?) Hpst HE Hwld]]; simpl in *. @@ -122,7 +122,7 @@ Proof. { by apply: (excl_validN_inv_l (S n) _ σ1); rewrite -Hpst_r assoc. } assert (σ1' = σ1) as ->. { apply leibniz_equiv, (timeless _), dist_le with (S n); auto. - apply (inj Excl). + apply (inj Excl), (inj Some). by rewrite -Hpst_r -Hpst -assoc Hpst' right_id. } split; [done|exists rs]. by constructor; first split_and!; try rewrite /= -assoc Hpst'. @@ -132,7 +132,7 @@ Lemma wsat_update_gst n E σ r rf m1 (P : iGst Λ Σ → Prop) : wsat (S n) E σ (r ⋅ rf) → ∃ m2, wsat (S n) E σ (update_gst m2 r ⋅ rf) ∧ P m2. Proof. intros [mf Hr] Hup [rs [(?&?&?) Hσ HE Hwld]]. - destruct (Hup (S n) (mf ⋅ gst (rf ⋅ big_opM rs))) as (m2&?&Hval'); try done. + destruct (Hup (S n) (Some (mf ⋅ gst (rf ⋅ big_opM rs)))) as (m2&?&Hval'); try done. { by rewrite /= (assoc _ m1) -Hr assoc. } exists m2; split; [exists rs|done]. by constructor; first split_and!; auto.