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

make entailment notation look like entailment

parent 0c0ee757
...@@ -133,11 +133,11 @@ Lemma to_agree_car n (x : agree A) : ✓{n} x → to_agree (x n) ≡{n}≡ x. ...@@ -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. Proof. intros [??]; split; naive_solver eauto using agree_valid_le. Qed.
(** Internalized properties *) (** 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. Proof.
uPred.unseal. do 2 split. by intros [? Hv]; apply (Hv n). apply: to_agree_ne. uPred.unseal. do 2 split. by intros [? Hv]; apply (Hv n). apply: to_agree_ne.
Qed. 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. Proof. uPred.unseal; split=> r n _ ?; by apply: agree_op_inv. Qed.
End agree. End agree.
......
...@@ -144,14 +144,14 @@ Qed. ...@@ -144,14 +144,14 @@ Qed.
(** Internalized properties *) (** Internalized properties *)
Lemma auth_equivI {M} (x y : auth A) : 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. Proof. by uPred.unseal. Qed.
Lemma auth_validI {M} (x : auth A) : 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 | Excl a => ( b, a own x b) a
| ExclUnit => own x | ExclUnit => own x
| ExclBot => False | ExclBot => False
end : uPred M)%I. end : uPred M).
Proof. uPred.unseal. by destruct x as [[]]. Qed. Proof. uPred.unseal. by destruct x as [[]]. Qed.
(** The notations ◯ and ● only work for CMRAs with an empty element. So, in (** The notations ◯ and ● only work for CMRAs with an empty element. So, in
......
...@@ -145,16 +145,16 @@ Qed. ...@@ -145,16 +145,16 @@ Qed.
(** Internalized properties *) (** Internalized properties *)
Lemma excl_equivI {M} (x y : excl A) : 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 | Excl a, Excl b => a b
| ExclUnit, ExclUnit | ExclBot, ExclBot => True | ExclUnit, ExclUnit | ExclBot, ExclBot => True
| _, _ => False | _, _ => False
end : uPred M)%I. end : uPred M).
Proof. Proof.
uPred.unseal. do 2 split. by destruct 1. by destruct x, y; try constructor. uPred.unseal. do 2 split. by destruct 1. by destruct x, y; try constructor.
Qed. Qed.
Lemma excl_validI {M} (x : excl A) : 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. Proof. uPred.unseal. by destruct x. Qed.
(** ** Local updates *) (** ** Local updates *)
......
...@@ -170,9 +170,9 @@ Global Instance map_cmra_discrete : CMRADiscrete A → CMRADiscrete mapR. ...@@ -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. Proof. split; [apply _|]. intros m ? i. by apply: cmra_discrete_valid. Qed.
(** Internalized properties *) (** 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. 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. Proof. by uPred.unseal. Qed.
End cmra. End cmra.
......
...@@ -190,17 +190,17 @@ Proof. intros. by apply frac_validN_inv_l with 0 a, cmra_valid_validN. Qed. ...@@ -190,17 +190,17 @@ Proof. intros. by apply frac_validN_inv_l with 0 a, cmra_valid_validN. Qed.
(** Internalized properties *) (** Internalized properties *)
Lemma frac_equivI {M} (x y : frac A) : 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 | Frac q1 a, Frac q2 b => q1 = q2 a b
| FracUnit, FracUnit => True | FracUnit, FracUnit => True
| _, _ => False | _, _ => False
end : uPred M)%I. end : uPred M).
Proof. Proof.
uPred.unseal; do 2 split; first by destruct 1. uPred.unseal; do 2 split; first by destruct 1.
by destruct x, y; destruct 1; try constructor. by destruct x, y; destruct 1; try constructor.
Qed. Qed.
Lemma frac_validI {M} (x : frac A) : 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. Proof. uPred.unseal. by destruct x. Qed.
(** ** Local updates *) (** ** Local updates *)
......
...@@ -170,9 +170,9 @@ Section iprod_cmra. ...@@ -170,9 +170,9 @@ Section iprod_cmra.
Qed. Qed.
(** Internalized properties *) (** 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. 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. Proof. by uPred.unseal. Qed.
(** Properties of iprod_insert. *) (** Properties of iprod_insert. *)
......
...@@ -138,14 +138,14 @@ Proof. by destruct mx, my; inversion_clear 1. Qed. ...@@ -138,14 +138,14 @@ Proof. by destruct mx, my; inversion_clear 1. Qed.
(** Internalized properties *) (** Internalized properties *)
Lemma option_equivI {M} (x y : option A) : 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 | Some a, Some b => a b | None, None => True | _, _ => False
end : uPred M)%I. end : uPred M).
Proof. Proof.
uPred.unseal. do 2 split. by destruct 1. by destruct x, y; try constructor. uPred.unseal. do 2 split. by destruct 1. by destruct x, y; try constructor.
Qed. Qed.
Lemma option_validI {M} (x : option A) : 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. Proof. uPred.unseal. by destruct x. Qed.
(** Updates *) (** Updates *)
......
...@@ -269,8 +269,10 @@ Definition uPred_valid {M A} := proj1_sig uPred_valid_aux M A. ...@@ -269,8 +269,10 @@ Definition uPred_valid {M A} := proj1_sig uPred_valid_aux M A.
Definition uPred_valid_eq : Definition uPred_valid_eq :
@uPred_valid = @uPred_valid_def := proj2_sig uPred_valid_aux. @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 "P ⊢ Q" := (uPred_entails P%I Q%I) (at level 70) : C_scope.
Notation "(⊑)" := uPred_entails (only parsing) : 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) Notation "■ φ" := (uPred_const φ%C%type)
(at level 20, right associativity) : uPred_scope. (at level 20, right associativity) : uPred_scope.
Notation "x = y" := (uPred_const (x%C%type = y%C%type)) : 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. ...@@ -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. Definition uPred_iff {M} (P Q : uPred M) : uPred M := ((P Q) (Q P))%I.
Infix "↔" := uPred_iff : uPred_scope. 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 {_} _ {_}. Arguments timelessP {_} _ {_}.
(* TODO: Derek suggested to call such assertions "persistent", which we now (* TODO: Derek suggested to call such assertions "persistent", which we now
do in the paper. *) 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 {_} _ {_}. Arguments always_stable {_} _ {_}.
Module uPred. Module uPred.
...@@ -318,7 +320,8 @@ Context {M : cmraT}. ...@@ -318,7 +320,8 @@ Context {M : cmraT}.
Implicit Types φ : Prop. Implicit Types φ : Prop.
Implicit Types P Q : uPred M. Implicit Types P Q : uPred M.
Implicit Types A : Type. 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 {_} !_ _ _ /. Arguments uPred_holds {_} !_ _ _ /.
Hint Immediate uPred_in_entails. Hint Immediate uPred_in_entails.
...@@ -328,31 +331,31 @@ Proof. ...@@ -328,31 +331,31 @@ Proof.
* by intros P; split=> x i. * by intros P; split=> x i.
* by intros P Q Q' HP HQ; split=> x i ??; apply HQ, HP. * by intros P Q Q' HP HQ; split=> x i ??; apply HQ, HP.
Qed. 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. 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. Proof.
split; [|by intros [??]; apply (anti_symm ())]. split; [|by intros [??]; apply (anti_symm ())].
intros HPQ; split; split=> x i; apply HPQ. intros HPQ; split; split=> x i; apply HPQ.
Qed. Qed.
Lemma equiv_entails P Q : P Q P Q. Lemma equiv_entails P Q : P Q P Q.
Proof. apply equiv_spec. Qed. 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. Proof. apply equiv_spec. Qed.
Global Instance entails_proper : Global Instance entails_proper :
Proper (() ==> () ==> iff) (() : relation (uPred M)). Proper (() ==> () ==> iff) (() : relation (uPred M)).
Proof. Proof.
move => P1 P2 /equiv_spec [HP1 HP2] Q1 Q2 /equiv_spec [HQ1 HQ2]; split; intros. move => P1 P2 /equiv_spec [HP1 HP2] Q1 Q2 /equiv_spec [HQ1 HQ2]; split; intros.
- by trans P1; [|trans Q1]. - by trans P1; [|trans Q1].
- by trans P2; [|trans Q2]. - by trans P2; [|trans Q2].
Qed. 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. 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. Proof. by intros ? <-. Qed.
(** Non-expansiveness and setoid morphisms *) (** 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. 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). Global Instance and_ne n : Proper (dist n ==> dist n ==> dist n) (@uPred_and M).
Proof. Proof.
...@@ -360,14 +363,14 @@ Proof. ...@@ -360,14 +363,14 @@ Proof.
split; (intros [??]; split; [by apply HP|by apply HQ]). split; (intros [??]; split; [by apply HP|by apply HQ]).
Qed. Qed.
Global Instance and_proper : 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). Global Instance or_ne n : Proper (dist n ==> dist n ==> dist n) (@uPred_or M).
Proof. Proof.
intros P P' HP Q Q' HQ; split=> x n' ??. intros P P' HP Q Q' HQ; split=> x n' ??.
unseal; split; (intros [?|?]; [left; by apply HP|right; by apply HQ]). unseal; split; (intros [?|?]; [left; by apply HP|right; by apply HQ]).
Qed. Qed.
Global Instance or_proper : Global Instance or_proper :
Proper (() ==> () ==> ()) (@uPred_or M) := ne_proper_2 _. Proper (() ==> () ==> ()) (@uPred_or M) := ne_proper_2 _.
Global Instance impl_ne n : Global Instance impl_ne n :
Proper (dist n ==> dist n ==> dist n) (@uPred_impl M). Proper (dist n ==> dist n ==> dist n) (@uPred_impl M).
Proof. Proof.
...@@ -375,7 +378,7 @@ Proof. ...@@ -375,7 +378,7 @@ Proof.
unseal; split; intros HPQ x' n'' ????; apply HQ, HPQ, HP; auto. unseal; split; intros HPQ x' n'' ????; apply HQ, HPQ, HP; auto.
Qed. Qed.
Global Instance impl_proper : 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). Global Instance sep_ne n : Proper (dist n ==> dist n ==> dist n) (@uPred_sep M).
Proof. Proof.
intros P P' HP Q Q' HQ; split=> n' x ??. intros P P' HP Q Q' HQ; split=> n' x ??.
...@@ -384,7 +387,7 @@ Proof. ...@@ -384,7 +387,7 @@ Proof.
eauto using cmra_validN_op_l, cmra_validN_op_r. eauto using cmra_validN_op_l, cmra_validN_op_r.
Qed. Qed.
Global Instance sep_proper : Global Instance sep_proper :
Proper (() ==> () ==> ()) (@uPred_sep M) := ne_proper_2 _. Proper (() ==> () ==> ()) (@uPred_sep M) := ne_proper_2 _.
Global Instance wand_ne n : Global Instance wand_ne n :
Proper (dist n ==> dist n ==> dist n) (@uPred_wand M). Proper (dist n ==> dist n ==> dist n) (@uPred_wand M).
Proof. Proof.
...@@ -392,7 +395,7 @@ Proof. ...@@ -392,7 +395,7 @@ Proof.
apply HQ, HPQ, HP; eauto using cmra_validN_op_r. apply HQ, HPQ, HP; eauto using cmra_validN_op_r.
Qed. Qed.
Global Instance wand_proper : 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 : Global Instance eq_ne (A : cofeT) n :
Proper (dist n ==> dist n ==> dist n) (@uPred_eq M A). Proper (dist n ==> dist n ==> dist n) (@uPred_eq M A).
Proof. Proof.
...@@ -401,14 +404,14 @@ Proof. ...@@ -401,14 +404,14 @@ Proof.
* by rewrite (dist_le _ _ _ _ Hx) ?(dist_le _ _ _ _ Hy); auto. * by rewrite (dist_le _ _ _ _ Hx) ?(dist_le _ _ _ _ Hy); auto.
Qed. Qed.
Global Instance eq_proper (A : cofeT) : 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 : Global Instance forall_ne A n :
Proper (pointwise_relation _ (dist n) ==> dist n) (@uPred_forall M A). Proper (pointwise_relation _ (dist n) ==> dist n) (@uPred_forall M A).
Proof. Proof.
by intros Ψ1 Ψ2 HΨ; unseal; split=> n' x; split; intros HP a; apply HΨ. by intros Ψ1 Ψ2 HΨ; unseal; split=> n' x; split; intros HP a; apply HΨ.
Qed. Qed.
Global Instance forall_proper A : Global Instance forall_proper A :
Proper (pointwise_relation _ () ==> ()) (@uPred_forall M A). Proper (pointwise_relation _ () ==> ()) (@uPred_forall M A).
Proof. Proof.
by intros Ψ1 Ψ2 HΨ; unseal; split=> n' x; split; intros HP a; apply HΨ. by intros Ψ1 Ψ2 HΨ; unseal; split=> n' x; split; intros HP a; apply HΨ.
Qed. Qed.
...@@ -419,7 +422,7 @@ Proof. ...@@ -419,7 +422,7 @@ Proof.
unseal; split=> n' x ??; split; intros [a ?]; exists a; by apply HΨ. unseal; split=> n' x ??; split; intros [a ?]; exists a; by apply HΨ.
Qed. Qed.
Global Instance exist_proper A : Global Instance exist_proper A :
Proper (pointwise_relation _ () ==> ()) (@uPred_exist M A). Proper (pointwise_relation _ () ==> ()) (@uPred_exist M A).
Proof. Proof.
intros Ψ1 Ψ2 HΨ. intros Ψ1 Ψ2 HΨ.
unseal; split=> n' x ?; split; intros [a ?]; exists a; by apply HΨ. unseal; split=> n' x ?; split; intros [a ?]; exists a; by apply HΨ.
...@@ -430,20 +433,20 @@ Proof. ...@@ -430,20 +433,20 @@ Proof.
apply (HPQ n'); eauto using cmra_validN_S. apply (HPQ n'); eauto using cmra_validN_S.
Qed. Qed.
Global Instance later_proper : 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). Global Instance always_ne n : Proper (dist n ==> dist n) (@uPred_always M).
Proof. Proof.
intros P1 P2 HP. 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. Qed.
Global Instance always_proper : 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). Global Instance ownM_ne n : Proper (dist n ==> dist n) (@uPred_ownM M).
Proof. Proof.
intros a b Ha. intros a b Ha.
unseal; split=> n' x ? /=. by rewrite (dist_le _ _ _ _ Ha); last lia. unseal; split=> n' x ? /=. by rewrite (dist_le _ _ _ _ Ha); last lia.
Qed. 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 : Global Instance valid_ne {A : cmraT} n :
Proper (dist n ==> dist n) (@uPred_valid M A). Proper (dist n ==> dist n) (@uPred_valid M A).
Proof. Proof.
...@@ -451,252 +454,252 @@ Proof. ...@@ -451,252 +454,252 @@ Proof.
by rewrite (dist_le _ _ _ _ Ha); last lia. by rewrite (dist_le _ _ _ _ Ha); last lia.
Qed. Qed.
Global Instance valid_proper {A : cmraT} : 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). Global Instance iff_ne n : Proper (dist n ==> dist n ==> dist n) (@uPred_iff M).
Proof. unfold uPred_iff; solve_proper. Qed. Proof. unfold uPred_iff; solve_proper. Qed.
Global Instance iff_proper : Global Instance iff_proper :
Proper (() ==> () ==> ()) (@uPred_iff M) := ne_proper_2 _. Proper (() ==> () ==> ()) (@uPred_iff M) := ne_proper_2 _.
(** Introduction and elimination rules *) (** Introduction and elimination rules *)
Lemma const_intro φ P : φ P φ. Lemma const_intro φ P : φ P φ.
Proof. by intros ?; unseal; split. Qed. 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. Proof.
unseal; intros HQP HQR; split=> n x ??; apply HQR; first eapply HQP; eauto. unseal; intros HQP HQR; split=> n x ??; apply HQR; first eapply HQP; eauto.
Qed. Qed.
Lemma False_elim P : False P. Lemma False_elim P : False P.
Proof. by unseal; split=> n x ?. Qed. 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. 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. 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. 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. 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. 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. 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. Proof.
unseal; intros HQ; split=> n x ?? n' x' ????. unseal; intros HQ; split=> n x ?? n' x' ????.
apply HQ; naive_solver eauto using uPred_weaken. apply HQ; naive_solver eauto using uPred_weaken.
Qed. 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. 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. 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. 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. Proof. unseal; split=> n x ??; by exists a. Qed.
Lemma exist_elim {A} (Φ : A uPred M) Q : ( a, Φ a Q) ( a, Φ a)