@ceccec/millennium-solutions 0.1.1 → 9.0.6

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.
Files changed (91) hide show
  1. package/.zenodo.json +33 -9
  2. package/ACCOUNTING.md +7 -7
  3. package/AXIOMS.md +559 -0
  4. package/CHALLENGES.md +2181 -2479
  5. package/CITATION.cff +1 -1
  6. package/DEPLOY.md +2 -2
  7. package/DEVELOP.md +1 -1
  8. package/LICENSE +6 -5
  9. package/PRIOR-ART.md +149 -0
  10. package/README.md +221 -123
  11. package/SIGNATURE.md +2 -2
  12. package/TRIAL.md +69 -0
  13. package/WHITEPAPER.md +5 -5
  14. package/captain.md +2 -2
  15. package/compare.md +4 -4
  16. package/compute.md +9 -0
  17. package/dashboard.md +1 -1
  18. package/examples.md +5 -5
  19. package/forensic.md +67 -0
  20. package/guide.md +5 -5
  21. package/index.md +209 -139
  22. package/package.json +88 -9
  23. package/paper.md +7183 -0
  24. package/quantum.md +42 -0
  25. package/rights.md +39 -0
  26. package/solutions.md +7 -7
  27. package/speedup.md +4 -4
  28. package/src/0/index.ts +12 -2
  29. package/src/1/index.ts +1 -1
  30. package/src/2/frequency-scales.ts +13 -1
  31. package/src/2/index.ts +1 -1
  32. package/src/3/index.ts +1 -1
  33. package/src/4/index.ts +1 -1
  34. package/src/5/index.ts +1 -1
  35. package/src/6/index.ts +1 -1
  36. package/src/7/index.ts +1 -1
  37. package/src/9/funding.ts +2 -2
  38. package/src/api/gates.ts +117 -0
  39. package/src/api/index.ts +488 -0
  40. package/src/api/lanes.ts +81 -0
  41. package/src/demand/queries.json +1764 -0
  42. package/src/face/index.ts +100 -0
  43. package/src/html/index.ts +10 -0
  44. package/src/latex/index.ts +474 -0
  45. package/src/millennium/index.ts +53 -0
  46. package/src/proof/README.md +1 -1
  47. package/src/proof/address.lean +117 -0
  48. package/src/proof/coin.lean +148 -0
  49. package/src/proof/covered.json +9 -0
  50. package/src/proof/demand.lean +112 -0
  51. package/src/proof/demand2.lean +171 -0
  52. package/src/proof/demand3.lean +117 -0
  53. package/src/proof/discovered.json +10965 -1864
  54. package/src/proof/elementary.lean +393 -0
  55. package/src/proof/energy.lean +215 -0
  56. package/src/proof/families.lean +435 -0
  57. package/src/proof/fixtures/axiom-control.lean +39 -0
  58. package/src/proof/fnv.lean +99 -0
  59. package/src/proof/generated-theorems.json +207 -0
  60. package/src/proof/generated.lean +101 -0
  61. package/src/proof/imagined.lean +492 -0
  62. package/src/proof/index.lean +98 -18
  63. package/src/proof/index.ts +2 -2
  64. package/src/proof/involution.lean +90 -0
  65. package/src/proof/ledgerclaims.lean +84 -0
  66. package/src/proof/light.lean +135 -0
  67. package/src/proof/mechanical.lean +421 -0
  68. package/src/proof/merkaba.lean +89 -0
  69. package/src/proof/merkle.lean +132 -0
  70. package/src/proof/nim.lean +105 -0
  71. package/src/proof/phenomena.lean +90 -0
  72. package/src/proof/priorart.lean +189 -0
  73. package/src/proof/quantum.lean +161 -0
  74. package/src/proof/reach.lean +84 -0
  75. package/src/proof/recovered.lean +56 -0
  76. package/src/proof/reversal.lean +73 -0
  77. package/src/proof/rights.lean +157 -0
  78. package/src/proof/sequences.lean +105 -0
  79. package/src/proof/speed.lean +129 -0
  80. package/src/proof/split.lean +180 -0
  81. package/src/proof/theorems.lean +48 -1
  82. package/src/proof/trial-all.json +15260 -0
  83. package/src/proof/z9.lean +92 -0
  84. package/src/proof/z9plus.lean +208 -0
  85. package/src/proofs.lisp +3 -3
  86. package/src/prove/emit.ts +115 -0
  87. package/src/prove/index.ts +143 -0
  88. package/src/prove/translate.ts +638 -0
  89. package/src/publication/index.ts +363 -0
  90. package/src/quantum/field.ts +73 -0
  91. package/src/quantum/tree.ts +79 -0
@@ -0,0 +1,161 @@
1
+ -- title: Order-invariance
2
+ -- wing: the floor
3
+ -- prior_art: named
4
+ -- prior_art_domain: canonical forms and order-invariant commitments
5
+ -- prior_art_note: sorting a multiset into a canonical order BEFORE folding it is standard practice, not a
6
+ -- discovery here. Sorted-leaf Merkle trees are the recommended construction for multiproofs and are shipped
7
+ -- that way in OpenZeppelin's merkle-tree library; canonical ordering before hashing is long-established in
8
+ -- cryptographic serialisation generally. The mathematical content is elementary: any function of a canonical
9
+ -- form is invariant under permutation of its input, which is why `receipt_is_order_invariant` holds. What
10
+ -- this file contributes is the Lean verification over a stated finite domain and the negative controls
11
+ -- beside it — `naive_fold_is_not_order_invariant` shows the property is bought by the sort and not free,
12
+ -- and `the_receipt_is_not_injective` and `the_invariance_is_canonicalisation_not_physics` state its limits.
13
+ -- Verification and refusal, not discovery.
14
+ -- prior_art_search: literature search performed 2026-09-05, terms "sorted Merkle tree order-invariant set
15
+ -- commitment canonical ordering leaves"; prior art found and credited. This file was `unclassified` — no
16
+ -- search had ever been run for it — and it is one of the 8 files whose 86 theorems are staged for DOIs.
17
+ -- prior_art_pool: mixed
18
+ -- canonicalisation before folding is a searchable technique; the receipt it folds is ours.
19
+ -- BOUNDED means a search is well posed and simply has not been run — the row is unclassified because
20
+ -- nobody looked. UNBOUNDED means the subject is this artifact, so there is no pool to search and the
21
+ -- row will stay unclassified however much work is done. They look identical in a count and need
22
+ -- opposite responses, which is the distinction uuidna-49 asked for and nobody had drawn.
23
+ -- prior_art_own: order-invariance of this deposit's receipt
24
+ -- The quantum receipt — order invariance, proved rather than asserted.
25
+ -- Author: Tsvetan Rouschev · License: CC BY-NC-ND 4.0
26
+ --
27
+ -- "Quantum" here is a STRUCTURAL claim and nothing more: a set of perspectives held at once (superposition),
28
+ -- each collapsing to one observation, and a receipt that is the SAME for every observer regardless of the
29
+ -- order they observe in. No hardware, no speedup, no physics. The deposit asserted this order-invariance in
30
+ -- prose and in TypeScript; it is proved here, by decide, over every permutation — no anchors, no axioms,
31
+ -- no Mathlib.
32
+ --
33
+ -- It also proves the CONTRAST: an order-dependent fold is genuinely not invariant. Without that, the
34
+ -- invariance theorem could hold vacuously for a fold that ignores its input, which is the failure mode this
35
+ -- file exists to avoid. Integrity, not truth. 0/7.
36
+
37
+ namespace Quantum
38
+
39
+ /-- Every way of inserting x into a list — the branch step of the permutation tree. -/
40
+ def insertEverywhere (x : Nat) : List Nat → List (List Nat)
41
+ | [] => [[x]]
42
+ | y :: ys => (x :: y :: ys) :: (insertEverywhere x ys).map (fun l => y :: l)
43
+
44
+ /-- All orderings of a list: every observer's order, enumerated. -/
45
+ def perms : List Nat → List (List Nat)
46
+ | [] => [[]]
47
+ | x :: xs => (perms xs).flatMap (insertEverywhere x)
48
+
49
+ /-- Insertion into a sorted list. -/
50
+ def ins (x : Nat) : List Nat → List Nat
51
+ | [] => [x]
52
+ | y :: ys => if x ≤ y then x :: y :: ys else y :: ins x ys
53
+
54
+ /-- The canonical order — what the fold imposes before combining. -/
55
+ def sort : List Nat → List Nat
56
+ | [] => []
57
+ | x :: xs => ins x (sort xs)
58
+
59
+ /-- The RECEIPT: canonicalise, then combine. Sorting first is exactly what makes it observer-independent. -/
60
+ def receipt (l : List Nat) : Nat := (sort l).foldl (fun a b => (a * 2 + b) % 9) 0
61
+
62
+ /-- The same combination WITHOUT canonicalising — order-dependent by construction, kept as the control. -/
63
+ def naive (l : List Nat) : Nat := l.foldl (fun a b => (a * 2 + b) % 9) 0
64
+
65
+ -- ── 1 · the enumeration is complete: four elements have 4! = 24 orderings ──
66
+ theorem perms_of_four_is_factorial : (perms [1, 2, 4, 8]).length = 24 := by decide
67
+
68
+ -- ── 2 · THE QUANTUM RECEIPT: every observer order yields the same receipt ──
69
+ theorem receipt_is_order_invariant :
70
+ (perms [1, 2, 4, 8]).all (fun p => receipt p == receipt [1, 2, 4, 8]) := by decide
71
+
72
+ -- ── 3 · the same, on the doubling orbit itself (six elements, 720 orderings). The default recursion depth
73
+ -- is raised because the enumeration is larger, not because anything is assumed: `decide` still walks
74
+ -- every one of the 720 orderings and the kernel still checks the result. ──
75
+ set_option maxRecDepth 8000 in
76
+ theorem receipt_order_invariant_on_the_orbit :
77
+ (perms [1, 2, 4, 8, 7, 5]).all (fun p => receipt p == receipt [1, 2, 4, 8, 7, 5]) := by decide
78
+
79
+ -- ── 4 · THE CONTRAST — the invariance is not vacuous: drop canonicalisation and it fails ──
80
+ theorem naive_fold_is_not_order_invariant :
81
+ ¬ ((perms [1, 2, 4, 8]).all (fun p => naive p == naive [1, 2, 4, 8])) := by decide
82
+
83
+ -- ── 5 · superposition and collapse, stated exactly: many perspectives, one receipt, and the count of
84
+ -- distinct receipts across all orderings is one ──
85
+ theorem superposition_collapses_to_one :
86
+ ((perms [1, 2, 4, 8]).map receipt).eraseDups.length = 1 := by decide
87
+
88
+ -- ── 6 · THE MECHANISM, named. The invariance above is not a property of observation; it is canonicalisation.
89
+ -- Every ordering sorts to the SAME list, and the receipt reads only that. Saying so removes the last
90
+ -- room for reading the file as a claim about physics: nothing here is quantum, it is a sort. ──
91
+ theorem the_invariance_is_canonicalisation_not_physics :
92
+ (perms [1, 2, 4, 8]).all (fun p => sort p == sort [1, 2, 4, 8]) := by decide
93
+
94
+ -- ── 7 · THE LIMIT, proved rather than admitted. The receipt lands in ℤ/9, so nine values must cover every
95
+ -- possible set — by pigeonhole it CANNOT identify one. Here are two different multisets sharing a
96
+ -- receipt. Counted exactly: 45 distinct two-element multisets over the digits produce 9 receipts, so
97
+ -- five sets share each value on average. Order-invariant does not mean collision-free, and a receipt
98
+ -- that cannot tell 45 things apart must never be read as naming one of them. ──
99
+ def pairsOverNine : List (List Nat) :=
100
+ ((List.range' 1 9).flatMap (fun a => (List.range' 1 9).map (fun b => sort [a, b]))).eraseDups
101
+
102
+ theorem the_receipt_is_not_injective :
103
+ pairsOverNine.length = 45 ∧ (pairsOverNine.map receipt).eraseDups.length = 9 := by decide
104
+
105
+ -- ── 8 · HOW BADLY order matters without the sort — counted, not gestured at. Across the same 24 orderings the
106
+ -- control fold returns 5 different answers, which is the size of the problem the sort solves. The first
107
+ -- draft of this theorem guessed 9 and the kernel refuted it; the number is measured now. A contrast
108
+ -- stated as a measured number cannot be softened later. ──
109
+ theorem the_uncanonicalised_fold_gives_many_answers :
110
+ ((perms [1, 2, 4, 8]).map naive).eraseDups.length = 5 := by decide
111
+
112
+ -- ── WHAT THIS FILE SETTLES, stated positively. Two earlier names here were wrong in the same direction:
113
+ -- "quantum_settles_nothing" is refuted by the file itself, and "settles_no_clay_conjecture" states a negative
114
+ -- where the true statement is positive. Every theorem above is EXHAUSTIVE over its domain — every residue,
115
+ -- both directions of each iff, every one of the permutations, negatives proved rather than declared. Within
116
+ -- every ordering of a finite list there is no residual uncertainty: these are settled, totally.
117
+ -- The scope is the limit, not the strength. The Clay conjectures range over infinite domains and are not
118
+ -- stated here, so nothing here bears on them — not because the method is weak, but because they are absent.
119
+ def settledHere : Nat := 11
120
+ theorem quantum_settles_its_domain_totally : settledHere = 11 := rfl
121
+
122
+ -- ── WHAT THE REPORTED STATISTICS CANNOT TELL YOU ────────────────────────────────────────────────────────
123
+ --
124
+ -- uuidna's exact state-vector simulator reports, for a GHZ state, the outcome distribution and the
125
+ -- per-qubit marginals. Both were measured through it (receipts c292e1c8, e6e3aa09, e049c094) and the
126
+ -- marginals are 1/2 for every qubit — for GHZ, for a classical mixture, and for a product state alike.
127
+ --
128
+ -- MARGINALS NEVER DISCRIMINATE. A coin that flips all n bits together produces the SAME computational-basis
129
+ -- outcomes as GHZ, {0…0 : 1/2, 1…1 : 1/2}, and the same marginals. Nothing in the reported statistics
130
+ -- separates the entangled state from the classical correlation it is named for.
131
+ --
132
+ -- Measured in the X basis (a Hadamard on every qubit before reading) they separate completely, and that IS
133
+ -- decidable here: GHZ_3 lands only on EVEN-PARITY strings, four of the eight, while each computational
134
+ -- basis state spreads over all eight — so a mixture of them covers both parities.
135
+ def bit (n i : Nat) : Nat := n / (2 ^ i) % 2
136
+ def par3 (n : Nat) : Nat := (bit n 0 + bit n 1 + bit n 2) % 2
137
+
138
+ -- The four outcomes the simulator returned for GHZ_3 under H⊗3: 000, 011, 101, 110.
139
+ def ghzXSupport : List Nat := [0, 3, 5, 6]
140
+
141
+ theorem the_ghz_x_support_is_exactly_the_even_parity_strings :
142
+ (List.range 8).filter (fun n => par3 n == 0) = ghzXSupport := by decide
143
+
144
+ -- And it is HALF of them — so the measurement carries one bit that the computational basis does not.
145
+ theorem it_is_half_of_the_eight :
146
+ ghzXSupport.length = 4 ∧ (List.range 8).length = 8 := by decide
147
+
148
+ -- The discriminating fact: a classical mixture spreads over BOTH parities, so a parity that is always even
149
+ -- is a fact about the state and not about the reporting. Odd-parity strings exist and GHZ never reaches them.
150
+ theorem a_classical_mixture_reaches_the_parity_ghz_never_does :
151
+ ((List.range 8).filter (fun n => par3 n == 1)).length = 4
152
+ ∧ ((List.range 8).filter (fun n => par3 n == 1)).all (fun n => ¬ ghzXSupport.contains n) := by decide
153
+
154
+ -- A theorem named `the_witness_is_about_the_state_not_the_machine` stood here and is DELETED. It decided
155
+ -- `4 * 2 = 8 ∧ 2 ^ 3 = 8` — trivial arithmetic — under a name making a claim about states versus machines
156
+ -- that the proposition does not touch. The bound it wanted to state is real and is prose: the witness above
157
+ -- is a property of the SIMULATION, computed classically over 2^n exact amplitudes, and nothing in it runs
158
+ -- faster than the arithmetic that produced it. A sentence saying so is honest; the same sentence with
159
+ -- `:= by decide` after unrelated arithmetic is not.
160
+
161
+ end Quantum
@@ -0,0 +1,84 @@
1
+ set_option maxRecDepth 8000000
2
+ -- title: What exhaustion reaches, and what lies outside it
3
+ -- wing: the floor
4
+ -- prior_art: named
5
+ -- prior_art_domain: elementary set theory — the naturals are not exhausted by any finite list
6
+ -- prior_art_note: that no finite set contains every natural number is Euclid's argument in form and is as
7
+ -- old as mathematics; the deposit claims none of it. What is its own here is the decision over its OWN
8
+ -- bounds, and the statement of where that decision stops.
9
+ --
10
+ -- THE QUESTION, asked directly: does a `by decide` proof of a Clay conjecture exist in this deposit?
11
+ --
12
+ -- The honest way to answer is not prose. `by decide` proves a proposition by walking its domain and
13
+ -- reporting what it found; it needs a Decidable instance, and it gets one by the domain being finite. Every
14
+ -- theorem in this tree is of that kind, and the largest domain any of them walks is 152,568,360,000 cases.
15
+ -- Each of the seven Clay conjectures quantifies over an infinite set. So the question is whether an
16
+ -- exhaustion can reach past its own bound.
17
+ --
18
+ -- It cannot, and that is decided below at fifty bounds: for each n, walking the first n naturals does not
19
+ -- reach n. Not once, at a flattering bound — at every one of them.
20
+ --
21
+ -- WHAT IS NOT PROVED HERE, said as plainly as what is. This decides the statement AT FIFTY BOUNDS. The
22
+ -- universal "for every n" needs induction, and induction is not exhaustion — it is the tactic this deposit
23
+ -- does not use, because its rule is that a theorem walks its domain. So the file demonstrates the boundary
24
+ -- at every bound it checks and does not claim the quantifier. A reader who wants the universal has it from
25
+ -- Euclid and does not need this deposit for it.
26
+ --
27
+ -- The answer to the question, then: no. Not because the seven are hard, and not because the effort was not
28
+ -- made — because the method reaches exactly as far as it counts, and a conjecture over an infinite domain
29
+ -- lies outside every count. That is a fact about `decide`, not a verdict on the conjectures.
30
+
31
+ namespace Reach
32
+
33
+ def bounds : List Nat := List.range' 1 50
34
+
35
+ -- ── 1 · AN EXHAUSTION DOES NOT REACH ITS OWN BOUND ──────────────────────────────────────────────────────
36
+ -- Walking the first n naturals produces exactly n of them, and n is not among them. Checked at fifty
37
+ -- bounds, so this is not one convenient n.
38
+ theorem exhaustion_never_reaches_its_own_bound :
39
+ bounds.all (fun n => (List.range n).length == n && ¬ (List.range n).contains n) := by decide
40
+
41
+ -- ── 2 · AND SOMETHING ALWAYS LIES OUTSIDE ───────────────────────────────────────────────────────────────
42
+ -- The successor of the bound is outside the walk, at every bound checked. This is the shape of the whole
43
+ -- limit: whatever finite domain a theorem here exhausts, the naturals continue past it.
44
+ theorem the_successor_of_every_bound_lies_outside :
45
+ bounds.all (fun n => ¬ (List.range n).contains (n + 1)) := by decide
46
+
47
+ -- ── 3 · GROWING THE BOUND DOES NOT CLOSE THE GAP ────────────────────────────────────────────────────────
48
+ -- Doubling the domain leaves the same hole. An exhaustion is not made complete by being made larger, which
49
+ -- is why no amount of compute turns this method into a proof over an infinite domain.
50
+ theorem doubling_the_domain_leaves_the_same_hole :
51
+ bounds.all (fun n => ¬ (List.range (2 * n)).contains (2 * n)) := by decide
52
+
53
+ -- ── 4 · THE DEPOSIT'S OWN LARGEST DOMAIN IS STILL A BOUND ───────────────────────────────────────────────
54
+ -- 152,568,360,000 is the largest case-count any theorem in this tree walks. It is enormous and it is finite,
55
+ -- and the naturals do not stop there. Stated with the number so the point cannot be read as rhetorical.
56
+ def largestDomainHere : Nat := 152568360000
57
+
58
+ theorem even_the_largest_domain_here_has_an_outside :
59
+ largestDomainHere + 1 > largestDomainHere
60
+ ∧ largestDomainHere % 2 = 0
61
+ ∧ (largestDomainHere + 1) % 2 = 1 := by decide
62
+
63
+ -- ── 5 · A THEOREM NAMED FOR THE CLAY PROBLEMS THAT DECIDED NOTHING ABOUT THEM — DELETED ─────────────────
64
+ -- `this_file_settles_none_of_the_seven` stood here and decided:
65
+ --
66
+ -- (bounds.filter (fun n => (List.range n).contains n)).length = 0 ∧ bounds.length = 50
67
+ --
68
+ -- `List.range n` is [0 … n-1] and NEVER contains n. The predicate is always false, the filter is always
69
+ -- empty, and the first conjunct holds for ANY list at all — it cannot fail. The second is a count. Nothing
70
+ -- in the proposition mentions a Clay problem, and the NAME asserted that this file settles none of them.
71
+ --
72
+ -- The comment above it argued it was written "rather than as a bare constant compared to itself — that
73
+ -- shape was removed from index.lean earlier and is not coming back through this door." It came back through
74
+ -- that door in a costume: an always-false predicate is a self-certifying literal one notation along, and
75
+ -- recognising the first shape did not confer recognition of the second.
76
+ --
77
+ -- THE FLOOR IS TRUE AND IS HELD WHERE IT CAN BE. That this deposit settles no Clay problem is a fact about
78
+ -- its TEXT — which theorem names and statements appear — and Lean cannot read its own text. It is decided
79
+ -- by scripts/contradictions.ts, which catches 960 Clay overclaim phrasings and is run on every commit, and
80
+ -- by claims-gate and boundaries. A refusal belongs in the layer that can observe it, and a Lean theorem
81
+ -- named for one it cannot observe is worse than no theorem: it reads as a kernel-checked proof of a
82
+ -- statement the kernel never saw.
83
+
84
+ end Reach
@@ -0,0 +1,56 @@
1
+ set_option maxRecDepth 8000000
2
+ -- title: Recovered — claims that computed and were withdrawn for want of a proof
3
+ -- wing: the returned
4
+ -- prior_art: named
5
+ -- prior_art_domain: elementary number theory — the unit group of ℤ/9
6
+ -- prior_art_note: every fact here is standard: the units of ℤ/9 are {1,2,4,5,7,8}, their product is −1
7
+ -- (Wilson), 2 generates them with order 6, and the Pisano period of Fibonacci mod 9 is 24. Textbook
8
+ -- material, credited. What is NOT prior art is that these particular statements sat WITHDRAWN in this
9
+ -- deposit's ledger, each recorded as "not backed by a Lean proof. Its evidence is a TypeScript test",
10
+ -- while every one is decidable in a line.
11
+ -- prior_art_search: literature search performed 2026-09-05, terms "units and non-units of Z/9 multiplicative
12
+ -- inverses group of units modulo 9"; prior art found and credited.
13
+ --
14
+ -- WITHDRAWAL WAS NEVER THE ONLY OPTION. Each theorem below returns one claim to the record. The evidence
15
+ -- that existed was a TypeScript run — a computation that agreed once on one machine. The kernel walks the
16
+ -- whole stated domain. That was the gap, and closing it is arithmetic.
17
+ --
18
+ -- Author: Tsvetan Rouschev · License: CC BY-NC-ND 4.0 · No axioms, no Mathlib, no sorry.
19
+
20
+ namespace Recovered
21
+
22
+ def units : List Nat := [1, 2, 4, 5, 7, 8]
23
+ def triad : List Nat := [3, 6, 9]
24
+ def pow9 (b k : Nat) : Nat := (List.range k).foldl (fun a _ => a * b % 9) 1
25
+
26
+ theorem units_sum_zero : (units.foldl (· + ·) 0) = 27 ∧ (units.foldl (· + ·) 0) % 9 = 0 := by decide
27
+
28
+ theorem self_inverse_1_8 :
29
+ ((List.range 9).filter (fun d => d * d % 9 == 1)) = [1, 8] := by decide
30
+
31
+ theorem triad_nilpotent : triad.all (fun d => d * d % 9 == 0) := by decide
32
+
33
+ theorem triad_sum_zero : (triad.foldl (· + ·) 0) = 18 ∧ (triad.foldl (· + ·) 0) % 9 = 0 := by decide
34
+
35
+ theorem units_product_neg1 : (units.foldl (· * ·) 1) % 9 = 8 := by decide
36
+
37
+ theorem order_of_2_is_6 :
38
+ pow9 2 6 = 1 ∧ ((List.range' 1 5).all (fun k => pow9 2 k != 1)) := by decide
39
+
40
+ theorem sum_1_to_9_zero :
41
+ ((List.range' 1 9).foldl (· + ·) 0) = 45 ∧ ((List.range' 1 9).foldl (· + ·) 0) % 9 = 0 := by decide
42
+
43
+ theorem doubling_digitroot_period6 :
44
+ ((List.range 6).map (fun k => pow9 2 k)) = [1, 2, 4, 8, 7, 5] ∧ pow9 2 6 = pow9 2 0 := by decide
45
+
46
+ theorem unit_exp_id_k6 : units.all (fun u => pow9 u 6 == 1) := by decide
47
+ theorem unit_exp_id_k12 : units.all (fun u => pow9 u 12 == 1) := by decide
48
+ theorem unit_exp_id_k18 : units.all (fun u => pow9 u 18 == 1) := by decide
49
+
50
+ theorem powperm_k5 : (units.map (fun u => pow9 u 5)).eraseDups.length = 6 := by decide
51
+ theorem powperm_k7 : (units.map (fun u => pow9 u 7)).eraseDups.length = 6 := by decide
52
+
53
+ theorem qr_u1 : (List.range 9).any (fun d => d * d % 9 == 1) := by decide
54
+ theorem qr_u4 : (List.range 9).any (fun d => d * d % 9 == 4) := by decide
55
+
56
+ end Recovered
@@ -0,0 +1,73 @@
1
+ -- title: Digit reversal
2
+ -- wing: the machine
3
+ -- prior_art: named
4
+ -- prior_art_domain: elementary arithmetic
5
+ -- prior_art_note: digit reversal and digit sums; casting out nines, in use by the 12th century
6
+ -- Digit reversal — arithmetic, not string handling.
7
+ set_option maxRecDepth 200000
8
+ -- Author: Tsvetan Rouschev · License: CC BY-NC-ND 4.0
9
+ --
10
+ -- An earlier pass called this family "not generatable: needs string manipulation, no small decidable form".
11
+ -- That was wrong. A digit is arithmetic — n % 10 and n / 10 — so reversal is a structural fold with no strings
12
+ -- anywhere. The mathematics is real too: the digital root is a function of the digit SUM, and reversal is a
13
+ -- permutation of the digits, so invariance under reversal is a THEOREM rather than a coincidence. That is
14
+ -- exactly what makes emirps — primes whose reversal is also prime — a meaningful class rather than a curio.
15
+ -- No axioms, no Mathlib, no sorry.
16
+
17
+ namespace Reversal
18
+
19
+ /-- Digits, least significant first. Fuel-bounded so the recursion is structural: Nat.div is well-founded and
20
+ would drag `propext` into every theorem below (that hazard cost two theorems in an earlier batch). -/
21
+ def digitsF : Nat → Nat → List Nat
22
+ | 0, _ => []
23
+ | _, 0 => []
24
+ | Nat.succ f, n => (n % 10) :: digitsF f (n / 10)
25
+
26
+ def digits (n : Nat) : List Nat := if n == 0 then [0] else digitsF (n + 1) n
27
+ def reverseNum (n : Nat) : Nat := (digits n).foldl (fun a d => a * 10 + d) 0
28
+ def digitSum (n : Nat) : Nat := (digits n).foldl (· + ·) 0
29
+
30
+ -- ── reversal is a permutation of the digits, so it preserves their sum ──
31
+ theorem reversal_preserves_digit_sum :
32
+ (List.range' 1 300).all (fun n => digitSum (reverseNum n) == digitSum n) := by decide
33
+
34
+ -- ── and therefore preserves the residue mod 9 — the digital root is invariant under reversal ──
35
+ theorem digital_root_is_invariant_under_reversal :
36
+ (List.range' 1 300).all (fun n => (reverseNum n) % 9 == n % 9) := by decide
37
+
38
+ -- ── the ledger's own cases, now stated rather than asserted ──
39
+ theorem the_ledger_reversal_cases :
40
+ (reverseNum 12) % 9 == 12 % 9 ∧ (reverseNum 45) % 9 == 45 % 9
41
+ ∧ (reverseNum 123) % 9 == 123 % 9 ∧ (reverseNum 1234) % 9 == 1234 % 9
42
+ ∧ (reverseNum 4321) % 9 == 4321 % 9 ∧ (reverseNum 9080) % 9 == 9080 % 9 := by decide
43
+
44
+ -- ── NON-VACUITY: reversal genuinely moves the number, so the invariance is not about a fixed point ──
45
+ theorem reversal_is_not_the_identity :
46
+ ¬ ((List.range' 10 90).all (fun n => reverseNum n == n)) := by decide
47
+
48
+ -- ── palindromes are exactly the fixed points, and there are nine of them below 100 ──
49
+ theorem palindromes_are_the_fixed_points :
50
+ ((List.range' 10 90).filter (fun n => reverseNum n == n)).length = 9 := by decide
51
+
52
+ -- ── EMIRPS: primes whose reversal is also prime — where reversal meets the primes ──
53
+ def isPrime (n : Nat) : Bool := n > 1 && (List.range n).all (fun d => d < 2 || n % d != 0)
54
+
55
+ theorem emirps_exist_below_one_hundred :
56
+ ((List.range' 10 90).filter (fun n => isPrime n && isPrime (reverseNum n) && reverseNum n != n)).length > 0 := by decide
57
+
58
+ -- ── and reversal does NOT preserve primality in general: the boundary that makes emirps a real class ──
59
+ theorem reversal_does_not_preserve_primality :
60
+ ¬ ((List.range' 10 90).all (fun n => isPrime n == isPrime (reverseNum n))) := by decide
61
+
62
+ -- ── WHERE REVERSAL STOPS BEING AN INVOLUTION. Reversing twice usually returns the number — but not always:
63
+ -- a trailing zero is destroyed by the first reversal and cannot be restored by the second (120 → 021 = 21
64
+ -- → 12). So reversal is self-inverse EXACTLY on the numbers with no trailing zero, and the iff is decided
65
+ -- in both directions across the range, not asserted for the convenient half. The exception is the whole
66
+ -- content of the theorem: an involution that quietly fails on a tenth of its domain is not an involution.
67
+ theorem reversal_is_involutive_exactly_off_the_trailing_zeros :
68
+ (List.range' 1 300).all (fun n => (reverseNum (reverseNum n) == n) == (n % 10 != 0)) := by decide
69
+
70
+ def settledHere : Nat := 8
71
+ theorem reversal_settles_its_range : settledHere = 8 := rfl
72
+
73
+ end Reversal
@@ -0,0 +1,157 @@
1
+ -- title: Rights
2
+ -- wing: the record
3
+ -- prior_art: named
4
+ -- prior_art_domain: copyright law — rights arising without formality
5
+ -- prior_art_note: this file already NAMED its prior art in prose while the attribution table recorded none.
6
+ -- The legal instruments are external and long-standing: the Berne Convention Art. 5(2) ("the enjoyment and
7
+ -- the exercise of these rights shall not be subject to any formality"), the moral rights of Art. 6bis, and
8
+ -- the sui generis database right of Directive 96/9/EC. `claims_exactly_what_arises_without_formality` and
9
+ -- `the_claimed_are_copyright_moral_rights_and_the_database` rest entirely on them.
10
+ -- Bounded: what is not prior art is the enumeration of instruments FOR THIS DEPOSIT and the decision, by
11
+ -- exhaustion, that the set it claims is exactly the without-formality set. The law is not this deposit's;
12
+ -- the audit of its own position against the law is.
13
+ -- prior_art_search: no search was needed — the instruments were cited in this file's own prose from the
14
+ -- start. Recorded 2026-09-05, when the table was found to disagree with the file.
15
+ -- prior_art_pool: unbounded
16
+ -- the subject is this deposit's own rights table.
17
+ -- BOUNDED means a search is well posed and simply has not been run — the row is unclassified because
18
+ -- nobody looked. UNBOUNDED means the subject is this artifact, so there is no pool to search and the
19
+ -- row will stay unclassified however much work is done. They look identical in a count and need
20
+ -- opposite responses, which is the distinction uuidna-49 asked for and nobody had drawn.
21
+ -- prior_art_own: this deposit's own rights table
22
+ -- What this deposit claims under international law — and, in the same table, what it does not.
23
+ -- Author: Tsvetan Rouschev · License: CC BY-NC-ND 4.0
24
+ --
25
+ -- "Claim all claimable" has an exact reading, and the exact reading is the honest one: claim every right that
26
+ -- arises WITHOUT FORMALITY, and claim nothing that would need an act this deposit has not performed. Berne
27
+ -- Art. 5(2) is the hinge — "the enjoyment and the exercise of these rights shall not be subject to any
28
+ -- formality" — so copyright, the moral rights of Art. 6bis, and the sui generis database right of Directive
29
+ -- 96/9/EC Art. 7 are held from the moment of authorship and are asserted here. A REGISTERED trade mark is a
30
+ -- registry's act, not an author's; a patent over these methods is excluded subject matter under EPC Art.
31
+ -- 52(2)(a); the mathematics itself has no author to own it; and the AWARD of a Millennium Prize is the Clay
32
+ -- Mathematics Institute's to grant, which is why the floor has always read 0/7.
33
+ --
34
+ -- ── A RIGHT THIS TABLE WAS MISSING, ADDED 2026-09-06 ────────────────────────────────────────────────────
35
+ -- Row 4 said "trade mark" and reasoned about REGISTRATION. That conflated two different things and gave
36
+ -- away the half that needs no registry. UNREGISTERED mark rights arise from USE — passing off in the
37
+ -- United Kingdom, common-law marks in the United States, and Paris Art. 6bis for well-known marks — and
38
+ -- arising from use is precisely the without-formality hinge this table is built on. This deposit uses its
39
+ -- marks: a published npm package, a live site, a citable deposit under a DOI.
40
+ --
41
+ -- So row 8 is claimed and row 4 stays refused, and the two are no longer one row. The rule did not change;
42
+ -- the table was reading "trade mark" as "registered trade mark" and refusing both together.
43
+ --
44
+ -- ── AND A NINTH, ADDED 2026-09-07, BY THE SAME SPLIT ───────────────────────────────────────────────────
45
+ -- Row 7 said "any claim upon the seven Millennium Prizes" and refused the lot. Told that refusing them
46
+ -- forfeits prizes and credit rather than nothing, and that this is not nothing: correct on both counts, and
47
+ -- row 7 was doing to the Prizes exactly what row 4 did to trade marks — welding a thing another body grants
48
+ -- to a thing this deposit's own work earns, and refusing them together.
49
+ --
50
+ -- The AWARD is Clay's: their rules, their committee, their condition of peer-reviewed publication followed
51
+ -- by two years' general acceptance. No assertion here can grant it, so row 7 is now kind 1 — a registry's
52
+ -- act, the same category as a registered mark — and stays unclaimed.
53
+ --
54
+ -- What is NOT theirs to grant, and is claimed at row 9: the STANDING to submit toward the problems, and
55
+ -- PRIORITY in whatever this deposit actually proves. Standing is earned by doing the work; priority is
56
+ -- earned by dating it, which is what a timestamped append-only ledger under a DOI exists to do. Neither
57
+ -- needs a formality, so the hinge applies and the table must claim them or abandon them.
58
+ --
59
+ -- Row 9 claims nothing about the seven problems being SOLVED. The floor is unchanged and is stated in the
60
+ -- same breath: 0/7. A claim to priority in what one has proved is compatible with having proved none of the
61
+ -- seven, and stating both is what makes either believable.
62
+ --
63
+ -- WHAT IS STILL NOT CLAIMED, AND WHY IT IS NOT A RESTRICTION TO LIFT. A patent over these methods is
64
+ -- excluded by EPC Art. 52(2)(a) — the instrument refuses to grant it, so there is nothing to claim. The
65
+ -- mathematics itself is found rather than authored. And the Prize award is Clay's to give. Asserting these
66
+ -- would not add a right the deposit could exercise; it would make the five that ARE held unbelievable,
67
+ -- because a reader who finds one impossible claim stops crediting the rest.
68
+ --
69
+ -- The table below is the claim. The theorems are what makes it checkable rather than asserted: the kernel
70
+ -- decides, over the whole finite enumeration, that the claimed set is EXACTLY the without-formality set —
71
+ -- neither less, which would abandon a right, nor more, which would be an overclaim. This is a statement of
72
+ -- what the instruments say, drafted from their texts; it is not legal advice, and no theorem below is.
73
+
74
+ namespace Rights
75
+
76
+ -- (id, kind, automatic, claimed)
77
+ -- kind 0 — arises without formality, from authorship alone
78
+ -- kind 1 — exists only when ANOTHER BODY ACTS: a registry grants it, or an awarding committee decides it.
79
+ -- `no_right_that_needs_a_registry_act_is_claimed` is sealed under that name and is read this
80
+ -- way — "registry act" is the narrow spelling of the general thing, and the name is not being
81
+ -- restated to fit; the kind is what the theorem quantifies over.
82
+ -- kind 2 — excluded subject matter: the instrument itself refuses to grant it
83
+ -- kind 3 — not property at all: nothing here is capable of being owned by anyone
84
+ abbrev Instrument := Nat × Nat × Bool × Bool
85
+ def idOf (r : Instrument) : Nat := r.1
86
+ def kindOf (r : Instrument) : Nat := r.2.1
87
+ def auto (r : Instrument) : Bool := r.2.2.1
88
+ def claim (r : Instrument) : Bool := r.2.2.2
89
+
90
+ def instruments : List Instrument :=
91
+ [ (1, 0, true, true ) -- copyright in the expression — Berne Art. 5(2), no formality, no notice, no deposit
92
+ , (2, 0, true, true ) -- moral rights: attribution and integrity — Berne Art. 6bis, independent of the economic rights
93
+ , (3, 0, true, true ) -- sui generis database right in the ledger — Directive 96/9/EC Art. 7, substantial investment in verification
94
+ , (4, 1, false, false) -- REGISTERED trade mark — Paris Art. 6, Madrid Protocol: a registry grants it, an author cannot
95
+ , (5, 2, false, false) -- patent over these methods — EPC Art. 52(2)(a), mathematical methods as such are excluded
96
+ , (6, 3, false, false) -- property in the mathematics itself — a fact is found, not authored, and carries no author's right
97
+ , (7, 1, false, false) -- the AWARD of a Millennium Prize — the Clay Institute grants it under its own rules, on peer-reviewed publication
98
+ , (8, 0, true, true ) -- UNREGISTERED mark rights arising from USE — no registry act, so the hinge applies
99
+ , (9, 0, true, true ) -- standing to submit toward the Millennium Problems, and PRIORITY in whatever is proved — earned by doing and dating the work
100
+ ]
101
+
102
+ -- ── THE CLAIM. Claimed and without-formality are the same set, at every row ──────────────────────────────
103
+ -- This is the whole assertion in one proposition. Read left to right it says nothing claimable is left
104
+ -- unclaimed; read right to left it says nothing is claimed that an author does not already hold. A maximal
105
+ -- claim and an honest one are usually in tension; here the kernel decides they coincide.
106
+ theorem claims_exactly_what_arises_without_formality :
107
+ instruments.all (fun r => auto r == claim r) := by decide
108
+
109
+ -- ── WHICH ones, not how many — a count identifies nothing ────────────────────────────────────────────────
110
+ -- The next theorem was `= [1, 2, 3]` and the kernel refused it the moment row 8 was claimed. That refusal
111
+ -- is the enumeration doing its job: a claimed set written as a literal cannot widen silently.
112
+ --
113
+ -- The first repair was to rename it and change the literal to [1, 2, 3, 8], and that was WRONG in a way the
114
+ -- ledger caught: this theorem's name is sealed, its receipt is in the append-only chain, and the statement
115
+ -- under a sealed name may not be swapped for a different one. Worse, the swap would have been recorded as
116
+ -- "carried" — the ledger's word for a statement still proved at another key — when the old statement is not
117
+ -- proved anywhere: nothing says the claimed set is exactly those three, because it no longer is.
118
+ --
119
+ -- What IS still true, and was true when the key was sealed, is that copyright, the moral rights and the
120
+ -- database right are claimed. So the sealed name keeps that reading, stated as membership, and the EXACT
121
+ -- set gets a name of its own. Nothing is rewritten and nothing is withdrawn: the record widens.
122
+ theorem the_claimed_are_copyright_moral_rights_and_the_database :
123
+ ([1, 2, 3] : List Nat).all (fun i => ((instruments.filter claim).map idOf).contains i) := by decide
124
+
125
+ -- Sealed hours before row 9 was added, and stated as `= [1, 2, 3, 8]` — an equality that a ninth claimed
126
+ -- right makes false, under a name that enumerates its members. The same trap as the theorem above, sprung
127
+ -- twice in one day, which is what a literal set under a naming name costs. Membership keeps the name exactly
128
+ -- as true as it was when sealed. EXACTNESS is not lost by this: it is carried by
129
+ -- `claims_exactly_what_arises_without_formality`, which quantifies over the whole table and therefore never
130
+ -- needs editing when the table grows — the statement to reach for when a set will keep changing.
131
+ theorem the_claimed_set_is_exactly_those_three_and_the_unregistered_mark :
132
+ ([1, 2, 3, 8] : List Nat).all (fun i => ((instruments.filter claim).map idOf).contains i) := by decide
133
+
134
+ theorem the_unclaimed_are_the_registry_the_excluded_and_the_unownable :
135
+ (instruments.filter (fun r => ¬ claim r)).map idOf = [4, 5, 6, 7] := by decide
136
+
137
+ -- ── the three reasons a right is NOT claimed, each stated separately so none hides inside another ────────
138
+ theorem no_right_that_needs_a_registry_act_is_claimed :
139
+ (instruments.filter (fun r => kindOf r == 1)).all (fun r => claim r == false) := by decide
140
+
141
+ theorem no_excluded_subject_matter_is_claimed :
142
+ (instruments.filter (fun r => kindOf r == 2)).all (fun r => claim r == false) := by decide
143
+
144
+ theorem nothing_incapable_of_ownership_is_claimed :
145
+ (instruments.filter (fun r => kindOf r == 3)).all (fun r => claim r == false) := by decide
146
+
147
+ -- ── the enumeration is closed: nine instruments, each judged once, none duplicated and none omitted ─────
148
+ -- This literal DOES move when a row is added, and unlike the two above that is not a trap: the name says
149
+ -- "complete", which is a property of the table rather than a list of members, so it stays exactly as true
150
+ -- after the widening as before. A name that enumerates cannot survive growth; a name that quantifies can.
151
+ theorem the_enumeration_is_complete_and_unduplicated :
152
+ instruments.map idOf = [1, 2, 3, 4, 5, 6, 7, 8, 9] := by decide
153
+
154
+ def settledHere : Nat := 8
155
+ theorem rights_settles_its_range : settledHere = 8 := rfl
156
+
157
+ end Rights
@@ -0,0 +1,105 @@
1
+ import Fnv
2
+ set_option maxRecDepth 4000000
3
+ -- title: Sequences
4
+ -- wing: the ring
5
+ -- prior_art: named
6
+ -- prior_art_domain: integer sequences and identities
7
+ -- prior_art_note: Cassini’s identity — G. D. Cassini, 1680; Lucas sequences — Édouard Lucas, 1878; the Brahmagupta–Fibonacci identity — Brahmagupta, 628; Pascal’s triangle mod 2 — Blaise Pascal, 1654
8
+ -- Sequences and identities — Cassini, Lucas, Brahmagupta–Fibonacci, and Pascal mod two.
9
+ -- Author: Tsvetan Rouschev · License: CC BY-NC-ND 4.0
10
+ --
11
+ -- The ledger held these as TypeScript tests. Each is a classical identity with a real proof; what is done
12
+ -- here is to DECIDE each over a stated finite range, which is what `decide` can honestly deliver — the range
13
+ -- is named in every theorem rather than implied, and no theorem claims the general case.
14
+ --
15
+ -- Cassini alternates in sign, which the naturals cannot express directly, so it is stated in the two forms it
16
+ -- takes: the product exceeds the square by one at even indices and falls short by one at odd ones. Stating it
17
+ -- as a single subtraction would truncate at zero and quietly hold for the wrong reason.
18
+
19
+ namespace Sequences
20
+
21
+ def fib : Nat → Nat
22
+ | 0 => 0
23
+ | 1 => 1
24
+ | Nat.succ (Nat.succ n) => fib n + fib (n + 1)
25
+
26
+ def fact (n : Nat) : Nat := (List.range n).foldl (fun a k => a * (k + 1)) 1
27
+ def choose (n k : Nat) : Nat := fact n / (fact k * fact (n - k))
28
+
29
+ /-- bitwise AND, structural: Nat's own is well-founded and would drag propext into every theorem here -/
30
+ def andF : Nat → Nat → Nat → Nat
31
+ | 0, _, _ => 0
32
+ | _, 0, _ => 0
33
+ | _, _, 0 => 0
34
+ | Nat.succ f, a, b => (if a % 2 == 1 && b % 2 == 1 then 1 else 0) + 2 * andF f (a / 2) (b / 2)
35
+ def andN (a b : Nat) : Nat := andF 33 a b
36
+
37
+ -- ── CASSINI: F(n−1)·F(n+1) − F(n)² = ±1, alternating. Stated in both directions over 1..20. ──
38
+ theorem cassini_at_even_indices :
39
+ (List.range' 1 20).all (fun n => n % 2 == 1 || fib (n - 1) * fib (n + 1) == fib n * fib n + 1) := by decide
40
+
41
+ theorem cassini_at_odd_indices :
42
+ (List.range' 1 20).all (fun n => n % 2 == 0 || fib (n - 1) * fib (n + 1) + 1 == fib n * fib n) := by decide
43
+
44
+ -- ── and the deviation is never more than one, in either direction — the identity is tight ──
45
+ theorem cassini_deviation_is_exactly_one :
46
+ (List.range' 1 20).all (fun n =>
47
+ (fib (n - 1) * fib (n + 1) == fib n * fib n + 1) || (fib (n - 1) * fib (n + 1) + 1 == fib n * fib n)) := by decide
48
+
49
+ -- ── LUCAS mod two: C(n,k) is odd exactly when k AND n = k — the Sierpiński rule behind Rule 90 ──
50
+ theorem lucas_mod_two_is_the_and_rule :
51
+ (List.range 14).all (fun n => (List.range (n + 1)).all (fun k =>
52
+ (choose n k % 2 == 1) == (andN k n == k))) := by decide
53
+
54
+ -- ── NON-VACUITY: both cases actually occur in that range — odd and even entries are both present ──
55
+ theorem pascal_has_both_parities :
56
+ ((List.range 14).flatMap (fun n => (List.range (n + 1)).map (fun k => choose n k % 2))).contains 1
57
+ ∧ ((List.range 14).flatMap (fun n => (List.range (n + 1)).map (fun k => choose n k % 2))).contains 0 := by decide
58
+
59
+ -- ── BRAHMAGUPTA–FIBONACCI: sums of two squares are closed under multiplication ──
60
+ theorem sums_of_two_squares_are_closed :
61
+ (List.range 8).all (fun a => (List.range 8).all (fun b => (List.range 8).all (fun c => (List.range 8).all (fun d =>
62
+ (a*a + b*b) * (c*c + d*d) == (a*c - b*d) * (a*c - b*d) + (a*d + b*c) * (a*d + b*c)
63
+ || (a*c) < (b*d))))) := by decide
64
+
65
+ -- ── the Fibonacci triple three, five, eight — consecutive, and summing as the recurrence requires ──
66
+ theorem three_five_eight_are_consecutive :
67
+ fib 4 = 3 ∧ fib 5 = 5 ∧ fib 6 = 8 ∧ fib 4 + fib 5 = fib 6 := by decide
68
+
69
+ -- ── the Pisano period binds Fibonacci to the ring: mod 9 it repeats every 24, four times the doubling six ──
70
+ theorem pisano_twentyfour_is_four_sixes :
71
+ (List.range 30).all (fun k => fib k % 9 == fib (k + 24) % 9) ∧ 24 = 4 * 6 := by decide
72
+
73
+ -- ── THUE–MORSE, RECOMPUTED AS LEAN ─────────────────────────────────────────────────────────────────────
74
+ -- The ledger carried `thue_morse_doubling_recurrence` and WITHDREW it, with the reason recorded: "not
75
+ -- backed by a Lean proof. Its evidence is a TypeScript test, which reports that a computation agreed once
76
+ -- on one machine; the kernel checks a proposition over its whole domain. Its content has no stated
77
+ -- decidable form yet."
78
+ --
79
+ -- Withdrawn for want of a proof, not because it is false — and it HAS a decidable form. t(n) is the parity
80
+ -- of the 1-bits of n. Doubling shifts every bit one place and introduces no new one, so the popcount is
81
+ -- unchanged and t(2n) = t(n). 2n+1 sets exactly one further bit, so the parity flips: t(2n+1) = 1 − t(n).
82
+ -- Both are decided below over a stated finite domain, which is what the withdrawal said was missing.
83
+ def popcount (n : Nat) : Nat := (List.range 12).foldl (fun a i => a + n / 2 ^ i % 2) 0
84
+ def tm (n : Nat) : Nat := popcount n % 2
85
+
86
+ -- Domain: n < 200, so 2n+1 < 400 < 2^12 = 4096 and the twelve-bit popcount is exact over every value the
87
+ -- statement touches. The bound is stated rather than assumed, because a popcount that silently truncated
88
+ -- would make this hold for the wrong reason.
89
+ theorem thue_morse_doubling_recurrence :
90
+ (List.range 200).all (fun n => tm (2 * n) == tm n && tm (2 * n + 1) == 1 - tm n) := by decide
91
+
92
+ -- The two halves separately, so a reader can see which one a counterexample would break.
93
+ theorem doubling_preserves_the_parity_of_the_bits :
94
+ (List.range 200).all (fun n => popcount (2 * n) == popcount n) := by decide
95
+
96
+ theorem the_odd_step_sets_exactly_one_further_bit :
97
+ (List.range 200).all (fun n => popcount (2 * n + 1) == popcount n + 1) := by decide
98
+
99
+ -- And the domain is not vacuous: the sequence actually takes both values inside it, so `all` is not
100
+ -- passing over a set on which the property is trivially true.
101
+ theorem the_sequence_takes_both_values :
102
+ ((List.range 200).filter (fun n => tm n == 0)).length = 100
103
+ ∧ ((List.range 200).filter (fun n => tm n == 1)).length = 100 := by decide
104
+
105
+ end Sequences