diff --git a/src/Iris/BI/Lib/BUpdPlain.lean b/src/Iris/BI/Lib/BUpdPlain.lean index b525eeb8..1cdd96e2 100644 --- a/src/Iris/BI/Lib/BUpdPlain.lean +++ b/src/Iris/BI/Lib/BUpdPlain.lean @@ -34,8 +34,7 @@ theorem BUpdPlain_intro {P : PROP} : P ⊢ BUpdPlain P := by iintro Hp unfold BUpdPlain iintro _ H - iapply H - iexact Hp + iapply H $$ Hp theorem BUpdPlain_mono {P Q : PROP} : (P ⊢ Q) → (BUpdPlain P ⊢ BUpdPlain Q) := by intros H @@ -43,27 +42,24 @@ theorem BUpdPlain_mono {P Q : PROP} : (P ⊢ Q) → (BUpdPlain P ⊢ BUpdPlain Q iintro R HQR iintro Hp have H1 : ⊢ iprop(Q -∗ ■ HQR) -∗ iprop(P -∗ ■ HQR) := by - iintro H - iintro Hp + iintro H Hp iapply H apply H iintro ⟨Ha, H2⟩ - iapply Ha $! HQR - iapply H1 - iexact H2 + iapply Ha + iapply H1 $$ H2 theorem BUpdPlain_idemp {P : PROP} : BUpdPlain (BUpdPlain P) ⊢ BUpdPlain P := by unfold BUpdPlain iintro Hp R H - iapply Hp $! R + iapply Hp iintro Hp - iapply Hp $! R - iassumption + iapply Hp $$ H theorem BUpdPlain_frame_r {P Q : PROP} : BUpdPlain P ∗ Q ⊢ (BUpdPlain iprop(P ∗ Q)) := by unfold BUpdPlain iintro ⟨Hp, Hq⟩ R H - iapply Hp $! R + iapply Hp iintro Hp iapply H isplitl [Hp] @@ -73,7 +69,7 @@ theorem BUpdPlain_frame_r {P Q : PROP} : BUpdPlain P ∗ Q ⊢ (BUpdPlain iprop( theorem BUpdPlain_plainly {P : PROP} : BUpdPlain iprop(■ P) ⊢ (■ P) := by unfold BUpdPlain iintro H - iapply H $! P + iapply H exact wand_rfl /- BiBUpdPlainly entails the alternative definition -/ diff --git a/src/Iris/Examples/Proofs.lean b/src/Iris/Examples/Proofs.lean index e61cb97c..106fac2e 100644 --- a/src/Iris/Examples/Proofs.lean +++ b/src/Iris/Examples/Proofs.lean @@ -13,7 +13,7 @@ theorem proof_example_1 [BI PROP] (P Q R : PROP) (Φ : α → PROP) : P ∗ Q ∗ □ R ⊢ □ (R -∗ ∃ x, Φ x) -∗ ∃ x, Φ x ∗ P ∗ Q := by iintro ⟨HP, HQ, □HR⟩ □HRΦ - ihave HΦ := HRΦ with HR + ihave HΦ := HRΦ $$ HR icases HΦ with ⟨x, _HΦ⟩ iexists x isplitr diff --git a/src/Iris/ProofMode/Goals.lean b/src/Iris/ProofMode/Goals.lean index 80a9ba77..2ac3ce6e 100644 --- a/src/Iris/ProofMode/Goals.lean +++ b/src/Iris/ProofMode/Goals.lean @@ -34,10 +34,12 @@ def Goals.addPureGoal {prop : Q(Type u)} {bi : Q(BI $prop)} (g : Goals bi) g.goals.modify (·.push m) -- TODO: change this to replace main goal that deduplicates goals -def Goals.getGoals {prop : Q(Type u)} {bi : Q(BI $prop)} (g : Goals bi) : MetaM (List MVarId) := do +def Goals.getGoals {prop : Q(Type u)} {bi : Q(BI $prop)} (g : Goals bi) : TermElabM (List MVarId) := do let goals ← g.goals.get -- put the goals that depend on other goals last let mvars ← goals.foldlM (λ m g => do return m ∪ (← g.getMVarDependencies)) ∅ let (dep, nonDep) := goals.partition (λ x => mvars.contains x) + -- TODO: Is this the right place to do this? + Term.synthesizeSyntheticMVarsNoPostponing return (nonDep ++ dep).toList diff --git a/src/Iris/ProofMode/Instances.lean b/src/Iris/ProofMode/Instances.lean index f7ea079e..c191e3c4 100644 --- a/src/Iris/ProofMode/Instances.lean +++ b/src/Iris/ProofMode/Instances.lean @@ -86,6 +86,13 @@ instance intoForall_intuitionistically [BI PROP] (P : PROP) (Φ : α → PROP) [h : IntoForall P Φ] : IntoForall iprop(□ P) (fun a => iprop(□ (Φ a))) where into_forall := (intuitionistically_mono h.1).trans intuitionistically_forall_1 +instance intoForall_wand_pure [BI PROP] (P Q : PROP) Φ + [h : FromPure a P Φ] : IntoForall iprop(P -∗ Q) (fun _ : Φ => Q) where + into_forall := forall_intro λ hΦ => + emp_sep.2.trans <| (sep_mono_l <| + (affinelyIf_emp.mpr.trans (affinelyIf_mono (pure_intro hΦ))).trans + h.1).trans wand_elim_r + -- FromExists instance (priority := default + 10) fromExists_exists [BI PROP] (Φ : α → PROP) : FromExists iprop(∃ a, Φ a) Φ := ⟨.rfl⟩ diff --git a/src/Iris/ProofMode/Patterns/ProofModeTerm.lean b/src/Iris/ProofMode/Patterns/ProofModeTerm.lean index 0b45b19d..17fdc605 100644 --- a/src/Iris/ProofMode/Patterns/ProofModeTerm.lean +++ b/src/Iris/ProofMode/Patterns/ProofModeTerm.lean @@ -11,23 +11,17 @@ open Lean declare_syntax_cat pmTerm syntax term : pmTerm -syntax term "with" specPat,+ : pmTerm -syntax term "$!" term,+ : pmTerm -syntax term "$!" term,+ "with" specPat,+ : pmTerm +syntax term "$$" specPat,+ : pmTerm structure PMTerm where term : Term - terms : List Term spats : List SpecPat deriving Repr, Inhabited partial def PMTerm.parse (term : Syntax) : MacroM PMTerm := do match ← expandMacros term with - | `(pmTerm| $trm:term) => return ⟨trm, [], []⟩ - | `(pmTerm| $trm:term with $spats,*) => return ⟨trm, [], ← parseSpats spats⟩ - | `(pmTerm| $trm:term $! $ts,*) => return ⟨trm, ts.getElems.toList, []⟩ - | `(pmTerm| $trm:term $! $ts,* with $spats,*) => - return ⟨trm, ts.getElems.toList, ← parseSpats spats⟩ + | `(pmTerm| $trm:term) => return ⟨trm, []⟩ + | `(pmTerm| $trm:term $$ $spats,*) => return ⟨trm, ← parseSpats spats⟩ | _ => Macro.throwUnsupported where parseSpats (spats : Syntax.TSepArray `specPat ",") : MacroM (List SpecPat) := diff --git a/src/Iris/ProofMode/Patterns/SpecPattern.lean b/src/Iris/ProofMode/Patterns/SpecPattern.lean index c118734b..a482ca60 100644 --- a/src/Iris/ProofMode/Patterns/SpecPattern.lean +++ b/src/Iris/ProofMode/Patterns/SpecPattern.lean @@ -9,11 +9,13 @@ open Lean declare_syntax_cat specPat syntax ident : specPat +syntax "%" term : specPat syntax "[" ident,* "]" optional(" as " ident) : specPat -- see https://gitlab.mpi-sws.org/iris/iris/-/blob/master/iris/proofmode/spec_patterns.v?ref_type=heads#L15 inductive SpecPat | ident (name : Ident) + | pure (t : Term) | goal (names : List Ident) (goalName : Name) deriving Repr, Inhabited @@ -24,14 +26,9 @@ partial def SpecPat.parse (pat : Syntax) : MacroM SpecPat := do where go : TSyntax `specPat → Option SpecPat | `(specPat| $name:ident) => some <| .ident name + | `(specPat| % $term:term) => some <| .pure term | `(specPat| [$[$names:ident],*]) => some <| .goal names.toList .anonymous | `(specPat| [$[$names:ident],*] as $goal:ident) => match goal.raw with | .ident _ _ val _ => some <| .goal names.toList val | _ => none | _ => none - -def headName (spats : List SpecPat) : Name := - match spats.head? with - | some <| .ident _ => .anonymous - | some <| .goal _ name => name - | _ => .anonymous diff --git a/src/Iris/ProofMode/Tactics/Apply.lean b/src/Iris/ProofMode/Tactics/Apply.lean index 58c36120..105c19ec 100644 --- a/src/Iris/ProofMode/Tactics/Apply.lean +++ b/src/Iris/ProofMode/Tactics/Apply.lean @@ -23,7 +23,7 @@ partial def iApplyCore {prop : Q(Type u)} {bi : Q(BI $prop)} (gs : Goals bi) {e} let pf' ← gs.addGoal hyps' A return q(apply $pf $pf') - let some ⟨_, hyps'', pf''⟩ ← try? <| iSpecializeCore gs hyps uniq [] [.goal [] .anonymous] | throwError m!"iapply: cannot apply {out} to {goal}" + let some ⟨_, hyps'', pf''⟩ ← try? <| iSpecializeCore gs hyps uniq [.goal [] .anonymous] | throwError m!"iapply: cannot apply {out} to {goal}" let pf''' ← iApplyCore gs hyps'' goal uniq return q($(pf'').trans $pf''') diff --git a/src/Iris/ProofMode/Tactics/Have.lean b/src/Iris/ProofMode/Tactics/Have.lean index f9d6b169..1c4e97a5 100644 --- a/src/Iris/ProofMode/Tactics/Have.lean +++ b/src/Iris/ProofMode/Tactics/Have.lean @@ -47,7 +47,7 @@ private def iHaveCore (gs : @Goals u prop bi) {e} (hyps : Hyps bi e) def iHave (gs : @Goals u prop bi) {e} (hyps : Hyps bi e) (pmt : PMTerm) (name : TSyntax ``binderIdent) (keep : Bool) (mayPostpone := false) : TacticM (Name × (e' : _) × Hyps bi e' × Q($e ⊢ $e')) := do let ⟨uniq, _, hyps', pf⟩ ← iHaveCore gs hyps pmt.term name keep mayPostpone - let ⟨_, hyps'', pf'⟩ ← iSpecializeCore gs hyps' uniq pmt.terms pmt.spats + let ⟨_, hyps'', pf'⟩ ← iSpecializeCore gs hyps' uniq pmt.spats return ⟨uniq, _, hyps'', q($(pf).trans $pf')⟩ elab "ihave" colGt name:binderIdent " := " pmt:pmTerm : tactic => do diff --git a/src/Iris/ProofMode/Tactics/Specialize.lean b/src/Iris/ProofMode/Tactics/Specialize.lean index 70c23eac..082192a7 100644 --- a/src/Iris/ProofMode/Tactics/Specialize.lean +++ b/src/Iris/ProofMode/Tactics/Specialize.lean @@ -38,18 +38,6 @@ theorem specialize_forall [BI PROP] {p : Bool} {A1 A2 P : PROP} {α : Sort _} { [inst : IntoForall P Φ] (h : A1 ⊢ A2 ∗ □?p P) (a : α) : A1 ⊢ A2 ∗ □?p (Φ a) := by refine h.trans <| sep_mono_r <| intuitionisticallyIf_mono <| inst.1.trans (forall_elim a) -def SpecializeState.process_forall (gs : @Goals u prop bi) : - @SpecializeState u prop bi orig → Term → TermElabM (SpecializeState bi orig) - | { e, hyps, p, out, pf }, arg => do - let v ← mkFreshLevelMVar - let α : Q(Sort v) ← mkFreshExprMVarQ q(Sort v) - let Φ : Q($α → $prop) ← mkFreshExprMVarQ q($α → $prop) - let some _ ← ProofMode.trySynthInstanceQAddingGoals gs q(IntoForall $out $Φ) | throwError "ispecialize: {out} is not a forall" - let x ← elabTermEnsuringTypeQ (u := .succ .zero) arg α - have out' : Q($prop) := Expr.headBeta q($Φ $x) - have : $out' =Q $Φ $x := ⟨⟩ - return { e, hyps, p, out := out', pf := q(specialize_forall $pf $x) } - def SpecializeState.process_wand (gs : @Goals u prop bi) : @SpecializeState u prop bi orig → SpecPat → TermElabM (SpecializeState bi orig) | { hyps, p, out, pf, .. }, .ident i => do @@ -64,6 +52,17 @@ def SpecializeState.process_wand (gs : @Goals u prop bi) : throwError m!"ispecialize: cannot instantiate {out} with {out₁'}" let pf := q(specialize_wand $pf $pf') return { e := e', hyps := hyps', p := p2, out := out₂, pf } + | { e, hyps, p, out, pf, .. }, .pure t => do + let v ← mkFreshLevelMVar + let α : Q(Sort v) ← mkFreshExprMVarQ q(Sort v) + let Φ : Q($α → $prop) ← mkFreshExprMVarQ q($α → $prop) + let some _ ← ProofMode.trySynthInstanceQAddingGoals gs q(IntoForall $out $Φ) | throwError "ispecialize: {out} is not a lean premise" + let x ← elabTermEnsuringTypeQ (u := .succ .zero) t α + have out' : Q($prop) := Expr.headBeta q($Φ $x) + have : $out' =Q $Φ $x := ⟨⟩ + let newMVarIds ← getMVarsNoDelayed x + for mvar in newMVarIds do gs.addPureGoal mvar + return { e, hyps, p, out := out', pf := q(specialize_forall $pf $x) } | { hyps, p, out, pf, .. }, .goal ns g => do let mut uniqs : NameSet := {} for name in ns do @@ -77,12 +76,11 @@ def SpecializeState.process_wand (gs : @Goals u prop bi) : return { e := el', hyps := hypsl', p := q(false), out := out₂, pf } def iSpecializeCore (gs : @Goals u prop bi) {e} (hyps : Hyps bi e) - (uniq : Name) (alls : List Term) (spats : List SpecPat) : TacticM ((e' : _) × Hyps bi e' × Q($e ⊢ $e')) := do + (uniq : Name) (spats : List SpecPat) : TacticM ((e' : _) × Hyps bi e' × Q($e ⊢ $e')) := do let some ⟨name, _, hyps, _, out, p, _, pf⟩ := Id.run <| hyps.removeG true λ name uniq' _ _ => if uniq == uniq' then some name else none | throwError "ispecialize: cannot find argument" let state := { hyps, out, p, pf := q(($pf).1), .. } - let state ← liftM <| alls.foldlM (SpecializeState.process_forall gs) state let state ← liftM <| spats.foldlM (SpecializeState.process_wand gs) state let hyps' := Hyps.add bi name uniq state.p state.out state.hyps @@ -96,7 +94,7 @@ elab "ispecialize" colGt pmt:pmTerm : tactic => do -- hypothesis must be in the context, otherwise use pose proof let name := ⟨pmt.term⟩ let some uniq ← try? <| hyps.findWithInfo name | throwError s!"{name} should be a hypothesis, use ihave instead" - let ⟨_, hyps', pf⟩ ← iSpecializeCore gs hyps uniq pmt.terms pmt.spats + let ⟨_, hyps', pf⟩ ← iSpecializeCore gs hyps uniq pmt.spats let pf' ← gs.addGoal hyps' goal mvar.assign q(($pf).trans $pf') replaceMainGoal (← gs.getGoals) diff --git a/src/Iris/Tests/Tactics.lean b/src/Iris/Tests/Tactics.lean index 800af982..669bbb20 100644 --- a/src/Iris/Tests/Tactics.lean +++ b/src/Iris/Tests/Tactics.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2022 Lars König. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Lars König, Oliver Soeser +Authors: Lars König, Oliver Soeser, Michael Sammler -/ import Iris.BI import Iris.ProofMode @@ -12,7 +12,8 @@ open Iris.BI /- This file contains tests with various scenarios for all available tactics. -/ -- start stop -theorem start_stop [BI PROP] (Q : PROP) (H : Q ⊢ Q) : Q ⊢ Q := by +/-- Tests `istart` and `istop` for entering and exiting proof mode -/ +example [BI PROP] (Q : PROP) (H : Q ⊢ Q) : Q ⊢ Q := by istart iintro _HQ istop @@ -21,23 +22,27 @@ theorem start_stop [BI PROP] (Q : PROP) (H : Q ⊢ Q) : Q ⊢ Q := by -- rename namespace rename -theorem rename [BI PROP] (Q : PROP) : Q ⊢ Q := by +/-- Tests basic hypothesis renaming with `irename` -/ +example [BI PROP] (Q : PROP) : Q ⊢ Q := by iintro HQ irename HQ => H iexact H -theorem rename_by_type [BI PROP] (Q : PROP) : □ P ∗ Q ⊢ Q := by +/-- Tests renaming a hypothesis by its type -/ +example [BI PROP] (P Q : PROP) : □ P ∗ Q ⊢ Q := by iintro ⟨_HP, HQ⟩ irename: Q => H iexact H -theorem rename_twice [BI PROP] (Q : PROP) : Q ⊢ Q := by +/-- Tests renaming a hypothesis twice -/ +example [BI PROP] (Q : PROP) : Q ⊢ Q := by iintro HQ irename HQ => H irename H => HQ iexact HQ -theorem rename_id [BI PROP] (Q : PROP) : Q ⊢ Q := by +/-- Tests renaming a hypothesis to itself (no-op) -/ +example [BI PROP] (Q : PROP) : Q ⊢ Q := by iintro HQ irename HQ => HQ iexact HQ @@ -47,13 +52,15 @@ end rename -- clear namespace clear -theorem intuitionistic [BI PROP] (Q : PROP) : □ P ⊢ Q -∗ Q := by +/-- Tests clearing an intuitionistic hypothesis with `iclear` -/ +example [BI PROP] (Q : PROP) : □ P ⊢ Q -∗ Q := by iintro □HP iintro HQ iclear HP iexact HQ -theorem spatial [BI PROP] (Q : PROP) : P ⊢ Q -∗ Q := by +/-- Tests clearing a spatial affine hypothesis with `iclear` -/ +example [BI PROP] (Q : PROP) : P ⊢ Q -∗ Q := by iintro HP iintro HQ iclear HP @@ -64,52 +71,64 @@ end clear -- intro namespace intro -theorem spatial [BI PROP] (Q : PROP) : Q ⊢ Q := by +/-- Tests introducing a spatial hypothesis -/ +example [BI PROP] (Q : PROP) : Q ⊢ Q := by iintro HQ iexact HQ -theorem intuitionistic [BI PROP] (Q : PROP) : □ Q ⊢ Q := by +/-- Tests introducing an intuitionistic hypothesis with the `□` pattern -/ +example [BI PROP] (Q : PROP) : □ Q ⊢ Q := by iintro □HQ iexact HQ -theorem as_intuitionistic [BI PROP] (Q : PROP) : Q ⊢ Q := by +/-- Tests introducing an affine persistent proposition as intuitionistic -/ +example [BI PROP] (Q : PROP) : Q ⊢ Q := by iintro □HQ iexact HQ -theorem as_intuitionistic_in_spatial [BI PROP] (Q : PROP) : ⊢ Q → Q := by +/-- Tests introducing a persistent implication in the spatial context -/ +example [BI PROP] (Q : PROP) : ⊢ Q → Q := by iintro HQ iexact HQ -theorem drop [BI PROP] (Q : PROP) : ⊢ P → Q -∗ Q := by +/-- Tests dropping a hypothesis in an implication with the `-` pattern -/ +example [BI PROP] (Q : PROP) : ⊢ P → Q -∗ Q := by iintro - HQ iexact HQ -theorem drop_after [BI PROP] (Q : PROP) : ⊢ Q -∗ P → Q := by +/-- Tests dropping a hypothesis in an implication in a non-empty context -/ +example [BI PROP] (Q : PROP) : ⊢ Q -∗ P → Q := by iintro HQ - iexact HQ -theorem «forall» [BI PROP] : ⊢ ∀ x, ⌜x = 0⌝ → (⌜x = 0⌝ : PROP) := by +/-- Tests introducing an universally quantified variable -/ +example [BI PROP] : ⊢@{PROP} ∀ x, ⌜x = 0⌝ → ⌜x = 0⌝ := by iintro x iintro H iexact H -theorem pure [BI PROP] [BIAffine PROP] (Q : PROP) : ⊢ ⌜φ⌝ -∗ Q -∗ Q := by +/-- Tests introducing and extracting a pure hypothesis in affine BI -/ +example [BI PROP] [BIAffine PROP] φ (Q : PROP) : ⊢ ⌜φ⌝ -∗ Q -∗ Q := by iintro ⌜Hφ⌝ HQ iexact HQ -theorem pattern [BI PROP] (Q : PROP) : □ (P1 ∨ P2) ∗ Q ⊢ Q := by +/-- Tests introducing with disjunction pattern inside intuitionistic -/ +example [BI PROP] (P1 P2 Q : PROP) : □ (P1 ∨ P2) ∗ Q ⊢ Q := by iintro ⟨□(_HP1 | _HP2), HQ⟩ <;> iexact HQ -theorem multiple_spatial [BI PROP] (Q : PROP) : ⊢ P -∗ Q -∗ Q := by +/-- Tests introducing multiple spatial hypotheses -/ +example [BI PROP] (P Q : PROP) : ⊢ P -∗ Q -∗ Q := by iintro _HP HQ iexact HQ -theorem multiple_intuitionistic [BI PROP] (Q : PROP) : ⊢ □ P -∗ □ Q -∗ Q := by +/-- Tests introducing multiple intuitionistic hypotheses -/ +example [BI PROP] (Q : PROP) : ⊢ □ P -∗ □ Q -∗ Q := by iintro □_HP □HQ iexact HQ -theorem multiple_patterns [BI PROP] (Q : PROP) : ⊢ □ (P1 ∧ P2) -∗ Q ∨ Q -∗ Q := by +/-- Tests introducing with complex nested patterns -/ +example [BI PROP] (Q : PROP) : ⊢ □ (P1 ∧ P2) -∗ Q ∨ Q -∗ Q := by iintro □⟨_HP1, ∗_HP2⟩ (HQ | HQ) <;> iexact HQ @@ -118,34 +137,40 @@ end intro -- exists namespace «exists» -theorem id [BI PROP] : ⊢@{PROP} ∃ x, x := by +/-- Tests `iexists` with a BI proposition -/ +example [BI PROP] : ⊢@{PROP} ∃ x, x := by iexists iprop(True) ipure_intro exact True.intro -theorem f [BI PROP] : ⊢@{PROP} ∃ (_x : Nat), True ∨ False := by +/-- Tests `iexists` with a natural number -/ +example [BI PROP] : ⊢@{PROP} ∃ (_x : Nat), True ∨ False := by iexists 42 ileft ipure_intro exact True.intro -theorem pure [BI PROP] : ⊢@{PROP} ⌜∃ x, x ∨ False⌝ := by +/-- Tests `iexists` with Prop -/ +example [BI PROP] : ⊢@{PROP} ⌜∃ x, x ∨ False⌝ := by iexists True ipure_intro exact Or.inl True.intro -theorem mvar [BI PROP] : ⊢@{PROP} ∃ x, ⌜x = 42⌝ := by +/-- Tests `iexists` with a named metavariable -/ +example [BI PROP] : ⊢@{PROP} ∃ x, ⌜x = 42⌝ := by iexists ?y ipure_intro rfl -theorem mvar_anon [BI PROP] : ⊢@{PROP} ∃ x, ⌜x = 42⌝ := by +/-- Tests `iexists` with anonymous metavariable -/ +example [BI PROP] : ⊢@{PROP} ∃ x, ⌜x = 42⌝ := by iexists _ ipure_intro rfl -theorem mvar_two [BI PROP] : ⊢@{PROP} ∃ x y : Nat, ⌜x = y⌝ := by +/-- Tests `iexists` with two quantifiers -/ +example [BI PROP] : ⊢@{PROP} ∃ x y : Nat, ⌜x = y⌝ := by iexists _, 1 ipure_intro rfl @@ -156,15 +181,18 @@ end «exists» -- exact namespace exact -theorem exact [BI PROP] (Q : PROP) : Q ⊢ Q := by +/-- Tests basic `iexact` -/ +example [BI PROP] (Q : PROP) : Q ⊢ Q := by iintro HQ iexact HQ -theorem def_eq [BI PROP] (Q : PROP) : Q ⊢ □ Q := by +/-- Tests `iexact` with affine pers to intuitionistic -/ +example [BI PROP] (Q : PROP) : Q ⊢ □ Q := by iintro HQ iexact HQ -theorem intuitionistic [BI PROP] (Q : PROP) : □ Q ⊢ Q := by +/-- Tests `iexact` with intuitionistic hypothesis -/ +example [BI PROP] (Q : PROP) : □ Q ⊢ Q := by iintro HQ iexact HQ @@ -173,23 +201,28 @@ end exact -- assumption namespace assumption -theorem exact [BI PROP] (Q : PROP) : Q ⊢ Q := by +/-- Tests `iassumption` for exact match -/ +example [BI PROP] (Q : PROP) : Q ⊢ Q := by iintro _HQ iassumption -theorem from_assumption [BI PROP] (Q : PROP) : Q ⊢ □ Q := by +/-- Tests `iassumption` with affine pers to intuitionistic -/ +example [BI PROP] (Q : PROP) : Q ⊢ □ Q := by iintro _HQ iassumption -theorem intuitionistic [BI PROP] (Q : PROP) : □ Q ⊢ Q := by +/-- Tests `iassumption` with intuitionistic hypothesis -/ +example [BI PROP] (Q : PROP) : □ Q ⊢ Q := by iintro □_HQ iassumption -theorem lean [BI PROP] (Q : PROP) (H : ⊢ Q) : P ⊢ Q := by +/-- Tests `iassumption` using a Lean hypothesis -/ +example [BI PROP] (Q : PROP) (H : ⊢ Q) : P ⊢ Q := by iintro _HP iassumption -theorem lean_pure [BI PROP] (Q : PROP) : ⌜⊢ Q⌝ ⊢ Q := by +/-- Tests `iassumption` with Lean hypothesis first introduced -/ +example [BI PROP] (Q : PROP) : ⌜⊢ Q⌝ ⊢ Q := by iintro ⌜H⌝ iassumption @@ -198,157 +231,196 @@ end assumption -- apply namespace apply -theorem exact [BI PROP] (Q : PROP) : Q ⊢ Q := by +/-- Tests `iapply` with exact match -/ +example [BI PROP] (Q : PROP) : Q ⊢ Q := by iintro HQ iapply HQ -theorem apply [BI PROP] (P Q : PROP) : ⊢ P -∗ (P -∗ Q) -∗ Q := by +/-- Tests `iapply` with wand -/ +example [BI PROP] (P Q : PROP) : ⊢ P -∗ (P -∗ Q) -∗ Q := by iintro HP H - iapply H with HP + iapply H $$ HP -theorem multiple [BI PROP] (P Q R : PROP) : ⊢ P -∗ Q -∗ (P -∗ Q -∗ R) -∗ R := by +/-- Tests `iapply` with multiple hypotheses -/ +example [BI PROP] (P Q R : PROP) : ⊢ P -∗ Q -∗ (P -∗ Q -∗ R) -∗ R := by iintro HP HQ H - iapply H with HP, HQ + iapply H $$ HP, HQ -theorem multiple' [BI PROP] (P Q R S : PROP) : ⊢ (P -∗ Q) -∗ P -∗ R -∗ (Q -∗ R -∗ S) -∗ S := by +/-- Tests `iapply` with nested wand application -/ +example [BI PROP] (P Q R S : PROP) : ⊢ (P -∗ Q) -∗ P -∗ R -∗ (Q -∗ R -∗ S) -∗ S := by iintro HPQ HP HR H - iapply H with [HPQ, HP], HR - iapply HPQ with HP + iapply H $$ [HPQ, HP], HR + iapply HPQ $$ HP -theorem exact_intuitionistic [BI PROP] (Q : PROP) : □ Q ⊢ Q := by +/-- Tests `iapply` with intuitionistic exact -/ +example [BI PROP] (Q : PROP) : □ Q ⊢ Q := by iintro □HQ iapply HQ -theorem apply_intuitionistic [BI PROP] (P Q : PROP) : ⊢ □ P -∗ (P -∗ Q) -∗ Q := by +/-- Tests `iapply` with intuitionistic wand argument -/ +example [BI PROP] (P Q : PROP) : ⊢ □ P -∗ (P -∗ Q) -∗ Q := by iintro HP H - iapply H with HP + iapply H $$ HP -theorem multiple_intuitionistic [BI PROP] (P Q R : PROP) : ⊢ □ P -∗ Q -∗ □ (P -∗ Q -∗ □ R) -∗ R := by +/-- Tests `iapply` with multiple intuitionistic hypotheses and subgoals -/ +example [BI PROP] (P Q R : PROP) : ⊢ □ P -∗ Q -∗ □ (P -∗ Q -∗ □ R) -∗ R := by iintro □HP HQ □H - iapply H with [], [HQ] as Q + iapply H $$ [], [HQ] as Q case Q => iexact HQ iexact HP -theorem later [BI PROP] (P Q : PROP) : ⊢ (▷ P -∗ Q) -∗ P -∗ Q := by +/-- Tests `iapply` with later modality -/ +example [BI PROP] (P Q : PROP) : ⊢ (▷ P -∗ Q) -∗ P -∗ Q := by iintro H HP - iapply H with HP + iapply H $$ HP -theorem test_affine [BI PROP] [BIAffine PROP] (P Q : PROP) : ⊢ (P → Q) -∗ P -∗ Q := by +/-- Tests `iapply` with implication -/ +example [BI PROP] [BIAffine PROP] (P Q : PROP) : ⊢ (P → Q) -∗ P -∗ Q := by iintro H HP - iapply H with HP + iapply H $$ HP -theorem later_affine [BI PROP] [BIAffine PROP] (P Q : PROP) : ⊢ (▷ P → Q) -∗ P -∗ Q := by +/-- Tests `iapply` with later and implication -/ +example [BI PROP] [BIAffine PROP] (P Q : PROP) : ⊢ (▷ P → Q) -∗ P -∗ Q := by iintro H HP - iapply H with HP + iapply H $$ HP -theorem exact_lean [BI PROP] (Q : PROP) (H : ⊢ Q) : ⊢ Q := by +/-- Tests `iapply` with Lean hypothesis -/ +example [BI PROP] (Q : PROP) (H : ⊢ Q) : ⊢ Q := by iapply H -theorem exact_lean' [BI PROP] (Q : PROP) : Q ⊢ (emp ∗ Q) ∗ emp := by +/-- Tests `iapply` with lemma -/ +example [BI PROP] (Q : PROP) : Q ⊢ (emp ∗ Q) ∗ emp := by iapply (wand_intro sep_emp.mpr) iemp_intro -theorem exact_lean'' [BI PROP] (Q : PROP) (H : 0 = 0 → ⊢ Q) : ⊢ Q := by +/-- Tests `iapply` with pure sidecondition -/ +example [BI PROP] (Q : PROP) (H : 0 = 0 → ⊢ Q) : ⊢ Q := by iapply H rfl -theorem exact_lean''' [BI PROP] : ⊢@{PROP} ⌜1 = 1⌝ := by +/-- Tests `iapply` with lemma with sidecondition -/ +example [BI PROP] : ⊢@{PROP} ⌜1 = 1⌝ := by istart iapply (pure_intro (P:=emp)) . rfl iemp_intro -theorem apply_lean [BI PROP] (P Q : PROP) (H : P ⊢ Q) (HP : ⊢ P) : ⊢ Q := by +/-- Tests `iapply` with entailment as Lean hypothesis -/ +example [BI PROP] (P Q : PROP) (H : P ⊢ Q) (HP : ⊢ P) : ⊢ Q := by iapply H iapply HP -theorem apply_lean' [BI PROP] (P Q : PROP) (H : ⊢ P -∗ Q) (HP : ⊢ P) : ⊢ Q := by - iapply H with [] +/-- Tests `iapply` with wand entailment as Lean hypothesis -/ +example [BI PROP] (P Q : PROP) (H : ⊢ P -∗ Q) (HP : ⊢ P) : ⊢ Q := by + iapply H $$ [] iapply HP -theorem apply_lean'' [BI PROP] (P Q : PROP) (H1 : P ⊢ Q) (H2 : Q ⊢ R) : P ⊢ R := by +/-- Tests `iapply` with constructed term -/ +example [BI PROP] (P Q : PROP) (H1 : P ⊢ Q) (H2 : Q ⊢ R) : P ⊢ R := by iintro HP iapply (wand_intro (emp_sep.mp.trans H2)) . ipure_intro; trivial - iapply H1 with HP + iapply H1 $$ HP -theorem multiple_lean [BI PROP] (P Q R : PROP) (H : P ⊢ Q -∗ R) (HP : ⊢ P) : ⊢ Q -∗ R := by +/-- Tests `iapply` with Lean wand entailment and subgoal -/ +example [BI PROP] (P Q R : PROP) (H : P ⊢ Q -∗ R) (HP : ⊢ P) : ⊢ Q -∗ R := by iintro HQ - iapply H with [], HQ + iapply H $$ [], HQ iapply HP -theorem multiple_lean' [BI PROP] (P Q R : PROP) (H : P ∗ Q ⊢ R) (HP : ⊢ P) : ⊢ Q -∗ R := by +/-- Tests `iapply` with lemma and subgoal -/ +example [BI PROP] (P Q R : PROP) (H : P ∗ Q ⊢ R) (HP : ⊢ P) : ⊢ Q -∗ R := by iintro HQ - iapply (wand_intro H) with [], HQ + iapply (wand_intro H) $$ [], HQ iapply HP -theorem exact_forall [BI PROP] (P : α → PROP) (a : α) (H : ⊢ ∀ x, P x) : ⊢ P a := by +/-- Tests `iapply` with forall -/ +example [BI PROP] (P : α → PROP) (a : α) (H : ⊢ ∀ x, P x) : ⊢ P a := by istart iapply H -theorem exact_forall' [BI PROP] (P : α → PROP) (a : α) (H : ∀ x, ⊢ P x) : ⊢ P a := by +/-- Tests `iapply` with Lean forall -/ +example [BI PROP] (P : α → PROP) (a : α) (H : ∀ x, ⊢ P x) : ⊢ P a := by iapply H -theorem apply_forall [BI PROP] (P Q : α → PROP) (a b : α) (H : ⊢ ∀ x, ∀ y, P x -∗ Q y) : P a ⊢ Q b := by +/-- Tests `iapply` with forall specialization -/ +example [BI PROP] (P Q : α → PROP) (a b : α) (H : ⊢ ∀ x, ∀ y, P x -∗ Q y) : P a ⊢ Q b := by iintro HP - iapply H $! a, b with HP + iapply H $$ %a, %b, HP -theorem apply_forall' [BI PROP] (P Q : α → PROP) (a b : α) : (∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by +/-- Tests `iapply` with forall specialization from hypothesis -/ +example [BI PROP] (P Q : α → PROP) (a b : α) : (∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by iintro H HP - iapply H $! a, b with HP + iapply H $$ %a, %b, HP -/-- error: ispecialize: iprop(P a -∗ Q b) is not a forall -/ +/-- Tests `iapply` with tactic -/ +example [BI PROP] (P Q : α → PROP) (a b : α) : (∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by + iintro H HP + iapply H $$ %by exact a, %b, [HP] + iapply HP + +/-- error: ispecialize: iprop(P a -∗ Q b) is not a lean premise -/ #guard_msgs in -theorem apply_forall_too_many [BI PROP] (P Q : α → PROP) (a b : α) : (∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by +example [BI PROP] (P Q : α → PROP) (a b : α) : (∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by iintro H HP - iapply H $! a, b, _ with HP + iapply H $$ %a, %b, %_, HP -theorem apply_forall2 [BI PROP] (P Q : α → PROP) (a b : α) : (∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by +/-- Tests `iapply` using unification for foralls -/ +example [BI PROP] (P Q : α → PROP) (a b : α) : (∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by iintro H HP - iapply H with HP + iapply H $$ HP -theorem apply_forall3 [BI PROP] (P Q : α → PROP) (a b : α) : (∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by +/-- Tests `iapply` using manually created metavariables -/ +example [BI PROP] (P Q : α → PROP) (a b : α) : (∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by iintro H HP - iapply H $! ?_, ?_ with HP + iapply H $$ %?_, %?_, HP -theorem apply_forall4 [BI PROP] (P Q : α → PROP) (a b : α) : (∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by +/-- Tests `iapply` using unification in two steps, instantiating metavars -/ +example [BI PROP] (P Q : α → PROP) (a b : α) : (∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by iintro H HP iapply H iapply HP -theorem apply_forall_intuitionistic [BI PROP] (P Q : α → PROP) (a b : α) (H : ⊢ □ ∀ x, ∀ y, P x -∗ Q y) : P a ⊢ Q b := by +/-- Tests `iapply` with intuitionistic forall from Lean -/ +example [BI PROP] (P Q : α → PROP) (a b : α) (H : ⊢ □ ∀ x, ∀ y, P x -∗ Q y) : P a ⊢ Q b := by iintro HP - iapply H $! a with HP + iapply H $$ %a, HP -theorem apply_forall_intuitionistic' [BI PROP] (P Q : α → PROP) (a b : α) : (□ ∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by +/-- Tests `iapply` with intuitionistic forall from hypothesis -/ +example [BI PROP] (P Q : α → PROP) (a b : α) : (□ ∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by iintro H HP - iapply H $! a, b with HP + iapply H $$ %a, %b, HP -theorem apply_two_wands [BI PROP] (P Q : Nat → PROP) : +/-- Tests `iapply` with two wands and subgoals -/ +example [BI PROP] (P Q : Nat → PROP) : (P 1 -∗ P 2 -∗ Q 1) ⊢ □ P 1 -∗ P 2 -∗ Q 1 := by iintro H □HP1 HP2 iapply H . iexact HP1 . iexact HP2 -theorem apply_and_l [BI PROP] (P Q : Nat → PROP) : +/-- Tests `iapply` selecting left conjunct -/ +example [BI PROP] (P Q : Nat → PROP) : ((P 1 -∗ P 2) ∧ (Q 1 -∗ Q 2)) ⊢ P 1 -∗ P 2 := by iintro H HP1 iapply H iexact HP1 -theorem apply_and_r [BI PROP] (P Q : Nat → PROP) : +/-- Tests `iapply` selecting right conjunct -/ +example [BI PROP] (P Q : Nat → PROP) : ((P 1 -∗ P 2) ∧ (Q 1 -∗ Q 2)) ⊢ Q 1 -∗ Q 2 := by iintro H HQ1 iapply H iexact HQ1 -theorem apply_and_l_exact [BI PROP] (P Q : Nat → PROP) : +/-- Tests `iapply` selecting left conjunct (exact match) -/ +example [BI PROP] (P Q : Nat → PROP) : (P 1 ∧ Q 1) ⊢ P 1 := by iintro H iapply H -theorem apply_and_r_exact [BI PROP] (P Q : Nat → PROP) : +/-- Tests `iapply` selecting right conjunct (exact match) -/ +example [BI PROP] (P Q : Nat → PROP) : (P 1 ∧ Q 1) ⊢ Q 1 := by iintro H iapply H @@ -358,67 +430,80 @@ end apply -- have namespace ihave -theorem exact_lean [BI PROP] (Q : PROP) (H : ⊢ Q) : ⊢ Q := by +/-- Tests `ihave` with Lean hypothesis -/ +example [BI PROP] (Q : PROP) (H : ⊢ Q) : ⊢ Q := by ihave HQ := H iexact HQ -theorem exact_lean_forall [BI PROP] (Q : Nat → PROP) (H : ∀ x, ⊢ Q x) : ⊢ Q 1 := by +/-- Tests `ihave` with forall specialization via case -/ +example [BI PROP] (Q : Nat → PROP) (H : ∀ x, ⊢ Q x) : ⊢ Q 1 := by ihave HQ := H case x => exact 1 iapply HQ -theorem exact_lean_forall2 [BI PROP] (Q : Nat → PROP) (H : ∀ x, ⊢ Q x) : ⊢ Q 1 := by +/-- Tests `ihave` with forall specialization via named hole -/ +example [BI PROP] (Q : Nat → PROP) (H : ∀ x, ⊢ Q x) : ⊢ Q 1 := by ihave HQ := H ?res case res => exact 1 iexact HQ -theorem exact_lean_forall3 [BI PROP] (Q : Nat → Nat → PROP) (H : ∀ x y, ⊢ Q x y) : ⊢ Q 1 1 := by +/-- Tests `ihave` with two named holes -/ +example [BI PROP] (Q : Nat → Nat → PROP) (H : ∀ x y, ⊢ Q x y) : ⊢ Q 1 1 := by ihave HQ := H ?res ?res case res => exact 1 iexact HQ -theorem exact_lean_forall4 [BI PROP] (Q : Nat → PROP) (H : ∀ x, ⊢ Q x) : ⊢ Q 1 := by +/-- Tests `ihave` creating metavars -/ +example [BI PROP] (Q : Nat → PROP) (H : ∀ x, ⊢ Q x) : ⊢ Q 1 := by ihave HQ := H iexact HQ -theorem exact_lean_tc [BI PROP] (Q : Nat → PROP) (H : ∀ (P : PROP) [Persistent P], ⊢ P) : ⊢ Q 1 := by +/-- Tests `ihave` with typeclass argument (failing search) -/ +example [BI PROP] (Q : Nat → PROP) (H : ∀ (P : PROP) [Persistent P], ⊢ P) : ⊢ Q 1 := by ihave HQ := H rotate_right 1; exact iprop(□ Q 1) . apply inferInstance iexact HQ -theorem exact_lean_tc2 [BI PROP] (Q : Nat → PROP) (H : ∀ (P : PROP) [Persistent P], ⊢ P) : ⊢ Q 1 := by +/-- Tests `ihave` with typeclass argument (successful search) -/ +example [BI PROP] (Q : Nat → PROP) (H : ∀ (P : PROP) [Persistent P], ⊢ P) : ⊢ Q 1 := by ihave HQ := H iprop(□ Q _) rotate_right 1; exact 1 iexact HQ -theorem exact_spatial [BI PROP] (Q : PROP) : Q ⊢ Q := by +/-- Tests `ihave` from spatial hypothesis -/ +example [BI PROP] (Q : PROP) : Q ⊢ Q := by iintro H ihave HQ := H iexact HQ -theorem apply_lean [BI PROP] (P Q : PROP) (H : P ⊢ Q) : ⊢ P -∗ Q := by +/-- Tests `ihave` with Lean entailment -/ +example [BI PROP] (P Q : PROP) (H : P ⊢ Q) : ⊢ P -∗ Q := by ihave HPQ := H iexact HPQ -theorem apply_forall [BI PROP] (P Q : α → PROP) (a b : α) (H : ⊢ ∀ x, ∀ y, P x -∗ Q y) : P a ⊢ Q b := by +/-- Tests `ihave` with forall specialization from Lean -/ +example [BI PROP] (P Q : α → PROP) (a b : α) (H : ⊢ ∀ x, ∀ y, P x -∗ Q y) : P a ⊢ Q b := by iintro HP - ihave H' := H $! a, b - iapply H' with HP + ihave H' := H $$ %a, %b + iapply H' $$ HP -theorem apply_forall_spatial [BI PROP] (P Q : α → PROP) (a b : α) : (∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by +/-- Tests `ihave` with forall specialization from hypothesis -/ +example [BI PROP] (P Q : α → PROP) (a b : α) : (∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by iintro H HP - ihave H' := H $! a, b with HP + ihave H' := H $$ %a, %b, HP iexact H' -theorem apply_forall_intuitionistic [BI PROP] (P Q : α → PROP) (a b : α) (H : ⊢ □ ∀ x, ∀ y, P x -∗ Q y) : P a ⊢ Q b := by +/-- Tests `ihave` with intuitionistic forall specialization from Lean -/ +example [BI PROP] (P Q : α → PROP) (a b : α) (H : ⊢ □ ∀ x, ∀ y, P x -∗ Q y) : P a ⊢ Q b := by iintro HP - ihave H' := H $! a, b - iapply H' with HP + ihave H' := H $$ %a, %b + iapply H' $$ HP -theorem apply_forall_intuitionistic_iris [BI PROP] (P Q : α → PROP) (a b : α) : (□ ∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by +/-- Tests `ihave` with intuitionistic forall specialization and subgoal -/ +example [BI PROP] (P Q : α → PROP) (a b : α) : (□ ∀ x, ∀ y, P x -∗ Q y) ⊢ P a -∗ Q b := by iintro H HP - ihave H' := H $! a, b with [HP] + ihave H' := H $$ %a, %b, [HP] . iexact HP iexact H' @@ -427,15 +512,18 @@ end ihave -- ex falso namespace exfalso -theorem false_intro [BI PROP] (Q : PROP) : False ⊢ Q := by +/-- Tests false elimination via empty pattern -/ +example [BI PROP] (Q : PROP) : False ⊢ Q := by iintro ⟨⟩ -theorem false [BI PROP] (P : PROP) : □ P ⊢ False -∗ Q := by +/-- Tests `iexfalso` with false hypothesis -/ +example [BI PROP] (P : PROP) : □ P ⊢ False -∗ Q := by iintro _HP HF iexfalso iexact HF -theorem pure [BI PROP] (P : PROP) (HF : False) : ⊢ P := by +/-- Tests `iexfalso` with pure false from Lean -/ +example [BI PROP] (P : PROP) (HF : False) : ⊢ P := by istart iexfalso ipure_intro @@ -446,13 +534,15 @@ end exfalso -- pure namespace pure -theorem move [BI PROP] (Q : PROP) : ⌜φ⌝ ⊢ Q -∗ Q := by +/-- Tests `ipure` to move pure hypothesis to Lean context -/ +example [BI PROP] (Q : PROP) : ⌜φ⌝ ⊢ Q -∗ Q := by iintro Hφ iintro HQ ipure Hφ iexact HQ -theorem move_multiple [BI PROP] (Q : PROP) : ⌜φ1⌝ ⊢ ⌜φ2⌝ -∗ Q -∗ Q := by +/-- Tests `ipure` with multiple pure hypotheses -/ +example [BI PROP] (Q : PROP) : ⌜φ1⌝ ⊢ ⌜φ2⌝ -∗ Q -∗ Q := by iintro Hφ1 iintro Hφ2 iintro HQ @@ -460,7 +550,8 @@ theorem move_multiple [BI PROP] (Q : PROP) : ⌜φ1⌝ ⊢ ⌜ ipure Hφ2 iexact HQ -theorem move_conjunction [BI PROP] (Q : PROP) : (⌜φ1⌝ ∧ ⌜φ2⌝) ⊢ Q -∗ Q := by +/-- Tests `ipure` with conjunction containing pure -/ +example [BI PROP] (Q : PROP) : (⌜φ1⌝ ∧ ⌜φ2⌝) ⊢ Q -∗ Q := by iintro Hφ iintro HQ ipure Hφ @@ -471,20 +562,23 @@ end pure -- intuitionistic namespace intuitionistic -theorem move [BI PROP] (P : PROP) : □ P ⊢ Q -∗ Q := by +/-- Tests `iintuitionistic` to move hypothesis to intuitionistic context -/ +example [BI PROP] (P : PROP) : □ P ⊢ Q -∗ Q := by iintro HP iintro HQ iintuitionistic HP iexact HQ -theorem move_multiple [BI PROP] (P : PROP) : □ P ⊢ □ Q -∗ Q := by +/-- Tests `iintuitionistic` with multiple hypotheses -/ +example [BI PROP] (P : PROP) : □ P ⊢ □ Q -∗ Q := by iintro HP iintro HQ iintuitionistic HP iintuitionistic HQ iexact HQ -theorem move_twice [BI PROP] (P : PROP) : □ P ⊢ Q -∗ Q := by +/-- Tests `iintuitionistic` applied twice to same hypothesis -/ +example [BI PROP] (P : PROP) : □ P ⊢ Q -∗ Q := by iintro HP iintro HQ iintuitionistic HP @@ -496,20 +590,23 @@ end intuitionistic -- spatial namespace spatial -theorem move [BI PROP] (P : PROP) : □ P ⊢ □ Q -∗ Q := by +/-- Tests `ispatial` to move hypothesis to spatial context -/ +example [BI PROP] (P : PROP) : □ P ⊢ □ Q -∗ Q := by iintro □HP iintro □HQ ispatial HP iexact HQ -theorem move_multiple [BI PROP] (P : PROP) : □ P ⊢ □ Q -∗ Q := by +/-- Tests `ispatial` with multiple hypotheses -/ +example [BI PROP] (P : PROP) : □ P ⊢ □ Q -∗ Q := by iintro □HP iintro □HQ ispatial HP ispatial HQ iexact HQ -theorem move_twice [BI PROP] (P : PROP) : □ P ⊢ □ Q -∗ Q := by +/-- Tests `ispatial` applied twice to same hypothesis -/ +example [BI PROP] (P : PROP) : □ P ⊢ □ Q -∗ Q := by iintro □HP iintro □HQ ispatial HP @@ -521,10 +618,12 @@ end spatial -- emp intro namespace empintro -theorem simple [BI PROP] : ⊢ (emp : PROP) := by +/-- Tests `iemp_intro` for proving emp -/ +example [BI PROP] : ⊢@{PROP} emp := by iemp_intro -theorem affine_env [BI PROP] (P : PROP) : P ⊢ emp := by +/-- Tests `iemp_intro` with affine environment -/ +example [BI PROP] (P : PROP) : P ⊢ emp := by iintro _HP iemp_intro @@ -533,15 +632,18 @@ end empintro -- pure intro namespace pureintro -theorem simple [BI PROP] : ⊢ (⌜True⌝ : PROP) := by +/-- Tests `ipure_intro` for True -/ +example [BI PROP] : ⊢@{PROP} ⌜True⌝ := by ipure_intro exact True.intro -theorem or [BI PROP] : ⊢ True ∨ (False : PROP) := by +/-- Tests `ipure_intro` for disjunction -/ +example [BI PROP] : ⊢@{PROP} True ∨ False := by ipure_intro apply Or.inl True.intro -theorem with_proof [BI PROP] (H : A → B) (P Q : PROP) : P ⊢ Q → ⌜A⌝ → ⌜B⌝ := by +/-- Tests `ipure_intro` with context -/ +example [BI PROP] (H : A → B) (P Q : PROP) : P ⊢ Q → ⌜A⌝ → ⌜B⌝ := by iintro _HP □_HQ ipure_intro exact H @@ -551,128 +653,178 @@ end pureintro -- specialize namespace specialize -theorem wand_spatial [BI PROP] (Q : PROP) : P ⊢ (P -∗ Q) -∗ Q := by +/-- Tests `ispecialize` with spatial wand -/ +example [BI PROP] (Q : PROP) : P ⊢ (P -∗ Q) -∗ Q := by iintro HP HPQ - ispecialize HPQ with HP + ispecialize HPQ $$ HP iexact HPQ -theorem wand_spatial_subgoal [BI PROP] (Q : PROP) : P ⊢ (P -∗ Q) -∗ Q := by +/-- Tests `ispecialize` with subgoal -/ +example [BI PROP] (Q : PROP) : P ⊢ (P -∗ Q) -∗ Q := by iintro HP HPQ - ispecialize HPQ with [HP] + ispecialize HPQ $$ [HP] . iexact HP iexact HPQ -theorem wand_spatial_subgoal_named [BI PROP] (Q : PROP) : P ⊢ (P -∗ Q) -∗ Q := by +/-- Tests `ispecialize` with named subgoal -/ +example [BI PROP] (Q : PROP) : P ⊢ (P -∗ Q) -∗ Q := by iintro HP HPQ - ispecialize HPQ with [HP] as G + ispecialize HPQ $$ [HP] as G case G => iexact HP iexact HPQ -theorem wand_intuitionistic [BI PROP] (Q : PROP) : □ P ⊢ □ (P -∗ Q) -∗ □ Q := by +/-- Tests `ispecialize` with intuitionistic wand -/ +example [BI PROP] (Q : PROP) : □ P ⊢ □ (P -∗ Q) -∗ □ Q := by iintro □HP □HPQ - ispecialize HPQ with HP + ispecialize HPQ $$ HP iexact HPQ -theorem wand_intuitionistic_subgoal [BI PROP] (Q : PROP) : □ P ⊢ □ (P -∗ Q) -∗ Q := by +/-- Tests `ispecialize` with intuitionistic wand and subgoal -/ +example [BI PROP] (Q : PROP) : □ P ⊢ □ (P -∗ Q) -∗ Q := by iintro □HP □HPQ - ispecialize HPQ with [] + ispecialize HPQ $$ [] . iexact HP iexact HPQ -theorem wand_intuitionistic_required [BI PROP] (Q : PROP) : □ P ⊢ □ (□ P -∗ Q) -∗ □ Q := by +/-- Tests `ispecialize` with intuitionistic wand requiring intuitionistic argument -/ +example [BI PROP] (Q : PROP) : □ P ⊢ □ (□ P -∗ Q) -∗ □ Q := by iintro □HP □HPQ - ispecialize HPQ with HP + ispecialize HPQ $$ HP iexact HPQ -theorem wand_intuitionistic_spatial [BI PROP] (Q : PROP) : □ P ⊢ (P -∗ Q) -∗ Q := by +/-- Tests `ispecialize` with intuitionistic premise and spatial wand -/ +example [BI PROP] (Q : PROP) : □ P ⊢ (P -∗ Q) -∗ Q := by iintro □HP HPQ - ispecialize HPQ with HP + ispecialize HPQ $$ HP iexact HPQ -theorem wand_intuitionistic_required_spatial [BI PROP] (Q : PROP) : □ P ⊢ (□ P -∗ Q) -∗ Q := by +/-- Tests `ispecialize` with intuitionistic premise required by spatial wand -/ +example [BI PROP] (Q : PROP) : □ P ⊢ (□ P -∗ Q) -∗ Q := by iintro □HP HPQ - ispecialize HPQ with HP + ispecialize HPQ $$ HP iexact HPQ -theorem wand_spatial_intuitionistic [BI PROP] (Q : PROP) : P ⊢ □ (P -∗ Q) -∗ Q := by +/-- Tests `ispecialize` with spatial premise and intuitionistic wand -/ +example [BI PROP] (Q : PROP) : P ⊢ □ (P -∗ Q) -∗ Q := by iintro HP □HPQ - ispecialize HPQ with HP + ispecialize HPQ $$ HP iexact HPQ -theorem wand_spatial_multiple [BI PROP] (Q : PROP) : ⊢ P1 -∗ P2 -∗ (P1 -∗ P2 -∗ Q) -∗ Q := by +/-- Tests `ispecialize` with multiple spatial arguments -/ +example [BI PROP] (Q : PROP) : ⊢ P1 -∗ P2 -∗ (P1 -∗ P2 -∗ Q) -∗ Q := by iintro HP1 HP2 HPQ - ispecialize HPQ with HP1, HP2 + ispecialize HPQ $$ HP1, HP2 iexact HPQ -theorem wand_spatial_multiple_subgoal [BI PROP] (Q : PROP) : ⊢ P1 -∗ P2 -∗ (P1 -∗ P2 -∗ Q) -∗ Q := by +/-- Tests `ispecialize` with multiple subgoals -/ +example [BI PROP] (Q : PROP) : ⊢ P1 -∗ P2 -∗ (P1 -∗ P2 -∗ Q) -∗ Q := by iintro HP1 HP2 HPQ - ispecialize HPQ with [HP1], [HP2] + ispecialize HPQ $$ [HP1], [HP2] . iexact HP1 . iexact HP2 iexact HPQ -theorem wand_intuitionistic_multiple [BI PROP] (Q : PROP) : +/-- Tests `ispecialize` with multiple intuitionistic arguments -/ +example [BI PROP] (Q : PROP) : ⊢ □ P1 -∗ □ P2 -∗ □ (P1 -∗ □ P2 -∗ Q) -∗ □ Q := by iintro □HP1 □HP2 □HPQ - ispecialize HPQ with HP1, HP2 + ispecialize HPQ $$ HP1, HP2 iexact HPQ -theorem wand_multiple [BI PROP] (Q : PROP) : +/-- Tests `ispecialize` with mixed spatial and intuitionistic arguments -/ +example [BI PROP] (Q : PROP) : ⊢ P1 -∗ □ P2 -∗ P3 -∗ □ (P1 -∗ P2 -∗ P3 -∗ Q) -∗ Q := by iintro HP1 □HP2 HP3 HPQ - ispecialize HPQ with HP1, HP2, HP3 + ispecialize HPQ $$ HP1, HP2, HP3 iexact HPQ -theorem forall_spatial [BI PROP] (Q : Nat → PROP) : ⊢ (∀ x, Q x) -∗ Q (y + 1) := by +/-- Tests `ispecialize` with forall in spatial context -/ +example [BI PROP] (Q : Nat → PROP) : ⊢ (∀ x, Q x) -∗ Q (y + 1) := by iintro HQ - ispecialize HQ $! (y + 1) + ispecialize HQ $$ %(y + 1) iexact HQ -theorem forall_intuitionistic [BI PROP] (Q : Nat → PROP) : ⊢ □ (∀ x, Q x) -∗ □ Q y := by +/-- Tests `ispecialize` with forall in intuitionistic context -/ +example [BI PROP] (Q : Nat → PROP) : ⊢ □ (∀ x, Q x) -∗ □ Q y := by iintro □HQ - ispecialize HQ $! y + ispecialize HQ $$ %y iexact HQ -theorem forall_spatial_intuitionistic [BI PROP] (Q : Nat → PROP) : ⊢ (∀ x, □ Q x) -∗ □ Q y := by +/-- Tests `ispecialize` with forall returning intuitionistic proposition -/ +example [BI PROP] (Q : Nat → PROP) : ⊢ (∀ x, □ Q x) -∗ □ Q y := by iintro HQ - ispecialize HQ $! y + ispecialize HQ $$ %y iexact HQ -theorem forall_spatial_multiple [BI PROP] (Q : Nat → Nat → PROP) : +/-- Tests `ispecialize` with multiple forall in spatial context -/ +example [BI PROP] (Q : Nat → Nat → PROP) : ⊢ (∀ x, ∀ y, Q x y) -∗ Q x y := by iintro HQ - ispecialize HQ $! x, y + ispecialize HQ $$ %x, %y iexact HQ -theorem forall_intuitionistic_multiple [BI PROP] (Q : Nat → Nat → PROP) : +/-- Tests `ispecialize` with multiple forall in intuitionistic context -/ +example [BI PROP] (Q : Nat → Nat → PROP) : ⊢ □ (∀ x, ∀ y, Q x y) -∗ □ Q x y := by iintro □HQ - ispecialize HQ $! x, y + ispecialize HQ $$ %x, %y iexact HQ -theorem forall_multiple [BI PROP] (Q : Nat → Nat → PROP) : ⊢ (∀ x, □ (∀ y, Q x y)) -∗ □ Q x y := by +/-- Tests `ispecialize` with nested forall and intuitionistic -/ +example [BI PROP] (Q : Nat → Nat → PROP) : ⊢ (∀ x, □ (∀ y, Q x y)) -∗ □ Q x y := by iintro HQ - ispecialize HQ $! x, y + ispecialize HQ $$ %x, %y iexact HQ -theorem multiple [BI PROP] (Q : Nat → PROP) : +/-- Tests `ispecialize` with mixed forall and wand specialization -/ +example [BI PROP] (Q : Nat → PROP) : ⊢ □ P1 -∗ P2 -∗ (□ P1 -∗ (∀ x, P2 -∗ Q x)) -∗ Q y := by iintro □HP1 HP2 HPQ - ispecialize HPQ with HP1 - ispecialize HPQ $! y with HP2 + ispecialize HPQ $$ HP1, %y, HP2 iexact HPQ +/-- Tests `ispecialize` with pure True wand using `.intro` -/ +example [BI PROP] (P : PROP) : + ⊢ (True -∗ P) -∗ P := by + iintro H + ispecialize H $$ %.intro + iexact H + +/-- Tests `ispecialize` with pure wand using tactic -/ +example [BI PROP] (P : PROP) : + ⊢ (True -∗ P) -∗ P := by + iintro H + ispecialize H $$ %(by grind) + iexact H + +/-- Tests `ispecialize` alternating pure and spatial arguments -/ +example [BI PROP] (P Q : PROP) : + ⊢ (∀ x, P -∗ ⌜x = 1⌝ -∗ Q) -∗ P -∗ Q := by + iintro H HP + ispecialize H $$ %_, HP, %rfl + iexact H + +/-- Tests `ispecialize` with pure subgoal -/ +example [BI PROP] (P Q : PROP) : + ⊢ (∀ x, P -∗ ⌜x = 1⌝ -∗ Q) -∗ P -∗ Q := by + iintro H HP + ispecialize H $$ %_, HP, %_ + · rfl + iexact H + end specialize -- split namespace split -theorem and [BI PROP] (Q : PROP) : Q ⊢ Q ∧ Q := by +/-- Tests `isplit` for conjunction -/ +example [BI PROP] (Q : PROP) : Q ⊢ Q ∧ Q := by iintro HQ isplit <;> iexact HQ -theorem sep_left [BI PROP] [BIAffine PROP] (Q : PROP) : ⊢ P -∗ Q -∗ R -∗ P ∗ Q := by +/-- Tests `isplitl` with explicit left hypotheses -/ +example [BI PROP] [BIAffine PROP] (Q : PROP) : ⊢ P -∗ Q -∗ R -∗ P ∗ Q := by iintro HP iintro HQ iintro _HR @@ -680,7 +832,8 @@ theorem sep_left [BI PROP] [BIAffine PROP] (Q : PROP) : ⊢ P -∗ Q -∗ R -∗ · iexact HP · iexact HQ -theorem sep_right [BI PROP] [BIAffine PROP] (Q : PROP) : ⊢ P -∗ Q -∗ R -∗ P ∗ Q := by +/-- Tests `isplitr` with explicit right hypotheses -/ +example [BI PROP] [BIAffine PROP] (Q : PROP) : ⊢ P -∗ Q -∗ R -∗ P ∗ Q := by iintro HP iintro HQ iintro _HR @@ -688,7 +841,8 @@ theorem sep_right [BI PROP] [BIAffine PROP] (Q : PROP) : ⊢ P -∗ Q -∗ R - · iexact HP · iexact HQ -theorem sep_left_all [BI PROP] [BIAffine PROP] (Q : PROP) : ⊢ P -∗ □ Q -∗ R -∗ P ∗ Q := by +/-- Tests `isplitl` without argument -/ +example [BI PROP] [BIAffine PROP] (Q : PROP) : ⊢ P -∗ □ Q -∗ R -∗ P ∗ Q := by iintro HP iintro □HQ iintro _HR @@ -696,7 +850,8 @@ theorem sep_left_all [BI PROP] [BIAffine PROP] (Q : PROP) : ⊢ P -∗ □ Q - · iexact HP · iexact HQ -theorem sep_right_all [BI PROP] [BIAffine PROP] (Q : PROP) : ⊢ □ P -∗ Q -∗ R -∗ P ∗ Q := by +/-- Tests `isplitr` without argument -/ +example [BI PROP] [BIAffine PROP] (Q : PROP) : ⊢ □ P -∗ Q -∗ R -∗ P ∗ Q := by iintro □HP iintro HQ iintro _HR @@ -709,17 +864,20 @@ end split -- left / right namespace leftright -theorem left [BI PROP] (P : PROP) : P ⊢ P ∨ Q := by +/-- Tests `ileft` -/ +example [BI PROP] (P : PROP) : P ⊢ P ∨ Q := by iintro HP ileft iexact HP -theorem right [BI PROP] (Q : PROP) : Q ⊢ P ∨ Q := by +/-- Tests `iright` -/ +example [BI PROP] (Q : PROP) : Q ⊢ P ∨ Q := by iintro HQ iright iexact HQ -theorem complex [BI PROP] (P Q : PROP) : ⊢ P -∗ Q -∗ P ∗ (R ∨ Q ∨ R) := by +/-- Tests nested disjunction with left and right -/ +example [BI PROP] (P Q : PROP) : ⊢ P -∗ Q -∗ P ∗ (R ∨ Q ∨ R) := by iintro HP HQ isplitl [HP] · iassumption @@ -732,177 +890,212 @@ end leftright -- cases namespace cases -theorem rename [BI PROP] (P : PROP) : P ⊢ P := by +/-- Tests `icases` for simple renaming -/ +example [BI PROP] (P : PROP) : P ⊢ P := by iintro HP icases HP with H iexact H -theorem clear [BI PROP] (P Q : PROP) : ⊢ P -∗ Q -∗ P := by +/-- Tests `icases` to clear hypothesis -/ +example [BI PROP] (P Q : PROP) : ⊢ P -∗ Q -∗ P := by iintro HP iintro HQ icases HQ with - iexact HP -theorem and [BI PROP] (Q : PROP) : □ (P1 ∧ P2 ∧ Q) ⊢ Q := by +/-- Tests `icases` with nested conjunction -/ +example [BI PROP] (Q : PROP) : □ (P1 ∧ P2 ∧ Q) ⊢ Q := by iintro □HP icases HP with ⟨_HP1, _HP2, HQ⟩ iexact HQ -theorem and_intuitionistic [BI PROP] (Q : PROP) : □ P ∧ Q ⊢ Q := by +/-- Tests `icases` with intuitionistic conjunction -/ +example [BI PROP] (Q : PROP) : □ P ∧ Q ⊢ Q := by iintro HPQ icases HPQ with ⟨_HP, HQ⟩ iexact HQ -theorem and_persistent_left [BI PROP] (Q : PROP) : Q ∧ P ⊢ Q := by +/-- Tests `icases` on conjunction with persistent left -/ +example [BI PROP] (Q : PROP) : Q ∧ P ⊢ Q := by iintro HQP icases HQP with ⟨□HQ, _HP⟩ iexact HQ -theorem and_persistent_right [BI PROP] (Q : PROP) : Q ∧ P ⊢ Q := by +/-- Tests `icases` on conjunction with persistent right -/ +example [BI PROP] (Q : PROP) : Q ∧ P ⊢ Q := by iintro HQP icases HQP with ⟨HQ, _HP⟩ iexact HQ -theorem sep [BI PROP] [BIAffine PROP] (Q : PROP) : P1 ∗ P2 ∗ Q ⊢ Q := by +/-- Tests `icases` with nested separating conjunction -/ +example [BI PROP] [BIAffine PROP] (Q : PROP) : P1 ∗ P2 ∗ Q ⊢ Q := by iintro HPQ icases HPQ with ⟨_HP1, _HP2, HQ⟩ iexact HQ -theorem disjunction [BI PROP] (Q : PROP) : Q ⊢ (P1 ∨ P2 ∨ P3) -∗ Q := by +/-- Tests `icases` with nested disjunction -/ +example [BI PROP] (Q : PROP) : Q ⊢ (P1 ∨ P2 ∨ P3) -∗ Q := by iintro HQ iintro HP icases HP with (_HP1 | _HP2 | _HP3) <;> iexact HQ -theorem conjunction_and_disjunction [BI PROP] [BIAffine PROP] (Q : PROP) : +/-- Tests `icases` with complex mixed conjunction and disjunction -/ +example [BI PROP] [BIAffine PROP] (Q : PROP) : (P11 ∨ P12 ∨ P13) ∗ P2 ∗ (P31 ∨ P32 ∨ P33) ∗ Q ⊢ Q := by iintro HP icases HP with ⟨_HP11 | _HP12 | _HP13, HP2, HP31 | HP32 | HP33, HQ⟩ <;> iexact HQ -theorem move_to_pure [BI PROP] (Q : PROP) : ⊢ ⌜⊢ Q⌝ -∗ Q := by +/-- Tests `icases` moving pure to Lean context with ⌜⌝ -/ +example [BI PROP] (Q : PROP) : ⊢ ⌜⊢ Q⌝ -∗ Q := by iintro HQ icases HQ with ⌜HQ⌝ istop exact HQ -theorem move_to_pure_ascii [BI PROP] (Q : PROP) : ⊢ ⌜⊢ Q⌝ -∗ Q := by +/-- Tests `icases` moving pure to Lean context with % -/ +example [BI PROP] (Q : PROP) : ⊢ ⌜⊢ Q⌝ -∗ Q := by iintro HQ icases HQ with %HQ istop exact HQ -theorem move_to_intuitionistic [BI PROP] (Q : PROP) : ⊢ □ Q -∗ Q := by +/-- Tests `icases` moving to intuitionistic with □ -/ +example [BI PROP] (Q : PROP) : ⊢ □ Q -∗ Q := by iintro HQ icases HQ with □HQ iexact HQ -theorem move_to_intuitionistic_ascii [BI PROP] (Q : PROP) : ⊢ □ Q -∗ Q := by +/-- Tests `icases` moving to intuitionistic with # -/ +example [BI PROP] (Q : PROP) : ⊢ □ Q -∗ Q := by iintro HQ icases HQ with #HQ iexact HQ -theorem move_to_spatial [BI PROP] (Q : PROP) : ⊢ □ Q -∗ Q := by +/-- Tests `icases` moving to spatial with ∗ -/ +example [BI PROP] (Q : PROP) : ⊢ □ Q -∗ Q := by iintro □HQ icases HQ with ∗HQ iexact HQ -theorem move_to_spatial_ascii [BI PROP] (Q : PROP) : ⊢ □ Q -∗ Q := by +/-- Tests `icases` moving to spatial with * -/ +example [BI PROP] (Q : PROP) : ⊢ □ Q -∗ Q := by iintro □HQ icases HQ with *HQ iexact HQ -theorem move_to_pure_conjunction [BI PROP] (Q : PROP) : ⊢ ⌜φ⌝ ∗ Q -∗ Q := by +/-- Tests `icases` with pure in conjunction -/ +example [BI PROP] (Q : PROP) : ⊢ ⌜φ⌝ ∗ Q -∗ Q := by iintro HφQ icases HφQ with ⟨⌜Hφ⌝, HQ⟩ iexact HQ -theorem move_to_pure_disjunction [BI PROP] (Q : PROP) : +/-- Tests `icases` with pure in disjunction -/ +example [BI PROP] (Q : PROP) : ⊢ ⌜φ1⌝ ∨ ⌜φ2⌝ -∗ Q -∗ Q := by iintro Hφ iintro HQ icases Hφ with (⌜Hφ1⌝ | ⌜Hφ2⌝) <;> iexact HQ -theorem move_to_intuitionistic_conjunction [BI PROP] (Q : PROP) : ⊢ □ P ∗ Q -∗ Q := by +/-- Tests `icases` with intuitionistic in conjunction -/ +example [BI PROP] (Q : PROP) : ⊢ □ P ∗ Q -∗ Q := by iintro HPQ icases HPQ with ⟨□_HP, HQ⟩ iexact HQ -theorem move_to_intuitionistic_disjunction [BI PROP] (Q : PROP) : ⊢ □ Q ∨ Q -∗ Q := by +/-- Tests `icases` with intuitionistic in disjunction -/ +example [BI PROP] (Q : PROP) : ⊢ □ Q ∨ Q -∗ Q := by iintro HQQ icases HQQ with (□HQ | HQ) <;> iexact HQ -theorem move_to_spatial_conjunction [BI PROP] (Q : PROP) : ⊢ □ (P ∧ Q) -∗ Q := by +/-- Tests `icases` moving to spatial inside intuitionistic conjunction -/ +example [BI PROP] (Q : PROP) : ⊢ □ (P ∧ Q) -∗ Q := by iintro □HPQ icases HPQ with ⟨_HP, ∗HQ⟩ iexact HQ -theorem move_to_spatial_disjunction [BI PROP] (Q : PROP) : ⊢ □ (Q ∨ Q) -∗ Q := by +/-- Tests `icases` with or inside intuitionistic, moving one to spatial -/ +example [BI PROP] (Q : PROP) : ⊢ □ (Q ∨ Q) -∗ Q := by iintro □HPQ icases HPQ with (HQ | ∗HQ) <;> iexact HQ -theorem move_to_intuitionistic_and_back_conjunction [BI PROP] (Q : PROP) : ⊢ □ (P ∧ Q) -∗ Q := by +/-- Tests `icases` moving whole hypothesis to intuitionistic then destructing -/ +example [BI PROP] (Q : PROP) : ⊢ □ (P ∧ Q) -∗ Q := by iintro HPQ icases HPQ with □⟨_HP, ∗HQ⟩ iexact HQ -theorem move_to_intuitionistic_and_back_disjunction [BI PROP] (Q : PROP) : ⊢ □ (Q ∨ Q) -∗ Q := by +/-- Tests `icases` with or, moving whole to intuitionistic -/ +example [BI PROP] (Q : PROP) : ⊢ □ (Q ∨ Q) -∗ Q := by iintro HPQ icases HPQ with □(HQ | ∗HQ) <;> iexact HQ -theorem conjunction_clear [BI PROP] [BIAffine PROP] (Q : PROP) : Q ∗ P ⊢ Q := by +/-- Tests `icases` clearing in conjunction -/ +example [BI PROP] [BIAffine PROP] (Q : PROP) : Q ∗ P ⊢ Q := by iintro HQP icases HQP with ⟨HQ, -⟩ iexact HQ -theorem disjunction_clear [BI PROP] [BIAffine PROP] (Q : PROP) : Q ⊢ P1 ∨ P2 -∗ Q := by +/-- Tests `icases` clearing in disjunction -/ +example [BI PROP] [BIAffine PROP] (Q : PROP) : Q ⊢ P1 ∨ P2 -∗ Q := by iintro HQ iintro HP icases HP with (- | _HP2) <;> iexact HQ -theorem and_destruct_spatial_right [BI PROP] (Q : PROP) : P ∧ Q ⊢ Q := by +/-- Tests `icases` destructing conjunction left -/ +example [BI PROP] (Q : PROP) : P ∧ Q ⊢ Q := by iintro HPQ icases HPQ with ⟨-, HQ⟩ iexact HQ -theorem and_destruct_spatial_left [BI PROP] (Q : PROP) : Q ∧ P ⊢ Q := by +/-- Tests `icases` destructing conjunction right -/ +example [BI PROP] (Q : PROP) : Q ∧ P ⊢ Q := by iintro HQP icases HQP with ⟨HQ, -⟩ iexact HQ -theorem and_clear_spatial_multiple [BI PROP] (Q : PROP) : P1 ∧ P2 ∧ Q ∧ P3 ⊢ Q := by +/-- Tests `icases` destructing multiple conjunctions -/ +example [BI PROP] (Q : PROP) : P1 ∧ P2 ∧ Q ∧ P3 ⊢ Q := by iintro HPQ icases HPQ with ⟨-, -, HQ, -⟩ iexact HQ -theorem and_destruct_intuitionistic_right [BI PROP] (Q : PROP) : □ (P ∧ Q) ⊢ Q := by +/-- Tests `icases` destructing intuitionistic conjunction, clearing left -/ +example [BI PROP] (Q : PROP) : □ (P ∧ Q) ⊢ Q := by iintro □HPQ icases HPQ with ⟨-, HQ⟩ iexact HQ -theorem and_destruct_intuitionistic_left [BI PROP] (Q : PROP) : □ (Q ∧ P) ⊢ Q := by +/-- Tests `icases` destructing intuitionistic conjunction, clearing right -/ +example [BI PROP] (Q : PROP) : □ (Q ∧ P) ⊢ Q := by iintro □HQP icases HQP with ⟨HQ, -⟩ iexact HQ -theorem and_clear_intuitionistic_multiple [BI PROP] (Q : PROP) : □ (P1 ∧ P2 ∧ Q ∧ P3) ⊢ Q := by +/-- Tests `icases` destructing multiple intuitionistic conjunctions -/ +example [BI PROP] (Q : PROP) : □ (P1 ∧ P2 ∧ Q ∧ P3) ⊢ Q := by iintro □HPQ icases HPQ with ⟨-, -, HQ, -⟩ iexact HQ -theorem «exists» [BI PROP] (Q : Nat → PROP) : (∃ x, Q x) ⊢ ∃ x, Q x ∨ False := by +/-- Tests `icases` with existential -/ +example [BI PROP] (Q : Nat → PROP) : (∃ x, Q x) ⊢ ∃ x, Q x ∨ False := by iintro ⟨x, H⟩ iexists x ileft iexact H -theorem exists_intuitionistic [BI PROP] (Q : Nat → PROP) : □ (∃ x, Q x) ⊢ ∃ x, □ Q x ∨ False := by +/-- Tests `icases` with intuitionistic existential -/ +example [BI PROP] (Q : Nat → PROP) : □ (∃ x, Q x) ⊢ ∃ x, □ Q x ∨ False := by iintro ⟨x, □H⟩ iexists x ileft iexact H + +end cases