Zulip Chat Archive
Stream: lean4
Topic: Induction generalizes given instance arguments
pandaman (Dec 19 2025 at 10:54):
I'm defining a custom induction principle that takes a class instance as a parameter. When I used the induction principle with the induction tactic, it seems to generalize the instance parameter even when the instance is given (explicitly or via the instance search). Is the behavior expected? I'd like it to use the given instance.
MWE:
open String (Pos)
class PositionRecorder (s : String) (α : Type) where
instance instPos {s : String} : PositionRecorder s (Pos s) where
theorem inductionOn {s : String} (α : Type) (inst : PositionRecorder s α)
(motive : Pos s → Prop)
(not_found : motive s.endPos)
(pos : Pos s) :
motive pos := sorry
theorem test {s : String} {pos : Pos s}:
True := by
induction pos using inductionOn (Pos s) inferInstance with
| not_found => sorry
-- BUG: induction tactic introduces `x_1` for `PositionRecorder s (Pos s)` even though it's provided explicitly.
-- Without this branch, the tactic fails with "Alternative `x_1` has not been provided"
| x_1 => sorry
theorem inductionOnInst {s : String} (α : Type) [inst : PositionRecorder s α]
(motive : Pos s → Prop)
(not_found : motive s.endPos)
(pos : Pos s) :
motive pos := sorry
theorem test' {s : String} {pos : Pos s}:
True := by
induction pos using inductionOnInst (Pos s) with
| not_found => sorry
-- BUG: induction tactic introduces `x_1` for `PositionRecorder s (Pos s)` even though it's provided via the instance search.
-- Without this branch, the tactic fails with "Alternative `x_1` has not been provided"
| x_1 => sorry
Aaron Liu (Dec 19 2025 at 11:19):
the x_1 branch seems to be going into the implicit argument of inferInstance
pandaman (Dec 19 2025 at 12:19):
Interesting. Passing instPos explicitly to inductionOn seems to work. Do you have any ideas for the inductionOnInst version? It's closer to the one I want to use.
Last updated: Dec 20 2025 at 21:32 UTC