Skip to content

Commit b6d0b68

Browse files
authored
feat: port all missing theorems in BI/DerivedLaws.lean and BI/DerivedLawsLater.lean (#539)
1 parent 4ac92a5 commit b6d0b68

3 files changed

Lines changed: 246 additions & 8 deletions

File tree

Iris/Iris/BI/DerivedLaws.lean

Lines changed: 211 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/-
22
Copyright (c) 2022 Lars König. All rights reserved.
33
Released 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
-/
66
module
77

@@ -24,8 +24,11 @@ open Iris.Std BI
2424
/- Necessary for `calc`-style proofs. -/
2525
instance 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]
2729
instance 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

3134
instance 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
3740
instance 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]
605610
theorem 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]
608654
instance 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)) :=
613659
theorem 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]
617705
instance 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
642730
theorem 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]
648746
theorem 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]
653751
theorem 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

658757
theorem 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
854971
instance [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

10881210
theorem 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]
13041446
theorem 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]
13081450
theorem 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) ⊣⊢
15091651
theorem 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]
15121655
theorem 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+
15161673
theorem 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} :
15231680
theorem 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]
21482323
theorem 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} :
21792354
theorem 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]
21992404
instance limitPreserving_persistent [BI PROP] [COFE A] (Φ : A → PROP) [Φne : OFE.NonExpansive Φ] :
22002405
LimitPreserving (fun x => Persistent (Φ x)) := by

0 commit comments

Comments
 (0)