11/-
22Copyright (c) 2022 Lars König. All rights reserved.
33Released under Apache 2.0 license as described in the file LICENSE.
4- Authors: Lars König, Mario Carneiro, Markus de Medeiros, Michael Sammler
4+ Authors: Lars König, Mario Carneiro, Markus de Medeiros, Michael Sammler, Alvin Tang
55-/
66module
77
@@ -24,8 +24,11 @@ open Iris.Std BI
2424/- Necessary for `calc`-style proofs. -/
2525instance entails_trans' [BI PROP] : Trans (α := PROP) Entails Entails Entails where
2626 trans h1 h2 := h1.trans h2
27+
28+ @ [rocq_alias bi.entails_anti_sym]
2729instance entails_antisymm [BI PROP] : Antisymmetric (α := PROP) BiEntails Entails where
2830 antisymm h1 h2 := ⟨h1, h2⟩
31+
2932#rocq_ignore bi.entails_proper "Derivable from _ne with NonExpansive.eqv."
3033
3134instance equiv_trans [BI PROP] : Trans (α := PROP) BiEntails BiEntails BiEntails where
@@ -37,6 +40,8 @@ instance equiv_entails_trans [BI PROP] : Trans (α := PROP) BiEntails Entails En
3740instance entails_equiv_trans [BI PROP] : Trans (α := PROP) Entails BiEntails Entails where
3841 trans h1 h2 := h1.trans h2.1
3942
43+ #rocq_ignore bi.equiv_entails_2 "Use the BiEntails constructor directly"
44+
4045/-! # Logic -/
4146
4247@ [rocq_alias bi.and_elim_l']
@@ -604,6 +609,47 @@ theorem wandIff_congr_right [BI PROP] {P Q Q' : PROP} (h : Q ⊣⊢ Q') : (P ∗
604609@ [rocq_alias bi.wand_iff_refl]
605610theorem wandIff_refl [BI PROP] {P : PROP} : ⊢ P ∗-∗ P := and_intro wand_rfl wand_rfl
606611
612+ @ [rocq_alias bi.wand_iff_sym]
613+ theorem wandIff_sym [BI PROP] {P Q : PROP} : (P ∗-∗ Q) ⊣⊢ (Q ∗-∗ P) :=
614+ ⟨and_symm, and_symm⟩
615+
616+ @ [rocq_alias bi.wand_iff_trans]
617+ theorem wandIff_trans [BI PROP] {P Q R : PROP} :
618+ (P ∗-∗ Q) ∗ (Q ∗-∗ R) ⊢ (P ∗-∗ R) := by
619+ apply and_intro
620+ · exact (sep_mono and_elim_l and_elim_l).trans wand_trans
621+ · calc
622+ _ ⊢ (Q -∗ P) ∗ (R -∗ Q) := sep_mono and_elim_r and_elim_r
623+ _ ⊢ (R -∗ Q) ∗ (Q -∗ P) := sep_comm.mp
624+ _ ⊢ R -∗ P := wand_trans
625+
626+ @ [rocq_alias bi.exist_wand_forall]
627+ theorem exists_wand_forall [BI PROP] {P : PROP} {Ψ : α → PROP} :
628+ ((∃ x, Ψ x) -∗ P) ⊣⊢ (∀ x, Ψ x -∗ P) := by
629+ constructor
630+ · exact forall_intro (wand_mono_left <| exists_intro ·)
631+ · apply wand_intro
632+ refine sep_exists_left.mp.trans ?_
633+ refine exists_elim fun x => ?_
634+ exact (sep_mono_left <| forall_elim x).trans wand_elim_left
635+
636+ @ [rocq_alias bi.and_parallel]
637+ theorem and_parallel [BI PROP] {P1 P2 Q1 Q2 : PROP} :
638+ ⊢ (P1 ∧ P2) -∗ ((P1 -∗ Q1) ∧ (P2 -∗ Q2)) -∗ Q1 ∧ Q2 := by
639+ apply wand_intro
640+ apply wand_intro
641+ apply and_intro
642+ · apply wand_elim
643+ apply wand_intro
644+ refine (sep_mono_right and_elim_l).trans ?_
645+ refine (sep_mono_left <| emp_sep.mp.trans and_elim_l).trans ?_
646+ exact wand_elim_right
647+ · apply wand_elim
648+ apply wand_intro
649+ refine (sep_mono_right and_elim_r).trans ?_
650+ refine (sep_mono_left <| emp_sep.mp.trans and_elim_r).trans ?_
651+ exact wand_elim_right
652+
607653@ [rocq_alias bi.iff_ne]
608654instance iff_ne [BI PROP] : OFE.NonExpansive₂ (BIBase.iff (PROP := PROP)) :=
609655 ⟨fun {_ _ _} h₁ {_ _} h₂ => and_ne.ne (imp_ne.ne h₁ h₂) (imp_ne.ne h₂ h₁)⟩
@@ -613,6 +659,48 @@ instance iff_ne [BI PROP] : OFE.NonExpansive₂ (BIBase.iff (PROP := PROP)) :=
613659theorem iff_refl_alias [BI PROP] {Q P : PROP} : Q ⊢ iprop(P ↔ P) :=
614660 true_intro.trans <| and_intro (imp_intro and_elim_r) (imp_intro and_elim_r)
615661
662+ @ [rocq_alias bi.iff_sym]
663+ theorem iff_sym [BI PROP] {P Q : PROP} : (P ↔ Q) ⊣⊢ (Q ↔ P) :=
664+ ⟨and_intro and_elim_r and_elim_l, and_intro and_elim_r and_elim_l⟩
665+
666+ @ [rocq_alias bi.iff_trans]
667+ theorem iff_trans [BI PROP] {P Q R : PROP} : (P ↔ Q) ∧ (Q ↔ R) ⊢ (P ↔ R) := by
668+ apply and_intro
669+ · exact (and_mono and_elim_l and_elim_l).trans imp_trans
670+ · calc
671+ _ ⊢ (Q → P) ∧ (R → Q) := and_mono and_elim_r and_elim_r
672+ _ ⊢ (R → Q) ∧ (Q → P) := and_comm.mp
673+ _ ⊢ R → P := imp_trans
674+
675+ @ [rocq_alias bi.entails_impl]
676+ theorem entails_imp [BI PROP] {P Q : PROP} (h : P ⊢ Q) : ⊢ P → Q :=
677+ imp_intro <| and_elim_r.trans h
678+
679+ @ [rocq_alias bi.impl_entails]
680+ theorem imp_entails [BI PROP] {P Q : PROP} [inst : Affine P] (h : ⊢ P → Q) : P ⊢ Q :=
681+ imp_mp (inst.affine.trans h) .rfl
682+
683+ @ [rocq_alias bi.equiv_iff]
684+ theorem equiv_iff_thm [BI PROP] {P Q : PROP} (h : P ⊣⊢ Q) : ⊢ iprop(P ↔ Q) := by
685+ apply and_intro
686+ · exact imp_intro <| and_elim_r.trans h.mp
687+ · exact imp_intro <| and_elim_r.trans h.mpr
688+
689+ @ [rocq_alias bi.iff_equiv]
690+ theorem iff_equiv [BI PROP] {P Q : PROP} [Affine P] [Affine Q] (h : ⊢ iprop(P ↔ Q)) :
691+ P ⊣⊢ Q := by
692+ constructor
693+ · refine (and_intro .rfl ?_).trans imp_elim_right
694+ calc
695+ _ ⊢ emp := Affine.affine
696+ _ ⊢ (P ↔ Q) := h
697+ _ ⊢ P → Q := and_elim_l
698+ · refine (and_intro .rfl ?_).trans imp_elim_right
699+ calc
700+ _ ⊢ emp := Affine.affine
701+ _ ⊢ (P ↔ Q) := h
702+ _ ⊢ Q → P := and_elim_r
703+
616704@ [rocq_alias bi.wand_iff_ne]
617705instance wandIff_ne [BI PROP] : OFE.NonExpansive₂ (wandIff (PROP := PROP)) :=
618706 ⟨fun {_ _ _} h₁ {_ _} h₂ => and_ne.ne (wand_ne.ne h₁ h₂) (wand_ne.ne h₂ h₁)⟩
@@ -642,18 +730,29 @@ theorem equiv_wandIff [BI PROP] {P Q : PROP} (h : P ⊣⊢ Q) : ⊢ P ∗-∗ Q
642730theorem wandIff_equiv [BI PROP] {P Q : PROP} (h : ⊢ P ∗-∗ Q) : P ⊣⊢ Q :=
643731 ⟨wand_entails (h.trans and_elim_l), wand_entails (h.trans and_elim_r)⟩
644732
733+ @ [rocq_alias bi.bi_or_monoid]
734+ instance bi_or_monoid [BI PROP] : LawfulBigOp or (iprop(False) : PROP) BiEntails where
735+ refl := .rfl
736+ symm h := h.symm
737+ trans h1 h2 := h1.trans h2
738+ comm := or_comm
739+ assoc := or_assoc
740+ left_id := left_id
741+ congr_l := or_congr_left
742+
645743/-! # Pure -/
646744
647745@ [rocq_alias bi.pure_elim]
648746theorem pure_elim [BI PROP] (φ : Prop ) {Q R : PROP} (h1 : Q ⊢ ⌜φ⌝) (h2 : φ → Q ⊢ R) : Q ⊢ R :=
649747 (and_self (PROP := PROP)).2 .trans <| imp_elim <| h1.trans <| pure_elim' fun h =>
650748 imp_intro_swap <| and_elim_l.trans (h2 h)
651749
652- @ [rocq_alias bi.pure_mono]
750+ @ [rw_mono_rule, rocq_alias bi.pure_mono]
653751theorem pure_mono [BI PROP] {φ1 φ2 : Prop } (h : φ1 → φ2 ) : ⌜φ1 ⌝ ⊢ (⌜φ2 ⌝ : PROP) :=
654752 pure_elim' <| pure_intro ∘ h
655- #rocq_ignore bi.pure_mono' "Use _mono ."
753+ #rocq_ignore bi.pure_mono' "Use pure_mono ."
656754#rocq_ignore bi.pure_proper "Derivable from _ne with NonExpansive.eqv."
755+ #rocq_ignore bi.pure_flip_mono "No Proper type class in Lean. Use pure_mono directly."
657756
658757theorem pure_congr [BI PROP] {φ1 φ2 : Prop } (h : φ1 ↔ φ2 ) : ⌜φ1 ⌝ ⊣⊢ (⌜φ2 ⌝ : PROP) :=
659758 ⟨pure_mono h.1 ,pure_mono h.2 ⟩
@@ -721,6 +820,24 @@ theorem pure_alt {PROP : Type _} [BI PROP] (φ : Prop) :
721820 (⌜φ⌝ : PROP) ⊣⊢ ∃ _ : φ, True :=
722821 (pure_congr ⟨fun h => ⟨h, trivial⟩, fun ⟨h, _⟩ => h⟩).trans pure_exists.symm
723822
823+ @ [rocq_alias bi.pure_wand_forall]
824+ theorem pure_wand_forall [BI PROP] {φ : Prop } {P : PROP} [Absorbing P] :
825+ (⌜φ⌝ -∗ P) ⊣⊢ (∀ _ : φ, P) := by
826+ constructor
827+ · refine forall_intro fun hφ => ?_
828+ calc
829+ _ ⊢ (⌜φ⌝ -∗ P) ∗ emp := sep_emp.mpr
830+ _ ⊢ (⌜φ⌝ -∗ P) ∗ ⌜φ⌝ := sep_mono_right <| pure_intro hφ
831+ _ ⊢ P := wand_elim_left
832+ · apply wand_intro_left
833+ apply wand_elim
834+ refine pure_elim' fun hφ => ?_
835+ apply wand_intro_left
836+ calc
837+ _ ⊢ P ∗ True := sep_mono_left <| forall_elim hφ
838+ _ ⊢ True ∗ P := sep_comm.mp
839+ _ ⊢ P := absorbing
840+
724841/-! # Affine -/
725842
726843@ [rocq_alias bi.affinely_ne]
@@ -854,6 +971,11 @@ instance affinely_affine [BI PROP] (P : PROP) : Affine iprop(<affine> P) where
854971instance [BIBase PROP] : Inhabited PROP where
855972 default := emp
856973
974+ @ [rocq_alias bi.pure_impl_forall]
975+ theorem pure_imp_forall [BI PROP] {φ : Prop } {P : PROP} :
976+ (⌜φ⌝ → P) ⊣⊢ (∀ _ : φ, P) :=
977+ ⟨forall_intro pure_imp_elim, imp_intro_swap <| pure_elim_left (forall_elim ·)⟩
978+
857979/-! # Absorbing -/
858980
859981@ [rocq_alias bi.absorbingly_ne]
@@ -1082,7 +1204,7 @@ instance bi_affine_positive [BI PROP] [BIAffine PROP] : BIPositive PROP where
10821204 affinely_sep_l := (affine_affinely _).1 .trans (sep_mono_left (affine_affinely _).2 )
10831205
10841206@ [rocq_alias bi.impl_wand_1]
1085- theorem imp_wand [BI PROP] [BIAffine PROP] {P Q : PROP} : (P → Q) ⊢ P -∗ Q :=
1207+ theorem imp_wand_1 [BI PROP] [BIAffine PROP] {P Q : PROP} : (P → Q) ⊢ P -∗ Q :=
10861208 wand_intro <| sep_and.trans imp_elim_left
10871209
10881210theorem pure_sep [BI PROP] {φ1 φ2 : Prop } : ⌜φ1 ⌝ ∗ (⌜φ2 ⌝ : PROP) ⊣⊢ ⌜φ1 ∧ φ2 ⌝ :=
@@ -1096,6 +1218,26 @@ theorem pure_wand [BI PROP] {φ1 φ2 : Prop} : (⌜φ1⌝ -∗ (⌜φ2⌝ : PROP
10961218 refine ⟨(imp_intro_swap ?_).trans pure_imp.2 , pure_wand_mpr⟩
10971219 exact pure_elim_left fun h => true_sep_mpr.trans (eq_true h ▸ wand_elim_right)
10981220
1221+ /-! # Decidable pure propositions -/
1222+
1223+ @ [rocq_alias bi.decide_bi_True]
1224+ theorem decide_true [BI PROP] (φ : Prop ) [Decidable φ] (P : PROP) :
1225+ (if φ then P else iprop(True)) ⊣⊢ (⌜φ⌝ → P) := by
1226+ by_cases h : φ
1227+ · rw [if_pos h]
1228+ exact ((imp_congr_left (pure_true h)).trans true_imp).symm
1229+ · rw [if_neg h]
1230+ exact ((imp_congr_left (pure_false h)).trans false_imp).symm
1231+
1232+ @ [rocq_alias bi.decide_emp]
1233+ theorem decide_emp [BI PROP] [BIAffine PROP] (φ : Prop ) [Decidable φ] (P : PROP) :
1234+ (if φ then P else iprop(emp)) ⊣⊢ (⌜φ⌝ → P) := by
1235+ by_cases h : φ
1236+ · rw [if_pos h]
1237+ exact ((imp_congr_left <| pure_true h).trans true_imp).symm
1238+ · rw [if_neg h]
1239+ exact true_emp.symm.trans ((imp_congr_left <| pure_false h).trans false_imp).symm
1240+
10991241/-! # Properties of the persistence modality -/
11001242
11011243@[rw_mono_rule]
@@ -1302,7 +1444,7 @@ theorem persistently_imp_wand [BI PROP] [BIAffine PROP] {P Q : PROP} :
13021444
13031445@ [rocq_alias bi.impl_wand_persistently]
13041446theorem imp_wand_persistently [BI PROP] [BIAffine PROP] {P Q : PROP} :
1305- (<pers> P → Q) ⊣⊢ (<pers> P -∗ Q) := ⟨imp_wand , imp_wand_persistently_mpr⟩
1447+ (<pers> P → Q) ⊣⊢ (<pers> P -∗ Q) := ⟨imp_wand_1 , imp_wand_persistently_mpr⟩
13061448
13071449@ [rocq_alias bi.wand_alt]
13081450theorem wand_iff_exists_persistently [BI PROP] [BIAffine PROP] {P Q : PROP} :
@@ -1509,10 +1651,25 @@ theorem intuitionistically_and_sep [BI PROP] {P Q : PROP} : □ (P ∧ Q) ⊣⊢
15091651theorem intuitionistically_sep_idem [BI PROP] {P : PROP} : □ P ∗ □ P ⊣⊢ □ P :=
15101652 and_sep_intuitionistically.symm.trans and_self
15111653
1654+ @ [rocq_alias bi.impl_wand_intuitionistically]
15121655theorem intuitionistically_wand [BI PROP] {P Q : PROP} : (□ P -∗ Q) ⊣⊢ (<pers> P → Q) :=
15131656 ⟨imp_intro <| persistently_and_intuitionistically_sep_right.1 .trans wand_elim_left,
15141657 wand_intro <|persistently_and_intuitionistically_sep_right.2 .trans imp_elim_left⟩
15151658
1659+ @ [rocq_alias bi.intuitionistically_alt_fixpoint]
1660+ theorem self_sep_intuitionistically [BI PROP] {P : PROP} :
1661+ □ P ⊣⊢ emp ∧ (P ∗ □ P) := by
1662+ constructor
1663+ · refine and_intro intuitionistically_elim_emp ?_
1664+ exact intuitionistically_sep_idem.mpr.trans <| sep_mono_left intuitionistically_elim
1665+ · refine and_mono .rfl ?_
1666+ exact (sep_mono_right <| and_elim_r).trans self_sep_persistently.mp
1667+
1668+ @ [rocq_alias bi.intuitionistically_intro]
1669+ theorem intuitionistically_intro [BI PROP] {P Q : PROP}
1670+ [Affine P] [Persistent P] (h : P ⊢ Q) : P ⊢ □ Q :=
1671+ intuitionistic_alias.trans <| intuitionistically_mono h
1672+
15161673theorem affinely_self_sep_intuitionistically [BI PROP] {P : PROP} :
15171674 <affine> (P ∗ □ P) ⊣⊢ □ P :=
15181675 ⟨affinely_mono <| (sep_mono_right persistently_of_intuitionistically).trans self_sep_persistently.1 ,
@@ -1523,7 +1680,8 @@ theorem affinely_self_sep_intuitionistically [BI PROP] {P : PROP} :
15231680theorem intuitionistically_imp_wand [BI PROP] {P Q : PROP} : □ (P -∗ Q) ⊢ □ (P → Q) :=
15241681 affinely_mono persistently_imp_wand_mpr
15251682
1526- theorem imp_iff_exists_persistently [BI PROP] [BIAffine PROP] {P Q : PROP} :
1683+ @ [rocq_alias bi.impl_alt]
1684+ theorem imp_iff_exists_persistently [BI PROP] {P Q : PROP} :
15271685 (P → Q) ⊣⊢ ∃ R, R ∧ <pers> (P ∧ R -∗ Q) := by
15281686 constructor
15291687 · refine (and_true.2 .trans ?_).trans (exists_intro iprop(P → Q))
@@ -2144,6 +2302,23 @@ theorem persistent_and_sep [BI PROP] [BIAffine PROP] {P Q : PROP} :
21442302 and_persistently_iff_sep.trans (sep_congr_right persistently_iff)
21452303
21462304
2305+ @ [rocq_alias bi.impl_wand_2]
2306+ theorem imp_wand_2 [BI PROP] {P Q : PROP} [Persistent P] :
2307+ (P -∗ Q) ⊢ P → Q := imp_intro <| persistent_and_sep_mp.trans wand_elim_left
2308+
2309+ @ [rocq_alias bi.impl_wand]
2310+ theorem imp_wand [BI PROP] [BIAffine PROP] {P Q : PROP} [Persistent P] :
2311+ (P → Q) ⊣⊢ (P -∗ Q) := ⟨imp_wand_1, imp_wand_2⟩
2312+
2313+ @ [rocq_alias bi.persistent_sep_dup_1]
2314+ theorem persistent_sep_dup_mp [BI PROP] {P : PROP} [inst : Persistent P] : P ⊢ P ∗ P :=
2315+ and_self.mpr.trans persistent_and_sep_mp
2316+
2317+ @ [rocq_alias bi.persistent_sep_dup]
2318+ theorem persistent_sep_dup [BI PROP] {P : PROP} [Persistent P]
2319+ [TCOr (Affine P) (Absorbing P)] : P ⊣⊢ P ∗ P :=
2320+ ⟨persistent_sep_dup_mp, sep_elim_left⟩
2321+
21472322@ [rocq_alias bi.persistent_entails_l]
21482323theorem persistent_entails_right [BI PROP] {P Q : PROP} [Persistent Q] (H : P ⊢ Q) : P ⊢ Q ∗ P :=
21492324 (and_intro H .rfl).trans persistent_and_sep_mp
@@ -2179,6 +2354,31 @@ theorem bigOp_sep_cons [BI PROP] {P : PROP} {Ps : List PROP} :
21792354theorem bigOp_and_cons [BI PROP] {P : PROP} {Ps : List PROP} :
21802355 [∧] (P :: Ps) ⊣⊢ P ∧ [∧] Ps := bigOp_cons
21812356
2357+ @ [rocq_alias bi.persistent_absorbingly_affinely]
2358+ theorem persistent_absorbingly_affinely [BI PROP] {P : PROP}
2359+ [Persistent P] [Absorbing P] : <absorb> <affine> P ⊣⊢ P :=
2360+ ⟨(sep_mono_right affinely_elim).trans absorbing, absorbingly_affinely_intro_of_persistent⟩
2361+
2362+ @ [rocq_alias bi.persistent_and_sep_assoc]
2363+ theorem persistent_and_sep_assoc [BI PROP] {P Q R : PROP}
2364+ [Persistent P] [Absorbing P] : P ∧ (Q ∗ R) ⊣⊢ (P ∧ Q) ∗ R :=
2365+ (and_congr_left persistently_iff.symm).trans <| persistently_and_sep_assoc.trans <|
2366+ sep_congr_left <| and_congr_left persistently_iff
2367+
2368+ @ [rocq_alias bi.persistent_impl_wand_affinely]
2369+ theorem persistent_impl_wand_affinely [BI PROP] {P Q : PROP} [Persistent P] [Absorbing P] :
2370+ (P → Q) ⊣⊢ (<affine> P -∗ Q) := by
2371+ constructor
2372+ · exact wand_intro_left <| persistent_and_affinely_sep_left.mpr.trans imp_elim_right
2373+ · exact imp_intro_swap <| persistent_and_affinely_sep_left.mp.trans wand_elim_right
2374+
2375+ @ [rocq_alias bi.from_option_persistent]
2376+ instance from_option_persistent [BI PROP] {P : PROP} {Ψ : α → PROP} {mx : Option α}
2377+ [inst : ∀ x, Persistent (Ψ x)] [Persistent P] : Persistent (mx.elim P Ψ) := by
2378+ cases mx with
2379+ | none => assumption
2380+ | some x => apply inst
2381+
21822382/-! # Limits -/
21832383
21842384@ [rocq_alias bi.limit_preserving_entails]
@@ -2195,6 +2395,11 @@ theorem LimitPreserving.entails [BI PROP] [COFE A] (Φ Ψ : A → PROP) [Φne :
21952395 refine BIBase.BiEntails.of_eq (LimitPreserving.equiv f g _ ?_)
21962396 exact fun n => (h' n).to_eq
21972397
2398+ @ [rocq_alias bi.limit_preserving_emp_valid]
2399+ theorem limitPreserving_emp_valid [BI PROP] [COFE A] (Φ : A → PROP)
2400+ [OFE.NonExpansive Φ] : LimitPreserving (fun x => ⊢ Φ x) :=
2401+ LimitPreserving.entails (fun _ => iprop(emp)) Φ
2402+
21982403@ [rocq_alias bi.limit_preserving_Persistent]
21992404instance limitPreserving_persistent [BI PROP] [COFE A] (Φ : A → PROP) [Φne : OFE.NonExpansive Φ] :
22002405 LimitPreserving (fun x => Persistent (Φ x)) := by
0 commit comments