Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
f175420
Use `colGt` and `ppSpace` for specialisation pattern syntax
alvinylt Jul 4, 2026
55224af
Add docstrings to `specPat` syntax declarations
alvinylt Jul 4, 2026
6b4bdbd
Improve docstrings and condense `specPat` syntax
alvinylt Jul 4, 2026
6465eff
Add a test for `ispecialize` for the syntax `[- ...]`
alvinylt Jul 4, 2026
e62679b
Docstring for `pmTerm`
alvinylt Jul 4, 2026
69674fd
Start extending `processWand` for the remaining specialisation patterns
alvinylt Jul 5, 2026
95b72fa
Add a test for `.autoframe` for the intuitionistic kind
alvinylt Jul 5, 2026
f6f317a
Add `ipm_backtrack` for `intoAbsorbingly_absorbing`
alvinylt Jul 5, 2026
62db857
Towards implementing `.autoframe` for the persistent kind
alvinylt Jul 5, 2026
a9785be
Finish proof for `specialize_wand_autoframe_persistent`
alvinylt Jul 5, 2026
ba99bdb
Refactor `processWand`
alvinylt Jul 5, 2026
d0cf885
Implement `[# ...]` specialisation pattern, more tests
alvinylt Jul 5, 2026
1053db6
Use `withRef` in `processWand` for more accurate error highlighting
alvinylt Jul 5, 2026
0dde59c
Update `Porting.lean` and `tactics.md`
alvinylt Jul 5, 2026
976511e
Typo fix
alvinylt Jul 5, 2026
b5921a6
Extend `specPat` syntax for nested specialisation patterns
alvinylt Jul 5, 2026
6f57286
Implement nested specialisation patterns
alvinylt Jul 5, 2026
a0f06d5
Finish the proof for nested specialisation patterns in `processWand`
alvinylt Jul 5, 2026
1a71cc5
Update documentation
alvinylt Jul 5, 2026
ca7332f
Minor docstring improvement
alvinylt Jul 5, 2026
3c14a21
Use `ProofModeM` type class synthesiser instaed of the built-in one
alvinylt Jul 6, 2026
33c9d72
Port the type class `AddModal` and the theorem `addModal_id`
alvinylt Jul 6, 2026
32df6d0
Port `add_modal_bupd`
alvinylt Jul 6, 2026
9d5f5f0
Start implementing `.autoframe .modal`
alvinylt Jul 6, 2026
a83284e
Pass the proof goal to `processWand` and `iSpecializeCore` for `.auto…
alvinylt Jul 6, 2026
baeeed9
Add a test for `ispecialize` with `[>$]` using type class instance `a…
alvinylt Jul 6, 2026
45f0e96
Partially refactoring `SpecializeState`
alvinylt Jul 6, 2026
c9a97ec
Refactor code for `.autoframe .modal`
alvinylt Jul 6, 2026
9c4be10
Update `ihave`, `irewrite`, `icases` and `iapply` because of the upda…
alvinylt Jul 6, 2026
ef042c8
Finish proof construction for `.autoframe .modal`
alvinylt Jul 6, 2026
3501e64
Finish proof for `specialize_modal`
alvinylt Jul 6, 2026
0fc3a8d
Implement `.goal` with `kind := .modal`
alvinylt Jul 6, 2026
a0ade88
Tweak the handling of `try_dup_context` in `iSpecializeCore`
alvinylt Jul 6, 2026
60fd209
Minor formatting
alvinylt Jul 6, 2026
257f6e8
Add instance `addModal_wand`
alvinylt Jul 7, 2026
755ff1c
Complete proof for `addModal_wand`
alvinylt Jul 7, 2026
2d0195b
Implement support for nested patterns along with modality handling
alvinylt Jul 7, 2026
978191b
Update documentation and tests
alvinylt Jul 7, 2026
dad0201
Remove TODO: `should_try_dup_context` should not check modality patterns
alvinylt Jul 7, 2026
ee97f6d
Add a test for `try_dup_context`
alvinylt Jul 7, 2026
5889796
Minor code formatting
alvinylt Jul 7, 2026
fbde70f
Add another test for `ihave`
alvinylt Jul 7, 2026
decc7dc
Bug fix for `iCasesPat.should_try_dup_context` and add missing `ipm_b…
alvinylt Jul 7, 2026
8786002
Improve `specPat` syntax with `colGt` and `ppSpace`
alvinylt Jul 7, 2026
95fdd9a
Merge branch 'SpecPats' into SpecPatsModal
alvinylt Jul 7, 2026
11e1a18
Code refactoring
alvinylt Jul 7, 2026
b5acfe2
`processWand`: Combine `.ident i []` and `.ident i spats` cases into one
alvinylt Jul 7, 2026
9c9aee5
Major refactoring to reduce repetitve code
alvinylt Jul 7, 2026
4d66aed
Minor formatting
alvinylt Jul 7, 2026
d852a87
Code refactoring: `findFrameIVars`
alvinylt Jul 7, 2026
bf5027c
Update error message for consistency
alvinylt Jul 7, 2026
c87a0a1
Code refactoring: helper function `finishFrameSubgoal`
alvinylt Jul 7, 2026
a36db2a
Minor formatting
alvinylt Jul 7, 2026
c99add9
Code refactoring: `synthIntoWandPersistent`
alvinylt Jul 7, 2026
e637fae
Code refactoring: `synthIntoWandModal`
alvinylt Jul 7, 2026
6cd6e93
More refactoring
alvinylt Jul 7, 2026
dc32001
Minor formatting
alvinylt Jul 7, 2026
2349a04
More minor formatting
alvinylt Jul 7, 2026
f07cd62
Refactor `iSpecializeCore`
alvinylt Jul 7, 2026
561b11c
Consolidate three theorems into one
alvinylt Jul 7, 2026
81ef183
Rename theorems
alvinylt Jul 7, 2026
e841bb1
Slight optimisations in `processWand`
alvinylt Jul 7, 2026
364e5ea
Add some comments
alvinylt Jul 7, 2026
8426722
Add comments and reuse `synthIntoWand`
alvinylt Jul 7, 2026
10e8a59
Code refactoring: `splitFrameHyps`
alvinylt Jul 7, 2026
8bfda62
Condense code, more comments
alvinylt Jul 7, 2026
e54e73d
Move `pmTerm` and its parser into `SpecPattern.lean` for mutual induc…
alvinylt Jul 8, 2026
e27f1eb
Add comments
alvinylt Jul 8, 2026
16c6a71
Code refactoring
alvinylt Jul 8, 2026
135b4d9
Refactor theorem proofs
alvinylt Jul 8, 2026
2af916d
Theorem and proof refactoring
alvinylt Jul 8, 2026
1147f46
Port `add_modal_forall`
alvinylt Jul 8, 2026
db59b6d
Port `wandM`
alvinylt Jul 8, 2026
a5e0a7e
Port `add_modal_wandM`
alvinylt Jul 8, 2026
066ad20
`HaveCore.lean`: typo fix
alvinylt Jul 8, 2026
77a4685
Port `add_modal_fupd`
alvinylt Jul 8, 2026
591a638
Port `AddModal` instances in `InstancesLater.lean`
alvinylt Jul 8, 2026
220ebef
Port `add_modal_fupd_wp`
alvinylt Jul 8, 2026
893e0cb
Improve error messages and more tests
alvinylt Jul 8, 2026
0ca25ef
Test `addModal_fupd`
alvinylt Jul 8, 2026
926dc0c
Add more tests for the use of `AddModal` instances by `ispecialize`
alvinylt Jul 8, 2026
58a8c92
Minor formatting
alvinylt Jul 8, 2026
cbf8435
Add `ispecialize` test with `specPat` naming the subgoal
alvinylt Jul 8, 2026
39e5ebe
Revert code commenting
alvinylt Jul 8, 2026
9ece000
Set higher priority for `addModal_later` and `addModal_later_except_0`
alvinylt Jul 8, 2026
4623eb0
Typo fix
alvinylt Jul 8, 2026
bccc6ae
Add `rocq_ignore` for `add_modal_tforall`
alvinylt Jul 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Iris/Iris/BI/BIBase.lean
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ syntax "⌜" term "⌝" : term
syntax:35 term:36 " ∗ " term:35 : term
/-- Separating implication. -/
syntax:25 term:26 " -∗ " term:25 : term
/-- Separating implication with an optional wand premise. -/
syntax:25 term:26 " -∗? " term:25 : term
/-- Persistency modality. `persistently` is a primitive of BI. -/
syntax:max "<pers> " term:40 : term
/-- Later modality. `later` is a primitive of BI. -/
Expand Down Expand Up @@ -163,6 +165,18 @@ delab_rule iff
delab_rule wandIff
| `($_ $P $Q) => do ``(iprop($(← unpackIprop P) ∗-∗ $(← unpackIprop Q)))

@[simp, rocq_alias bi_wandM]
def wandM [BIBase PROP] (mP : Option PROP) (Q : PROP) : PROP :=
match mP with
| none => Q
| some P => iprop(P -∗ Q)

macro_rules
| `(iprop($mP -∗? $Q)) => ``(wandM $mP iprop($Q))

delab_rule wandM
| `($_ $mP $Q) => do ``(iprop($mP -∗? $(← unpackIprop Q)))

/-- Affine modality.
```
def affinely (P) := emp ∧ P
Expand Down
6 changes: 6 additions & 0 deletions Iris/Iris/BI/DerivedLaws.lean
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,12 @@ theorem emp_or [BI PROP] {P : PROP} [Affine P] : emp ∨ P ⊣⊢ emp := ⟨or_e
theorem emp_wand [BI PROP] {P : PROP} : (emp -∗ P) ⊣⊢ P :=
⟨emp_sep.mpr.trans wand_elim_right, wand_intro_left emp_sep.mp⟩

@[rocq_alias bi.wandM_sound]
theorem wandM_sound [BI PROP] {mP : Option PROP} {Q : PROP} :
(mP -∗? Q) ⊣⊢ (mP.getD emp -∗ Q) := by
cases mP <;> simp [BIBase.wandM]
exact emp_wand.symm

@[rocq_alias bi.or_emp]
theorem or_emp [BI PROP] {P : PROP} [Affine P] : P ∨ emp ⊣⊢ emp := or_comm.trans emp_or

Expand Down
7 changes: 7 additions & 0 deletions Iris/Iris/ProgramLogic/WeakestPre.lean
Original file line number Diff line number Diff line change
Expand Up @@ -681,4 +681,11 @@ instance elimModalFupdWpAtomic_wrongMask :
p false iprop(|={E₁,E₂}=> P) iprop(False) (WP e @ s ; E₁ {{ Φ }}) iprop(False) where
elim_modal := nofun

@[rocq_alias add_modal_fupd_wp]
instance addModalFupdWp : AddModal iprop(|={E}=> P) P (WP e @ s ; E {{ Φ }}) where
add_modal := by
iintro ⟨H1, H2⟩
imod H1
iapply H2 $$ H1

end ProofModeClasses
13 changes: 13 additions & 0 deletions Iris/Iris/ProofMode/Classes.lean
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,19 @@ class ElimModal {PROP} [BI PROP] (φ : outParam $ Prop) (p : Bool) (p' : outPara
elim_modal : φ → □?p P ∗ (□?p' P' -∗ Q') ⊢ Q
export ElimModal (elim_modal)

/--
`AddModal` is used by `ispecialize` and `iassert` to add a modality to the
goal corresponding to the premise/asserted proposition.
-/
@[ipm_class, rocq_alias AddModal]
class AddModal {PROP} [BI PROP] (P : outParam $ PROP) (P' Q : PROP) where
add_modal : P ∗ (P' -∗ Q) ⊢ Q
export AddModal (add_modal)

@[rocq_alias add_modal_id]
theorem addModal_id {PROP} [BI PROP] (P Q : PROP) : AddModal P P Q where
add_modal := wand_elim_right

@[ipm_class, rocq_alias Frame]
class Frame {PROP} [BI PROP] (p : Bool) (R P : PROP) (Q : outParam $ PROP) where
frame : □?p R ∗ Q ⊢ P
Expand Down
59 changes: 56 additions & 3 deletions Iris/Iris/ProofMode/Instances.lean
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ instance fromImp_imp [BI PROP] (P1 P2 : PROP) : FromImp iprop(P1 → P2) P1 P2 :
@[rocq_alias from_wand_wand]
instance fromWand_wand [BI PROP] (P1 P2 : PROP) : FromWand iprop(P1 -∗ P2) io P1 P2 := ⟨.rfl⟩

-- FromWandM
@[rocq_alias from_wand_wandM]
instance fromWand_wandM [BI PROP] (mP1 : Option PROP) (P2 : PROP) :
FromWand iprop(mP1 -∗? P2) io (mP1.getD emp) P2 where
from_wand := wandM_sound.mpr

-- IntoWand
#rocq_ignore into_wand_wand' "IntoWand' is not used in Lean"
#rocq_ignore into_wand_impl' "IntoWand' is not used in Lean"
Expand All @@ -61,6 +67,13 @@ instance intoWand_wand (p q : Bool) [BI PROP] (P Q P' : PROP) [h : FromAssumptio
IntoWand p q iprop(P' -∗ Q) ioP P ioQ Q where
into_wand := (intuitionisticallyIf_mono <| wand_mono_left h.1).trans intuitionisticallyIf_elim

@[rocq_alias into_wand_wandM]
instance intoWand_wandM (p q : Bool) [BI PROP] (mP' : Option PROP) (P Q : PROP)
[h : FromAssumption q ioP P (mP'.getD emp)] :
IntoWand p q iprop(mP' -∗? Q) ioP P ioQ Q where
into_wand := (intuitionisticallyIf_mono wandM_sound.mp).trans <|
(intuitionisticallyIf_mono <| wand_mono_left h.1).trans intuitionisticallyIf_elim

-- TODO: compare this with into_wand_impl_false_false, into_wand_impl_false_true, ... in Rocq
instance intoWand_imp_false [BI PROP] (P Q P' : PROP) [Absorbing P'] [Absorbing iprop(P' → Q)]
[h : FromAssumption b ioP P P'] : IntoWand false b iprop(P' → Q) ioP P ioQ Q where
Expand Down Expand Up @@ -321,12 +334,12 @@ instance intoAnd_and_affine_r [BI PROP] (P P' Q : PROP) [Affine Q]
into_and := (and_mono_right (affine_affinely _).2).trans <|
affinely_and_right.1.trans <| affinely_and.1.trans <| and_mono h.1 (affine_affinely _).1

@[rocq_alias into_and_sep]
@[ipm_backtrack, rocq_alias into_and_sep]
instance intoAnd_sep [BI PROP] [BIPositive PROP] (P Q : PROP) :
IntoAnd true iprop(P ∗ Q) P Q where
into_and := intuitionistically_sep.1.trans <| and_sep_intuitionistically.2.trans <| intuitionistically_and.2

@[rocq_alias into_and_sep_affine]
@[ipm_backtrack, rocq_alias into_and_sep_affine]
instance intoAnd_sep_affine (p : Bool) [BI PROP] (P Q : PROP)
[TCOr (Affine P) (Absorbing Q)] [TCOr (Affine Q) (Absorbing P)] :
IntoAnd p iprop(P ∗ Q) P Q where
Expand Down Expand Up @@ -573,7 +586,7 @@ instance (priority := default + 30) intoAbsorbingly_true [BI PROP] :
IntoAbsorbingly (PROP := PROP) iprop(True) emp where
into_absorbingly := absorbingly_emp.2

@[rocq_alias into_absorbingly_absorbing]
@[ipm_backtrack, rocq_alias into_absorbingly_absorbing]
instance (priority := default + 20) intoAbsorbingly_absorbing [BI PROP] (P : PROP) [Absorbing P] :
IntoAbsorbingly P P where
into_absorbingly := absorbing_absorbingly.2
Expand Down Expand Up @@ -856,6 +869,46 @@ instance elimModal_absorbingly_here [BI PROP] p (P Q : PROP) [Absorbing Q] :
ElimModal True p false iprop(<absorb> P) P Q Q where
elim_modal _ := (sep_mono_left intuitionisticallyIf_elim).trans $ absorbingly_sep_left.1.trans $ absorbing_absorbingly.1.trans wand_elim_right

theorem addModal_wand_mp [BI PROP] {P P' Q R : PROP} [h : AddModal P P' Q] :
P ∗ (P' -∗ R -∗ Q) ⊢ R -∗ Q := by
have h1 : (P' -∗ R -∗ Q) ∗ R ⊢ P' -∗ Q := by
apply wand_intro
calc
_ ⊢ (P' -∗ R -∗ Q) ∗ R ∗ P' := sep_assoc.mp
_ ⊢ (P' -∗ R -∗ Q) ∗ P' ∗ R := sep_mono_right sep_comm.mp
_ ⊢ ((P' -∗ R -∗ Q) ∗ P') ∗ R := sep_assoc.mpr
_ ⊢ (R -∗ Q) ∗ R := sep_mono_left wand_elim_left
_ ⊢ Q := wand_elim_left
apply wand_intro
calc
_ ⊢ P ∗ (P' -∗ R -∗ Q) ∗ R := sep_assoc.mp
_ ⊢ P ∗ (P' -∗ Q) := sep_mono_right h1
_ ⊢ Q := h.add_modal

-- AddModal
@[rocq_alias add_modal_wand]
instance addModal_wand [BI PROP] (P P' Q R : PROP) [h : AddModal P P' Q] :
AddModal P P' iprop(R -∗ Q) where
add_modal := addModal_wand_mp

@[rocq_alias add_modal_wandM]
instance addModal_wandM [BI PROP] (P P' Q : PROP) (mR : Option PROP)
[h : AddModal P P' Q] : AddModal P P' iprop(mR -∗? Q) where
add_modal := by
cases mR with
| none => exact h.add_modal
| some R => exact addModal_wand_mp

@[rocq_alias add_modal_forall]
instance addModal_forall {A : Type} [BI PROP] (P P' : PROP) (Φ : A → PROP)
[h : ∀ x, AddModal P P' (Φ x)] : AddModal P P' iprop(∀ x, Φ x) where
add_modal := by
apply forall_intro
intro a
exact (sep_mono_right (wand_mono .rfl (forall_elim a))).trans (h a).add_modal

#rocq_ignore add_modal_tforall "Rocq-specific telescope infrastructure not needed in the Lean metaprogram"

-- CombineSepAs
@[rocq_alias maybe_combine_sep_as_default]
instance (priority := default - 20) combineSepAs_default [BI PROP] (P Q : PROP) :
Expand Down
36 changes: 36 additions & 0 deletions Iris/Iris/ProofMode/InstancesLater.lean
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,42 @@ instance (priority := default - 10) elimModal_timeless [BI PROP] p (P P' Q : PRO
ElimModal True p p P P' Q Q where
elim_modal _ := ((sep_mono ((intuitionisticallyIf_mono into_except0).trans except0_intuitionisticallyIf) except0_intro).trans $ except0_sep.2.trans (except0_mono wand_elim_right)).trans is_except0

/-- AddModal -/
@[rocq_alias add_modal_later_except_0]
instance (priority := default + 10) addModal_later_except_0 [BI PROP] (P Q : PROP) [h : Timeless P] :
AddModal iprop(▷ P) P iprop(◇ Q) where
add_modal := calc
_ ⊢ ◇ P ∗ (P -∗ ◇ Q) := sep_mono_left h.timeless
_ ⊢ ◇ (P ∗ (P -∗ ◇ Q)) := except0_frame_right
_ ⊢ ◇ (◇ Q) := except0_mono wand_elim_right
_ ⊢ ◇ Q := except0_idem.mp

@[rocq_alias add_modal_later]
instance (priority := default + 10) addModal_later [BI PROP] (P Q : PROP) [h : Timeless P] :
AddModal iprop(▷ P) P iprop(▷ Q) where
add_modal := calc
_ ⊢ ◇ P ∗ (P -∗ ▷ Q) := sep_mono_left h.timeless
_ ⊢ ◇ (P ∗ (P -∗ ▷ Q)) := except0_frame_right
_ ⊢ ◇ (▷ Q) := except0_mono wand_elim_right
_ ⊢ ▷ Q := except0_later

@[rocq_alias add_modal_except_0]
instance addModal_except_0 [BI PROP] (P Q : PROP) :
AddModal iprop(◇ P) P iprop(◇ Q) where
add_modal :=
calc
_ ⊢ ◇ (P ∗ (P -∗ ◇ Q)) := except0_frame_right
_ ⊢ ◇ (◇ Q) := except0_mono wand_elim_right
_ ⊢ ◇ Q := except0_idem.mp

@[rocq_alias add_modal_except_0_later]
instance addModal_except_0_later [BI PROP] (P Q : PROP) :
AddModal iprop(◇ P) P iprop(▷ Q) where
add_modal := calc
_ ⊢ ◇ (P ∗ (P -∗ ▷ Q)) := except0_frame_right
_ ⊢ ◇ (▷ Q) := except0_mono wand_elim_right
_ ⊢ ▷ Q := except0_later

/-- IntoLaterN -/
@[rocq_alias maybe_into_laterN_default]
instance (priority := low) intoLaterN_default [BI PROP] only_head n (P : PROP) :
Expand Down
15 changes: 15 additions & 0 deletions Iris/Iris/ProofMode/InstancesUpdates.lean
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ instance elimModal_bupd p (P Q : PROP) :
elim_modal _ := (sep_mono_left intuitionisticallyIf_elim).trans <|
bupd_frame_right.trans <| (BIUpdate.mono wand_elim_right).trans BIUpdate.trans

@[rocq_alias add_modal_bupd]
instance addModal_bupd (P Q : PROP) :
AddModal iprop(|==> P) P iprop(|==> Q) where
add_modal := bupd_wand_right.trans bupd_trans

end BIBasicUpdate

section SBIBasicUpdate
Expand Down Expand Up @@ -200,6 +205,16 @@ instance (priority := low) elimModal_fupd_fupd_wrongMask p E0 E1 E2 E3 (P Q : PR
p false iprop(|={E1,E2}=> P) iprop(False) iprop(|={E0,E3}=> Q) iprop(False) where
elim_modal h := by cases h

@[rocq_alias add_modal_fupd]
instance addModal_fupd E1 E2 (P Q : PROP) :
AddModal iprop(|={E1}=> P) P iprop(|={E1,E2}=> Q) where
add_modal := by
calc
_ ⊢ (P ={E1, E2}=∗ Q) ∗ (|={E1}=> P) := sep_comm.mp
_ ⊢ |={E1}=> ((P -∗ |={E1,E2}=> Q) ∗ P) := fupd_frame_left
_ ⊢ |={E1}=> (|={E1,E2}=> Q) := BIFUpdate.mono wand_elim_left
_ ⊢ |={E1, E2}=> Q := BIFUpdate.trans

end BIFancyUpdate

section SBIFancyUpdate
Expand Down
1 change: 0 additions & 1 deletion Iris/Iris/ProofMode/Patterns.lean
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ module

public import Iris.ProofMode.Patterns.CasesPattern
public import Iris.ProofMode.Patterns.IntroPattern
public import Iris.ProofMode.Patterns.ProofModeTerm
public import Iris.ProofMode.Patterns.SelPattern
public import Iris.ProofMode.Patterns.SpecPattern
36 changes: 0 additions & 36 deletions Iris/Iris/ProofMode/Patterns/ProofModeTerm.lean

This file was deleted.

Loading