primitive.v 25.4 KB
 Robbert Krebbers committed Oct 25, 2016 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 ``````From iris.base_logic Require Export upred. From iris.algebra Require Export updates. Local Hint Extern 1 (_ ≼ _) => etrans; [eassumption|]. Local Hint Extern 1 (_ ≼ _) => etrans; [|eassumption]. Local Hint Extern 10 (_ ≤ _) => omega. (** logical connectives *) Program Definition uPred_pure_def {M} (φ : Prop) : uPred M := {| uPred_holds n x := φ |}. Solve Obligations with done. Definition uPred_pure_aux : { x | x = @uPred_pure_def }. by eexists. Qed. Definition uPred_pure {M} := proj1_sig uPred_pure_aux M. Definition uPred_pure_eq : @uPred_pure = @uPred_pure_def := proj2_sig uPred_pure_aux. Instance uPred_inhabited M : Inhabited (uPred M) := populate (uPred_pure True). Program Definition uPred_and_def {M} (P Q : uPred M) : uPred M := {| uPred_holds n x := P n x ∧ Q n x |}. Solve Obligations with naive_solver eauto 2 with uPred_def. Definition uPred_and_aux : { x | x = @uPred_and_def }. by eexists. Qed. Definition uPred_and {M} := proj1_sig uPred_and_aux M. Definition uPred_and_eq: @uPred_and = @uPred_and_def := proj2_sig uPred_and_aux. Program Definition uPred_or_def {M} (P Q : uPred M) : uPred M := {| uPred_holds n x := P n x ∨ Q n x |}. Solve Obligations with naive_solver eauto 2 with uPred_def. Definition uPred_or_aux : { x | x = @uPred_or_def }. by eexists. Qed. Definition uPred_or {M} := proj1_sig uPred_or_aux M. Definition uPred_or_eq: @uPred_or = @uPred_or_def := proj2_sig uPred_or_aux. Program Definition uPred_impl_def {M} (P Q : uPred M) : uPred M := {| uPred_holds n x := ∀ n' x', x ≼ x' → n' ≤ n → ✓{n'} x' → P n' x' → Q n' x' |}. Next Obligation. intros M P Q n1 x1 x1' HPQ [x2 Hx1'] n2 x3 [x4 Hx3] ?; simpl in *. rewrite Hx3 (dist_le _ _ _ _ Hx1'); auto. intros ??. eapply HPQ; auto. exists (x2 ⋅ x4); by rewrite assoc. Qed. Next Obligation. intros M P Q [|n1] [|n2] x; auto with lia. Qed. Definition uPred_impl_aux : { x | x = @uPred_impl_def }. by eexists. Qed. Definition uPred_impl {M} := proj1_sig uPred_impl_aux M. Definition uPred_impl_eq : @uPred_impl = @uPred_impl_def := proj2_sig uPred_impl_aux. Program Definition uPred_forall_def {M A} (Ψ : A → uPred M) : uPred M := {| uPred_holds n x := ∀ a, Ψ a n x |}. Solve Obligations with naive_solver eauto 2 with uPred_def. Definition uPred_forall_aux : { x | x = @uPred_forall_def }. by eexists. Qed. Definition uPred_forall {M A} := proj1_sig uPred_forall_aux M A. Definition uPred_forall_eq : @uPred_forall = @uPred_forall_def := proj2_sig uPred_forall_aux. Program Definition uPred_exist_def {M A} (Ψ : A → uPred M) : uPred M := {| uPred_holds n x := ∃ a, Ψ a n x |}. Solve Obligations with naive_solver eauto 2 with uPred_def. Definition uPred_exist_aux : { x | x = @uPred_exist_def }. by eexists. Qed. Definition uPred_exist {M A} := proj1_sig uPred_exist_aux M A. Definition uPred_exist_eq: @uPred_exist = @uPred_exist_def := proj2_sig uPred_exist_aux. `````` Ralf Jung committed Nov 22, 2016 61 ``````Program Definition uPred_internal_eq_def {M} {A : ofeT} (a1 a2 : A) : uPred M := `````` Robbert Krebbers committed Oct 25, 2016 62 63 `````` {| uPred_holds n x := a1 ≡{n}≡ a2 |}. Solve Obligations with naive_solver eauto 2 using (dist_le (A:=A)). `````` Robbert Krebbers committed Oct 25, 2016 64 65 66 67 ``````Definition uPred_internal_eq_aux : { x | x = @uPred_internal_eq_def }. by eexists. Qed. Definition uPred_internal_eq {M A} := proj1_sig uPred_internal_eq_aux M A. Definition uPred_internal_eq_eq: @uPred_internal_eq = @uPred_internal_eq_def := proj2_sig uPred_internal_eq_aux. `````` Robbert Krebbers committed Oct 25, 2016 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 `````` Program Definition uPred_sep_def {M} (P Q : uPred M) : uPred M := {| uPred_holds n x := ∃ x1 x2, x ≡{n}≡ x1 ⋅ x2 ∧ P n x1 ∧ Q n x2 |}. Next Obligation. intros M P Q n x y (x1&x2&Hx&?&?) [z Hy]. exists x1, (x2 ⋅ z); split_and?; eauto using uPred_mono, cmra_includedN_l. by rewrite Hy Hx assoc. Qed. Next Obligation. intros M P Q n1 n2 x (x1&x2&Hx&?&?) ?; rewrite {1}(dist_le _ _ _ _ Hx) // =>?. exists x1, x2; cofe_subst; split_and!; eauto using dist_le, uPred_closed, cmra_validN_op_l, cmra_validN_op_r. Qed. Definition uPred_sep_aux : { x | x = @uPred_sep_def }. by eexists. Qed. Definition uPred_sep {M} := proj1_sig uPred_sep_aux M. Definition uPred_sep_eq: @uPred_sep = @uPred_sep_def := proj2_sig uPred_sep_aux. Program Definition uPred_wand_def {M} (P Q : uPred M) : uPred M := {| uPred_holds n x := ∀ n' x', n' ≤ n → ✓{n'} (x ⋅ x') → P n' x' → Q n' (x ⋅ x') |}. Next Obligation. intros M P Q n x1 x1' HPQ ? n3 x3 ???; simpl in *. apply uPred_mono with (x1 ⋅ x3); eauto using cmra_validN_includedN, cmra_monoN_r, cmra_includedN_le. Qed. Next Obligation. naive_solver. Qed. Definition uPred_wand_aux : { x | x = @uPred_wand_def }. by eexists. Qed. Definition uPred_wand {M} := proj1_sig uPred_wand_aux M. Definition uPred_wand_eq : @uPred_wand = @uPred_wand_def := proj2_sig uPred_wand_aux. Program Definition uPred_always_def {M} (P : uPred M) : uPred M := {| uPred_holds n x := P n (core x) |}. Next Obligation. intros M; naive_solver eauto using uPred_mono, @cmra_core_monoN. 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 : @uPred_always = @uPred_always_def := proj2_sig uPred_always_aux. Program Definition uPred_later_def {M} (P : uPred M) : uPred M := {| uPred_holds n x := match n return _ with 0 => True | S n' => P n' x end |}. Next Obligation. intros M P [|n] x1 x2; eauto using uPred_mono, cmra_includedN_S. Qed. Next Obligation. intros M P [|n1] [|n2] x; eauto using uPred_closed, cmra_validN_S with lia. Qed. Definition uPred_later_aux : { x | x = @uPred_later_def }. by eexists. Qed. Definition uPred_later {M} := proj1_sig uPred_later_aux M. Definition uPred_later_eq : @uPred_later = @uPred_later_def := proj2_sig uPred_later_aux. Program Definition uPred_ownM_def {M : ucmraT} (a : M) : uPred M := {| uPred_holds n x := a ≼{n} x |}. Next Obligation. intros M a n x1 x [a' Hx1] [x2 ->]. exists (a' ⋅ x2). by rewrite (assoc op) Hx1. Qed. Next Obligation. naive_solver eauto using cmra_includedN_le. Qed. Definition uPred_ownM_aux : { x | x = @uPred_ownM_def }. by eexists. Qed. Definition uPred_ownM {M} := proj1_sig uPred_ownM_aux M. Definition uPred_ownM_eq : @uPred_ownM = @uPred_ownM_def := proj2_sig uPred_ownM_aux. Program Definition uPred_cmra_valid_def {M} {A : cmraT} (a : A) : uPred M := {| uPred_holds n x := ✓{n} a |}. Solve Obligations with naive_solver eauto 2 using cmra_validN_le. Definition uPred_cmra_valid_aux : { x | x = @uPred_cmra_valid_def }. by eexists. Qed. Definition uPred_cmra_valid {M A} := proj1_sig uPred_cmra_valid_aux M A. Definition uPred_cmra_valid_eq : @uPred_cmra_valid = @uPred_cmra_valid_def := proj2_sig uPred_cmra_valid_aux. Program Definition uPred_bupd_def {M} (Q : uPred M) : uPred M := {| uPred_holds n x := ∀ k yf, k ≤ n → ✓{k} (x ⋅ yf) → ∃ x', ✓{k} (x' ⋅ yf) ∧ Q k x' |}. Next Obligation. intros M Q n x1 x2 HQ [x3 Hx] k yf Hk. rewrite (dist_le _ _ _ _ Hx); last lia. intros Hxy. destruct (HQ k (x3 ⋅ yf)) as (x'&?&?); [auto|by rewrite assoc|]. exists (x' ⋅ x3); split; first by rewrite -assoc. apply uPred_mono with x'; eauto using cmra_includedN_l. Qed. Next Obligation. naive_solver. Qed. Definition uPred_bupd_aux : { x | x = @uPred_bupd_def }. by eexists. Qed. Definition uPred_bupd {M} := proj1_sig uPred_bupd_aux M. Definition uPred_bupd_eq : @uPred_bupd = @uPred_bupd_def := proj2_sig uPred_bupd_aux. `````` Ralf Jung committed Nov 22, 2016 158 159 160 ``````(* Latest notation *) Notation "'⌜' φ '⌝'" := (uPred_pure φ%C%type) (at level 1, φ at level 200, format "⌜ φ ⌝") : uPred_scope. `````` Robbert Krebbers committed Oct 25, 2016 161 162 163 164 165 166 167 ``````Notation "'False'" := (uPred_pure False) : uPred_scope. Notation "'True'" := (uPred_pure True) : uPred_scope. Infix "∧" := uPred_and : uPred_scope. Notation "(∧)" := uPred_and (only parsing) : uPred_scope. Infix "∨" := uPred_or : uPred_scope. Notation "(∨)" := uPred_or (only parsing) : uPred_scope. Infix "→" := uPred_impl : uPred_scope. `````` Robbert Krebbers committed Nov 03, 2016 168 169 170 ``````Infix "∗" := uPred_sep (at level 80, right associativity) : uPred_scope. Notation "(∗)" := uPred_sep (only parsing) : uPred_scope. Notation "P -∗ Q" := (uPred_wand P Q) `````` Robbert Krebbers committed Oct 25, 2016 171 172 `````` (at level 99, Q at level 200, right associativity) : uPred_scope. Notation "∀ x .. y , P" := `````` Ralf Jung committed Oct 27, 2016 173 174 `````` (uPred_forall (λ x, .. (uPred_forall (λ y, P)) ..)%I) (at level 200, x binder, y binder, right associativity) : uPred_scope. `````` Robbert Krebbers committed Oct 25, 2016 175 ``````Notation "∃ x .. y , P" := `````` Ralf Jung committed Oct 27, 2016 176 177 `````` (uPred_exist (λ x, .. (uPred_exist (λ y, P)) ..)%I) (at level 200, x binder, y binder, right associativity) : uPred_scope. `````` Robbert Krebbers committed Oct 25, 2016 178 179 180 181 ``````Notation "□ P" := (uPred_always P) (at level 20, right associativity) : uPred_scope. Notation "▷ P" := (uPred_later P) (at level 20, right associativity) : uPred_scope. `````` Robbert Krebbers committed Oct 25, 2016 182 ``````Infix "≡" := uPred_internal_eq : uPred_scope. `````` Robbert Krebbers committed Oct 25, 2016 183 184 185 ``````Notation "✓ x" := (uPred_cmra_valid x) (at level 20) : uPred_scope. Notation "|==> Q" := (uPred_bupd Q) (at level 99, Q at level 200, format "|==> Q") : uPred_scope. `````` Robbert Krebbers committed Nov 03, 2016 186 ``````Notation "P ==∗ Q" := (P ⊢ |==> Q) `````` Robbert Krebbers committed Oct 25, 2016 187 `````` (at level 99, Q at level 200, only parsing) : C_scope. `````` Robbert Krebbers committed Nov 03, 2016 188 189 ``````Notation "P ==∗ Q" := (P -∗ |==> Q)%I (at level 99, Q at level 200, format "P ==∗ Q") : uPred_scope. `````` Robbert Krebbers committed Oct 25, 2016 190 `````` `````` 191 192 ``````Coercion uPred_valid {M} (P : uPred M) : Prop := True%I ⊢ P. Notation "P -∗ Q" := (P ⊢ Q) `````` Ralf Jung committed Nov 25, 2016 193 `````` (at level 99, Q at level 200, right associativity) : C_scope. `````` 194 `````` `````` Robbert Krebbers committed Oct 25, 2016 195 196 197 ``````Module uPred_primitive. Definition unseal := (uPred_pure_eq, uPred_and_eq, uPred_or_eq, uPred_impl_eq, uPred_forall_eq, `````` Robbert Krebbers committed Oct 25, 2016 198 `````` uPred_exist_eq, uPred_internal_eq_eq, uPred_sep_eq, uPred_wand_eq, uPred_always_eq, `````` Robbert Krebbers committed Oct 25, 2016 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 `````` uPred_later_eq, uPred_ownM_eq, uPred_cmra_valid_eq, uPred_bupd_eq). Ltac unseal := rewrite !unseal /=. Section primitive. Context {M : ucmraT}. 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" := (equiv (A:=uPred M) P%I Q%I). (* Force implicit argument M *) Arguments uPred_holds {_} !_ _ _ /. Hint Immediate uPred_in_entails. (** Non-expansiveness and setoid morphisms *) Global Instance pure_proper : Proper (iff ==> (⊣⊢)) (@uPred_pure 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. intros P P' HP Q Q' HQ; unseal; split=> x n' ??. split; (intros [??]; split; [by apply HP|by apply HQ]). Qed. Global Instance and_proper : 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 _. Global Instance impl_ne n : Proper (dist n ==> dist n ==> dist n) (@uPred_impl M). Proof. intros P P' HP Q Q' HQ; split=> x n' ??. unseal; split; intros HPQ x' n'' ????; apply HQ, HPQ, HP; auto. Qed. Global Instance impl_proper : 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 ??. unseal; split; intros (x1&x2&?&?&?); cofe_subst x; exists x1, x2; split_and!; try (apply HP || apply HQ); eauto using cmra_validN_op_l, cmra_validN_op_r. Qed. Global Instance sep_proper : Proper ((⊣⊢) ==> (⊣⊢) ==> (⊣⊢)) (@uPred_sep M) := ne_proper_2 _. Global Instance wand_ne n : Proper (dist n ==> dist n ==> dist n) (@uPred_wand M). Proof. intros P P' HP Q Q' HQ; split=> n' x ??; unseal; split; intros HPQ x' n'' ???; apply HQ, HPQ, HP; eauto using cmra_validN_op_r. Qed. Global Instance wand_proper : Proper ((⊣⊢) ==> (⊣⊢) ==> (⊣⊢)) (@uPred_wand M) := ne_proper_2 _. `````` Ralf Jung committed Nov 22, 2016 254 ``````Global Instance internal_eq_ne (A : ofeT) n : `````` Robbert Krebbers committed Oct 25, 2016 255 `````` Proper (dist n ==> dist n ==> dist n) (@uPred_internal_eq M A). `````` Robbert Krebbers committed Oct 25, 2016 256 257 258 259 260 ``````Proof. intros x x' Hx y y' Hy; split=> n' z; unseal; split; intros; simpl in *. - by rewrite -(dist_le _ _ _ _ Hx) -?(dist_le _ _ _ _ Hy); auto. - by rewrite (dist_le _ _ _ _ Hx) ?(dist_le _ _ _ _ Hy); auto. Qed. `````` Ralf Jung committed Nov 22, 2016 261 ``````Global Instance internal_eq_proper (A : ofeT) : `````` Robbert Krebbers committed Oct 25, 2016 262 `````` Proper ((≡) ==> (≡) ==> (⊣⊢)) (@uPred_internal_eq M A) := ne_proper_2 _. `````` Robbert Krebbers committed Oct 25, 2016 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 ``````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). Proof. by intros Ψ1 Ψ2 HΨ; unseal; split=> n' x; split; intros HP a; apply HΨ. Qed. Global Instance exist_ne A n : Proper (pointwise_relation _ (dist n) ==> dist n) (@uPred_exist M A). Proof. intros Ψ1 Ψ2 HΨ. 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). Proof. intros Ψ1 Ψ2 HΨ. unseal; split=> n' x ?; split; intros [a ?]; exists a; by apply HΨ. Qed. Global Instance later_contractive : Contractive (@uPred_later M). Proof. intros n P Q HPQ; unseal; split=> -[|n'] x ??; simpl; [done|]. apply (HPQ n'); eauto using cmra_validN_S. Qed. Global Instance later_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 _. 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 cmra_valid_ne {A : cmraT} n : Proper (dist n ==> dist n) (@uPred_cmra_valid M A). Proof. intros a b Ha; unseal; split=> n' x ? /=. by rewrite (dist_le _ _ _ _ Ha); last lia. Qed. Global Instance cmra_valid_proper {A : cmraT} : Proper ((≡) ==> (⊣⊢)) (@uPred_cmra_valid M A) := ne_proper _. Global Instance bupd_ne n : Proper (dist n ==> dist n) (@uPred_bupd M). Proof. intros P Q HPQ. unseal; split=> n' x; split; intros HP k yf ??; destruct (HP k yf) as (x'&?&?); auto; exists x'; split; auto; apply HPQ; eauto using cmra_validN_op_l. Qed. Global Instance bupd_proper : Proper ((≡) ==> (≡)) (@uPred_bupd M) := ne_proper _. `````` 321 322 323 324 ``````Global Instance uPred_valid_proper : Proper ((⊣⊢) ==> iff) (@uPred_valid M). Proof. solve_proper. Qed. Global Instance uPred_valid_mono : Proper ((⊢) ==> impl) (@uPred_valid M). Proof. solve_proper. Qed. `````` Robbert Krebbers committed Dec 02, 2016 325 326 327 ``````Global Instance uPred_valid_flip_mono : Proper (flip (⊢) ==> flip impl) (@uPred_valid M). Proof. solve_proper. Qed. `````` Robbert Krebbers committed Oct 25, 2016 328 329 `````` (** Introduction and elimination rules *) `````` Ralf Jung committed Nov 22, 2016 330 ``````Lemma pure_intro φ P : φ → P ⊢ ⌜φ⌝. `````` Robbert Krebbers committed Oct 25, 2016 331 ``````Proof. by intros ?; unseal; split. Qed. `````` Ralf Jung committed Nov 22, 2016 332 ``````Lemma pure_elim' φ P : (φ → True ⊢ P) → ⌜φ⌝ ⊢ P. `````` Robbert Krebbers committed Nov 22, 2016 333 ``````Proof. unseal; intros HP; split=> n x ??. by apply HP. Qed. `````` Ralf Jung committed Nov 22, 2016 334 ``````Lemma pure_forall_2 {A} (φ : A → Prop) : (∀ x : A, ⌜φ x⌝) ⊢ ⌜∀ x : A, φ x⌝. `````` Robbert Krebbers committed Oct 25, 2016 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 ``````Proof. by unseal. Qed. 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. Proof. by unseal; split=> n x ? [??]. Qed. 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. Proof. unseal; split=> n x ??; left; auto. Qed. 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. 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. Proof. unseal; intros HQ; split=> n x ?? n' x' ????. apply HQ; naive_solver eauto using uPred_mono, uPred_closed, cmra_included_includedN. Qed. 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. Proof. unseal; intros HPΨ; split=> n x ?? a; by apply HPΨ. Qed. 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. Proof. unseal; split=> n x ??; by exists a. Qed. 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. `````` 369 ``````Lemma internal_eq_refl {A : ofeT} (a : A) : uPred_valid (M:=M) (a ≡ a). `````` Robbert Krebbers committed Oct 25, 2016 370 ``````Proof. unseal; by split=> n x ??; simpl. Qed. `````` Ralf Jung committed Nov 22, 2016 371 ``````Lemma internal_eq_rewrite {A : ofeT} a b (Ψ : A → uPred M) P `````` Robbert Krebbers committed Oct 25, 2016 372 373 374 375 376 377 `````` {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. `````` Ralf Jung committed Nov 22, 2016 378 ``````Lemma internal_eq_rewrite_contractive {A : ofeT} a b (Ψ : A → uPred M) P `````` Robbert Krebbers committed Oct 25, 2016 379 380 381 382 383 384 385 386 387 `````` {HΨ : Contractive Ψ} : (P ⊢ ▷ (a ≡ b)) → (P ⊢ Ψ a) → P ⊢ Ψ b. Proof. unseal; intros Hab Ha; split=> n x ??. apply HΨ with n a; auto. - destruct n; intros m ?; first omega. apply (dist_le n); last omega. symmetry. by destruct Hab as [Hab]; eapply (Hab (S n)). - by apply Ha. Qed. (* BI connectives *) `````` Robbert Krebbers committed Nov 03, 2016 388 ``````Lemma sep_mono P P' Q Q' : (P ⊢ Q) → (P' ⊢ Q') → P ∗ P' ⊢ Q ∗ Q'. `````` Robbert Krebbers committed Oct 25, 2016 389 390 391 392 393 ``````Proof. intros HQ HQ'; unseal. split; intros n' x ? (x1&x2&?&?&?); exists x1,x2; cofe_subst x; eauto 7 using cmra_validN_op_l, cmra_validN_op_r, uPred_in_entails. Qed. `````` Robbert Krebbers committed Nov 03, 2016 394 ``````Lemma True_sep_1 P : P ⊢ True ∗ P. `````` Robbert Krebbers committed Oct 25, 2016 395 396 397 ``````Proof. unseal; split; intros n x ??. exists (core x), x. by rewrite cmra_core_l. Qed. `````` Robbert Krebbers committed Nov 03, 2016 398 ``````Lemma True_sep_2 P : True ∗ P ⊢ P. `````` Robbert Krebbers committed Oct 25, 2016 399 400 401 402 ``````Proof. unseal; split; intros n x ? (x1&x2&?&_&?); cofe_subst; eauto using uPred_mono, cmra_includedN_r. Qed. `````` Robbert Krebbers committed Nov 03, 2016 403 ``````Lemma sep_comm' P Q : P ∗ Q ⊢ Q ∗ P. `````` Robbert Krebbers committed Oct 25, 2016 404 405 406 ``````Proof. unseal; split; intros n x ? (x1&x2&?&?&?); exists x2, x1; by rewrite (comm op). Qed. `````` Robbert Krebbers committed Nov 03, 2016 407 ``````Lemma sep_assoc' P Q R : (P ∗ Q) ∗ R ⊢ P ∗ (Q ∗ R). `````` Robbert Krebbers committed Oct 25, 2016 408 409 410 411 412 413 ``````Proof. unseal; split; intros n x ? (x1&x2&Hx&(y1&y2&Hy&?&?)&?). exists y1, (y2 ⋅ x2); split_and?; auto. + by rewrite (assoc op) -Hy -Hx. + by exists y2, x2. Qed. `````` Robbert Krebbers committed Nov 03, 2016 414 ``````Lemma wand_intro_r P Q R : (P ∗ Q ⊢ R) → P ⊢ Q -∗ R. `````` Robbert Krebbers committed Oct 25, 2016 415 416 417 418 419 ``````Proof. unseal=> HPQR; split=> n x ?? n' x' ???; apply HPQR; auto. exists x, x'; split_and?; auto. eapply uPred_closed with n; eauto using cmra_validN_op_l. Qed. `````` Robbert Krebbers committed Nov 03, 2016 420 ``````Lemma wand_elim_l' P Q R : (P ⊢ Q -∗ R) → P ∗ Q ⊢ R. `````` Robbert Krebbers committed Oct 25, 2016 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 ``````Proof. unseal =>HPQR. split; intros n x ? (?&?&?&?&?). cofe_subst. eapply HPQR; eauto using cmra_validN_op_l. Qed. (* Always *) Lemma always_mono P Q : (P ⊢ Q) → □ P ⊢ □ Q. Proof. intros HP; unseal; split=> n x ? /=. by apply HP, cmra_core_validN. Qed. Lemma always_elim P : □ P ⊢ P. Proof. unseal; split=> n x ? /=. eauto using uPred_mono, @cmra_included_core, cmra_included_includedN. Qed. Lemma always_idemp P : □ P ⊢ □ □ P. Proof. unseal; split=> n x ?? /=. by rewrite cmra_core_idemp. Qed. `````` Ralf Jung committed Nov 22, 2016 437 ``````Lemma always_pure_2 φ : ⌜φ⌝ ⊢ □ ⌜φ⌝. `````` Robbert Krebbers committed Oct 25, 2016 438 439 440 441 442 443 ``````Proof. by unseal. Qed. Lemma always_forall_2 {A} (Ψ : A → uPred M) : (∀ a, □ Ψ a) ⊢ (□ ∀ a, Ψ a). Proof. by unseal. Qed. Lemma always_exist_1 {A} (Ψ : A → uPred M) : (□ ∃ a, Ψ a) ⊢ (∃ a, □ Ψ a). Proof. by unseal. Qed. `````` Robbert Krebbers committed Nov 03, 2016 444 ``````Lemma always_and_sep_1 P Q : □ (P ∧ Q) ⊢ □ (P ∗ Q). `````` Robbert Krebbers committed Oct 25, 2016 445 446 447 448 ``````Proof. unseal; split=> n x ? [??]. exists (core x), (core x); rewrite -cmra_core_dup; auto. Qed. `````` Robbert Krebbers committed Nov 03, 2016 449 ``````Lemma always_and_sep_l_1 P Q : □ P ∧ Q ⊢ □ P ∗ Q. `````` Robbert Krebbers committed Oct 25, 2016 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 ``````Proof. unseal; split=> n x ? [??]; exists (core x), x; simpl in *. by rewrite cmra_core_l cmra_core_idemp. Qed. (* Later *) Lemma later_mono P Q : (P ⊢ Q) → ▷ P ⊢ ▷ Q. Proof. unseal=> HP; split=>-[|n] x ??; [done|apply HP; eauto using cmra_validN_S]. Qed. Lemma löb P : (▷ P → P) ⊢ P. Proof. unseal; split=> n x ? HP; induction n as [|n IH]; [by apply HP|]. apply HP, IH, uPred_closed with (S n); eauto using cmra_validN_S. Qed. Lemma later_forall_2 {A} (Φ : A → uPred M) : (∀ a, ▷ Φ a) ⊢ ▷ ∀ a, Φ a. Proof. unseal; by split=> -[|n] x. Qed. Lemma later_exist_false {A} (Φ : A → uPred M) : (▷ ∃ a, Φ a) ⊢ ▷ False ∨ (∃ a, ▷ Φ a). Proof. unseal; split=> -[|[|n]] x /=; eauto. Qed. `````` Robbert Krebbers committed Nov 03, 2016 470 ``````Lemma later_sep P Q : ▷ (P ∗ Q) ⊣⊢ ▷ P ∗ ▷ Q. `````` Robbert Krebbers committed Oct 25, 2016 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 ``````Proof. unseal; split=> n x ?; split. - destruct n as [|n]; simpl. { by exists x, (core x); rewrite cmra_core_r. } intros (x1&x2&Hx&?&?); destruct (cmra_extend n x x1 x2) as (y1&y2&Hx'&Hy1&Hy2); eauto using cmra_validN_S; simpl in *. exists y1, y2; split; [by rewrite Hx'|by rewrite Hy1 Hy2]. - destruct n as [|n]; simpl; [done|intros (x1&x2&Hx&?&?)]. exists x1, x2; eauto using dist_S. Qed. Lemma later_false_excluded_middle P : ▷ P ⊢ ▷ False ∨ (▷ False → P). Proof. unseal; split=> -[|n] x ? /= HP; [by left|right]. intros [|n'] x' ????; [|done]. eauto using uPred_closed, uPred_mono, cmra_included_includedN. Qed. Lemma always_later P : □ ▷ P ⊣⊢ ▷ □ P. Proof. by unseal. Qed. (* Own *) Lemma ownM_op (a1 a2 : M) : `````` Robbert Krebbers committed Nov 03, 2016 492 `````` uPred_ownM (a1 ⋅ a2) ⊣⊢ uPred_ownM a1 ∗ uPred_ownM a2. `````` Robbert Krebbers committed Oct 25, 2016 493 494 495 496 497 498 499 500 501 502 503 504 ``````Proof. unseal; split=> n x ?; split. - intros [z ?]; exists a1, (a2 ⋅ z); split; [by rewrite (assoc op)|]. split. by exists (core a1); rewrite cmra_core_r. by exists z. - intros (y1&y2&Hx&[z1 Hy1]&[z2 Hy2]); exists (z1 ⋅ z2). by rewrite (assoc op _ z1) -(comm op z1) (assoc op z1) -(assoc op _ a2) (comm op z1) -Hy1 -Hy2. Qed. Lemma always_ownM_core (a : M) : uPred_ownM a ⊢ □ uPred_ownM (core a). Proof. split=> n x /=; unseal; intros Hx. simpl. by apply cmra_core_monoN. Qed. `````` 505 ``````Lemma ownM_empty : uPred_valid (M:=M) (uPred_ownM ∅). `````` Robbert Krebbers committed Oct 25, 2016 506 507 508 509 510 511 512 513 514 515 516 517 518 519 ``````Proof. unseal; split=> n x ??; by exists x; rewrite left_id. Qed. Lemma later_ownM a : ▷ uPred_ownM a ⊢ ∃ b, uPred_ownM b ∧ ▷ (a ≡ b). Proof. unseal; split=> -[|n] x /= ? Hax; first by eauto using ucmra_unit_leastN. destruct Hax as [y ?]. destruct (cmra_extend n x a y) as (a'&y'&Hx&?&?); auto using cmra_validN_S. exists a'. rewrite Hx. eauto using cmra_includedN_l. Qed. (* Valid *) Lemma ownM_valid (a : M) : uPred_ownM a ⊢ ✓ a. Proof. unseal; split=> n x Hv [a' ?]; cofe_subst; eauto using cmra_validN_op_l. Qed. `````` 520 ``````Lemma cmra_valid_intro {A : cmraT} (a : A) : ✓ a → uPred_valid (M:=M) (✓ a). `````` Robbert Krebbers committed Oct 25, 2016 521 522 523 524 525 526 527 528 529 ``````Proof. unseal=> ?; split=> n x ? _ /=; by apply cmra_valid_validN. Qed. Lemma cmra_valid_elim {A : cmraT} (a : A) : ¬ ✓{0} a → ✓ a ⊢ False. Proof. unseal=> Ha; split=> n x ??; apply Ha, cmra_validN_le with n; auto. Qed. Lemma always_cmra_valid_1 {A : cmraT} (a : A) : ✓ a ⊢ □ ✓ a. Proof. by unseal. Qed. Lemma cmra_valid_weaken {A : cmraT} (a b : A) : ✓ (a ⋅ b) ⊢ ✓ a. Proof. unseal; split=> n x _; apply cmra_validN_op_l. Qed. (* Basic update modality *) `````` Robbert Krebbers committed Nov 03, 2016 530 ``````Lemma bupd_intro P : P ==∗ P. `````` Robbert Krebbers committed Oct 25, 2016 531 532 533 534 ``````Proof. unseal. split=> n x ? HP k yf ?; exists x; split; first done. apply uPred_closed with n; eauto using cmra_validN_op_l. Qed. `````` Robbert Krebbers committed Nov 03, 2016 535 ``````Lemma bupd_mono P Q : (P ⊢ Q) → (|==> P) ==∗ Q. `````` Robbert Krebbers committed Oct 25, 2016 536 537 538 539 540 ``````Proof. unseal. intros HPQ; split=> n x ? HP k yf ??. destruct (HP k yf) as (x'&?&?); eauto. exists x'; split; eauto using uPred_in_entails, cmra_validN_op_l. Qed. `````` Robbert Krebbers committed Nov 03, 2016 541 ``````Lemma bupd_trans P : (|==> |==> P) ==∗ P. `````` Robbert Krebbers committed Oct 25, 2016 542 ``````Proof. unseal; split; naive_solver. Qed. `````` Robbert Krebbers committed Nov 03, 2016 543 ``````Lemma bupd_frame_r P R : (|==> P) ∗ R ==∗ P ∗ R. `````` Robbert Krebbers committed Oct 25, 2016 544 545 546 547 548 549 550 551 552 ``````Proof. unseal; split; intros n x ? (x1&x2&Hx&HP&?) k yf ??. destruct (HP k (x2 ⋅ yf)) as (x'&?&?); eauto. { by rewrite assoc -(dist_le _ _ _ _ Hx); last lia. } exists (x' ⋅ x2); split; first by rewrite -assoc. exists x', x2; split_and?; auto. apply uPred_closed with n; eauto 3 using cmra_validN_op_l, cmra_validN_op_r. Qed. Lemma bupd_ownM_updateP x (Φ : M → Prop) : `````` Ralf Jung committed Nov 22, 2016 553 `````` x ~~>: Φ → uPred_ownM x ==∗ ∃ y, ⌜Φ y⌝ ∧ uPred_ownM y. `````` Robbert Krebbers committed Oct 25, 2016 554 555 556 557 558 559 560 561 562 ``````Proof. unseal=> Hup; split=> n x2 ? [x3 Hx] k yf ??. destruct (Hup k (Some (x3 ⋅ yf))) as (y&?&?); simpl in *. { rewrite /= assoc -(dist_le _ _ _ _ Hx); auto. } exists (y ⋅ x3); split; first by rewrite -assoc. exists y; eauto using cmra_includedN_l. Qed. (* Products *) `````` Ralf Jung committed Nov 22, 2016 563 ``````Lemma prod_equivI {A B : ofeT} (x y : A * B) : x ≡ y ⊣⊢ x.1 ≡ y.1 ∧ x.2 ≡ y.2. `````` Robbert Krebbers committed Oct 25, 2016 564 565 566 567 568 ``````Proof. by unseal. Qed. Lemma prod_validI {A B : cmraT} (x : A * B) : ✓ x ⊣⊢ ✓ x.1 ∧ ✓ x.2. Proof. by unseal. Qed. (* Later *) `````` Ralf Jung committed Nov 22, 2016 569 ``````Lemma later_equivI {A : ofeT} (x y : A) : Next x ≡ Next y ⊣⊢ ▷ (x ≡ y). `````` Robbert Krebbers committed Oct 25, 2016 570 571 572 ``````Proof. by unseal. Qed. (* Discrete *) `````` Ralf Jung committed Nov 22, 2016 573 ``````Lemma discrete_valid {A : cmraT} `{!CMRADiscrete A} (a : A) : ✓ a ⊣⊢ ⌜✓ a⌝. `````` Robbert Krebbers committed Oct 25, 2016 574 ``````Proof. unseal; split=> n x _. by rewrite /= -cmra_discrete_valid_iff. Qed. `````` Ralf Jung committed Nov 22, 2016 575 ``````Lemma timeless_eq {A : ofeT} (a b : A) : Timeless a → a ≡ b ⊣⊢ ⌜a ≡ b⌝. `````` Robbert Krebbers committed Oct 25, 2016 576 577 578 579 580 ``````Proof. unseal=> ?. apply (anti_symm (⊢)); split=> n x ?; by apply (timeless_iff n). Qed. (* Option *) `````` Ralf Jung committed Nov 22, 2016 581 ``````Lemma option_equivI {A : ofeT} (mx my : option A) : `````` Robbert Krebbers committed Oct 25, 2016 582 583 584 585 586 587 588 589 590 591 592 593 594 `````` mx ≡ my ⊣⊢ match mx, my with | Some x, Some y => x ≡ y | None, None => True | _, _ => False end. Proof. unseal. do 2 split. by destruct 1. by destruct mx, my; try constructor. Qed. Lemma option_validI {A : cmraT} (mx : option A) : ✓ mx ⊣⊢ match mx with Some x => ✓ x | None => True end. Proof. unseal. by destruct mx. Qed. (* Functions *) Lemma cofe_funC_equivI {A B} (f g : A -c> B) : f ≡ g ⊣⊢ ∀ x, f x ≡ g x. Proof. by unseal. Qed. `````` Ralf Jung committed Nov 22, 2016 595 ``````Lemma cofe_morC_equivI {A B : ofeT} (f g : A -n> B) : f ≡ g ⊣⊢ ∀ x, f x ≡ g x. `````` Robbert Krebbers committed Oct 25, 2016 596 597 598 ``````Proof. by unseal. Qed. End primitive. End uPred_primitive.``````