Zulip Chat Archive
Stream: batteries
Topic: Insufficient number of targets
Robin Green (Feb 04 2024 at 16:22):
I tried to do
induction data using String.utf8InductionOn
but I got insufficient number of targets for 'String.utf8InductionOn'
. I don't know what this error message means. Is this supported at all?
Kevin Buzzard (Feb 04 2024 at 17:26):
#mwe ?
Robin Green (Feb 04 2024 at 18:40):
import Std.Data.String.Lemmas
def count (s : Substring) (p : Char -> Bool) : Nat :=
s.foldr (fun ch c => if p ch then c + 1 else c) 0
theorem missing_char_count_zero (v : Substring.Valid word) : word.contains ch = false -> count word (· == ch) = 0 := by
cases word
. case mk str startPos stopPos =>
cases str
. case mk data =>
induction data using String.utf8InductionOn
Mario Carneiro (Feb 04 2024 at 19:04):
I don't think String.utf8InductionOn
is compatible with the induction
tactic
Mario Carneiro (Feb 04 2024 at 19:04):
you have to just call it directly
Mario Carneiro (Feb 04 2024 at 19:07):
which looks like this:
apply String.utf8InductionOn
(motive := fun data startPos =>
Substring.contains ⟨⟨data⟩, startPos, stopPos⟩ ch = false →
(count ⟨⟨data⟩, startPos, stopPos⟩ fun x ↦ x == ch) = 0)
data startPos stopPos
Mario Carneiro (Feb 04 2024 at 19:40):
cc: @Joachim Breitner , it would be nice to get the induction using
parser to support more theorems in std/mathlib with inductionOn
in the name - the lean 4 rules are more restrictive than lean 3 and mostly don't work at all when the motive has multiple targets
Eric Rodriguez (Feb 04 2024 at 20:25):
Eric Rodriguez (Feb 04 2024 at 20:26):
Oh, because the motive takes two parameters?
Joachim Breitner (Feb 04 2024 at 20:29):
On the phone right now. But does induction data, startPos using String.utf8InductionOn (p := stopPos)
not work?
Robin Green (Feb 04 2024 at 20:32):
No - now I get:
tactic 'introN' failed, insufficient number of binders
case p
ch : Char
startPos stopPos : String.Pos
data : List Char
⊢ String.PosLean 4
Though I'm having fun with the full power of using apply
directly :grinning_face_with_smiling_eyes:
Joachim Breitner (Feb 04 2024 at 20:34):
That's probably https://github.com/leanprover/lean4/issues/3212. So it's not much missing
Joachim Breitner (Feb 04 2024 at 20:35):
But yes, at some point it's easier to use apply or refine rather than fighting the induction tactic :-)
Joachim Breitner (Feb 04 2024 at 21:13):
Oh, and you can work around #3212 by revert
’ing yourself:
import Std.Data.String.Lemmas
def count (s : Substring) (p : Char -> Bool) : Nat :=
s.foldr (fun ch c => if p ch then c + 1 else c) 0
theorem missing_char_count_zero (v : Substring.Valid word) : word.contains ch = false -> count word (· == ch) = 0 := by
cases word
. case mk str startPos stopPos =>
cases str
. case mk data =>
revert v
induction data, startPos using String.utf8InductionOn (p := stopPos)
Robin Green (Feb 04 2024 at 21:18):
It considers the (p := stopPos)
a syntax error now, but it does appear to generate some subgoals if I remove that part
Joachim Breitner (Feb 04 2024 at 21:19):
You are probably on 4.5.0; it works already on live.lean-lang.org; this is a new feature I added recently.
Joachim Breitner (Feb 04 2024 at 21:20):
But yes, you can omit it, and then use exact p
as the first “case” instead
Last updated: May 02 2025 at 03:31 UTC