@ceccec/millennium-solutions 9.1.1 → 9.1.3

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/src/api/index.ts CHANGED
@@ -136,13 +136,13 @@ export const domainOf = (statement: string): number => {
136
136
  * before keys had a namespace (`lean_units_are_six`) and one after (`lean_z9_units_are_six`). Both were live
137
137
  * and both are legitimate history, but counting a key as a theorem overstates the deposit. Those 24 second
138
138
  * addresses were retired in favour of their namespaced form, so no theorem now carries two. The 8 `rfl`
139
- * DECLARATIONS have no key at all, because seal-lean.ts seals `by decide` only — and they are declarations,
139
+ * DECLARATIONS have no key at all, because seal-lean.ts seals exhaustions (`by decide`) and proofs, never rfl — and they are declarations,
140
140
  * never theorems, by the definition this file states.
141
141
  *
142
142
  * Lean decides what a theorem is. Every count of theorems is taken from src/proof; a count of keys is
143
143
  * called a count of keys. */
144
144
  export interface Census {
145
- theorems: number; byDecide: number; rfl: number
145
+ theorems: number; byDecide: number; proved: number; rfl: number
146
146
  liveKeys: number; sealedTheorems: number; surplusKeys: number; unresolvableKeys: number; unsealed: number
147
147
  }
148
148
 
@@ -303,6 +303,7 @@ export const census = (): Census => {
303
303
  return {
304
304
  theorems: T.length,
305
305
  byDecide: T.filter((t) => t.tactic === 'by decide').length,
306
+ proved: T.filter((t) => t.tactic !== 'by decide' && t.tactic !== 'rfl').length,
306
307
  rfl: T.filter((t) => t.tactic === 'rfl').length,
307
308
  liveKeys: keys.length,
308
309
  sealedTheorems: named.size,
@@ -18586,5 +18586,55 @@
18586
18586
  "key": "lean_speed_hexbits_are_slower_and_the_ratio_multiplies_back",
18587
18587
  "name": "lean speed.lean: hexbits_are_slower_and_the_ratio_multiplies_back — (List.range' 1 20).all (fun b => (List.range 400).all (fun a => (a / b) * b ≤ a && a < (a / b + 1) * b)) ∧ hexbitMs > hexMs ∧ hexbitMs * 10 / hexMs = 18 — decided by the Lean kernel over its whole finite domain, axiom-free",
18588
18588
  "receipt": "91a92ea5-bedd-8b9a-80b7-29130fbe5a93"
18589
+ },
18590
+ {
18591
+ "key": "lean_elementary_the_wythoff_sequences_partition_the_integers",
18592
+ "name": "lean elementary.lean: the_wythoff_sequences_partition_the_integers — (List.range' 1 50).all (fun m => ((List.range' 1 40).map lowerWythoff).count m + ((List.range' 1 40).map upperWythoff).count m == 1) — decided by the Lean kernel over its whole finite domain, axiom-free",
18593
+ "receipt": "45729b78-1ded-8539-a2da-71459d8d4183"
18594
+ },
18595
+ {
18596
+ "key": "lean_energy_the_atoms_read_back_from_the_mass",
18597
+ "name": "lean energy.lean: the_atoms_read_back_from_the_mass — (List.range 10).all (fun h => (List.range 10).all (fun o => atomsOf (mass h o) == some (h, o))) ∧ atomsOf mgH2 = some (2, 0) ∧ atomsOf mgO2 = some (0, 2) ∧ atomsOf mgH2O = some (2, 1) — decided by the Lean kernel over its whole finite domain, axiom-free",
18598
+ "receipt": "e49b5ab6-4f44-8b3c-aec8-b5b0a5f4d681"
18599
+ },
18600
+ {
18601
+ "key": "lean_families_invOf_is_an_inverse_and_an_involution_on_the_units",
18602
+ "name": "lean families.lean: invOf_is_an_inverse_and_an_involution_on_the_units — (List.range 9).all (fun d => match invOf d with | some e => d * e % 9 == 1 && invOf e == some d | none => gcd' d 9 != 1) — decided by the Lean kernel over its whole finite domain, axiom-free",
18603
+ "receipt": "85ad9b47-1b45-8b65-9a6c-72779f4782b0"
18604
+ },
18605
+ {
18606
+ "key": "lean_families_choose_is_invariant_under_the_involution_k_to_n_minus_k",
18607
+ "name": "lean families.lean: choose_is_invariant_under_the_involution_k_to_n_minus_k — (List.range 13).all (fun n => (List.range (n + 1)).all (fun k => choose n k == choose n (n - k) && n - (n - k) == k)) — decided by the Lean kernel over its whole finite domain, axiom-free",
18608
+ "receipt": "0affa1b0-91a0-8f5d-aa01-7f37496f2c87"
18609
+ },
18610
+ {
18611
+ "key": "lean_light_the_second_returns_from_the_metre_and_the_period",
18612
+ "name": "lean light.lean: the_second_returns_from_the_metre_and_the_period — (List.range 100).all (fun s => travel s / c == s && periods s / dNuCs == s) — decided by the Lean kernel over its whole finite domain, axiom-free",
18613
+ "receipt": "04685db2-fda6-844b-8b36-5b7f858baaac"
18614
+ },
18615
+ {
18616
+ "key": "lean_z9_the_orbit_step_is_read_back_by_its_log",
18617
+ "name": "lean z9.lean: the_orbit_step_is_read_back_by_its_log — (List.range 6).all (fun k => logOrbit (orbit k) == some k) ∧ units.all (fun u => (logOrbit u).map orbit == some u) — decided by the Lean kernel over its whole finite domain, axiom-free",
18618
+ "receipt": "e29d831e-5bde-8104-95bd-fc374ac46155"
18619
+ },
18620
+ {
18621
+ "key": "lean_energy_splitting_then_burning_is_the_identity_at_every_ledger_value",
18622
+ "name": "lean energy.lean: splitting_then_burning_is_the_identity_at_every_ledger_value — ∀ e : Nat, burnE (splitE e) = e — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
18623
+ "receipt": "2105157a-992b-8d52-8c5d-b7103bc12c7a"
18624
+ },
18625
+ {
18626
+ "key": "lean_light_the_second_returns_from_the_metre_and_the_period_at_every_duration",
18627
+ "name": "lean light.lean: the_second_returns_from_the_metre_and_the_period_at_every_duration — ∀ s : Nat, travel s / c = s ∧ periods s / dNuCs = s — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
18628
+ "receipt": "e6d8871f-bee4-8268-a94a-bdd31fdd6302"
18629
+ },
18630
+ {
18631
+ "key": "lean_reach_the_predecessor_returns_every_successor",
18632
+ "name": "lean reach.lean: the_predecessor_returns_every_successor — ∀ n : Nat, (n + 1) - 1 = n — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
18633
+ "receipt": "a1d55ab6-baca-8250-a413-285dc2cc2d5c"
18634
+ },
18635
+ {
18636
+ "key": "lean_speed_the_microseconds_return_from_the_nanoseconds_at_every_count",
18637
+ "name": "lean speed.lean: the_microseconds_return_from_the_nanoseconds_at_every_count — ∀ u : Nat, u * 1000 / 1000 = u — proved by the Lean kernel for every value (by\n intro), standard axioms only — checked by lean.ts",
18638
+ "receipt": "98899238-b934-8157-ae53-8b60284e56ab"
18589
18639
  }
18590
18640
  ]
@@ -344,6 +344,14 @@ theorem a_knight_has_exactly_eight_leaps_and_every_one_flips_the_colour :
344
344
  theorem the_golden_beatty_identity_holds_across_the_range :
345
345
  (List.range' 1 40).all (fun n => upperWythoff n - lowerWythoff n == n) := by decide
346
346
 
347
+ -- ── and the two sequences PARTITION the positive integers: every m up to fifty is hit by exactly one of the
348
+ -- lower and upper Wythoff sequences, never both, never neither (Beatty's theorem, 1926, at φ and φ²). The
349
+ -- identity above says how the two are paired; this says the pairing loses and duplicates nothing ──
350
+ set_option maxRecDepth 2000000 in
351
+ theorem the_wythoff_sequences_partition_the_integers :
352
+ (List.range' 1 50).all (fun m =>
353
+ ((List.range' 1 40).map lowerWythoff).count m + ((List.range' 1 40).map upperWythoff).count m == 1) := by decide
354
+
347
355
  -- ── the partition numbers count the partitions, and the Bell numbers count the set partitions ───────────
348
356
  -- Both are checked against an ENUMERATION of the objects rather than against another recurrence, which
349
357
  -- is the difference between confirming a formula and confirming what it counts.
@@ -387,7 +395,7 @@ theorem the_unit_graph_is_complete_bipartite_between_the_two_tetrahedra :
387
395
  (nbrs (unitsMod 9) d).all (fun y => x == y || !((nbrs (unitsMod 9) x).contains y)))) := by decide
388
396
 
389
397
  -- ── what these settle ──
390
- def settledHere : Nat := 31
391
- theorem elementary_settles_its_range : settledHere = 31 := rfl
398
+ def settledHere : Nat := 32
399
+ theorem elementary_settles_its_range : settledHere = 32 := rfl
392
400
 
393
401
  end Elementary
@@ -178,6 +178,13 @@ def burnE (e : Nat) : Nat := e - bondHundredthsKJ
178
178
  theorem splitting_then_burning_is_the_identity_at_the_ideal :
179
179
  (List.range 1000).all (fun e => burnE (splitE e) == e) ∧ pct burnYield splitCost = 23 := by decide
180
180
 
181
+ -- ── AND AT EVERY LEDGER VALUE, NOT A THOUSAND OF THEM. The theorem above decides the round trip below 1000;
182
+ -- this one PROVES it for every natural number, by the cancellation law of addition. A proof, not an
183
+ -- exhaustion — so it carries the standard axiom propext that core's lemmas rest on, and lean.ts prints it. ──
184
+ theorem splitting_then_burning_is_the_identity_at_every_ledger_value :
185
+ ∀ e : Nat, burnE (splitE e) = e := by
186
+ intro e; exact Nat.add_sub_cancel e bondHundredthsKJ
187
+
181
188
  -- ── WHAT A BUILDER RUNS INTO NEXT ────────────────────────────────────────────────────────────────────────
182
189
  -- The stoichiometry above is exact and favourable; these are the numbers that decide whether the machine can
183
190
  -- be built rather than whether it balances. They are the reason hydrogen systems are hard even when the
@@ -261,4 +268,15 @@ theorem the_residue_ratio_is_the_same_at_every_volume :
261
268
  (List.range' 1 200).all (fun l => residueMg l tdsSeawater == 700 * residueMg l tdsTapWater) ∧
262
269
  residueMg 100 tdsSeawater / 1000 = 3500 ∧ residueMg 100 tdsTapWater / 1000 = 5 := by decide
263
270
 
271
+ -- ── 19 · THE MASS READS BACK ITS ATOMS. `mass` takes a molecule's hydrogens and oxygens to its molar mass;
272
+ -- `atomsOf` goes the other way, finding the counts whose mass it is. At every molecule of up to nine
273
+ -- of each, reading the atoms back from the mass returns exactly those atoms — so on this range the
274
+ -- mass names the molecule, and no two formulas share one. H₂, O₂ and H₂O are three of the hundred. ──
275
+ def atomsOf (m : Nat) : Option (Nat × Nat) :=
276
+ ((List.range 10).flatMap (fun h => (List.range 10).map (fun o => (h, o)))).find? (fun p => mass p.1 p.2 == m)
277
+
278
+ theorem the_atoms_read_back_from_the_mass :
279
+ (List.range 10).all (fun h => (List.range 10).all (fun o => atomsOf (mass h o) == some (h, o))) ∧
280
+ atomsOf mgH2 = some (2, 0) ∧ atomsOf mgO2 = some (0, 2) ∧ atomsOf mgH2O = some (2, 1) := by decide
281
+
264
282
  end Energy
@@ -428,8 +428,23 @@ set_option maxRecDepth 100000 in
428
428
  theorem the_involutions_are_counted_by_the_telephone_numbers :
429
429
  (List.range 6).all (fun n => ((permsN (List.range n)).filter isInvolution).length == telephone n) := by decide
430
430
 
431
+ -- ── the unit inverse, stated AS an inverse. That invOf finds something at exactly the units was proved above;
432
+ -- this proves what it finds: the residue multiplies back to one, and inverting twice returns the unit — so
433
+ -- invOf is an involution on the six units, and the non-units, where it finds nothing, are exactly the
434
+ -- residues sharing a factor with nine ──
435
+ theorem invOf_is_an_inverse_and_an_involution_on_the_units :
436
+ (List.range 9).all (fun d => match invOf d with
437
+ | some e => d * e % 9 == 1 && invOf e == some d
438
+ | none => gcd' d 9 != 1) := by decide
439
+
440
+ -- ── the binomial coefficient does not see the involution k ↦ n − k: choosing k is choosing the n − k left
441
+ -- behind, and applying the involution twice returns k, at every n to twelve and every k ──
442
+ theorem choose_is_invariant_under_the_involution_k_to_n_minus_k :
443
+ (List.range 13).all (fun n => (List.range (n + 1)).all (fun k =>
444
+ choose n k == choose n (n - k) && n - (n - k) == k)) := by decide
445
+
431
446
  -- ── what these settle ──
432
- def settledHere : Nat := 40
433
- theorem families_settle_their_ranges : settledHere = 40 := rfl
447
+ def settledHere : Nat := 42
448
+ theorem families_settle_their_ranges : settledHere = 42 := rfl
434
449
 
435
450
  end Families
@@ -53,6 +53,18 @@ def periods (seconds : Nat) : Nat := dNuCs * seconds -- caesium periods elapsed
53
53
 
54
54
  theorem travel_at_one_returns_the_defined_constant : travel 1 = c := by decide
55
55
 
56
+ -- AND THE CHAIN RUNS BACK. Dividing the metres by c returns the seconds, and dividing the periods by ΔνCs
57
+ -- returns them too, at every whole second below a hundred: travel and periods are each undone by the
58
+ -- constant that defines them, so a length and a count of periods both read back the same duration.
59
+ theorem the_second_returns_from_the_metre_and_the_period :
60
+ (List.range 100).all (fun s => travel s / c == s && periods s / dNuCs == s) := by decide
61
+
62
+ -- And at EVERY duration, proved rather than decided: dividing by the constant that defines the map cancels it,
63
+ -- whatever the number of seconds. The standard axiom propext is carried and printed by lean.ts.
64
+ theorem the_second_returns_from_the_metre_and_the_period_at_every_duration :
65
+ ∀ s : Nat, travel s / c = s ∧ periods s / dNuCs = s := by
66
+ intro s; exact ⟨Nat.mul_div_cancel_left s (by decide), Nat.mul_div_cancel_left s (by decide)⟩
67
+
56
68
  -- ONE INTERVAL, TWO UNITS: the same second is 299792458 metres of light and 9192631770 caesium periods.
57
69
  -- That is the SI's join between space and time, and it is an identity between two definitions rather than
58
70
  -- a discovery about either.
@@ -61,6 +61,13 @@ theorem the_successor_leaves_every_domain_and_the_predecessor_returns :
61
61
  (bounds ++ [largestDomainHere]).all (fun n =>
62
62
  n + 1 > n && (n + 1) - 1 == n && (n + 1) % 2 != n % 2) := by decide
63
63
 
64
+ -- ── AND FOR EVERY n, WHICH NO EXHAUSTION ABOVE CAN SAY. The file's point is that `decide` stops at its bound;
65
+ -- this is what goes past it: a PROOF that the predecessor returns every successor, for all naturals at once.
66
+ -- It is the only kind of statement that reaches an unbounded domain, and it rests on the standard axiom
67
+ -- propext, printed by lean.ts. ──
68
+ theorem the_predecessor_returns_every_successor : ∀ n : Nat, (n + 1) - 1 = n := by
69
+ intro n; exact Nat.add_sub_cancel n 1
70
+
64
71
  -- ── 5 · A THEOREM NAMED FOR THE CLAY PROBLEMS THAT DECIDED NOTHING ABOUT THEM — DELETED ─────────────────
65
72
  -- `this_file_settles_none_of_the_seven` stood here and decided:
66
73
  --
@@ -88,6 +88,11 @@ theorem verification_grows_it_is_not_constant :
88
88
  -- the ledger next to the impressive one rather than only the impressive one being quotable. ──
89
89
  -- The nanosecond figure is not a second typed input: it is the microsecond input converted, and the
90
90
  -- conversion reads back at every microsecond count below a thousand. ──
91
+ -- ── The conversion reads back at EVERY count, proved rather than sampled — the theorem below it decides the
92
+ -- first thousand. A proof over all naturals, carrying the standard axiom propext (printed by lean.ts). ──
93
+ theorem the_microseconds_return_from_the_nanoseconds_at_every_count : ∀ u : Nat, u * 1000 / 1000 = u := by
94
+ intro u; exact Nat.mul_div_cancel u (by decide)
95
+
91
96
  theorem the_verify_in_nanoseconds_reads_back_its_microseconds :
92
97
  (List.range 1000).all (fun u => u * 1000 / 1000 == u) ∧
93
98
  nsPerVerify = verifyUs * 1000 ∧ nsPerVerify / 1000 = verifyUs ∧ nsPerVerify > 10000 := by decide
@@ -15400,5 +15400,65 @@
15400
15400
  "verdict": "UNVERIFIED",
15401
15401
  "ground": "no candidate in the current space — nothing to recompute",
15402
15402
  "receipt": "91a92ea5-bedd-8b9a-80b7-29130fbe5a93"
15403
+ },
15404
+ {
15405
+ "key": "lean_elementary_the_wythoff_sequences_partition_the_integers",
15406
+ "verdict": "UNVERIFIED",
15407
+ "ground": "no candidate in the current space — nothing to recompute",
15408
+ "receipt": "45729b78-1ded-8539-a2da-71459d8d4183"
15409
+ },
15410
+ {
15411
+ "key": "lean_energy_the_atoms_read_back_from_the_mass",
15412
+ "verdict": "UNVERIFIED",
15413
+ "ground": "no candidate in the current space — nothing to recompute",
15414
+ "receipt": "e49b5ab6-4f44-8b3c-aec8-b5b0a5f4d681"
15415
+ },
15416
+ {
15417
+ "key": "lean_families_invOf_is_an_inverse_and_an_involution_on_the_units",
15418
+ "verdict": "UNVERIFIED",
15419
+ "ground": "no candidate in the current space — nothing to recompute",
15420
+ "receipt": "85ad9b47-1b45-8b65-9a6c-72779f4782b0"
15421
+ },
15422
+ {
15423
+ "key": "lean_families_choose_is_invariant_under_the_involution_k_to_n_minus_k",
15424
+ "verdict": "UNVERIFIED",
15425
+ "ground": "no candidate in the current space — nothing to recompute",
15426
+ "receipt": "0affa1b0-91a0-8f5d-aa01-7f37496f2c87"
15427
+ },
15428
+ {
15429
+ "key": "lean_light_the_second_returns_from_the_metre_and_the_period",
15430
+ "verdict": "UNVERIFIED",
15431
+ "ground": "no candidate in the current space — nothing to recompute",
15432
+ "receipt": "04685db2-fda6-844b-8b36-5b7f858baaac"
15433
+ },
15434
+ {
15435
+ "key": "lean_z9_the_orbit_step_is_read_back_by_its_log",
15436
+ "verdict": "UNVERIFIED",
15437
+ "ground": "no candidate in the current space — nothing to recompute",
15438
+ "receipt": "e29d831e-5bde-8104-95bd-fc374ac46155"
15439
+ },
15440
+ {
15441
+ "key": "lean_energy_splitting_then_burning_is_the_identity_at_every_ledger_value",
15442
+ "verdict": "UNVERIFIED",
15443
+ "ground": "no candidate in the current space — nothing to recompute",
15444
+ "receipt": "2105157a-992b-8d52-8c5d-b7103bc12c7a"
15445
+ },
15446
+ {
15447
+ "key": "lean_light_the_second_returns_from_the_metre_and_the_period_at_every_duration",
15448
+ "verdict": "UNVERIFIED",
15449
+ "ground": "no candidate in the current space — nothing to recompute",
15450
+ "receipt": "e6d8871f-bee4-8268-a94a-bdd31fdd6302"
15451
+ },
15452
+ {
15453
+ "key": "lean_reach_the_predecessor_returns_every_successor",
15454
+ "verdict": "UNVERIFIED",
15455
+ "ground": "no candidate in the current space — nothing to recompute",
15456
+ "receipt": "a1d55ab6-baca-8250-a413-285dc2cc2d5c"
15457
+ },
15458
+ {
15459
+ "key": "lean_speed_the_microseconds_return_from_the_nanoseconds_at_every_count",
15460
+ "verdict": "UNVERIFIED",
15461
+ "ground": "no candidate in the current space — nothing to recompute",
15462
+ "receipt": "98899238-b934-8157-ae53-8b60284e56ab"
15403
15463
  }
15404
15464
  ]
package/src/proof/z9.lean CHANGED
@@ -65,6 +65,15 @@ theorem orbit_closes : orbit 6 = orbit 0 := by decide
65
65
  theorem orbit_distinct : ((List.range 6).map orbit).eraseDups.length = 6 := by decide
66
66
  theorem orbit_covers_units : ((List.range 6).map orbit).eraseDups.length = units.length := by decide
67
67
 
68
+ -- ── the orbit read back: a discrete log along the doubling circuit. orbit takes a step to its residue;
69
+ -- logOrbit takes the residue back to its step. Every step below six returns itself, and every unit is
70
+ -- reached and re-reached — the circuit and its log are inverse, which is what "2 generates the units" means ──
71
+ def logOrbit (u : Nat) : Option Nat := (List.range 6).find? (fun k => orbit k == u)
72
+
73
+ theorem the_orbit_step_is_read_back_by_its_log :
74
+ (List.range 6).all (fun k => logOrbit (orbit k) == some k) ∧
75
+ units.all (fun u => (logOrbit u).map orbit == some u) := by decide
76
+
68
77
  -- ── the triad {3,6,9} is off the circuit: no power of 3 or 6 ever reaches one ──
69
78
  theorem triad_never_reaches_one :
70
79
  ¬ ((List.range 12).any (fun k => pow9 3 (k + 1) == 1 || pow9 6 (k + 1) == 1)) := by decide
@@ -86,7 +95,7 @@ theorem neg_involution : (List.range B).all (fun d => m9 (B - m9 (B - d)) == m9
86
95
  -- The count is of declarations closing by EXHAUSTION, which is this deposit's definition of a theorem, so
87
96
  -- the rfl declaration below is excluded from its own total. It read 21 until the count was recomputed
88
97
  -- against the tree: it had been counting itself. A tautology is not one of the things settled here.
89
- def settledHere : Nat := 20
90
- theorem z9_settles_its_domain_totally : settledHere = 20 := rfl
98
+ def settledHere : Nat := 21
99
+ theorem z9_settles_its_domain_totally : settledHere = 21 := rfl
91
100
 
92
101
  end Z9