Zulip Chat Archive
Stream: new members
Topic: 2 step induction 5
Răzvan Flavius Panda (Jul 13 2025 at 20:36):
Trying to prove: https://github.com/hrmacbeth/math2001/blob/e660f42b13ddcb6d12b52ba036d6bd071a0cfb9b/Math2001/06_Induction/03_Two_Step_Induction.lean#L175
Got as far as:
example (m : ℕ) : s m ≡ 2 [ZMOD 5] ∨ s m ≡ 3 [ZMOD 5] := by
two_step_induction m with k ih1 ih2
· left
rw [s]
numbers
· right
rw [s]
numbers
· obtain ih1 | ih1 := ih1
· obtain ih2 | ih2 := ih2
· calc
s (k + 1 + 1)
= 2 * s (k + 1) + 3 * s k := by rw [s]
_ ≡ 2 * 2 + 3 * 2 [ZMOD 5] := by rel [ih1, ih2]
· sorry
· sorry
The issue is that what I got now in calc is 0 [ZMOD 5] but the goal is to prove 3 [ZMOD 5].
Răzvan Flavius Panda (Jul 13 2025 at 21:16):
Am I doing something silly here or how did I end up in a situation impossible to prove the goal?
Aaron Liu (Jul 13 2025 at 21:26):
your induction hypothesis is not strong enough
Aaron Liu (Jul 13 2025 at 21:29):
what you actually want to prove is "forall n : ℕ, if n is even then s n ≡ 2 [ZMOD 5] and if n is odd then s n ≡ 3 [ZMOD 5]"
Aaron Liu (Jul 13 2025 at 21:29):
then use this to prove your main goal
Răzvan Flavius Panda (Jul 13 2025 at 21:31):
does not strong enough mean, insufficient to prove the goals?
Răzvan Flavius Panda (Jul 13 2025 at 21:36):
Aaron Liu said:
what you actually want to prove is "forall
n : ℕ, ifnis even thens n ≡ 2 [ZMOD 5]and ifnis odd thens n ≡ 3 [ZMOD 5]"
How did you end up with this observation?
I mean I can see it's a pattern by eval-ing things but I can't guarantee it would go on forever.
Aaron Liu (Jul 13 2025 at 21:38):
you see a pattern and then you guess it will go on forever
Aaron Liu (Jul 13 2025 at 21:39):
then you try proving it in Lean and if it doesn't work you then diagnose the issue and try again
Aaron Liu (Jul 13 2025 at 21:39):
or well that's what I do
Aaron Liu (Jul 13 2025 at 21:40):
you should state you induction goal like ∀ n, s (2 * n) ≡ 2 [ZMOD 5] ∧ s (2 * n + 1) ≡ 3 [ZMOD 5]
Aaron Liu (Jul 13 2025 at 21:42):
then use something like docs#Nat.even_or_odd' to case on even or odd
Răzvan Flavius Panda (Jul 13 2025 at 21:55):
Was what I tried an unavoidable step on the path of realizing the induction is not strong enough or was there an easier way?
Aaron Liu (Jul 13 2025 at 21:56):
there is an easier way
Aaron Liu (Jul 13 2025 at 21:56):
do the whole thing in your head and realize the problem before putting it into Lean
Aaron Liu (Jul 13 2025 at 21:56):
that's what I did
Răzvan Flavius Panda (Jul 13 2025 at 21:56):
unfortunately my brain does not come yet with a LEAN compiler
Răzvan Flavius Panda (Jul 13 2025 at 21:57):
I'll see what I can do about that
Răzvan Flavius Panda (Jul 13 2025 at 22:12):
Shouldn't this conv => ring work?
· calc
s (2 * n)
= s (2 * n - 2 + 2) := by conv => ring
Aaron Liu (Jul 13 2025 at 22:26):
what are you expecting conv => ring to do?
Aaron Liu (Jul 13 2025 at 22:26):
by the way Nat isn't a ring
Aaron Liu (Jul 13 2025 at 22:26):
subtraction truncates at zero so 1 - 2 = 0
Răzvan Flavius Panda (Jul 13 2025 at 22:27):
oh
Aaron Liu (Jul 13 2025 at 22:27):
this means 1 - 2 + 2 = 2
Aaron Liu (Jul 13 2025 at 22:27):
find a better way
Aaron Liu (Jul 13 2025 at 22:27):
you shouldn't have to introduce Nat subtraction
Răzvan Flavius Panda (Jul 13 2025 at 22:30):
My issue is that to expand this into definition: s (2 * n) I need it to be in the form s (something + 2)
The only way I knew to do that was by using -2 + 2.
Aaron Liu (Jul 13 2025 at 22:31):
no you should induction n
Aaron Liu (Jul 13 2025 at 22:31):
since n could be zero
Răzvan Flavius Panda (Jul 13 2025 at 22:46):
Making progress but I got stuck on how to obtain from hypothesis:
**ih** : Int.Even ↑k → s (2 * k) ≡ 2 [ZMOD 5] ∧ s (2 * k + 1) ≡ 3 [ZMOD 5]
Aaron Liu (Jul 13 2025 at 22:46):
where'd Int.Even k come from?
Aaron Liu (Jul 13 2025 at 22:46):
drop that
Răzvan Flavius Panda (Jul 13 2025 at 22:47):
This is what I got:
example (m : ℕ) : s m ≡ 2 [ZMOD 5] ∨ s m ≡ 3 [ZMOD 5] := by
have h1 : ∀ n, s (2 * n) ≡ 2 [ZMOD 5] ∧ s (2 * n + 1) ≡ 3 [ZMOD 5] := by
intro n
obtain h1 | h2 := Int.even_or_odd n
simple_induction n with k ih
· constructor
· calc
s (2 * 0)
= 2 := by rw [s]
_ ≡ 2 [ZMOD 5] := by extra
· calc
s (2 * 0 + 1)
= 3 := by rw [s]
_ ≡ 3 [ZMOD 5] := by extra
· sorry
Aaron Liu (Jul 13 2025 at 22:48):
remove the obtain
Aaron Liu (Jul 13 2025 at 22:48):
put it after the have
Răzvan Flavius Panda (Jul 13 2025 at 22:49):
n doesn't exist if I put it before the intro n
Aaron Liu (Jul 13 2025 at 22:51):
yeah case on m instead
Răzvan Flavius Panda (Jul 13 2025 at 22:52):
Is this what you mean:
example (m : ℕ) : s m ≡ 2 [ZMOD 5] ∨ s m ≡ 3 [ZMOD 5] := by
have h1 : ∀ n, s (2 * n) ≡ 2 [ZMOD 5] ∧ s (2 * n + 1) ≡ 3 [ZMOD 5] := by
obtain h1 | h2 := Int.even_or_odd m
simple_induction m with k ih
?
Aaron Liu (Jul 13 2025 at 22:52):
no
Aaron Liu (Jul 13 2025 at 22:53):
example (m : ℕ) : s m ≡ 2 [ZMOD 5] ∨ s m ≡ 3 [ZMOD 5] := by
have h1 : ∀ n, s (2 * n) ≡ 2 [ZMOD 5] ∧ s (2 * n + 1) ≡ 3 [ZMOD 5] := by
intro n
simple_induction n with k ih
-- put an amazing proof here
all_goals sorry
obtain h2 | h3 := Int.even_or_odd m
-- continue an amazing proof here
all_goals sorry
Aaron Liu (Jul 13 2025 at 22:55):
oh I got it wrong (edited)
Răzvan Flavius Panda (Jul 13 2025 at 23:07):
Do you see what I am doing wrong here?
example (m : ℕ) : s m ≡ 2 [ZMOD 5] ∨ s m ≡ 3 [ZMOD 5] := by
have h1 : ∀ n, s (2 * n) ≡ 2 [ZMOD 5] ∧ s (2 * n + 1) ≡ 3 [ZMOD 5] := by
intro n
simple_induction n with k ih
· constructor
· calc
s (2 * 0)
= 2 := by rw [s]
_ ≡ 2 [ZMOD 5] := by extra
· calc
s (2 * 0 + 1)
= 3 := by rw [s]
_ ≡ 3 [ZMOD 5] := by extra
· obtain ⟨ih1, ih2⟩ := ih
· constructor
· calc
s (2 * (k + 1))
≡ 2 [ZMOD 5] := by rel [ih1]
· calc
unexpected token 'calc'; expected ':='
m k : ℕ
ih1 : s (2 * k) ≡ 2 [ZMOD 5]
ih2 : s (2 * k + 1) ≡ 3 [ZMOD 5]
⊢ s (2 * (k + 1)) ≡ 2 [ZMOD 5]
Răzvan Flavius Panda (Jul 13 2025 at 23:08):
It looks like the previous calc block goal did not close but it looks like should have.
Ruben Van de Velde (Jul 13 2025 at 23:17):
You should assume that calc with just a single step doesn't work
Răzvan Flavius Panda (Jul 13 2025 at 23:18):
Is that guaranteed or just unlikely?
Răzvan Flavius Panda (Jul 13 2025 at 23:19):
My issue is that LEAN does not complain, there is no red squigle for that subgoal.
Aaron Liu (Jul 13 2025 at 23:26):
it parses weird
Răzvan Flavius Panda (Jul 13 2025 at 23:28):
I am not even sure how **ih1** : s (2 * k) ≡ 2 [ZMOD 5] managed to apply since it does not look exactly like it could apply.
Aaron Liu (Jul 13 2025 at 23:28):
I have a way to fix the one line calc
Aaron Liu (Jul 13 2025 at 23:28):
but I haven't completed it yet
Răzvan Flavius Panda (Jul 13 2025 at 23:29):
So 1 line calc's can work, I see.
Aaron Liu (Jul 13 2025 at 23:29):
for now you should just avoid one line calcs
Răzvan Flavius Panda (Jul 13 2025 at 23:30):
Well, this doesn't work:
· calc
s (2 * (k + 1))
_ = s (2 * (k + 1)) := by rfl
≡ 2 [ZMOD 5] := by rel [ih1]
How am I supposed to make it multi-line?
Răzvan Flavius Panda (Jul 13 2025 at 23:37):
Oh, I placed _ in the wrong place.
Răzvan Flavius Panda (Jul 13 2025 at 23:37):
And now I get a squiggle on rel so it does not work.
Răzvan Flavius Panda (Jul 14 2025 at 18:31):
I don't know what to do.rel [ih1] clearly can't rewrite s (2 * (k + 1)) as it would be s (2 * k) even though they are both even arguments and the reply would be in both cases 2 [ZMOD 5]
Aaron Liu (Jul 14 2025 at 18:32):
well you need to rewrite 2 * (k + 1) into 2 * k + 1 + 1
Aaron Liu (Jul 14 2025 at 18:32):
these are actually definitionally equal
Răzvan Flavius Panda (Jul 14 2025 at 18:33):
How would that help, I still need to rel on s (2 * k) or s (2 * k + 1) and it wouldn't match.
Răzvan Flavius Panda (Jul 14 2025 at 18:35):
Also I tried to rewrite inside s argument using conv => ring and that didn't work. So no idea how to rewrite arguments.
Aaron Liu (Jul 14 2025 at 18:38):
well once you have s (2 * k + 1 + 1) you can start unfolding the definition of s
Răzvan Flavius Panda (Jul 14 2025 at 18:40):
Ok, I see, but how do I rewrite inside the s argument? conv => ring doesn't work
Aaron Liu (Jul 14 2025 at 18:41):
do you know how conv mode works?
Aaron Liu (Jul 14 2025 at 18:41):
you need to enter the argument you want
Răzvan Flavius Panda (Jul 14 2025 at 18:41):
No, it was never explained. From what I seen it allows to apply tactics inside other expressions.
Răzvan Flavius Panda (Jul 14 2025 at 18:42):
Aaron Liu said:
you need to
enterthe argument you want
How does that look like?
Aaron Liu (Jul 14 2025 at 18:46):
example {x y : Nat} (h : x = x * y + y) :
x + x + y + x * (x * y + y) = x + x + y + x * ((x * y + y) * y + y) := by
conv =>
enter [1, 2, 2, 1, 1]
rw [h]
Aaron Liu (Jul 14 2025 at 18:47):
put your cursor on the numbers and step through the enter command
Răzvan Flavius Panda (Jul 14 2025 at 18:57):
Well, I understand how your example works. :sweat_smile:
Răzvan Flavius Panda (Jul 14 2025 at 18:58):
I want something lke this but it's not working:
· calc
s (2 * (k + 1))
= s (2 * k + 2) := by conv =>
enter [2]
ring
Răzvan Flavius Panda (Jul 14 2025 at 18:59):
I seem to have broken the entire proof, getting squiggles everywhere or tactics in white:
Aaron Liu (Jul 14 2025 at 18:59):
that's because you have a one-line calc
Aaron Liu (Jul 14 2025 at 18:59):
you should fix that first
Răzvan Flavius Panda (Jul 14 2025 at 19:12):
Ok, so:
· calc
s (2 * (k + 1))
= s (2 * k + 2) := by conv =>
enter [2]
ring
_ = 2 * s (2 * k + 1) + 3 * s (2 * k) := by rw [s]
The conv is not working as I was hoping it would.
Răzvan Flavius Panda (Jul 14 2025 at 19:12):
Wanted to focus on the argument and apply ring on it.
Răzvan Flavius Panda (Jul 14 2025 at 19:14):
Hovering over the 2 in the enter does not focus on anything.
Aaron Liu (Jul 14 2025 at 19:15):
I think it should focus on the right side of the equality (whereas before it was focusing on the entire equality)
Aaron Liu (Jul 14 2025 at 19:16):
you can also just have h : 2 * (k + 1) = 2 * k + 2 := rfl and then rewrite using h
Răzvan Flavius Panda (Jul 14 2025 at 19:16):
I'll take anything that works!
Răzvan Flavius Panda (Jul 14 2025 at 19:29):
Sub-goal solved.
Răzvan Flavius Panda (Jul 14 2025 at 20:01):
-- continue an amazing proof here
I like your positivity :smile:
Răzvan Flavius Panda (Jul 14 2025 at 20:09):
How can I use obtain with:
h1 : ∀ (n : ℕ), s (2 * n) ≡ 2 [ZMOD 5] ∧ s (2 * n + 1) ≡ 3 [ZMOD 5]
the forall prevents me from using: obtain ⟨h11, h12⟩ := h1
Răzvan Flavius Panda (Jul 14 2025 at 20:14):
This works: obtain ⟨h11, h12⟩ := h1 m
Răzvan Flavius Panda (Jul 14 2025 at 20:15):
But the goal is problematic:
m : ℕ
h1 : ∀ (n : ℕ), s (2 * n) ≡ 2 [ZMOD 5] ∧ s (2 * n + 1) ≡ 3 [ZMOD 5]
n : ℤ
h2n : ↑m = 2 * n
h11 : s (2 * m) ≡ 2 [ZMOD 5]
h12 : s (2 * m + 1) ≡ 3 [ZMOD 5]
⊢ s m ≡ 2 [ZMOD 5] ∨ s m ≡ 3 [ZMOD 5]
Răzvan Flavius Panda (Jul 14 2025 at 20:16):
Was hoping to rw h2n at goal.
Aaron Liu (Jul 14 2025 at 20:16):
you want to show that there exists a n' : ℕ such that n = ↑n' and then obtain with h1 n'
Răzvan Flavius Panda (Jul 14 2025 at 20:16):
And then exact of h11 or h12 would have closed the goal but if they used n instead of m
Răzvan Flavius Panda (Jul 15 2025 at 17:47):
I don't know how to prove that. Not even sure what up arrow n means. Is that casting?
Gemini came up with:
theorem exists_nat_for_nonneg_int_term (n : ℤ) (h : 0 ≤ n) : ∃ n' : ℕ, n = ↑n' :=
-- The witness is `Int.toNat n`
-- The proof of the property is `(Int.coe_toNat_of_nonneg h).symm`
⟨Int.toNat n, (Int.coe_toNat_of_nonneg h).symm⟩
But Int.coe_toNat_of_nonneg is hallucinated.
Aaron Liu (Jul 15 2025 at 17:50):
@loogle "nonneg", Int.toNat, Nat.cast
loogle (Jul 15 2025 at 17:50):
:search: Int.toNat_of_nonneg, Int.emod_natAbs_of_nonneg
Răzvan Flavius Panda (Jul 15 2025 at 17:54):
Had a look, I don't see the up arrow explained.
Răzvan Flavius Panda (Jul 15 2025 at 18:03):
Oh, I see, it's type coercion. It's like upcasting.
Răzvan Flavius Panda (Jul 15 2025 at 18:05):
Is this the signature of what you wanted me to prove?
theorem exists_nat_for_nonneg_int_term (n : ℤ) (h : 0 ≤ n) : ∃ n' : ℕ, n = ↑n'
Răzvan Flavius Panda (Jul 17 2025 at 21:25):
Last updated: Dec 20 2025 at 21:32 UTC