Zulip Chat Archive
Stream: lean4
Topic: Induction with more than one base
Hannah Santos (Oct 12 2023 at 01:54):
I've been trying to make an induction with two definitions that have two bases, so I would like to know if I can work with that on lean4. To give a more detailed version of events, I want to prove odd n = !even n
, and I decided to make it so they are separate and this is a theorem, their definitions are as follows:
def even : Nat → Bool
| 0 => true
| succ zero => false
| succ (succ n) => even n
def odd : Nat → Bool
| 0 => false
| succ zero => true
| succ (succ n) => odd n
I know there must be better ways to do this, but that is not my point (I also don't want to define one as the opposite of the other, I really want that as a theorem). So, as I've started to write a proof I got here:
theorem odd_eq_not_even (n : Nat) :
odd n = not (even n) :=
by
induction n with
| zero => rw [odd, even, Bool.not_true]
| succ zero h => rw []
--| n+2 =>
/-case succ
l: ListNat
zero: Nat
h: odd zero = !even zero
⊢ odd (succ zero) = !even (succ zero)-/
I wanted to continue, but there's nothing else I can do, and that is (in my point of view) because there is another case I need to do for the induction to work. I don't know how to "hack" the induction tactic, but I read on the documentation that there is a way, I just couldn't translate it well to what I wanted. And roughly it's this: {p : Nat → Bool} (k n : Nat) (p zero ∧ p (succ zero) ∧ (∀k, p k ∧ p (succ k) → p (succ (succ k))) → ∀n, p n)
.... I think. Is there a better way to do it? Or am I way over my head or going through the wrong path?
Hannah Santos (Oct 12 2023 at 01:57):
(Sorry if my english is bad, it's not my first language, if I babbled too much you can just ask me to rephrase something and I'll try to make my thoughts clearer).
James Gallicchio (Oct 12 2023 at 03:08):
You can do this with strong induction :) the induction
tactic can take alternative induction schemes than the normal one. The syntax in this case is
induction n using Nat.strongInductionOn with
| ind n ih => ...
Then you can case on n
, handle the first two cases directly, and then use the ih
for the recursive case.
Mario Carneiro (Oct 12 2023 at 03:15):
you can also write the theorem as a definition by pattern matching in the same manner as the original definitions
Mario Carneiro (Oct 12 2023 at 03:17):
theorem odd_eq_not_even : ∀ (n : Nat), odd n = not (even n)
| 0 => rfl
| succ zero => rfl
| succ (succ n) => odd_eq_not_even n
Hannah Santos (Oct 13 2023 at 00:46):
Am I doing this right? This seems odd.
theorem odd_eq_not_even (n : Nat) :
odd n = not (even n) :=
by
induction n using Nat.strongInductionOn with
| ind n ih =>
cases n
rw [odd, even, Bool.not_true]
/-case ind.succ
l: ListNat
n✝: Nat
ih: ∀ (m : Nat), m < succ n✝ → odd m = !even m
⊢ odd (succ n✝) = !even (succ n✝)-/
Chris Wong (Oct 13 2023 at 01:31):
i think you need to do cases
twice
Chris Wong (Oct 13 2023 at 01:31):
because the induction is on succ succ n
, not just succ n
Chris Wong (Oct 13 2023 at 01:35):
See also: docs#Nat.twoStepInduction
James Gallicchio (Oct 13 2023 at 04:40):
You can also use match
in tactic mode, so you can have a match with the three cases.
Hannah Santos (Oct 13 2023 at 19:13):
It worked with match
. :)
Last updated: Dec 20 2023 at 11:08 UTC