@ceccec/millennium-solutions 9.2.7 → 9.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ACCOUNTING.md +6 -6
- package/AXIOMS.md +8 -8
- package/CHALLENGES.md +61 -3
- package/PRIOR-ART.md +13 -13
- package/README.md +24 -24
- package/dashboard.md +1 -1
- package/forensic.md +4 -4
- package/index.md +24 -24
- package/package.json +1 -1
- package/paper.md +852 -614
- package/speedup.md +4 -4
- package/src/proof/demand2.lean +36 -0
- package/src/proof/discovered.json +145 -0
- package/src/proof/elementary.lean +20 -0
- package/src/proof/families.lean +166 -0
- package/src/proof/nim.lean +209 -3
- package/src/proof/sequences.lean +31 -0
- package/src/proof/trial-all.json +174 -0
package/speedup.md
CHANGED
|
@@ -7,7 +7,7 @@ head:
|
|
|
7
7
|
|
|
8
8
|
# The real uuidna advantage — measured, in all domains
|
|
9
9
|
|
|
10
|
-
> Generated from the **
|
|
10
|
+
> Generated from the **2658** ledger entries and **59** domains, recomputed each build. The advantage is
|
|
11
11
|
> real and **measured**, and honestly bounded: a **verification and reuse** complexity reduction — **not**
|
|
12
12
|
> faster original compute, **not** faster than light, **not** quantum.
|
|
13
13
|
|
|
@@ -33,9 +33,9 @@ theorems verify in `⌈log₂N⌉`. So one proof covers the whole [rosetta](/):
|
|
|
33
33
|
|
|
34
34
|
## Discovery lead — a lead, never a verdict
|
|
35
35
|
|
|
36
|
-
Grouping the
|
|
37
|
-
**3** (
|
|
38
|
-
at **
|
|
36
|
+
Grouping the 2658 receipts by the digital root of their address, the **sparsest** region is digit
|
|
37
|
+
**3** (269) — a candidate area to examine, not a finding. The ledger is currently held
|
|
38
|
+
at **2658** (the captain's cap): improving a theorem's name or proof heals the record without changing the
|
|
39
39
|
count; discovering a new one would require lifting the cap.
|
|
40
40
|
|
|
41
41
|
A content-address proves **integrity, not truth**.
|
package/src/proof/demand2.lean
CHANGED
|
@@ -168,4 +168,40 @@ theorem two_twenty_and_two_eighty_four_are_the_smallest_amicable_pair :
|
|
|
168
168
|
(List.range' 2 218).all (fun a => ¬ (aliquot (aliquot a) == a && ¬ (aliquot a == a))) ∧
|
|
169
169
|
(List.range' 2 218).filter (fun a => aliquot a == a) = [6, 28] := by decide
|
|
170
170
|
|
|
171
|
+
|
|
172
|
+
-- ── the capped rows above, proved for every value — no bound ─────────────────────────────────────────────────
|
|
173
|
+
-- sumPow is Families.powSum written as a single fold, so the Faulhaber laws proved there carry
|
|
174
|
+
-- nicomachus_sum_of_cubes_is_the_square_of_the_triangular_number (n ≤ 40) and
|
|
175
|
+
-- the_sum_of_fifth_powers_has_the_closed_form_asked_for (n ≤ 20) to every n.
|
|
176
|
+
theorem the_two_power_sums_are_one_sum : ∀ p n : Nat, sumPow p n = powSum p n := by
|
|
177
|
+
intro p n
|
|
178
|
+
unfold sumPow powSum
|
|
179
|
+
rw [List.foldl_map]
|
|
180
|
+
|
|
181
|
+
theorem nicomachus_sum_of_cubes_is_the_square_of_the_triangular_number_for_every_n :
|
|
182
|
+
∀ n : Nat, sumPow 3 n = tri n * tri n := by
|
|
183
|
+
intro n
|
|
184
|
+
have c := the_cubes_sum_to_their_closed_form_for_every_n n
|
|
185
|
+
rw [← the_two_power_sums_are_one_sum] at c
|
|
186
|
+
have ev : n * (n + 1) % 2 = 0 := by
|
|
187
|
+
rcases Nat.mod_two_eq_zero_or_one n with e | e <;> simp [Nat.mul_mod, Nat.add_mod, e]
|
|
188
|
+
have hd : n * (n + 1) / 2 * 2 = n * (n + 1) := Nat.div_mul_cancel (Nat.dvd_of_mod_eq_zero ev)
|
|
189
|
+
unfold tri
|
|
190
|
+
generalize n * (n + 1) / 2 = t at hd ⊢
|
|
191
|
+
generalize sumPow 3 n = s at c ⊢
|
|
192
|
+
have q : 4 * s = 4 * (t * t) := by
|
|
193
|
+
have hsq : (t * 2) * (t * 2) = (n * (n + 1)) * (n * (n + 1)) := by rw [hd]
|
|
194
|
+
clear hd ev
|
|
195
|
+
try simp only [Nat.mul_add, Nat.add_mul, Nat.pow_succ, Nat.pow_zero, Nat.one_mul, Nat.mul_one, Nat.reduceMul, Nat.reduceAdd] at *
|
|
196
|
+
try simp only [Nat.mul_assoc, Nat.mul_comm, Nat.mul_left_comm, Nat.reduceMul] at *
|
|
197
|
+
try simp only [Nat.mul_comm _ (OfNat.ofNat _), Nat.mul_left_comm _ (OfNat.ofNat _), Nat.reduceMul] at *
|
|
198
|
+
all_goals omega
|
|
199
|
+
exact Nat.eq_of_mul_eq_mul_left (by decide) q
|
|
200
|
+
|
|
201
|
+
theorem the_sum_of_fifth_powers_has_the_closed_form_for_every_n :
|
|
202
|
+
∀ n : Nat, 12 * sumPow 5 n = n * n * (n + 1) * (n + 1) * (2 * n * n + 2 * n - 1) := by
|
|
203
|
+
intro n
|
|
204
|
+
rw [the_two_power_sums_are_one_sum]
|
|
205
|
+
exact the_fifth_powers_sum_to_their_closed_form_for_every_n n
|
|
206
|
+
|
|
171
207
|
end Demand2
|
|
@@ -18896,5 +18896,150 @@
|
|
|
18896
18896
|
"key": "lean_z9plus_digital_root_is_the_digit_sum_residue_for_every_n",
|
|
18897
18897
|
"name": "lean z9plus.lean: digital_root_is_the_digit_sum_residue_for_every_n — ∀ n : Nat, m9 (digitSum n) = m9 n — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18898
18898
|
"receipt": "694fefdf-a71b-8019-84e5-04477e7be3d8"
|
|
18899
|
+
},
|
|
18900
|
+
{
|
|
18901
|
+
"key": "lean_demand2_the_two_power_sums_are_one_sum",
|
|
18902
|
+
"name": "lean demand2.lean: the_two_power_sums_are_one_sum — ∀ p n : Nat, sumPow p n = powSum p n — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18903
|
+
"receipt": "6551630b-4917-8c1c-999f-4728c266cfd1"
|
|
18904
|
+
},
|
|
18905
|
+
{
|
|
18906
|
+
"key": "lean_demand2_nicomachus_sum_of_cubes_is_the_square_of_the_triangular_number_for_every_n",
|
|
18907
|
+
"name": "lean demand2.lean: nicomachus_sum_of_cubes_is_the_square_of_the_triangular_number_for_every_n — ∀ n : Nat, sumPow 3 n = tri n * tri n — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18908
|
+
"receipt": "7aa0bbe0-b4ae-82e8-8319-7aed7047d654"
|
|
18909
|
+
},
|
|
18910
|
+
{
|
|
18911
|
+
"key": "lean_demand2_the_sum_of_fifth_powers_has_the_closed_form_for_every_n",
|
|
18912
|
+
"name": "lean demand2.lean: the_sum_of_fifth_powers_has_the_closed_form_for_every_n — ∀ n : Nat, 12 * sumPow 5 n = n * n * (n + 1) * (n + 1) * (2 * n * n + 2 * n - 1) — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18913
|
+
"receipt": "6916652f-bda2-80d1-882e-009dee2d791d"
|
|
18914
|
+
},
|
|
18915
|
+
{
|
|
18916
|
+
"key": "lean_elementary_the_lucas_numbers_are_the_sum_of_the_neighbouring_fibonaccis_for_every_n",
|
|
18917
|
+
"name": "lean elementary.lean: the_lucas_numbers_are_the_sum_of_the_neighbouring_fibonaccis_for_every_n — ∀ n : Nat, lucas (n + 1) = fib n + fib (n + 2) — proved by the Lean kernel for every value (by\n have), standard axioms only — checked by lean.ts",
|
|
18918
|
+
"receipt": "cacb33f1-2fc1-8887-87a8-67aa352b3ac6"
|
|
18919
|
+
},
|
|
18920
|
+
{
|
|
18921
|
+
"key": "lean_families_cassinis_identity_for_every_m",
|
|
18922
|
+
"name": "lean families.lean: cassinis_identity_for_every_m — ∀ m : Nat, fib (2 * m + 1) * fib (2 * m + 3) = fib (2 * m + 2) * fib (2 * m + 2) + 1 ∧ fib (2 * m) * fib (2 * m + 2) + 1 = fib (2 * m + 1) * fib (2 * m + 1) — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18923
|
+
"receipt": "75a810f1-ae27-8fb7-b4d3-b257c0c917c7"
|
|
18924
|
+
},
|
|
18925
|
+
{
|
|
18926
|
+
"key": "lean_families_a_sum_over_one_to_n_plus_one_adds_the_last_term",
|
|
18927
|
+
"name": "lean families.lean: a_sum_over_one_to_n_plus_one_adds_the_last_term — ∀ (g : Nat → Nat) (n : Nat), ((List.range' 1 (n + 1)).map g).foldl (· + ·) 0 = ((List.range' 1 n).map g).foldl (· + ·) 0 + g (n + 1) — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18928
|
+
"receipt": "f664ca1d-8371-8bd5-a369-060e34e5baaf"
|
|
18929
|
+
},
|
|
18930
|
+
{
|
|
18931
|
+
"key": "lean_families_the_numbers_sum_to_their_closed_form_for_every_n",
|
|
18932
|
+
"name": "lean families.lean: the_numbers_sum_to_their_closed_form_for_every_n — ∀ n : Nat, 2 * powSum 1 n = n * (n + 1) — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18933
|
+
"receipt": "34fa9fc8-b8ed-8895-bb81-c92f4515e9fe"
|
|
18934
|
+
},
|
|
18935
|
+
{
|
|
18936
|
+
"key": "lean_families_the_squares_sum_to_their_closed_form_for_every_n",
|
|
18937
|
+
"name": "lean families.lean: the_squares_sum_to_their_closed_form_for_every_n — ∀ n : Nat, 6 * powSum 2 n = n * (n + 1) * (2 * n + 1) — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18938
|
+
"receipt": "0b7a0569-fb3f-8ba7-a49a-900c19bf369d"
|
|
18939
|
+
},
|
|
18940
|
+
{
|
|
18941
|
+
"key": "lean_families_the_cubes_sum_to_their_closed_form_for_every_n",
|
|
18942
|
+
"name": "lean families.lean: the_cubes_sum_to_their_closed_form_for_every_n — ∀ n : Nat, 4 * powSum 3 n = n * n * (n + 1) * (n + 1) — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18943
|
+
"receipt": "96b0047e-cf09-8755-be28-1cb49080d466"
|
|
18944
|
+
},
|
|
18945
|
+
{
|
|
18946
|
+
"key": "lean_families_the_fourth_powers_sum_to_their_closed_form_for_every_n",
|
|
18947
|
+
"name": "lean families.lean: the_fourth_powers_sum_to_their_closed_form_for_every_n — ∀ n : Nat, 30 * powSum 4 n = n * (n + 1) * (2 * n + 1) * (3 * n * n + 3 * n - 1) — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18948
|
+
"receipt": "3419aabd-970f-8738-ae26-0adbfd4cf7fb"
|
|
18949
|
+
},
|
|
18950
|
+
{
|
|
18951
|
+
"key": "lean_families_the_fifth_powers_sum_to_their_closed_form_for_every_n",
|
|
18952
|
+
"name": "lean families.lean: the_fifth_powers_sum_to_their_closed_form_for_every_n — ∀ n : Nat, 12 * powSum 5 n = n * n * (n + 1) * (n + 1) * (2 * n * n + 2 * n - 1) — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18953
|
+
"receipt": "790310ea-f06d-875d-89aa-2aba93d133e3"
|
|
18954
|
+
},
|
|
18955
|
+
{
|
|
18956
|
+
"key": "lean_families_power_sums_match_their_closed_forms_for_every_n",
|
|
18957
|
+
"name": "lean families.lean: power_sums_match_their_closed_forms_for_every_n — ∀ k n : Nat, 1 ≤ k → k ≤ 5 → powSum k n = faulhaber k n — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18958
|
+
"receipt": "04b04822-598b-8529-a44c-7881174ec382"
|
|
18959
|
+
},
|
|
18960
|
+
{
|
|
18961
|
+
"key": "lean_families_the_sums_of_triangular_numbers_are_the_tetrahedral_numbers_for_every_n",
|
|
18962
|
+
"name": "lean families.lean: the_sums_of_triangular_numbers_are_the_tetrahedral_numbers_for_every_n — ∀ n : Nat, ((List.range' 1 n).map (fun i => i * (i + 1) / 2)).foldl (· + ·) 0 = n * (n + 1) * (n + 2) / 6 — proved by the Lean kernel for every value (by\n have), standard axioms only — checked by lean.ts",
|
|
18963
|
+
"receipt": "43b9cdd8-7110-8f6f-887b-297d0262ae80"
|
|
18964
|
+
},
|
|
18965
|
+
{
|
|
18966
|
+
"key": "lean_sequences_cassinis_identity_for_every_m",
|
|
18967
|
+
"name": "lean sequences.lean: cassinis_identity_for_every_m — ∀ m : Nat, fib (2 * m + 1) * fib (2 * m + 3) = fib (2 * m + 2) * fib (2 * m + 2) + 1 ∧ fib (2 * m) * fib (2 * m + 2) + 1 = fib (2 * m + 1) * fib (2 * m + 1) — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18968
|
+
"receipt": "3b815427-42b8-8b8c-abf3-423b1e268af3"
|
|
18969
|
+
},
|
|
18970
|
+
{
|
|
18971
|
+
"key": "lean_nim_the_xor_of_two_bits_is_their_sum_mod_two",
|
|
18972
|
+
"name": "lean nim.lean: the_xor_of_two_bits_is_their_sum_mod_two — ∀ x y : Nat, (if x % 2 == y % 2 then 0 else 1) = (x + y) % 2 — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18973
|
+
"receipt": "322304d5-f000-8492-8e7f-69ce46520610"
|
|
18974
|
+
},
|
|
18975
|
+
{
|
|
18976
|
+
"key": "lean_nim_xor_commutes_at_every_fuel",
|
|
18977
|
+
"name": "lean nim.lean: xor_commutes_at_every_fuel — ∀ f a b : Nat, xorF f a b = xorF f b a — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18978
|
+
"receipt": "b091d5a8-4e4a-8116-93d8-199afc028903"
|
|
18979
|
+
},
|
|
18980
|
+
{
|
|
18981
|
+
"key": "lean_nim_one_more_step_of_fuel_changes_nothing_once_it_exceeds_an_argument",
|
|
18982
|
+
"name": "lean nim.lean: one_more_step_of_fuel_changes_nothing_once_it_exceeds_an_argument — ∀ f a b : Nat, (a < f ∨ b < f) → xorF (f + 1) a b = xorF f a b — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18983
|
+
"receipt": "adf2ef5a-ef44-84b9-adb7-2edf0437284f"
|
|
18984
|
+
},
|
|
18985
|
+
{
|
|
18986
|
+
"key": "lean_nim_more_fuel_changes_nothing_once_it_exceeds_an_argument",
|
|
18987
|
+
"name": "lean nim.lean: more_fuel_changes_nothing_once_it_exceeds_an_argument — ∀ k f a b : Nat, (a < f ∨ b < f) → xorF (f + k) a b = xorF f a b — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18988
|
+
"receipt": "961d94be-959c-80ff-b0c4-03079551178a"
|
|
18989
|
+
},
|
|
18990
|
+
{
|
|
18991
|
+
"key": "lean_nim_xor_reads_the_same_at_every_sufficient_fuel",
|
|
18992
|
+
"name": "lean nim.lean: xor_reads_the_same_at_every_sufficient_fuel — ∀ g a b : Nat, (a < g ∨ b < g) → xorN a b = xorF g a b — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18993
|
+
"receipt": "e04a45b5-8834-8bc4-bf6e-bff90869081f"
|
|
18994
|
+
},
|
|
18995
|
+
{
|
|
18996
|
+
"key": "lean_nim_a_number_xored_with_itself_is_zero_at_every_fuel",
|
|
18997
|
+
"name": "lean nim.lean: a_number_xored_with_itself_is_zero_at_every_fuel — ∀ f b : Nat, xorF f b b = 0 — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
18998
|
+
"receipt": "409e78df-b565-83bb-b177-aa46813c1cb7"
|
|
18999
|
+
},
|
|
19000
|
+
{
|
|
19001
|
+
"key": "lean_nim_xor_splits_off_its_lowest_bit",
|
|
19002
|
+
"name": "lean nim.lean: xor_splits_off_its_lowest_bit — ∀ g x c : Nat, 1 ≤ g → xorF (g + 1) x c = (x + c) % 2 + 2 * xorF g (x / 2) (c / 2) — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
19003
|
+
"receipt": "fa8f797f-95fa-80c6-9abc-4bd21309d53a"
|
|
19004
|
+
},
|
|
19005
|
+
{
|
|
19006
|
+
"key": "lean_nim_xor_undoes_itself_when_the_fuel_suffices",
|
|
19007
|
+
"name": "lean nim.lean: xor_undoes_itself_when_the_fuel_suffices — ∀ f a b g : Nat, (a < f ∨ b < f) → b < g → xorF g (xorF f a b) b = a — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
19008
|
+
"receipt": "ba799e13-9cb6-8fc8-ab55-3879eb845e7f"
|
|
19009
|
+
},
|
|
19010
|
+
{
|
|
19011
|
+
"key": "lean_nim_xor_is_commutative_for_every_a_b",
|
|
19012
|
+
"name": "lean nim.lean: xor_is_commutative_for_every_a_b — ∀ a b : Nat, xorN a b = xorN b a — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
19013
|
+
"receipt": "e62bc467-f90b-8bb2-844c-c44676d6fce0"
|
|
19014
|
+
},
|
|
19015
|
+
{
|
|
19016
|
+
"key": "lean_nim_xor_zero_is_identity_for_every_a",
|
|
19017
|
+
"name": "lean nim.lean: xor_zero_is_identity_for_every_a — ∀ a : Nat, xorN a 0 = a — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
19018
|
+
"receipt": "667bd69d-51ea-88da-a48e-ce4a33c4f518"
|
|
19019
|
+
},
|
|
19020
|
+
{
|
|
19021
|
+
"key": "lean_nim_xor_is_its_own_inverse_for_every_a_b",
|
|
19022
|
+
"name": "lean nim.lean: xor_is_its_own_inverse_for_every_a_b — ∀ a b : Nat, xorN (xorN a b) b = a — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
19023
|
+
"receipt": "e2f6d0f1-2fa2-832e-b884-1ac9f13160a0"
|
|
19024
|
+
},
|
|
19025
|
+
{
|
|
19026
|
+
"key": "lean_nim_xor_is_the_sum_of_the_bits_plus_twice_the_xor_of_the_halves",
|
|
19027
|
+
"name": "lean nim.lean: xor_is_the_sum_of_the_bits_plus_twice_the_xor_of_the_halves — ∀ a b : Nat, xorN a b = (a + b) % 2 + 2 * xorN (a / 2) (b / 2) — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
19028
|
+
"receipt": "07c467d9-8226-81d4-93b2-612ebd433b2b"
|
|
19029
|
+
},
|
|
19030
|
+
{
|
|
19031
|
+
"key": "lean_nim_xor_is_associative_below_every_bound",
|
|
19032
|
+
"name": "lean nim.lean: xor_is_associative_below_every_bound — ∀ n a b c : Nat, a + b + c ≤ n → xorN (xorN a b) c = xorN a (xorN b c) — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
19033
|
+
"receipt": "0c3ef805-2811-8035-a30b-cc03489171c1"
|
|
19034
|
+
},
|
|
19035
|
+
{
|
|
19036
|
+
"key": "lean_nim_xor_is_associative_for_every_a_b_c",
|
|
19037
|
+
"name": "lean nim.lean: xor_is_associative_for_every_a_b_c — ∀ a b c : Nat, xorN (xorN a b) c = xorN a (xorN b c) — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
19038
|
+
"receipt": "d2a922d9-f09d-82db-ae54-2f92149512c9"
|
|
19039
|
+
},
|
|
19040
|
+
{
|
|
19041
|
+
"key": "lean_nim_the_nim_sum_is_a_gf2_vector_addition_for_every_a_b_c",
|
|
19042
|
+
"name": "lean nim.lean: the_nim_sum_is_a_gf2_vector_addition_for_every_a_b_c — ∀ a b c : Nat, xorN a b = xorN b a ∧ xorN (xorN a b) c = xorN a (xorN b c) ∧ xorN (xorN a b) b = a ∧ xorN a 0 = a — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
|
|
19043
|
+
"receipt": "caa5c327-62cf-8171-9507-6453cfdaed0c"
|
|
18899
19044
|
}
|
|
18900
19045
|
]
|
|
@@ -423,4 +423,24 @@ theorem eight_times_a_triangular_number_plus_one_is_an_odd_square_for_every_n :
|
|
|
423
423
|
rw [hexp]
|
|
424
424
|
omega
|
|
425
425
|
|
|
426
|
+
|
|
427
|
+
-- ── the capped row above, proved for every value — no bound ──────────────────────────────────────────────────
|
|
428
|
+
-- the_lucas_numbers_are_the_sum_of_the_neighbouring_fibonaccis was checked n ≤ 28; this proves it for every n.
|
|
429
|
+
theorem the_lucas_numbers_are_the_sum_of_the_neighbouring_fibonaccis_for_every_n :
|
|
430
|
+
∀ n : Nat, lucas (n + 1) = fib n + fib (n + 2) := by
|
|
431
|
+
have key : ∀ n : Nat, lucas (n + 1) = fib n + fib (n + 2) ∧ lucas (n + 2) = fib (n + 1) + fib (n + 3) := by
|
|
432
|
+
intro n
|
|
433
|
+
induction n with
|
|
434
|
+
| zero => decide
|
|
435
|
+
| succ n ih =>
|
|
436
|
+
refine ⟨ih.2, ?_⟩
|
|
437
|
+
have l : lucas (n + 3) = lucas (n + 1) + lucas (n + 2) := rfl
|
|
438
|
+
have f4 : fib (n + 4) = fib (n + 2) + fib (n + 3) := rfl
|
|
439
|
+
have f2 : fib (n + 2) = fib n + fib (n + 1) := rfl
|
|
440
|
+
show lucas (n + 3) = fib (n + 2) + fib (n + 4)
|
|
441
|
+
rw [l, ih.1, ih.2, f4]
|
|
442
|
+
omega
|
|
443
|
+
intro n
|
|
444
|
+
exact (key n).1
|
|
445
|
+
|
|
426
446
|
end Elementary
|
package/src/proof/families.lean
CHANGED
|
@@ -479,4 +479,170 @@ theorem the_first_n_odd_numbers_sum_to_n_squared_for_every_n :
|
|
|
479
479
|
rw [square_of_successor]
|
|
480
480
|
omega
|
|
481
481
|
|
|
482
|
+
|
|
483
|
+
-- ── the capped rows above, proved for every value by induction — no bound ──────────────────────────────────
|
|
484
|
+
-- cassinis_identity_holds_across_the_range (n ≤ 30), power_sums_match_their_closed_forms (k = 1..5, n ≤ 40),
|
|
485
|
+
-- the_first_three_power_sums_hold_to_two_hundred (n ≤ 200) and the_sums_of_triangular_numbers_are_the_tetrahedral_
|
|
486
|
+
-- numbers (n ≤ 100) were checked up to a bound; these prove them for every value. Core Lean has no ring tactic, so each
|
|
487
|
+
-- polynomial step is expanded, each monomial sorted, its numeral moved to the front, and omega closes what is left.
|
|
488
|
+
theorem cassinis_identity_for_every_m :
|
|
489
|
+
∀ m : Nat, fib (2 * m + 1) * fib (2 * m + 3) = fib (2 * m + 2) * fib (2 * m + 2) + 1 ∧
|
|
490
|
+
fib (2 * m) * fib (2 * m + 2) + 1 = fib (2 * m + 1) * fib (2 * m + 1) := by
|
|
491
|
+
intro m
|
|
492
|
+
induction m with
|
|
493
|
+
| zero => decide
|
|
494
|
+
| succ m ih =>
|
|
495
|
+
have r3 : fib (2 * m + 3) = fib (2 * m + 1) + fib (2 * m + 2) := rfl
|
|
496
|
+
have r4 : fib (2 * m + 4) = fib (2 * m + 2) + fib (2 * m + 3) := rfl
|
|
497
|
+
have r5 : fib (2 * m + 5) = fib (2 * m + 3) + fib (2 * m + 4) := rfl
|
|
498
|
+
show fib (2 * m + 3) * fib (2 * m + 5) = fib (2 * m + 4) * fib (2 * m + 4) + 1 ∧
|
|
499
|
+
fib (2 * m + 2) * fib (2 * m + 4) + 1 = fib (2 * m + 3) * fib (2 * m + 3)
|
|
500
|
+
have h := ih.1
|
|
501
|
+
rw [r5, r4, r3]
|
|
502
|
+
rw [r3] at h
|
|
503
|
+
generalize fib (2 * m + 1) = a at h ⊢
|
|
504
|
+
generalize fib (2 * m + 2) = b at h ⊢
|
|
505
|
+
constructor
|
|
506
|
+
· try simp only [Nat.mul_add, Nat.add_mul, Nat.pow_succ, Nat.pow_zero, Nat.one_mul, Nat.mul_one, Nat.reduceMul, Nat.reduceAdd] at *
|
|
507
|
+
try simp only [Nat.mul_assoc, Nat.mul_comm, Nat.mul_left_comm, Nat.reduceMul] at *
|
|
508
|
+
try simp only [Nat.mul_comm _ (OfNat.ofNat _), Nat.mul_left_comm _ (OfNat.ofNat _), Nat.reduceMul] at *
|
|
509
|
+
all_goals omega
|
|
510
|
+
· try simp only [Nat.mul_add, Nat.add_mul, Nat.pow_succ, Nat.pow_zero, Nat.one_mul, Nat.mul_one, Nat.reduceMul, Nat.reduceAdd] at *
|
|
511
|
+
try simp only [Nat.mul_assoc, Nat.mul_comm, Nat.mul_left_comm, Nat.reduceMul] at *
|
|
512
|
+
try simp only [Nat.mul_comm _ (OfNat.ofNat _), Nat.mul_left_comm _ (OfNat.ofNat _), Nat.reduceMul] at *
|
|
513
|
+
all_goals omega
|
|
514
|
+
|
|
515
|
+
theorem a_sum_over_one_to_n_plus_one_adds_the_last_term :
|
|
516
|
+
∀ (g : Nat → Nat) (n : Nat),
|
|
517
|
+
((List.range' 1 (n + 1)).map g).foldl (· + ·) 0 = ((List.range' 1 n).map g).foldl (· + ·) 0 + g (n + 1) := by
|
|
518
|
+
intro g n
|
|
519
|
+
rw [List.range'_concat, List.map_append, List.foldl_append]
|
|
520
|
+
simp only [List.map, List.foldl, Nat.one_mul, Nat.add_comm 1 n]
|
|
521
|
+
|
|
522
|
+
theorem the_numbers_sum_to_their_closed_form_for_every_n : ∀ n : Nat, 2 * powSum 1 n = n * (n + 1) := by
|
|
523
|
+
intro n
|
|
524
|
+
induction n with
|
|
525
|
+
| zero => rfl
|
|
526
|
+
| succ n ih =>
|
|
527
|
+
unfold powSum at *
|
|
528
|
+
rw [a_sum_over_one_to_n_plus_one_adds_the_last_term]
|
|
529
|
+
generalize ((List.range' 1 n).map (fun i => i ^ 1)).foldl (· + ·) 0 = s at ih ⊢
|
|
530
|
+
try simp only [Nat.mul_add, Nat.add_mul, Nat.pow_succ, Nat.pow_zero, Nat.one_mul, Nat.mul_one, Nat.reduceMul, Nat.reduceAdd] at *
|
|
531
|
+
try simp only [Nat.mul_assoc, Nat.mul_comm, Nat.mul_left_comm, Nat.reduceMul] at *
|
|
532
|
+
try simp only [Nat.mul_comm _ (OfNat.ofNat _), Nat.mul_left_comm _ (OfNat.ofNat _), Nat.reduceMul] at *
|
|
533
|
+
all_goals omega
|
|
534
|
+
|
|
535
|
+
theorem the_squares_sum_to_their_closed_form_for_every_n : ∀ n : Nat, 6 * powSum 2 n = n * (n + 1) * (2 * n + 1) := by
|
|
536
|
+
intro n
|
|
537
|
+
induction n with
|
|
538
|
+
| zero => rfl
|
|
539
|
+
| succ n ih =>
|
|
540
|
+
unfold powSum at *
|
|
541
|
+
rw [a_sum_over_one_to_n_plus_one_adds_the_last_term]
|
|
542
|
+
generalize ((List.range' 1 n).map (fun i => i ^ 2)).foldl (· + ·) 0 = s at ih ⊢
|
|
543
|
+
try simp only [Nat.mul_add, Nat.add_mul, Nat.pow_succ, Nat.pow_zero, Nat.one_mul, Nat.mul_one, Nat.reduceMul, Nat.reduceAdd] at *
|
|
544
|
+
try simp only [Nat.mul_assoc, Nat.mul_comm, Nat.mul_left_comm, Nat.reduceMul] at *
|
|
545
|
+
try simp only [Nat.mul_comm _ (OfNat.ofNat _), Nat.mul_left_comm _ (OfNat.ofNat _), Nat.reduceMul] at *
|
|
546
|
+
all_goals omega
|
|
547
|
+
|
|
548
|
+
theorem the_cubes_sum_to_their_closed_form_for_every_n : ∀ n : Nat, 4 * powSum 3 n = n * n * (n + 1) * (n + 1) := by
|
|
549
|
+
intro n
|
|
550
|
+
induction n with
|
|
551
|
+
| zero => rfl
|
|
552
|
+
| succ n ih =>
|
|
553
|
+
unfold powSum at *
|
|
554
|
+
rw [a_sum_over_one_to_n_plus_one_adds_the_last_term]
|
|
555
|
+
generalize ((List.range' 1 n).map (fun i => i ^ 3)).foldl (· + ·) 0 = s at ih ⊢
|
|
556
|
+
try simp only [Nat.mul_add, Nat.add_mul, Nat.pow_succ, Nat.pow_zero, Nat.one_mul, Nat.mul_one, Nat.reduceMul, Nat.reduceAdd] at *
|
|
557
|
+
try simp only [Nat.mul_assoc, Nat.mul_comm, Nat.mul_left_comm, Nat.reduceMul] at *
|
|
558
|
+
try simp only [Nat.mul_comm _ (OfNat.ofNat _), Nat.mul_left_comm _ (OfNat.ofNat _), Nat.reduceMul] at *
|
|
559
|
+
all_goals omega
|
|
560
|
+
|
|
561
|
+
set_option maxRecDepth 200000 in
|
|
562
|
+
set_option maxHeartbeats 4000000 in
|
|
563
|
+
theorem the_fourth_powers_sum_to_their_closed_form_for_every_n :
|
|
564
|
+
∀ n : Nat, 30 * powSum 4 n = n * (n + 1) * (2 * n + 1) * (3 * n * n + 3 * n - 1) := by
|
|
565
|
+
intro n
|
|
566
|
+
induction n with
|
|
567
|
+
| zero => rfl
|
|
568
|
+
| succ n ih =>
|
|
569
|
+
unfold powSum at *
|
|
570
|
+
rw [a_sum_over_one_to_n_plus_one_adds_the_last_term]
|
|
571
|
+
generalize ((List.range' 1 n).map (fun i => i ^ 4)).foldl (· + ·) 0 = s at ih ⊢
|
|
572
|
+
have e2 : 3 * (n + 1) * (n + 1) + 3 * (n + 1) - 1 = 3 * n * n + 9 * n + 5 := by
|
|
573
|
+
simp only [Nat.mul_add, Nat.add_mul, Nat.mul_one, Nat.one_mul]; omega
|
|
574
|
+
rw [e2]
|
|
575
|
+
cases n with
|
|
576
|
+
| zero => simp at ih ⊢; omega
|
|
577
|
+
| succ m =>
|
|
578
|
+
have e1 : 3 * (m + 1) * (m + 1) + 3 * (m + 1) - 1 = 3 * m * m + 9 * m + 5 := by
|
|
579
|
+
simp only [Nat.mul_add, Nat.add_mul, Nat.mul_one, Nat.one_mul]; omega
|
|
580
|
+
rw [e1] at ih
|
|
581
|
+
try simp only [Nat.mul_add, Nat.add_mul, Nat.pow_succ, Nat.pow_zero, Nat.one_mul, Nat.mul_one, Nat.reduceMul, Nat.reduceAdd] at *
|
|
582
|
+
try simp only [Nat.mul_assoc, Nat.mul_comm, Nat.mul_left_comm, Nat.reduceMul] at *
|
|
583
|
+
try simp only [Nat.mul_comm _ (OfNat.ofNat _), Nat.mul_left_comm _ (OfNat.ofNat _), Nat.reduceMul] at *
|
|
584
|
+
all_goals omega
|
|
585
|
+
|
|
586
|
+
set_option maxRecDepth 200000 in
|
|
587
|
+
set_option maxHeartbeats 4000000 in
|
|
588
|
+
theorem the_fifth_powers_sum_to_their_closed_form_for_every_n :
|
|
589
|
+
∀ n : Nat, 12 * powSum 5 n = n * n * (n + 1) * (n + 1) * (2 * n * n + 2 * n - 1) := by
|
|
590
|
+
intro n
|
|
591
|
+
induction n with
|
|
592
|
+
| zero => rfl
|
|
593
|
+
| succ n ih =>
|
|
594
|
+
unfold powSum at *
|
|
595
|
+
rw [a_sum_over_one_to_n_plus_one_adds_the_last_term]
|
|
596
|
+
generalize ((List.range' 1 n).map (fun i => i ^ 5)).foldl (· + ·) 0 = s at ih ⊢
|
|
597
|
+
have e2 : 2 * (n + 1) * (n + 1) + 2 * (n + 1) - 1 = 2 * n * n + 6 * n + 3 := by
|
|
598
|
+
simp only [Nat.mul_add, Nat.add_mul, Nat.mul_one, Nat.one_mul]; omega
|
|
599
|
+
rw [e2]
|
|
600
|
+
cases n with
|
|
601
|
+
| zero => simp at ih ⊢; omega
|
|
602
|
+
| succ m =>
|
|
603
|
+
have e1 : 2 * (m + 1) * (m + 1) + 2 * (m + 1) - 1 = 2 * m * m + 6 * m + 3 := by
|
|
604
|
+
simp only [Nat.mul_add, Nat.add_mul, Nat.mul_one, Nat.one_mul]; omega
|
|
605
|
+
rw [e1] at ih
|
|
606
|
+
try simp only [Nat.mul_add, Nat.add_mul, Nat.pow_succ, Nat.pow_zero, Nat.one_mul, Nat.mul_one, Nat.reduceMul, Nat.reduceAdd] at *
|
|
607
|
+
try simp only [Nat.mul_assoc, Nat.mul_comm, Nat.mul_left_comm, Nat.reduceMul] at *
|
|
608
|
+
try simp only [Nat.mul_comm _ (OfNat.ofNat _), Nat.mul_left_comm _ (OfNat.ofNat _), Nat.reduceMul] at *
|
|
609
|
+
all_goals omega
|
|
610
|
+
|
|
611
|
+
theorem power_sums_match_their_closed_forms_for_every_n :
|
|
612
|
+
∀ k n : Nat, 1 ≤ k → k ≤ 5 → powSum k n = faulhaber k n := by
|
|
613
|
+
intro k n h1 h5
|
|
614
|
+
have c : k = 1 ∨ k = 2 ∨ k = 3 ∨ k = 4 ∨ k = 5 := by omega
|
|
615
|
+
rcases c with rfl | rfl | rfl | rfl | rfl
|
|
616
|
+
· show powSum 1 n = n * (n + 1) / 2
|
|
617
|
+
rw [← the_numbers_sum_to_their_closed_form_for_every_n n, Nat.mul_div_cancel_left _ (by decide)]
|
|
618
|
+
· show powSum 2 n = n * (n + 1) * (2 * n + 1) / 6
|
|
619
|
+
rw [← the_squares_sum_to_their_closed_form_for_every_n n, Nat.mul_div_cancel_left _ (by decide)]
|
|
620
|
+
· show powSum 3 n = n * n * (n + 1) * (n + 1) / 4
|
|
621
|
+
rw [← the_cubes_sum_to_their_closed_form_for_every_n n, Nat.mul_div_cancel_left _ (by decide)]
|
|
622
|
+
· show powSum 4 n = n * (n + 1) * (2 * n + 1) * (3 * n * n + 3 * n - 1) / 30
|
|
623
|
+
rw [← the_fourth_powers_sum_to_their_closed_form_for_every_n n, Nat.mul_div_cancel_left _ (by decide)]
|
|
624
|
+
· show powSum 5 n = n * n * (n + 1) * (n + 1) * (2 * n * n + 2 * n - 1) / 12
|
|
625
|
+
rw [← the_fifth_powers_sum_to_their_closed_form_for_every_n n, Nat.mul_div_cancel_left _ (by decide)]
|
|
626
|
+
|
|
627
|
+
theorem the_sums_of_triangular_numbers_are_the_tetrahedral_numbers_for_every_n :
|
|
628
|
+
∀ n : Nat, ((List.range' 1 n).map (fun i => i * (i + 1) / 2)).foldl (· + ·) 0 = n * (n + 1) * (n + 2) / 6 := by
|
|
629
|
+
have six : ∀ n : Nat, 6 * ((List.range' 1 n).map (fun i => i * (i + 1) / 2)).foldl (· + ·) 0 = n * (n + 1) * (n + 2) := by
|
|
630
|
+
intro n
|
|
631
|
+
induction n with
|
|
632
|
+
| zero => rfl
|
|
633
|
+
| succ n ih =>
|
|
634
|
+
rw [a_sum_over_one_to_n_plus_one_adds_the_last_term]
|
|
635
|
+
have ev : (n + 1) * (n + 1 + 1) % 2 = 0 := by
|
|
636
|
+
rcases Nat.mod_two_eq_zero_or_one n with e | e <;> simp [Nat.mul_mod, Nat.add_mod, e]
|
|
637
|
+
have hd : (n + 1) * (n + 1 + 1) / 2 * 2 = (n + 1) * (n + 1 + 1) := Nat.div_mul_cancel (Nat.dvd_of_mod_eq_zero ev)
|
|
638
|
+
generalize ((List.range' 1 n).map (fun i => i * (i + 1) / 2)).foldl (· + ·) 0 = s at ih ⊢
|
|
639
|
+
generalize (n + 1) * (n + 1 + 1) / 2 = t at hd ⊢
|
|
640
|
+
rw [Nat.mul_two] at hd
|
|
641
|
+
try simp only [Nat.mul_add, Nat.add_mul, Nat.pow_succ, Nat.pow_zero, Nat.one_mul, Nat.mul_one, Nat.reduceMul, Nat.reduceAdd] at *
|
|
642
|
+
try simp only [Nat.mul_assoc, Nat.mul_comm, Nat.mul_left_comm, Nat.reduceMul] at *
|
|
643
|
+
try simp only [Nat.mul_comm _ (OfNat.ofNat _), Nat.mul_left_comm _ (OfNat.ofNat _), Nat.reduceMul] at *
|
|
644
|
+
all_goals omega
|
|
645
|
+
intro n
|
|
646
|
+
rw [← six n, Nat.mul_div_cancel_left _ (by decide)]
|
|
647
|
+
|
|
482
648
|
end Families
|
package/src/proof/nim.lean
CHANGED
|
@@ -16,13 +16,16 @@ set_option maxHeartbeats 2000000
|
|
|
16
16
|
-- stated in each name rather than implied.
|
|
17
17
|
--
|
|
18
18
|
-- XOR is imported from Fnv rather than restated: it is the same fuel-bounded structural fold, built because
|
|
19
|
-
-- Nat's bitwise operations are well-founded and would drag `propext` into every theorem here.
|
|
19
|
+
-- Nat's bitwise operations are well-founded and would drag `propext` into every theorem here. Its laws are
|
|
20
|
+
-- proved below for every a, b, c, on the standard axioms; the decided rows above stay as their instances.
|
|
20
21
|
|
|
21
22
|
namespace Nim
|
|
22
23
|
|
|
23
24
|
open Fnv (xorF)
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
-- the fuel is a + b + 1, which always exceeds what the fold needs (each step halves both arguments and the fold
|
|
27
|
+
-- stops at the first zero); the earlier fuel of 33 read XOR correctly only below 2³³ — a cap, now gone
|
|
28
|
+
def xorN (a b : Nat) : Nat := xorF (a + b + 1) a b
|
|
26
29
|
-- The board is SMALL and stated, because the game tree is exponential: deciding `lost` explores every play
|
|
27
30
|
-- from every position, and at 8x8 the kernel exceeds its heartbeat budget. Six is what `decide` settles here
|
|
28
31
|
-- in reasonable time. A larger board is not a harder theorem, it is a longer computation — and claiming the
|
|
@@ -42,7 +45,7 @@ def lost : Nat → Nat → Nat → Bool
|
|
|
42
45
|
def isLost (a b : Nat) : Bool := lost (a + b + 1) a b
|
|
43
46
|
|
|
44
47
|
-- ── BOUTON: a two-heap position is lost for the mover exactly when the heaps are equal — which is exactly
|
|
45
|
-
-- when their XOR is zero. Decided over every position on the
|
|
48
|
+
-- when their XOR is zero. Decided over every position on the N×N board, N = 6. ──
|
|
46
49
|
theorem bouton_two_heaps_lost_iff_xor_zero :
|
|
47
50
|
(List.range N).all (fun a => (List.range N).all (fun b =>
|
|
48
51
|
isLost a b == (xorN a b == 0))) := by decide
|
|
@@ -102,4 +105,207 @@ set_option maxRecDepth 4000000 in
|
|
|
102
105
|
theorem bouton_holds_at_every_heap_size_to_six :
|
|
103
106
|
(List.range 7).all (fun a => (List.range 7).all (fun b => isLost a b == (xorN a b == 0))) := by decide
|
|
104
107
|
|
|
108
|
+
|
|
109
|
+
-- ── XOR's algebra for every a, b, c — no bound ───────────────────────────────────────────────────────────────
|
|
110
|
+
-- xor_is_its_own_inverse and xor_is_commutative (a, b < 16), xor_zero_is_identity (a < 32) and
|
|
111
|
+
-- the_nim_sum_is_a_gf2_vector_addition (a, b, c < 16) were decided over a range; these prove them for every value.
|
|
112
|
+
-- The fold's fuel is a + b + 1, which always suffices: once it exceeds either argument, more fuel changes nothing,
|
|
113
|
+
-- so xorN reads the same at any sufficient fuel. Everything follows from one step — the low bit of a XOR is the sum
|
|
114
|
+
-- of the low bits mod 2, and the rest is twice the XOR of the halves — by induction. Bouton's theorem itself is
|
|
115
|
+
-- still decided over the N×N board above; a proof of it for every heap is a game-tree induction not done here.
|
|
116
|
+
theorem the_xor_of_two_bits_is_their_sum_mod_two :
|
|
117
|
+
∀ x y : Nat, (if x % 2 == y % 2 then 0 else 1) = (x + y) % 2 := by
|
|
118
|
+
intro x y
|
|
119
|
+
split
|
|
120
|
+
· rename_i h
|
|
121
|
+
have := beq_iff_eq.mp h
|
|
122
|
+
omega
|
|
123
|
+
· rename_i h
|
|
124
|
+
have : x % 2 ≠ y % 2 := fun e => h (beq_iff_eq.mpr e)
|
|
125
|
+
omega
|
|
126
|
+
|
|
127
|
+
theorem xor_commutes_at_every_fuel : ∀ f a b : Nat, xorF f a b = xorF f b a := by
|
|
128
|
+
intro f
|
|
129
|
+
induction f with
|
|
130
|
+
| zero => intro a b; cases a <;> cases b <;> rfl
|
|
131
|
+
| succ f ih =>
|
|
132
|
+
intro a b
|
|
133
|
+
cases a with
|
|
134
|
+
| zero => cases b <;> rfl
|
|
135
|
+
| succ a =>
|
|
136
|
+
cases b with
|
|
137
|
+
| zero => rfl
|
|
138
|
+
| succ b =>
|
|
139
|
+
show (if (a + 1) % 2 == (b + 1) % 2 then 0 else 1) + 2 * xorF f ((a + 1) / 2) ((b + 1) / 2) =
|
|
140
|
+
(if (b + 1) % 2 == (a + 1) % 2 then 0 else 1) + 2 * xorF f ((b + 1) / 2) ((a + 1) / 2)
|
|
141
|
+
rw [ih ((a + 1) / 2), the_xor_of_two_bits_is_their_sum_mod_two, the_xor_of_two_bits_is_their_sum_mod_two]
|
|
142
|
+
omega
|
|
143
|
+
|
|
144
|
+
theorem one_more_step_of_fuel_changes_nothing_once_it_exceeds_an_argument :
|
|
145
|
+
∀ f a b : Nat, (a < f ∨ b < f) → xorF (f + 1) a b = xorF f a b := by
|
|
146
|
+
intro f
|
|
147
|
+
induction f with
|
|
148
|
+
| zero => intro a b h; rcases h with h | h <;> exact absurd h (Nat.not_lt_zero _)
|
|
149
|
+
| succ f ih =>
|
|
150
|
+
intro a b h
|
|
151
|
+
cases a with
|
|
152
|
+
| zero => cases b <;> rfl
|
|
153
|
+
| succ a =>
|
|
154
|
+
cases b with
|
|
155
|
+
| zero => rfl
|
|
156
|
+
| succ b =>
|
|
157
|
+
show (if (a + 1) % 2 == (b + 1) % 2 then 0 else 1) + 2 * xorF (f + 1) ((a + 1) / 2) ((b + 1) / 2) =
|
|
158
|
+
(if (a + 1) % 2 == (b + 1) % 2 then 0 else 1) + 2 * xorF f ((a + 1) / 2) ((b + 1) / 2)
|
|
159
|
+
have h' : (a + 1) / 2 < f ∨ (b + 1) / 2 < f := by
|
|
160
|
+
rcases h with h | h
|
|
161
|
+
· exact Or.inl (by omega)
|
|
162
|
+
· exact Or.inr (by omega)
|
|
163
|
+
rw [ih _ _ h']
|
|
164
|
+
|
|
165
|
+
theorem more_fuel_changes_nothing_once_it_exceeds_an_argument :
|
|
166
|
+
∀ k f a b : Nat, (a < f ∨ b < f) → xorF (f + k) a b = xorF f a b := by
|
|
167
|
+
intro k
|
|
168
|
+
induction k with
|
|
169
|
+
| zero => intro f a b _; rfl
|
|
170
|
+
| succ k ih =>
|
|
171
|
+
intro f a b h
|
|
172
|
+
have h' : a < f + k ∨ b < f + k := by
|
|
173
|
+
rcases h with h | h
|
|
174
|
+
· exact Or.inl (by omega)
|
|
175
|
+
· exact Or.inr (by omega)
|
|
176
|
+
rw [← Nat.add_assoc, one_more_step_of_fuel_changes_nothing_once_it_exceeds_an_argument _ _ _ h', ih f a b h]
|
|
177
|
+
|
|
178
|
+
theorem xor_reads_the_same_at_every_sufficient_fuel :
|
|
179
|
+
∀ g a b : Nat, (a < g ∨ b < g) → xorN a b = xorF g a b := by
|
|
180
|
+
intro g a b h
|
|
181
|
+
unfold xorN
|
|
182
|
+
have h1 : a < a + b + 1 ∨ b < a + b + 1 := Or.inl (by omega)
|
|
183
|
+
rw [← more_fuel_changes_nothing_once_it_exceeds_an_argument g (a + b + 1) a b h1,
|
|
184
|
+
← more_fuel_changes_nothing_once_it_exceeds_an_argument (a + b + 1) g a b h, Nat.add_comm g]
|
|
185
|
+
|
|
186
|
+
theorem a_number_xored_with_itself_is_zero_at_every_fuel : ∀ f b : Nat, xorF f b b = 0 := by
|
|
187
|
+
intro f
|
|
188
|
+
induction f with
|
|
189
|
+
| zero => intro b; cases b <;> rfl
|
|
190
|
+
| succ f ih =>
|
|
191
|
+
intro b
|
|
192
|
+
cases b with
|
|
193
|
+
| zero => rfl
|
|
194
|
+
| succ b =>
|
|
195
|
+
show (if (b + 1) % 2 == (b + 1) % 2 then 0 else 1) + 2 * xorF f ((b + 1) / 2) ((b + 1) / 2) = 0
|
|
196
|
+
rw [ih, the_xor_of_two_bits_is_their_sum_mod_two]
|
|
197
|
+
omega
|
|
198
|
+
|
|
199
|
+
theorem xor_splits_off_its_lowest_bit :
|
|
200
|
+
∀ g x c : Nat, 1 ≤ g → xorF (g + 1) x c = (x + c) % 2 + 2 * xorF g (x / 2) (c / 2) := by
|
|
201
|
+
intro g x c hg
|
|
202
|
+
obtain ⟨g', rfl⟩ : ∃ g', g = g' + 1 := ⟨g - 1, by omega⟩
|
|
203
|
+
cases x with
|
|
204
|
+
| zero =>
|
|
205
|
+
rw [show xorF (g' + 1 + 1) 0 c = c by cases c <;> rfl, Nat.zero_div,
|
|
206
|
+
show xorF (g' + 1) 0 (c / 2) = c / 2 by cases (c / 2) <;> rfl]
|
|
207
|
+
omega
|
|
208
|
+
| succ x =>
|
|
209
|
+
cases c with
|
|
210
|
+
| zero =>
|
|
211
|
+
rw [show xorF (g' + 1 + 1) (x + 1) 0 = x + 1 from rfl, Nat.zero_div,
|
|
212
|
+
show xorF (g' + 1) ((x + 1) / 2) 0 = (x + 1) / 2 by cases ((x + 1) / 2) <;> rfl]
|
|
213
|
+
omega
|
|
214
|
+
| succ c =>
|
|
215
|
+
show (if (x + 1) % 2 == (c + 1) % 2 then 0 else 1) + 2 * xorF (g' + 1) ((x + 1) / 2) ((c + 1) / 2) = _
|
|
216
|
+
rw [the_xor_of_two_bits_is_their_sum_mod_two]
|
|
217
|
+
|
|
218
|
+
theorem xor_undoes_itself_when_the_fuel_suffices :
|
|
219
|
+
∀ f a b g : Nat, (a < f ∨ b < f) → b < g → xorF g (xorF f a b) b = a := by
|
|
220
|
+
intro f
|
|
221
|
+
induction f with
|
|
222
|
+
| zero => intro a b g h; rcases h with h | h <;> exact absurd h (Nat.not_lt_zero _)
|
|
223
|
+
| succ f ih =>
|
|
224
|
+
intro a b g h hg
|
|
225
|
+
cases a with
|
|
226
|
+
| zero =>
|
|
227
|
+
rw [show xorF (f + 1) 0 b = b by cases b <;> rfl]
|
|
228
|
+
exact a_number_xored_with_itself_is_zero_at_every_fuel g b
|
|
229
|
+
| succ a =>
|
|
230
|
+
cases b with
|
|
231
|
+
| zero =>
|
|
232
|
+
obtain ⟨g', rfl⟩ : ∃ g', g = g' + 1 := ⟨g - 1, by omega⟩
|
|
233
|
+
rfl
|
|
234
|
+
| succ b =>
|
|
235
|
+
obtain ⟨g', rfl⟩ : ∃ g', g = g' + 1 := ⟨g - 1, by omega⟩
|
|
236
|
+
have hf : (a + 1) / 2 < f ∨ (b + 1) / 2 < f := by
|
|
237
|
+
rcases h with h | h
|
|
238
|
+
· exact Or.inl (by omega)
|
|
239
|
+
· exact Or.inr (by omega)
|
|
240
|
+
have ih' := ih ((a + 1) / 2) ((b + 1) / 2) g' hf (by omega)
|
|
241
|
+
rw [xor_splits_off_its_lowest_bit g' _ _ (by omega)]
|
|
242
|
+
rw [show xorF (f + 1) (a + 1) (b + 1) = (if (a + 1) % 2 == (b + 1) % 2 then 0 else 1) +
|
|
243
|
+
2 * xorF f ((a + 1) / 2) ((b + 1) / 2) from rfl, the_xor_of_two_bits_is_their_sum_mod_two]
|
|
244
|
+
generalize xorF f ((a + 1) / 2) ((b + 1) / 2) = y at ih' ⊢
|
|
245
|
+
have e : ((a + 1 + (b + 1)) % 2 + 2 * y) / 2 = y := by omega
|
|
246
|
+
rw [e, ih']
|
|
247
|
+
omega
|
|
248
|
+
|
|
249
|
+
theorem xor_is_commutative_for_every_a_b : ∀ a b : Nat, xorN a b = xorN b a := by
|
|
250
|
+
intro a b
|
|
251
|
+
unfold xorN
|
|
252
|
+
rw [Nat.add_comm a b, xor_commutes_at_every_fuel]
|
|
253
|
+
|
|
254
|
+
theorem xor_zero_is_identity_for_every_a : ∀ a : Nat, xorN a 0 = a := by
|
|
255
|
+
intro a
|
|
256
|
+
unfold xorN
|
|
257
|
+
cases a <;> rfl
|
|
258
|
+
|
|
259
|
+
theorem xor_is_its_own_inverse_for_every_a_b : ∀ a b : Nat, xorN (xorN a b) b = a := by
|
|
260
|
+
intro a b
|
|
261
|
+
rw [xor_reads_the_same_at_every_sufficient_fuel (b + 1) (xorN a b) b (Or.inr (by omega))]
|
|
262
|
+
unfold xorN
|
|
263
|
+
exact xor_undoes_itself_when_the_fuel_suffices (a + b + 1) a b (b + 1) (Or.inl (by omega)) (by omega)
|
|
264
|
+
theorem xor_is_the_sum_of_the_bits_plus_twice_the_xor_of_the_halves :
|
|
265
|
+
∀ a b : Nat, xorN a b = (a + b) % 2 + 2 * xorN (a / 2) (b / 2) := by
|
|
266
|
+
intro a b
|
|
267
|
+
rw [xor_reads_the_same_at_every_sufficient_fuel (a + b + 1 + 1) a b (Or.inl (by omega)),
|
|
268
|
+
xor_splits_off_its_lowest_bit (a + b + 1) a b (by omega),
|
|
269
|
+
← xor_reads_the_same_at_every_sufficient_fuel (a + b + 1) (a / 2) (b / 2) (Or.inl (by omega))]
|
|
270
|
+
|
|
271
|
+
theorem xor_is_associative_below_every_bound :
|
|
272
|
+
∀ n a b c : Nat, a + b + c ≤ n → xorN (xorN a b) c = xorN a (xorN b c) := by
|
|
273
|
+
intro n
|
|
274
|
+
induction n with
|
|
275
|
+
| zero =>
|
|
276
|
+
intro a b c h
|
|
277
|
+
have ha : a = 0 := by omega
|
|
278
|
+
have hb : b = 0 := by omega
|
|
279
|
+
have hc : c = 0 := by omega
|
|
280
|
+
subst ha hb hc
|
|
281
|
+
rfl
|
|
282
|
+
| succ n ih =>
|
|
283
|
+
intro a b c h
|
|
284
|
+
if hz : a + b + c = 0 then
|
|
285
|
+
have ha : a = 0 := by omega
|
|
286
|
+
have hb : b = 0 := by omega
|
|
287
|
+
have hc : c = 0 := by omega
|
|
288
|
+
subst ha hb hc
|
|
289
|
+
rfl
|
|
290
|
+
else
|
|
291
|
+
have ihh := ih (a / 2) (b / 2) (c / 2) (by omega)
|
|
292
|
+
have hab := xor_is_the_sum_of_the_bits_plus_twice_the_xor_of_the_halves a b
|
|
293
|
+
have hbc := xor_is_the_sum_of_the_bits_plus_twice_the_xor_of_the_halves b c
|
|
294
|
+
have hx2 : xorN a b / 2 = xorN (a / 2) (b / 2) := by omega
|
|
295
|
+
have hy2 : xorN b c / 2 = xorN (b / 2) (c / 2) := by omega
|
|
296
|
+
rw [xor_is_the_sum_of_the_bits_plus_twice_the_xor_of_the_halves (xorN a b) c,
|
|
297
|
+
xor_is_the_sum_of_the_bits_plus_twice_the_xor_of_the_halves a (xorN b c), hx2, hy2, ihh]
|
|
298
|
+
omega
|
|
299
|
+
|
|
300
|
+
theorem xor_is_associative_for_every_a_b_c : ∀ a b c : Nat, xorN (xorN a b) c = xorN a (xorN b c) := by
|
|
301
|
+
intro a b c
|
|
302
|
+
exact xor_is_associative_below_every_bound (a + b + c) a b c (Nat.le_refl _)
|
|
303
|
+
|
|
304
|
+
theorem the_nim_sum_is_a_gf2_vector_addition_for_every_a_b_c :
|
|
305
|
+
∀ a b c : Nat, xorN a b = xorN b a ∧ xorN (xorN a b) c = xorN a (xorN b c) ∧
|
|
306
|
+
xorN (xorN a b) b = a ∧ xorN a 0 = a := by
|
|
307
|
+
intro a b c
|
|
308
|
+
exact ⟨xor_is_commutative_for_every_a_b a b, xor_is_associative_for_every_a_b_c a b c,
|
|
309
|
+
xor_is_its_own_inverse_for_every_a_b a b, xor_zero_is_identity_for_every_a a⟩
|
|
310
|
+
|
|
105
311
|
end Nim
|