import MyNat.Power
import AdditionWorld.Level5 -- one_eq_succ_zero
import PowerWorld.Level3 -- pow_one
import AdditionWorld.Level6 -- simp additions
import MultiplicationWorld.Level7 -- add_mul
import MultiplicationWorld.Level9 -- simp additions
namespace MyNat
open MyNat
Power World
Level 8: add_squared
Theorem
For all naturals a
and b
, we have (a + b)^2 = a^2 + b^2 + 2ab.
The first step in writing this proof is to convert 2
into something we
have theorems about, which is 1
and 0
.
deftwo :two: MyNatMyNat :=MyNat: Type2 def2: MyNattwo_eq_succ_one :two_eq_succ_one: two = succ 1two =two: MyNatsuccsucc: MyNat → MyNat1 :=1: MyNattwo = succ 1lemmaGoals accomplished! 🐙one_plus_one : (one_plus_one: 1 + 1 = 21 :1: MyNatMyNat) + (MyNat: Type1 :1: MyNatMyNat) = (MyNat: Type2 :2: MyNatMyNat) :=MyNat: Type1 + 1 = 2-- and we already have one_eq_succ_zero.Goals accomplished! 🐙
Now we are ready to tackle the proof:
lemmaadd_squared (add_squared: ∀ (a b : MyNat), (a + b) ^ two = a ^ two + b ^ two + 2 * a * baa: MyNatb :b: MyNatMyNat) : (MyNat: Typea +a: MyNatb) ^b: MyNattwo =two: MyNata ^a: MyNattwo +two: MyNatb ^b: MyNattwo +two: MyNat2 *2: MyNata *a: MyNatb :=b: MyNata, b: MyNat(a + b) ^ two = a ^ two + b ^ two + 2 * a * ba, b: MyNat(a + b) ^ two = a ^ two + b ^ two + 2 * a * ba, b: MyNat(a + b) ^ succ 1 = a ^ succ 1 + b ^ succ 1 + 2 * a * ba, b: MyNat(a + b) ^ succ 1 = a ^ succ 1 + b ^ succ 1 + 2 * a * ba, b: MyNat(a + b) ^ succ 1 = a ^ succ 1 + b ^ succ 1 + 2 * a * ba, b: MyNat(a + b) ^ succ (succ 0) = a ^ succ (succ 0) + b ^ succ (succ 0) + 2 * a * ba, b: MyNat(a + b) ^ succ (succ 0) = a ^ succ (succ 0) + b ^ succ (succ 0) + 2 * a * ba, b: MyNat(a + b) ^ succ (succ 0) = a ^ succ (succ 0) + b ^ succ (succ 0) + 2 * a * ba, b: MyNat(a + b) ^ 0 * (a + b) * (a + b) = a ^ 0 * a * a + b ^ succ (succ 0) + 2 * a * ba, b: MyNat(a + b) ^ 0 * (a + b) * (a + b) = a ^ 0 * a * a + b ^ succ 0 * b + 2 * a * ba, b: MyNat(a + b) ^ 0 * (a + b) * (a + b) = a ^ succ 0 * a + b ^ succ (succ 0) + 2 * a * ba, b: MyNat(a + b) ^ 0 * (a + b) * (a + b) = a ^ 0 * a * a + b ^ 0 * b * b + 2 * a * ba, b: MyNat1 * (a + b) * (a + b) = a ^ 0 * a * a + b ^ 0 * b * b + 2 * a * ba, b: MyNat1 * (a + b) * (a + b) = 1 * a * a + 1 * b * b + 2 * a * ba, b: MyNat1 * (a + b) * (a + b) = 1 * a * a + b ^ 0 * b * b + 2 * a * ba, b: MyNat1 * (a + b) * (a + b) = 1 * a * a + 1 * b * b + 2 * a * ba, b: MyNat(a + b) * (a + b) = a * a + 1 * b * b + 2 * a * ba, b: MyNat(a + b) * (a + b) = a * a + 1 * b * b + 2 * a * ba, b: MyNat(a + b) * (a + b) = a * a + 1 * b * b + 2 * a * ba, b: MyNat(a + b) * (a + b) = a * a + b * b + 2 * a * ba, b: MyNat(a + b) * a + (a + b) * b = a * a + b * b + 2 * a * ba, b: MyNat(a + b) * a + (a + b) * b = a * a + b * b + 2 * a * ba, b: MyNat(a + b) * a + (a + b) * b = a * a + b * b + 2 * a * ba, b: MyNata * a + b * a + (a * b + b * b) = a * a + b * b + 2 * a * ba, b: MyNata * a + b * a + (a * b + b * b) = a * a + b * b + 2 * a * ba, b: MyNata * a + b * a + (a + b) * b = a * a + b * b + 2 * a * ba, b: MyNata * a + b * a + (a * b + b * b) = a * a + b * b + 2 * a * ba, b: MyNata * a + b * a + (a * b + b * b) = a * a + b * b + (1 + 1) * a * ba, b: MyNata * a + b * a + (a * b + b * b) = a * a + b * b + (1 + 1) * a * ba, b: MyNata * a + b * a + (a * b + b * b) = a * a + b * b + (1 + 1) * a * ba, b: MyNata * a + b * a + (a * b + b * b) = a * a + b * b + (1 + 1) * a * ba, b: MyNata * a + b * a + (a * b + b * b) = a * a + b * b + (1 * a * b + 1 * a * b)a, b: MyNata * a + b * a + (a * b + b * b) = a * a + b * b + (1 * a + 1 * a) * ba, b: MyNata * a + b * a + (a * b + b * b) = a * a + b * b + (1 * a * b + 1 * a * b)a, b: MyNata * a + b * a + (a * b + b * b) = a * a + b * b + (1 * a * b + 1 * a * b)a, b: MyNata * a + b * a + (a * b + b * b) = a * a + b * b + (a * b + a * b)a, b: MyNata * a + b * a + (a * b + b * b) = a * a + b * b + (a * b + a * b)Goals accomplished! 🐙
It is also helpful to teach simp
our new tricks:
attribute [simp] pow_succ: ∀ (m n : MyNat), m ^ succ n = m ^ n * m
pow_succ pow_one: ∀ (a : MyNat), a ^ 1 = a
pow_one pow_zero: ∀ (m : MyNat), m ^ 0 = 1
pow_zero
There is some fun discussion on Lean3 Zulip
about different ways to solve this one in fewer steps.
Feel free to try some of those solutions here, just note that the Lean 4 syntax is a bit different,
no commands between tactics, and square brackets are required on the rw
tactic.
Do you fancy doing (a+b)^3
now? You might want to read
this Xena Project blog post before you start though.
If you got this far -- very well done! If you only learnt the three
tactics rw
, induction
and refl
then there are now more tactics to
learn; time to try Function World.
The main thing we really want to impress upon people is that we believe that all of pure mathematics can be done in this new way.
The Liquid Tensor Experiment shows that Lean3 could be used to prove very large math theorems.
Lean 3 also has a definition of perfectoid spaces (a very complex modern mathematical structure). We believe that these systems will one day cause a paradigm shift in the way mathematics is done, but first we need to build what we know, or at least build enough to state what we mathematicians believe.
If you want to get involved, come and join us at the Zulip Lean chat. The #new members stream is a great place to start asking questions.
Next up Function World.