Commit 462cc285 authored by Ralf Jung's avatar Ralf Jung

make entailment notation look like entailment

parent 0c0ee757
Pipeline #303 passed with stage
......@@ -133,11 +133,11 @@ Lemma to_agree_car n (x : agree A) : ✓{n} x → to_agree (x n) ≡{n}≡ x.
Proof. intros [??]; split; naive_solver eauto using agree_valid_le. Qed.
(** Internalized properties *)
Lemma agree_equivI {M} a b : (to_agree a to_agree b)%I (a b : uPred M)%I.
Lemma agree_equivI {M} a b : (to_agree a to_agree b) (a b : uPred M).
Proof.
uPred.unseal. do 2 split. by intros [? Hv]; apply (Hv n). apply: to_agree_ne.
Qed.
Lemma agree_validI {M} x y : (x y) (x y : uPred M).
Lemma agree_validI {M} x y : (x y) (x y : uPred M).
Proof. uPred.unseal; split=> r n _ ?; by apply: agree_op_inv. Qed.
End agree.
......
......@@ -144,14 +144,14 @@ Qed.
(** Internalized properties *)
Lemma auth_equivI {M} (x y : auth A) :
(x y)%I (authoritative x authoritative y own x own y : uPred M)%I.
(x y) (authoritative x authoritative y own x own y : uPred M).
Proof. by uPred.unseal. Qed.
Lemma auth_validI {M} (x : auth A) :
( x)%I (match authoritative x with
( x) (match authoritative x with
| Excl a => ( b, a own x b) a
| ExclUnit => own x
| ExclBot => False
end : uPred M)%I.
end : uPred M).
Proof. uPred.unseal. by destruct x as [[]]. Qed.
(** The notations ◯ and ● only work for CMRAs with an empty element. So, in
......
......@@ -145,16 +145,16 @@ Qed.
(** Internalized properties *)
Lemma excl_equivI {M} (x y : excl A) :
(x y)%I (match x, y with
(x y) (match x, y with
| Excl a, Excl b => a b
| ExclUnit, ExclUnit | ExclBot, ExclBot => True
| _, _ => False
end : uPred M)%I.
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)%I (if x is ExclBot then False else True : uPred M)%I.
( x) (if x is ExclBot then False else True : uPred M).
Proof. uPred.unseal. by destruct x. Qed.
(** ** Local updates *)
......
......@@ -170,9 +170,9 @@ Global Instance map_cmra_discrete : CMRADiscrete A → CMRADiscrete mapR.
Proof. split; [apply _|]. intros m ? i. by apply: cmra_discrete_valid. Qed.
(** Internalized properties *)
Lemma map_equivI {M} m1 m2 : (m1 m2)%I ( i, m1 !! i m2 !! i : uPred M)%I.
Lemma map_equivI {M} m1 m2 : (m1 m2) ( i, m1 !! i m2 !! i : uPred M).
Proof. by uPred.unseal. Qed.
Lemma map_validI {M} m : ( m)%I ( i, (m !! i) : uPred M)%I.
Lemma map_validI {M} m : ( m) ( i, (m !! i) : uPred M).
Proof. by uPred.unseal. Qed.
End cmra.
......
......@@ -190,17 +190,17 @@ Proof. intros. by apply frac_validN_inv_l with 0 a, cmra_valid_validN. Qed.
(** Internalized properties *)
Lemma frac_equivI {M} (x y : frac A) :
(x y)%I (match x, y with
(x y) (match x, y with
| Frac q1 a, Frac q2 b => q1 = q2 a b
| FracUnit, FracUnit => True
| _, _ => False
end : uPred M)%I.
end : uPred M).
Proof.
uPred.unseal; do 2 split; first by destruct 1.
by destruct x, y; destruct 1; try constructor.
Qed.
Lemma frac_validI {M} (x : frac A) :
( x)%I (if x is Frac q a then (q 1)%Qc a else True : uPred M)%I.
( x) (if x is Frac q a then (q 1)%Qc a else True : uPred M).
Proof. uPred.unseal. by destruct x. Qed.
(** ** Local updates *)
......
......@@ -170,9 +170,9 @@ Section iprod_cmra.
Qed.
(** Internalized properties *)
Lemma iprod_equivI {M} g1 g2 : (g1 g2)%I ( i, g1 i g2 i : uPred M)%I.
Lemma iprod_equivI {M} g1 g2 : (g1 g2) ( i, g1 i g2 i : uPred M).
Proof. by uPred.unseal. Qed.
Lemma iprod_validI {M} g : ( g)%I ( i, g i : uPred M)%I.
Lemma iprod_validI {M} g : ( g) ( i, g i : uPred M).
Proof. by uPred.unseal. Qed.
(** Properties of iprod_insert. *)
......
......@@ -138,14 +138,14 @@ Proof. by destruct mx, my; inversion_clear 1. Qed.
(** Internalized properties *)
Lemma option_equivI {M} (x y : option A) :
(x y)%I (match x, y with
(x y) (match x, y with
| Some a, Some b => a b | None, None => True | _, _ => False
end : uPred M)%I.
end : uPred M).
Proof.
uPred.unseal. do 2 split. by destruct 1. by destruct x, y; try constructor.
Qed.
Lemma option_validI {M} (x : option A) :
( x)%I (match x with Some a => a | None => True end : uPred M)%I.
( x) (match x with Some a => a | None => True end : uPred M).
Proof. uPred.unseal. by destruct x. Qed.
(** Updates *)
......
......@@ -269,8 +269,10 @@ Definition uPred_valid {M A} := proj1_sig uPred_valid_aux M A.
Definition uPred_valid_eq :
@uPred_valid = @uPred_valid_def := proj2_sig uPred_valid_aux.
Notation "P ⊑ Q" := (uPred_entails P%I Q%I) (at level 70) : C_scope.
Notation "(⊑)" := uPred_entails (only parsing) : C_scope.
Notation "P ⊢ Q" := (uPred_entails P%I Q%I) (at level 70) : C_scope.
Notation "(⊢)" := uPred_entails (only parsing) : C_scope.
Notation "P ⊣⊢ Q" := (equiv (A:=uPred _) P%I Q%I) (at level 70) : C_scope.
Notation "(⊣⊢)" := (equiv (A:=uPred _)) (only parsing) : C_scope.
Notation "■ φ" := (uPred_const φ%C%type)
(at level 20, right associativity) : uPred_scope.
Notation "x = y" := (uPred_const (x%C%type = y%C%type)) : uPred_scope.
......@@ -299,11 +301,11 @@ Notation "✓ x" := (uPred_valid x) (at level 20) : uPred_scope.
Definition uPred_iff {M} (P Q : uPred M) : uPred M := ((P Q) (Q P))%I.
Infix "↔" := uPred_iff : uPred_scope.
Class TimelessP {M} (P : uPred M) := timelessP : P (P False).
Class TimelessP {M} (P : uPred M) := timelessP : P (P False).
Arguments timelessP {_} _ {_}.
(* TODO: Derek suggested to call such assertions "persistent", which we now
do in the paper. *)
Class AlwaysStable {M} (P : uPred M) := always_stable : P P.
Class AlwaysStable {M} (P : uPred M) := always_stable : P P.
Arguments always_stable {_} _ {_}.
Module uPred.
......@@ -318,7 +320,8 @@ Context {M : cmraT}.
Implicit Types φ : Prop.
Implicit Types P Q : uPred M.
Implicit Types A : Type.
Notation "P ⊑ Q" := (@uPred_entails M P%I Q%I). (* Force implicit argument M *)
Notation "P ⊢ Q" := (@uPred_entails M P%I Q%I). (* Force implicit argument M *)
Notation "P ⊣⊢ Q" := (equiv (A:=uPred M) P%I Q%I). (* Force implicit argument M *)
Arguments uPred_holds {_} !_ _ _ /.
Hint Immediate uPred_in_entails.
......@@ -328,31 +331,31 @@ Proof.
* by intros P; split=> x i.
* by intros P Q Q' HP HQ; split=> x i ??; apply HQ, HP.
Qed.
Global Instance: AntiSymm () (@uPred_entails M).
Global Instance: AntiSymm () (@uPred_entails M).
Proof. intros P Q HPQ HQP; split=> x n; by split; [apply HPQ|apply HQP]. Qed.
Lemma equiv_spec P Q : P Q P Q Q P.
Lemma equiv_spec P Q : P Q P Q Q P.
Proof.
split; [|by intros [??]; apply (anti_symm ())].
split; [|by intros [??]; apply (anti_symm ())].
intros HPQ; split; split=> x i; apply HPQ.
Qed.
Lemma equiv_entails P Q : P Q P Q.
Lemma equiv_entails P Q : P Q P Q.
Proof. apply equiv_spec. Qed.
Lemma equiv_entails_sym P Q : Q P P Q.
Lemma equiv_entails_sym P Q : Q P P Q.
Proof. apply equiv_spec. Qed.
Global Instance entails_proper :
Proper (() ==> () ==> iff) (() : relation (uPred M)).
Proper (() ==> () ==> iff) (() : relation (uPred M)).
Proof.
move => P1 P2 /equiv_spec [HP1 HP2] Q1 Q2 /equiv_spec [HQ1 HQ2]; split; intros.
- by trans P1; [|trans Q1].
- by trans P2; [|trans Q2].
Qed.
Lemma entails_equiv_l (P Q R : uPred M) : P Q Q R P R.
Lemma entails_equiv_l (P Q R : uPred M) : P Q Q R P R.
Proof. by intros ->. Qed.
Lemma entails_equiv_r (P Q R : uPred M) : P Q Q R P R.
Lemma entails_equiv_r (P Q R : uPred M) : P Q Q R P R.
Proof. by intros ? <-. Qed.
(** Non-expansiveness and setoid morphisms *)
Global Instance const_proper : Proper (iff ==> ()) (@uPred_const M).
Global Instance const_proper : Proper (iff ==> ()) (@uPred_const M).
Proof. intros φ1 φ2 Hφ. by unseal; split=> -[|n] ?; try apply Hφ. Qed.
Global Instance and_ne n : Proper (dist n ==> dist n ==> dist n) (@uPred_and M).
Proof.
......@@ -360,14 +363,14 @@ Proof.
split; (intros [??]; split; [by apply HP|by apply HQ]).
Qed.
Global Instance and_proper :
Proper (() ==> () ==> ()) (@uPred_and M) := ne_proper_2 _.
Proper (() ==> () ==> ()) (@uPred_and M) := ne_proper_2 _.
Global Instance or_ne n : Proper (dist n ==> dist n ==> dist n) (@uPred_or M).
Proof.
intros P P' HP Q Q' HQ; split=> x n' ??.
unseal; split; (intros [?|?]; [left; by apply HP|right; by apply HQ]).
Qed.
Global Instance or_proper :
Proper (() ==> () ==> ()) (@uPred_or M) := ne_proper_2 _.
Proper (() ==> () ==> ()) (@uPred_or M) := ne_proper_2 _.
Global Instance impl_ne n :
Proper (dist n ==> dist n ==> dist n) (@uPred_impl M).
Proof.
......@@ -375,7 +378,7 @@ Proof.
unseal; split; intros HPQ x' n'' ????; apply HQ, HPQ, HP; auto.
Qed.
Global Instance impl_proper :
Proper (() ==> () ==> ()) (@uPred_impl M) := ne_proper_2 _.
Proper (() ==> () ==> ()) (@uPred_impl M) := ne_proper_2 _.
Global Instance sep_ne n : Proper (dist n ==> dist n ==> dist n) (@uPred_sep M).
Proof.
intros P P' HP Q Q' HQ; split=> n' x ??.
......@@ -384,7 +387,7 @@ Proof.
eauto using cmra_validN_op_l, cmra_validN_op_r.
Qed.
Global Instance sep_proper :
Proper (() ==> () ==> ()) (@uPred_sep M) := ne_proper_2 _.
Proper (() ==> () ==> ()) (@uPred_sep M) := ne_proper_2 _.
Global Instance wand_ne n :
Proper (dist n ==> dist n ==> dist n) (@uPred_wand M).
Proof.
......@@ -392,7 +395,7 @@ Proof.
apply HQ, HPQ, HP; eauto using cmra_validN_op_r.
Qed.
Global Instance wand_proper :
Proper (() ==> () ==> ()) (@uPred_wand M) := ne_proper_2 _.
Proper (() ==> () ==> ()) (@uPred_wand M) := ne_proper_2 _.
Global Instance eq_ne (A : cofeT) n :
Proper (dist n ==> dist n ==> dist n) (@uPred_eq M A).
Proof.
......@@ -401,14 +404,14 @@ Proof.
* by rewrite (dist_le _ _ _ _ Hx) ?(dist_le _ _ _ _ Hy); auto.
Qed.
Global Instance eq_proper (A : cofeT) :
Proper (() ==> () ==> ()) (@uPred_eq M A) := ne_proper_2 _.
Proper (() ==> () ==> ()) (@uPred_eq M A) := ne_proper_2 _.
Global Instance forall_ne A n :
Proper (pointwise_relation _ (dist n) ==> dist n) (@uPred_forall M A).
Proof.
by intros Ψ1 Ψ2 HΨ; unseal; split=> n' x; split; intros HP a; apply HΨ.
Qed.
Global Instance forall_proper A :
Proper (pointwise_relation _ () ==> ()) (@uPred_forall M A).
Proper (pointwise_relation _ () ==> ()) (@uPred_forall M A).
Proof.
by intros Ψ1 Ψ2 HΨ; unseal; split=> n' x; split; intros HP a; apply HΨ.
Qed.
......@@ -419,7 +422,7 @@ Proof.
unseal; split=> n' x ??; split; intros [a ?]; exists a; by apply HΨ.
Qed.
Global Instance exist_proper A :
Proper (pointwise_relation _ () ==> ()) (@uPred_exist M A).
Proper (pointwise_relation _ () ==> ()) (@uPred_exist M A).
Proof.
intros Ψ1 Ψ2 HΨ.
unseal; split=> n' x ?; split; intros [a ?]; exists a; by apply HΨ.
......@@ -430,20 +433,20 @@ Proof.
apply (HPQ n'); eauto using cmra_validN_S.
Qed.
Global Instance later_proper :
Proper (() ==> ()) (@uPred_later M) := ne_proper _.
Proper (() ==> ()) (@uPred_later M) := ne_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.
Qed.
Global Instance always_proper :
Proper (() ==> ()) (@uPred_always M) := ne_proper _.
Proper (() ==> ()) (@uPred_always M) := ne_proper _.
Global Instance ownM_ne n : Proper (dist n ==> dist n) (@uPred_ownM M).
Proof.
intros a b Ha.
unseal; split=> n' x ? /=. by rewrite (dist_le _ _ _ _ Ha); last lia.
Qed.
Global Instance ownM_proper: Proper (() ==> ()) (@uPred_ownM M) := ne_proper _.
Global Instance ownM_proper: Proper (() ==> ()) (@uPred_ownM M) := ne_proper _.
Global Instance valid_ne {A : cmraT} n :
Proper (dist n ==> dist n) (@uPred_valid M A).
Proof.
......@@ -451,252 +454,252 @@ Proof.
by rewrite (dist_le _ _ _ _ Ha); last lia.
Qed.
Global Instance valid_proper {A : cmraT} :
Proper (() ==> ()) (@uPred_valid M A) := ne_proper _.
Proper (() ==> ()) (@uPred_valid M A) := ne_proper _.
Global Instance iff_ne n : Proper (dist n ==> dist n ==> dist n) (@uPred_iff M).
Proof. unfold uPred_iff; solve_proper. Qed.
Global Instance iff_proper :
Proper (() ==> () ==> ()) (@uPred_iff M) := ne_proper_2 _.
Proper (() ==> () ==> ()) (@uPred_iff M) := ne_proper_2 _.
(** Introduction and elimination rules *)
Lemma const_intro φ P : φ P φ.
Lemma const_intro φ P : φ P φ.
Proof. by intros ?; unseal; split. Qed.
Lemma const_elim φ Q R : Q φ (φ Q R) Q R.
Lemma const_elim φ Q R : Q φ (φ Q R) Q R.
Proof.
unseal; intros HQP HQR; split=> n x ??; apply HQR; first eapply HQP; eauto.
Qed.
Lemma False_elim P : False P.
Lemma False_elim P : False P.
Proof. by unseal; split=> n x ?. Qed.
Lemma and_elim_l P Q : (P Q) P.
Lemma and_elim_l P Q : (P Q) P.
Proof. by unseal; split=> n x ? [??]. Qed.
Lemma and_elim_r P Q : (P Q) Q.
Lemma and_elim_r P Q : (P Q) Q.
Proof. by unseal; split=> n x ? [??]. Qed.
Lemma and_intro P Q R : P Q P R P (Q R).
Lemma and_intro P Q R : P Q P R P (Q R).
Proof. intros HQ HR; unseal; split=> n x ??; by split; [apply HQ|apply HR]. Qed.
Lemma or_intro_l P Q : P (P Q).
Lemma or_intro_l P Q : P (P Q).
Proof. unseal; split=> n x ??; left; auto. Qed.
Lemma or_intro_r P Q : Q (P Q).
Lemma or_intro_r P Q : Q (P Q).
Proof. unseal; split=> n x ??; right; auto. Qed.
Lemma or_elim P Q R : P R Q R (P Q) R.
Lemma or_elim P Q R : P R Q R (P Q) R.
Proof. intros HP HQ; unseal; split=> n x ? [?|?]. by apply HP. by apply HQ. Qed.
Lemma impl_intro_r P Q R : (P Q) R P (Q R).
Lemma impl_intro_r P Q R : (P Q) R P (Q R).
Proof.
unseal; intros HQ; split=> n x ?? n' x' ????.
apply HQ; naive_solver eauto using uPred_weaken.
Qed.
Lemma impl_elim P Q R : P (Q R) P Q P R.
Lemma impl_elim P Q R : P (Q R) P Q P R.
Proof. by unseal; intros HP HP'; split=> n x ??; apply HP with n x, HP'. Qed.
Lemma forall_intro {A} P (Ψ : A uPred M): ( a, P Ψ a) P ( a, Ψ a).
Lemma forall_intro {A} P (Ψ : A uPred M): ( a, P Ψ a) P ( a, Ψ a).
Proof. unseal; intros HPΨ; split=> n x ?? a; by apply HPΨ. Qed.
Lemma forall_elim {A} {Ψ : A uPred M} a : ( a, Ψ a) Ψ a.
Lemma forall_elim {A} {Ψ : A uPred M} a : ( a, Ψ a) Ψ a.
Proof. unseal; split=> n x ? HP; apply HP. Qed.
Lemma exist_intro {A} {Ψ : A uPred M} a : Ψ a ( a, Ψ a).
Lemma exist_intro {A} {Ψ : A uPred M} a : Ψ a ( a, Ψ a).
Proof. unseal; split=> n x ??; by exists a. Qed.
Lemma exist_elim {A} (Φ : A uPred M) Q : ( a, Φ a Q) ( a, Φ a) Q.
Lemma exist_elim {A} (Φ : A uPred M) Q : ( a, Φ a Q) ( a, Φ a) Q.
Proof. unseal; intros HΦΨ; split=> n x ? [a ?]; by apply HΦΨ with a. Qed.
Lemma eq_refl {A : cofeT} (a : A) P : P (a a).
Lemma eq_refl {A : cofeT} (a : A) P : P (a a).
Proof. unseal; by split=> n x ??; simpl. Qed.
Lemma eq_rewrite {A : cofeT} a b (Ψ : A uPred M) P
`{HΨ : n, Proper (dist n ==> dist n) Ψ} : P (a b) P Ψ a P Ψ b.
`{HΨ : n, Proper (dist n ==> dist n) Ψ} : P (a b) P Ψ a P Ψ b.
Proof.
unseal; intros Hab Ha; split=> n x ??.
apply HΨ with n a; auto. by symmetry; apply Hab with x. by apply Ha.
Qed.
Lemma eq_equiv `{Empty M, !CMRAUnit M} {A : cofeT} (a b : A) :
True (a b) a b.
True (a b) a b.
Proof.
unseal=> Hab; apply equiv_dist; intros n; apply Hab with ; last done.
apply cmra_valid_validN, cmra_unit_valid.
Qed.
Lemma iff_equiv P Q : True (P Q) P Q.
Lemma iff_equiv P Q : True (P Q) P Q.
Proof.
rewrite /uPred_iff; unseal=> HPQ.
split=> n x ?; split; intros; by apply HPQ with n x.
Qed.
(* Derived logical stuff *)
Lemma True_intro P : P True.
Lemma True_intro P : P True.
Proof. by apply const_intro. Qed.
Lemma and_elim_l' P Q R : P R (P Q) R.
Lemma and_elim_l' P Q R : P R (P Q) R.
Proof. by rewrite and_elim_l. Qed.
Lemma and_elim_r' P Q R : Q R (P Q) R.
Lemma and_elim_r' P Q R : Q R (P Q) R.
Proof. by rewrite and_elim_r. Qed.
Lemma or_intro_l' P Q R : P Q P (Q R).
Lemma or_intro_l' P Q R : P Q P (Q R).
Proof. intros ->; apply or_intro_l. Qed.
Lemma or_intro_r' P Q R : P R P (Q R).
Lemma or_intro_r' P Q R : P R P (Q R).
Proof. intros ->; apply or_intro_r. Qed.
Lemma exist_intro' {A} P (Ψ : A uPred M) a : P Ψ a P ( a, Ψ a).
Lemma exist_intro' {A} P (Ψ : A uPred M) a : P Ψ a P ( a, Ψ a).
Proof. intros ->; apply exist_intro. Qed.
Lemma forall_elim' {A} P (Ψ : A uPred M) : P ( a, Ψ a) ( a, P Ψ a).
Lemma forall_elim' {A} P (Ψ : A uPred M) : P ( a, Ψ a) ( a, P Ψ a).
Proof. move=> HP a. by rewrite HP forall_elim. Qed.
Hint Resolve or_elim or_intro_l' or_intro_r'.
Hint Resolve and_intro and_elim_l' and_elim_r'.
Hint Immediate True_intro False_elim.
Lemma impl_intro_l P Q R : (Q P) R P (Q R).
Lemma impl_intro_l P Q R : (Q P) R P (Q R).
Proof. intros HR; apply impl_intro_r; rewrite -HR; auto. Qed.
Lemma impl_elim_l P Q : ((P Q) P) Q.
Lemma impl_elim_l P Q : ((P Q) P) Q.
Proof. apply impl_elim with P; auto. Qed.
Lemma impl_elim_r P Q : (P (P Q)) Q.
Lemma impl_elim_r P Q : (P (P Q)) Q.
Proof. apply impl_elim with P; auto. Qed.
Lemma impl_elim_l' P Q R : P (Q R) (P Q) R.
Lemma impl_elim_l' P Q R : P (Q R) (P Q) R.
Proof. intros; apply impl_elim with Q; auto. Qed.
Lemma impl_elim_r' P Q R : Q (P R) (P Q) R.
Lemma impl_elim_r' P Q R : Q (P R) (P Q) R.
Proof. intros; apply impl_elim with P; auto. Qed.
Lemma impl_entails P Q : True (P Q) P Q.
Lemma impl_entails P Q : True (P Q) P Q.
Proof. intros HPQ; apply impl_elim with P; rewrite -?HPQ; auto. Qed.
Lemma entails_impl P Q : (P Q) True (P Q).
Lemma entails_impl P Q : (P Q) True (P Q).
Proof. auto using impl_intro_l. Qed.
Lemma const_mono φ1 φ2 : (φ1 φ2) φ1 φ2.
Lemma const_mono φ1 φ2 : (φ1 φ2) φ1 φ2.
Proof. intros; apply const_elim with φ1; eauto using const_intro. Qed.
Lemma and_mono P P' Q Q' : P Q P' Q' (P P') (Q Q').
Lemma and_mono P P' Q Q' : P Q P' Q' (P P') (Q Q').
Proof. auto. Qed.
Lemma and_mono_l P P' Q : P Q (P P') (Q P').
Lemma and_mono_l P P' Q : P Q (P P') (Q P').
Proof. by intros; apply and_mono. Qed.
Lemma and_mono_r P P' Q' : P' Q' (P P') (P Q').
Lemma and_mono_r P P' Q' : P' Q' (P P') (P Q').
Proof. by apply and_mono. Qed.
Lemma or_mono P P' Q Q' : P Q P' Q' (P P') (Q Q').
Lemma or_mono P P' Q Q' : P Q P' Q' (P P') (Q Q').
Proof. auto. Qed.
Lemma or_mono_l P P' Q : P Q (P P') (Q P').
Lemma or_mono_l P P' Q : P Q (P P') (Q P').
Proof. by intros; apply or_mono. Qed.
Lemma or_mono_r P P' Q' : P' Q' (P P') (P Q').
Lemma or_mono_r P P' Q' : P' Q' (P P') (P Q').
Proof. by apply or_mono. Qed.
Lemma impl_mono P P' Q Q' : Q P P' Q' (P P') (Q Q').
Lemma impl_mono P P' Q Q' : Q P P' Q' (P P') (Q Q').
Proof.
intros HP HQ'; apply impl_intro_l; rewrite -HQ'.
apply impl_elim with P; eauto.
Qed.
Lemma forall_mono {A} (Φ Ψ : A uPred M) :
( a, Φ a Ψ a) ( a, Φ a) ( a, Ψ a).
( a, Φ a Ψ a) ( a, Φ a) ( a, Ψ a).
Proof.
intros HP. apply forall_intro=> a; rewrite -(HP a); apply forall_elim.
Qed.
Lemma exist_mono {A} (Φ Ψ : A uPred M) :
( a, Φ a Ψ a) ( a, Φ a) ( a, Ψ a).
( a, Φ a Ψ a) ( a, Φ a) ( a, Ψ a).
Proof. intros HΦ. apply exist_elim=> a; rewrite (HΦ a); apply exist_intro. Qed.
Global Instance const_mono' : Proper (impl ==> ()) (@uPred_const M).
Global Instance const_mono' : Proper (impl ==> ()) (@uPred_const M).
Proof. intros φ1 φ2; apply const_mono. Qed.
Global Instance and_mono' : Proper (() ==> () ==> ()) (@uPred_and M).
Global Instance and_mono' : Proper (() ==> () ==> ()) (@uPred_and M).
Proof. by intros P P' HP Q Q' HQ; apply and_mono. Qed.
Global Instance and_flip_mono' :
Proper (flip () ==> flip () ==> flip ()) (@uPred_and M).
Proper (flip () ==> flip () ==> flip ()) (@uPred_and M).
Proof. by intros P P' HP Q Q' HQ; apply and_mono. Qed.
Global Instance or_mono' : Proper (() ==> () ==> ()) (@uPred_or M).
Global Instance or_mono' : Proper (() ==> () ==> ()) (@uPred_or M).
Proof. by intros P P' HP Q Q' HQ; apply or_mono. Qed.
Global Instance or_flip_mono' :
Proper (flip () ==> flip () ==> flip ()) (@uPred_or M).
Proper (flip () ==> flip () ==> flip ()) (@uPred_or M).
Proof. by intros P P' HP Q Q' HQ; apply or_mono. Qed.
Global Instance impl_mono' :
Proper (flip () ==> () ==> ()) (@uPred_impl M).
Proper (flip () ==> (