Library iris.proofmode.class_instances
From iris.proofmode Require Export classes.
From iris.algebra Require Import upred_big_op gmap upred_tactics.
Import uPred.
Section classes.
Context {M : ucmraT}.
Implicit Types P Q R : uPred M.
Global Instance from_assumption_exact p P : FromAssumption p P P.
Proof. destruct p; by rewrite /FromAssumption /= ?relevant_elim. Qed.
Global Instance from_assumption_relevant_l p P Q :
FromAssumption p P Q → FromAssumption p (□ P) Q.
Proof. rewrite /FromAssumption=><-. by rewrite relevant_elim. Qed.
Global Instance from_assumption_relevant_r P Q :
FromAssumption true P Q → FromAssumption true P (□ Q).
Proof. rewrite /FromAssumption=><-.
by rewrite //= -relevant_relevant.
Qed.
Global Instance into_pure_pure φ : @IntoPure M (⧆■ φ) φ.
Proof. done. Qed.
Global Instance into_pure_eq {A : cofeT} (a b : A) :
Timeless a → @IntoPure M (⧆(a ≡ b)) (a ≡ b).
Proof. intros. by rewrite /IntoPure timeless_eq. Qed.
Global Instance into_pure_valid `{CMRADiscrete A} (a : A) : @IntoPure M (⧆✓ a) (✓ a).
Proof. by rewrite /IntoPure discrete_valid. Qed.
Global Instance from_pure_pure φ : @FromPure M (■ φ) φ.
Proof. intros ?. by apply pure_intro. Qed.
Global Instance from_pure_pure' φ : @FromPure M (⧆■ φ) φ.
Proof. intros ?. rewrite emp_True. by apply affine_mono, pure_intro. Qed.
Global Instance from_pure_eq {A : cofeT} (a b : A) : @FromPure M (⧆(a ≡ b)) (a ≡ b).
Proof. intros →. rewrite emp_True. apply affine_mono, eq_refl. Qed.
Global Instance from_pure_valid {A : cmraT} (a : A) : @FromPure M (⧆(✓ a)) (✓ a).
Proof. intros ?. rewrite emp_True. by apply affine_mono, valid_intro. Qed.
Global Instance from_pure_Emp : @FromPure M Emp True.
Proof. done. Qed.
Global Instance into_relevantP_always_trans P Q :
IntoRelevantP P Q → IntoRelevantP (□ P) Q | 0.
Proof. rewrite /IntoRelevantP⇒ →. by rewrite relevant_relevant'. Qed.
Global Instance into_relevantP_always P : IntoRelevantP (□ P) P | 1.
Proof. done. Qed.
Global Instance into_relevantP_always_affine P : IntoRelevantP (⧆□ P) (⧆P) | 1.
Proof. rewrite /IntoRelevantP. by rewrite relevant_affine. Qed.
Global Instance into_relevantP_relevant P :
RelevantP P → IntoRelevantP P P | 100.
Proof. done. Qed.
Global Instance into_later_default P : IntoLater P P | 1000.
Proof. apply later_intro. Qed.
Global Instance into_later_later P : IntoLater (▷ P) P.
Proof. done. Qed.
Global Instance into_later_and P1 P2 Q1 Q2 :
IntoLater P1 Q1 → IntoLater P2 Q2 → IntoLater (P1 ∧ P2) (Q1 ∧ Q2).
Proof. intros ??; red. by rewrite later_and; apply and_mono. Qed.
Global Instance into_later_or P1 P2 Q1 Q2 :
IntoLater P1 Q1 → IntoLater P2 Q2 → IntoLater (P1 ∨ P2) (Q1 ∨ Q2).
Proof. intros ??; red. by rewrite later_or; apply or_mono. Qed.
Global Instance into_later_sep P1 P2 Q1 Q2 :
IntoLater P1 Q1 → IntoLater P2 Q2 → IntoLater (P1 ★ P2) (Q1 ★ Q2).
Proof. intros ??; red. by rewrite later_sep; apply sep_mono. Qed.
Global Instance into_later_affine P: IntoLater (⧆▷ P) (⧆P).
Proof. red. by apply affine_later_1. Qed.
Global Instance from_later_later P : FromLater (▷ P) P.
Proof. done. Qed.
Global Instance from_later_and P1 P2 Q1 Q2 :
FromLater P1 Q1 → FromLater P2 Q2 → FromLater (P1 ∧ P2) (Q1 ∧ Q2).
Proof. intros ??; red. by rewrite later_and; apply and_mono. Qed.
Global Instance from_later_or P1 P2 Q1 Q2 :
FromLater P1 Q1 → FromLater P2 Q2 → FromLater (P1 ∨ P2) (Q1 ∨ Q2).
Proof. intros ??; red. by rewrite later_or; apply or_mono. Qed.
Global Instance from_later_sep P1 P2 Q1 Q2 :
FromLater P1 Q1 → FromLater P2 Q2 → FromLater (P1 ★ P2) (Q1 ★ Q2).
Proof. intros ??; red. by rewrite later_sep; apply sep_mono. Qed.
Global Instance into_wand_wand P Q : IntoWand (P -★ Q) P Q.
Proof. done. Qed.
Global Instance into_wand_wand_iff_l P Q : IntoWand ((P -★ Q) ∧ (Q -★ P)) P Q.
Proof. by apply and_elim_l'. Qed.
Global Instance into_wand_wand_iff_r P Q : IntoWand ((P -★ Q) ∧ (Q -★ P)) Q P.
Proof. by apply and_elim_r'. Qed.
Global Instance into_wand_always R P Q : IntoWand R P Q → IntoWand (□ R) P Q.
Proof. rewrite /IntoWand⇒ →. apply relevant_elim. Qed.
Global Instance into_wand_affine R P Q : IntoWand R P Q → IntoWand (⧆ R) P Q.
Proof. rewrite /IntoWand⇒ →. apply affine_elim. Qed.
Global Instance from_and_and P1 P2 : FromAnd (P1 ∧ P2) P1 P2.
Proof. done. Qed.
Global Instance from_and_sep_relevant_l P1 P2 :
RelevantP P1 → FromAnd (P1 ★ P2) P1 P2 | 9.
Proof. intros. by rewrite /FromAnd relevant_and_sep_l_1. Qed.
Global Instance from_and_sep_relevant_r P1 P2 :
RelevantP P2 → FromAnd (P1 ★ P2) P1 P2 | 10.
Proof. intros. by rewrite /FromAnd relevant_and_sep_r_1. Qed.
Global Instance from_and_always P Q1 Q2 :
FromAnd P Q1 Q2 → FromAnd (□ P) (□ Q1) (□ Q2).
Proof. rewrite /FromAnd⇒ <-. by rewrite relevant_and. Qed.
Global Instance from_and_later P Q1 Q2 :
FromAnd P Q1 Q2 → FromAnd (▷ P) (▷ Q1) (▷ Q2).
Proof. rewrite /FromAnd⇒ <-. by rewrite later_and. Qed.
Global Instance from_sep_sep P1 P2 : FromSep (P1 ★ P2) P1 P2 | 100.
Proof. done. Qed.
Global Instance from_sep_relevant P Q1 Q2 :
FromSep P Q1 Q2 → FromSep (□ P) (□ Q1) (□ Q2).
Proof. rewrite /FromSep⇒ <-. by rewrite relevant_sep. Qed.
Global Instance from_sep_affine P Q1 Q2 :
FromSep P Q1 Q2 → FromSep (⧆ P) (⧆ Q1) (⧆ Q2).
Proof. by rewrite /FromSep sep_affine_1⇒ →. Qed.
Global Instance from_sep_later P Q1 Q2 :
FromSep P Q1 Q2 → FromSep (▷ P) (▷ Q1) (▷ Q2).
Proof. rewrite /FromSep⇒ <-. by rewrite later_sep. Qed.
Global Instance from_sep_ownM (a b : M) :
FromSep (uPred_ownM (a ⋅ b)) (uPred_ownM a) (uPred_ownM b) | 99.
Proof. by rewrite /FromSep ownM_op. Qed.
Global Instance into_op_op {A : cmraT} (a b : A) : IntoOp (a ⋅ b) a b.
Proof. by rewrite /IntoOp. Qed.
Global Instance into_op_relevant {A : cmraT} (a : A) :
Persistent a → IntoOp a a a.
Proof. intros; apply (persistent_dup a). Qed.
Global Instance into_op_pair {A B : cmraT} (a b1 b2 : A) (a' b1' b2' : B) :
IntoOp a b1 b2 → IntoOp a' b1' b2' →
IntoOp (a,a') (b1,b1') (b2,b2').
Proof. by constructor. Qed.
Global Instance into_op_Some {A : cmraT} (a : A) b1 b2 :
IntoOp a b1 b2 → IntoOp (Some a) (Some b1) (Some b2).
Proof. by constructor. Qed.
Lemma into_sep_spatial P Q1 Q2 : (P ⊢ Q1 ★ Q2) → IntoSep false P Q1 Q2.
Proof. simpl=>->; by done. Qed.
Lemma into_sep_relevant P Q1 Q2 `{!RelevantP Q1, !RelevantP Q2}:
(P ⊢ Q1 ★ Q2) → IntoSep true P Q1 Q2.
Proof. simpl=>->. by rewrite -relevant_sep' (relevant_relevant' Q1) (relevant_relevant' Q2). Qed.
Lemma into_sep_affine P Q1 Q2 `{!AffineP Q1, !AffineP Q2}:
(P ⊢ Q1 ★ Q2) → IntoSep false (⧆P) Q1 Q2.
Proof. simpl=>->. by rewrite -sep_affine_distrib ?affine_elim. Qed.
Lemma into_sep_affine_later P Q1 Q2 `{!AffineP Q1, !AffineP Q2}:
(P ⊢ Q1 ★ Q2) → IntoSep false (⧆▷P) (⧆▷Q1) (⧆▷Q2).
Proof. simpl=>->. by apply affine_later_distrib'; auto. Qed.
Global Instance into_sep_sep P Q : IntoSep false (P ★ Q) P Q.
Proof. by rewrite /IntoSep. Qed.
Global Instance into_sep_sep' P Q :
RelevantP P → RelevantP Q → IntoSep true (P ★ Q) P Q.
Proof. intros; by rewrite /IntoSep; apply into_sep_relevant. Qed.
Global Instance into_sep_ownM (a b1 b2 : M) :
IntoOp a b1 b2 →
IntoSep false (uPred_ownM a) (uPred_ownM b1) (uPred_ownM b2).
Proof.
rewrite /IntoOp /IntoSep⇒ →. by rewrite ownM_op.
Qed.
Global Instance into_sep_and P Q : IntoSep true (P ∧ Q) P Q.
Proof. simpl. rewrite relevant_sep_dup'_1. rewrite {1}and_elim_l and_elim_r //=. Qed.
Global Instance into_sep_and_relevant_l P Q :
RelevantP P → IntoSep false (P ∧ Q) P Q.
Proof. intros; red. by rewrite -(relevant_relevant' P) relevant_and_sep_l_1. Qed.
Global Instance into_sep_and_relevant_r P Q :
RelevantP Q → IntoSep false (P ∧ Q) P Q.
Proof. intros; red. by rewrite ?(comm _ P) -(relevant_relevant' Q) relevant_and_sep_l_1. Qed.
Global Instance into_sep_later P Q1 Q2 :
IntoSep false P Q1 Q2 → IntoSep false (▷ P) (▷ Q1) (▷ Q2).
Proof. rewrite /= ⇒ HP. by rewrite -later_sep HP. Qed.
Global Instance into_sep_affine' P Q:
AffineP P → AffineP Q → classes.IntoSep false (⧆(P ★ Q)) (P) (Q).
Proof. intros; by apply into_sep_affine. Qed.
Global Instance into_sep_affine_later' P Q:
AffineP P → AffineP Q → classes.IntoSep false (⧆▷(P ★ Q)) (⧆▷P) (⧆▷Q).
Proof. intros; by apply into_sep_affine_later. Qed.
Global Instance frame_here R : Frame R R Emp.
Proof. by rewrite /Frame right_id. Qed.
Class MakeSep (P Q PQ : uPred M) := make_sep : P ★ Q ⊣⊢ PQ.
Global Instance make_sep_true_l P : MakeSep Emp P P.
Proof. by rewrite /MakeSep left_id. Qed.
Global Instance make_sep_true_r P : MakeSep P Emp P.
Proof. by rewrite /MakeSep right_id. Qed.
Global Instance make_sep_default P Q : MakeSep P Q (P ★ Q) | 100.
Proof. done. Qed.
Global Instance frame_sep_l R P1 P2 Q Q' :
Frame R P1 Q → MakeSep Q P2 Q' → Frame R (P1 ★ P2) Q' | 9.
Proof. rewrite /Frame /MakeSep ⇒ <- <-. by rewrite assoc. Qed.
Global Instance frame_sep_r R P1 P2 Q Q' :
Frame R P2 Q → MakeSep P1 Q Q' → Frame R (P1 ★ P2) Q' | 10.
Proof. rewrite /Frame /MakeSep ⇒ <- <-. solve_sep_entails. Qed.
Class MakeAnd (P Q PQ : uPred M) := make_and : P ∧ Q ⊣⊢ PQ.
Global Instance make_and_true_l P : MakeAnd True P P.
Proof. by rewrite /MakeAnd left_id. Qed.
Global Instance make_and_true_r P : MakeAnd P True P.
Proof. by rewrite /MakeAnd right_id. Qed.
Global Instance make_and_default P Q : MakeSep P Q (P ★ Q) | 100.
Proof. done. Qed.
Class MakeOr (P Q PQ : uPred M) := make_or : P ∨ Q ⊣⊢ PQ.
Global Instance make_or_true_l P : MakeOr True P True.
Proof. by rewrite /MakeOr left_absorb. Qed.
Global Instance make_or_true_r P : MakeOr P True True.
Proof. by rewrite /MakeOr right_absorb. Qed.
Global Instance make_or_default P Q : MakeOr P Q (P ∨ Q) | 100.
Proof. done. Qed.
Global Instance frame_or R P1 P2 Q1 Q2 Q :
Frame R P1 Q1 → Frame R P2 Q2 → MakeOr Q1 Q2 Q → Frame R (P1 ∨ P2) Q.
Proof. rewrite /Frame /MakeOr ⇒ <- <- <-. by rewrite -sep_or_l. Qed.
Global Instance frame_wand R P1 P2 Q2 :
Frame R P2 Q2 → Frame R (P1 -★ P2) (P1 -★ Q2).
Proof.
rewrite /Frame⇒ ?. apply wand_intro_l.
by rewrite assoc (comm _ P1) -assoc wand_elim_r.
Qed.
Class MakeLater (P lP : uPred M) := make_later : ▷ P ⊣⊢ lP.
Global Instance make_later_true : MakeLater True True.
Proof. by rewrite /MakeLater later_True. Qed.
Global Instance make_later_default P : MakeLater P (▷ P) | 100.
Proof. done. Qed.
Global Instance frame_later R P Q Q' :
Frame R P Q → MakeLater Q Q' → Frame R (▷ P) Q'.
Proof.
rewrite /Frame /MakeLater=><- <-. by rewrite later_sep -(later_intro R).
Qed.
Global Instance frame_exist {A} R (Φ Ψ : A → uPred M) :
(∀ a, Frame R (Φ a) (Ψ a)) → Frame R (∃ x, Φ x) (∃ x, Ψ x).
Proof. rewrite /Frame⇒ ?. by rewrite sep_exist_l; apply exist_mono. Qed.
Global Instance frame_forall {A} R (Φ Ψ : A → uPred M) :
(∀ a, Frame R (Φ a) (Ψ a)) → Frame R (∀ x, Φ x) (∀ x, Ψ x).
Proof. rewrite /Frame⇒ ?. by rewrite sep_forall_l; apply forall_mono. Qed.
Global Instance from_or_or P1 P2 : FromOr (P1 ∨ P2) P1 P2.
Proof. done. Qed.
Global Instance into_or_or P Q : IntoOr (P ∨ Q) P Q.
Proof. done. Qed.
Global Instance into_or_later P Q1 Q2 :
IntoOr P Q1 Q2 → IntoOr (▷ P) (▷ Q1) (▷ Q2).
Proof. rewrite /IntoOr=>->. by rewrite later_or. Qed.
Global Instance from_exist_exist {A} (Φ: A → uPred M): FromExist (∃ a, Φ a) Φ.
Proof. done. Qed.
Global Instance into_exist_exist {A} (Φ : A → uPred M) : IntoExist (∃ a, Φ a) Φ.
Proof. done. Qed.
Global Instance into_exist_later {A} P (Φ : A → uPred M) :
IntoExist P Φ → Inhabited A → IntoExist (▷ P) (λ a, ▷ (Φ a))%I.
Proof. rewrite /IntoExist⇒ HP ?. by rewrite HP later_exist. Qed.
Global Instance into_exist_relevant {A} P (Φ : A → uPred M) :
IntoExist P Φ → IntoExist (□ P) (λ a, □ (Φ a))%I.
Proof. rewrite /IntoExist⇒ HP. by rewrite HP relevant_exist. Qed.
Global Instance into_exist_affine {A} P (Φ : A → uPred M) :
IntoExist P Φ → IntoExist (⧆ P) (λ a, ⧆ (Φ a))%I.
Proof. rewrite /IntoExist⇒ HP. by rewrite HP affine_exist. Qed.
End classes.
From iris.algebra Require Import upred_big_op gmap upred_tactics.
Import uPred.
Section classes.
Context {M : ucmraT}.
Implicit Types P Q R : uPred M.
Global Instance from_assumption_exact p P : FromAssumption p P P.
Proof. destruct p; by rewrite /FromAssumption /= ?relevant_elim. Qed.
Global Instance from_assumption_relevant_l p P Q :
FromAssumption p P Q → FromAssumption p (□ P) Q.
Proof. rewrite /FromAssumption=><-. by rewrite relevant_elim. Qed.
Global Instance from_assumption_relevant_r P Q :
FromAssumption true P Q → FromAssumption true P (□ Q).
Proof. rewrite /FromAssumption=><-.
by rewrite //= -relevant_relevant.
Qed.
Global Instance into_pure_pure φ : @IntoPure M (⧆■ φ) φ.
Proof. done. Qed.
Global Instance into_pure_eq {A : cofeT} (a b : A) :
Timeless a → @IntoPure M (⧆(a ≡ b)) (a ≡ b).
Proof. intros. by rewrite /IntoPure timeless_eq. Qed.
Global Instance into_pure_valid `{CMRADiscrete A} (a : A) : @IntoPure M (⧆✓ a) (✓ a).
Proof. by rewrite /IntoPure discrete_valid. Qed.
Global Instance from_pure_pure φ : @FromPure M (■ φ) φ.
Proof. intros ?. by apply pure_intro. Qed.
Global Instance from_pure_pure' φ : @FromPure M (⧆■ φ) φ.
Proof. intros ?. rewrite emp_True. by apply affine_mono, pure_intro. Qed.
Global Instance from_pure_eq {A : cofeT} (a b : A) : @FromPure M (⧆(a ≡ b)) (a ≡ b).
Proof. intros →. rewrite emp_True. apply affine_mono, eq_refl. Qed.
Global Instance from_pure_valid {A : cmraT} (a : A) : @FromPure M (⧆(✓ a)) (✓ a).
Proof. intros ?. rewrite emp_True. by apply affine_mono, valid_intro. Qed.
Global Instance from_pure_Emp : @FromPure M Emp True.
Proof. done. Qed.
Global Instance into_relevantP_always_trans P Q :
IntoRelevantP P Q → IntoRelevantP (□ P) Q | 0.
Proof. rewrite /IntoRelevantP⇒ →. by rewrite relevant_relevant'. Qed.
Global Instance into_relevantP_always P : IntoRelevantP (□ P) P | 1.
Proof. done. Qed.
Global Instance into_relevantP_always_affine P : IntoRelevantP (⧆□ P) (⧆P) | 1.
Proof. rewrite /IntoRelevantP. by rewrite relevant_affine. Qed.
Global Instance into_relevantP_relevant P :
RelevantP P → IntoRelevantP P P | 100.
Proof. done. Qed.
Global Instance into_later_default P : IntoLater P P | 1000.
Proof. apply later_intro. Qed.
Global Instance into_later_later P : IntoLater (▷ P) P.
Proof. done. Qed.
Global Instance into_later_and P1 P2 Q1 Q2 :
IntoLater P1 Q1 → IntoLater P2 Q2 → IntoLater (P1 ∧ P2) (Q1 ∧ Q2).
Proof. intros ??; red. by rewrite later_and; apply and_mono. Qed.
Global Instance into_later_or P1 P2 Q1 Q2 :
IntoLater P1 Q1 → IntoLater P2 Q2 → IntoLater (P1 ∨ P2) (Q1 ∨ Q2).
Proof. intros ??; red. by rewrite later_or; apply or_mono. Qed.
Global Instance into_later_sep P1 P2 Q1 Q2 :
IntoLater P1 Q1 → IntoLater P2 Q2 → IntoLater (P1 ★ P2) (Q1 ★ Q2).
Proof. intros ??; red. by rewrite later_sep; apply sep_mono. Qed.
Global Instance into_later_affine P: IntoLater (⧆▷ P) (⧆P).
Proof. red. by apply affine_later_1. Qed.
Global Instance from_later_later P : FromLater (▷ P) P.
Proof. done. Qed.
Global Instance from_later_and P1 P2 Q1 Q2 :
FromLater P1 Q1 → FromLater P2 Q2 → FromLater (P1 ∧ P2) (Q1 ∧ Q2).
Proof. intros ??; red. by rewrite later_and; apply and_mono. Qed.
Global Instance from_later_or P1 P2 Q1 Q2 :
FromLater P1 Q1 → FromLater P2 Q2 → FromLater (P1 ∨ P2) (Q1 ∨ Q2).
Proof. intros ??; red. by rewrite later_or; apply or_mono. Qed.
Global Instance from_later_sep P1 P2 Q1 Q2 :
FromLater P1 Q1 → FromLater P2 Q2 → FromLater (P1 ★ P2) (Q1 ★ Q2).
Proof. intros ??; red. by rewrite later_sep; apply sep_mono. Qed.
Global Instance into_wand_wand P Q : IntoWand (P -★ Q) P Q.
Proof. done. Qed.
Global Instance into_wand_wand_iff_l P Q : IntoWand ((P -★ Q) ∧ (Q -★ P)) P Q.
Proof. by apply and_elim_l'. Qed.
Global Instance into_wand_wand_iff_r P Q : IntoWand ((P -★ Q) ∧ (Q -★ P)) Q P.
Proof. by apply and_elim_r'. Qed.
Global Instance into_wand_always R P Q : IntoWand R P Q → IntoWand (□ R) P Q.
Proof. rewrite /IntoWand⇒ →. apply relevant_elim. Qed.
Global Instance into_wand_affine R P Q : IntoWand R P Q → IntoWand (⧆ R) P Q.
Proof. rewrite /IntoWand⇒ →. apply affine_elim. Qed.
Global Instance from_and_and P1 P2 : FromAnd (P1 ∧ P2) P1 P2.
Proof. done. Qed.
Global Instance from_and_sep_relevant_l P1 P2 :
RelevantP P1 → FromAnd (P1 ★ P2) P1 P2 | 9.
Proof. intros. by rewrite /FromAnd relevant_and_sep_l_1. Qed.
Global Instance from_and_sep_relevant_r P1 P2 :
RelevantP P2 → FromAnd (P1 ★ P2) P1 P2 | 10.
Proof. intros. by rewrite /FromAnd relevant_and_sep_r_1. Qed.
Global Instance from_and_always P Q1 Q2 :
FromAnd P Q1 Q2 → FromAnd (□ P) (□ Q1) (□ Q2).
Proof. rewrite /FromAnd⇒ <-. by rewrite relevant_and. Qed.
Global Instance from_and_later P Q1 Q2 :
FromAnd P Q1 Q2 → FromAnd (▷ P) (▷ Q1) (▷ Q2).
Proof. rewrite /FromAnd⇒ <-. by rewrite later_and. Qed.
Global Instance from_sep_sep P1 P2 : FromSep (P1 ★ P2) P1 P2 | 100.
Proof. done. Qed.
Global Instance from_sep_relevant P Q1 Q2 :
FromSep P Q1 Q2 → FromSep (□ P) (□ Q1) (□ Q2).
Proof. rewrite /FromSep⇒ <-. by rewrite relevant_sep. Qed.
Global Instance from_sep_affine P Q1 Q2 :
FromSep P Q1 Q2 → FromSep (⧆ P) (⧆ Q1) (⧆ Q2).
Proof. by rewrite /FromSep sep_affine_1⇒ →. Qed.
Global Instance from_sep_later P Q1 Q2 :
FromSep P Q1 Q2 → FromSep (▷ P) (▷ Q1) (▷ Q2).
Proof. rewrite /FromSep⇒ <-. by rewrite later_sep. Qed.
Global Instance from_sep_ownM (a b : M) :
FromSep (uPred_ownM (a ⋅ b)) (uPred_ownM a) (uPred_ownM b) | 99.
Proof. by rewrite /FromSep ownM_op. Qed.
Global Instance into_op_op {A : cmraT} (a b : A) : IntoOp (a ⋅ b) a b.
Proof. by rewrite /IntoOp. Qed.
Global Instance into_op_relevant {A : cmraT} (a : A) :
Persistent a → IntoOp a a a.
Proof. intros; apply (persistent_dup a). Qed.
Global Instance into_op_pair {A B : cmraT} (a b1 b2 : A) (a' b1' b2' : B) :
IntoOp a b1 b2 → IntoOp a' b1' b2' →
IntoOp (a,a') (b1,b1') (b2,b2').
Proof. by constructor. Qed.
Global Instance into_op_Some {A : cmraT} (a : A) b1 b2 :
IntoOp a b1 b2 → IntoOp (Some a) (Some b1) (Some b2).
Proof. by constructor. Qed.
Lemma into_sep_spatial P Q1 Q2 : (P ⊢ Q1 ★ Q2) → IntoSep false P Q1 Q2.
Proof. simpl=>->; by done. Qed.
Lemma into_sep_relevant P Q1 Q2 `{!RelevantP Q1, !RelevantP Q2}:
(P ⊢ Q1 ★ Q2) → IntoSep true P Q1 Q2.
Proof. simpl=>->. by rewrite -relevant_sep' (relevant_relevant' Q1) (relevant_relevant' Q2). Qed.
Lemma into_sep_affine P Q1 Q2 `{!AffineP Q1, !AffineP Q2}:
(P ⊢ Q1 ★ Q2) → IntoSep false (⧆P) Q1 Q2.
Proof. simpl=>->. by rewrite -sep_affine_distrib ?affine_elim. Qed.
Lemma into_sep_affine_later P Q1 Q2 `{!AffineP Q1, !AffineP Q2}:
(P ⊢ Q1 ★ Q2) → IntoSep false (⧆▷P) (⧆▷Q1) (⧆▷Q2).
Proof. simpl=>->. by apply affine_later_distrib'; auto. Qed.
Global Instance into_sep_sep P Q : IntoSep false (P ★ Q) P Q.
Proof. by rewrite /IntoSep. Qed.
Global Instance into_sep_sep' P Q :
RelevantP P → RelevantP Q → IntoSep true (P ★ Q) P Q.
Proof. intros; by rewrite /IntoSep; apply into_sep_relevant. Qed.
Global Instance into_sep_ownM (a b1 b2 : M) :
IntoOp a b1 b2 →
IntoSep false (uPred_ownM a) (uPred_ownM b1) (uPred_ownM b2).
Proof.
rewrite /IntoOp /IntoSep⇒ →. by rewrite ownM_op.
Qed.
Global Instance into_sep_and P Q : IntoSep true (P ∧ Q) P Q.
Proof. simpl. rewrite relevant_sep_dup'_1. rewrite {1}and_elim_l and_elim_r //=. Qed.
Global Instance into_sep_and_relevant_l P Q :
RelevantP P → IntoSep false (P ∧ Q) P Q.
Proof. intros; red. by rewrite -(relevant_relevant' P) relevant_and_sep_l_1. Qed.
Global Instance into_sep_and_relevant_r P Q :
RelevantP Q → IntoSep false (P ∧ Q) P Q.
Proof. intros; red. by rewrite ?(comm _ P) -(relevant_relevant' Q) relevant_and_sep_l_1. Qed.
Global Instance into_sep_later P Q1 Q2 :
IntoSep false P Q1 Q2 → IntoSep false (▷ P) (▷ Q1) (▷ Q2).
Proof. rewrite /= ⇒ HP. by rewrite -later_sep HP. Qed.
Global Instance into_sep_affine' P Q:
AffineP P → AffineP Q → classes.IntoSep false (⧆(P ★ Q)) (P) (Q).
Proof. intros; by apply into_sep_affine. Qed.
Global Instance into_sep_affine_later' P Q:
AffineP P → AffineP Q → classes.IntoSep false (⧆▷(P ★ Q)) (⧆▷P) (⧆▷Q).
Proof. intros; by apply into_sep_affine_later. Qed.
Global Instance frame_here R : Frame R R Emp.
Proof. by rewrite /Frame right_id. Qed.
Class MakeSep (P Q PQ : uPred M) := make_sep : P ★ Q ⊣⊢ PQ.
Global Instance make_sep_true_l P : MakeSep Emp P P.
Proof. by rewrite /MakeSep left_id. Qed.
Global Instance make_sep_true_r P : MakeSep P Emp P.
Proof. by rewrite /MakeSep right_id. Qed.
Global Instance make_sep_default P Q : MakeSep P Q (P ★ Q) | 100.
Proof. done. Qed.
Global Instance frame_sep_l R P1 P2 Q Q' :
Frame R P1 Q → MakeSep Q P2 Q' → Frame R (P1 ★ P2) Q' | 9.
Proof. rewrite /Frame /MakeSep ⇒ <- <-. by rewrite assoc. Qed.
Global Instance frame_sep_r R P1 P2 Q Q' :
Frame R P2 Q → MakeSep P1 Q Q' → Frame R (P1 ★ P2) Q' | 10.
Proof. rewrite /Frame /MakeSep ⇒ <- <-. solve_sep_entails. Qed.
Class MakeAnd (P Q PQ : uPred M) := make_and : P ∧ Q ⊣⊢ PQ.
Global Instance make_and_true_l P : MakeAnd True P P.
Proof. by rewrite /MakeAnd left_id. Qed.
Global Instance make_and_true_r P : MakeAnd P True P.
Proof. by rewrite /MakeAnd right_id. Qed.
Global Instance make_and_default P Q : MakeSep P Q (P ★ Q) | 100.
Proof. done. Qed.
Class MakeOr (P Q PQ : uPred M) := make_or : P ∨ Q ⊣⊢ PQ.
Global Instance make_or_true_l P : MakeOr True P True.
Proof. by rewrite /MakeOr left_absorb. Qed.
Global Instance make_or_true_r P : MakeOr P True True.
Proof. by rewrite /MakeOr right_absorb. Qed.
Global Instance make_or_default P Q : MakeOr P Q (P ∨ Q) | 100.
Proof. done. Qed.
Global Instance frame_or R P1 P2 Q1 Q2 Q :
Frame R P1 Q1 → Frame R P2 Q2 → MakeOr Q1 Q2 Q → Frame R (P1 ∨ P2) Q.
Proof. rewrite /Frame /MakeOr ⇒ <- <- <-. by rewrite -sep_or_l. Qed.
Global Instance frame_wand R P1 P2 Q2 :
Frame R P2 Q2 → Frame R (P1 -★ P2) (P1 -★ Q2).
Proof.
rewrite /Frame⇒ ?. apply wand_intro_l.
by rewrite assoc (comm _ P1) -assoc wand_elim_r.
Qed.
Class MakeLater (P lP : uPred M) := make_later : ▷ P ⊣⊢ lP.
Global Instance make_later_true : MakeLater True True.
Proof. by rewrite /MakeLater later_True. Qed.
Global Instance make_later_default P : MakeLater P (▷ P) | 100.
Proof. done. Qed.
Global Instance frame_later R P Q Q' :
Frame R P Q → MakeLater Q Q' → Frame R (▷ P) Q'.
Proof.
rewrite /Frame /MakeLater=><- <-. by rewrite later_sep -(later_intro R).
Qed.
Global Instance frame_exist {A} R (Φ Ψ : A → uPred M) :
(∀ a, Frame R (Φ a) (Ψ a)) → Frame R (∃ x, Φ x) (∃ x, Ψ x).
Proof. rewrite /Frame⇒ ?. by rewrite sep_exist_l; apply exist_mono. Qed.
Global Instance frame_forall {A} R (Φ Ψ : A → uPred M) :
(∀ a, Frame R (Φ a) (Ψ a)) → Frame R (∀ x, Φ x) (∀ x, Ψ x).
Proof. rewrite /Frame⇒ ?. by rewrite sep_forall_l; apply forall_mono. Qed.
Global Instance from_or_or P1 P2 : FromOr (P1 ∨ P2) P1 P2.
Proof. done. Qed.
Global Instance into_or_or P Q : IntoOr (P ∨ Q) P Q.
Proof. done. Qed.
Global Instance into_or_later P Q1 Q2 :
IntoOr P Q1 Q2 → IntoOr (▷ P) (▷ Q1) (▷ Q2).
Proof. rewrite /IntoOr=>->. by rewrite later_or. Qed.
Global Instance from_exist_exist {A} (Φ: A → uPred M): FromExist (∃ a, Φ a) Φ.
Proof. done. Qed.
Global Instance into_exist_exist {A} (Φ : A → uPred M) : IntoExist (∃ a, Φ a) Φ.
Proof. done. Qed.
Global Instance into_exist_later {A} P (Φ : A → uPred M) :
IntoExist P Φ → Inhabited A → IntoExist (▷ P) (λ a, ▷ (Φ a))%I.
Proof. rewrite /IntoExist⇒ HP ?. by rewrite HP later_exist. Qed.
Global Instance into_exist_relevant {A} P (Φ : A → uPred M) :
IntoExist P Φ → IntoExist (□ P) (λ a, □ (Φ a))%I.
Proof. rewrite /IntoExist⇒ HP. by rewrite HP relevant_exist. Qed.
Global Instance into_exist_affine {A} P (Φ : A → uPred M) :
IntoExist P Φ → IntoExist (⧆ P) (λ a, ⧆ (Φ a))%I.
Proof. rewrite /IntoExist⇒ HP. by rewrite HP affine_exist. Qed.
End classes.