@ceccec/millennium-solutions 9.3.1 → 9.3.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.
@@ -288,4 +288,42 @@ theorem two_parts_in_three_is_two_thirds_at_every_scale_for_every_m :
288
288
  unfold pct
289
289
  rw [Nat.mul_comm 2 m, Nat.mul_assoc, Nat.mul_comm 3 m, Nat.mul_div_mul_left _ _ hm]
290
290
 
291
+
292
+ -- ── reflections, from the easy batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
293
+ theorem burning_then_splitting_is_the_identity_above_the_bond :
294
+ ∀ e : Nat, bondHundredthsKJ ≤ e → splitE (burnE e) = e := by
295
+ intro e h; unfold splitE burnE; omega
296
+
297
+ theorem one_part_in_three_is_a_third_at_every_scale_for_every_m :
298
+ ∀ m : Nat, 0 < m → pct m (3 * m) = 33 := by
299
+ intro m hm; unfold pct
300
+ rw [Nat.mul_comm 3 m, Nat.mul_div_mul_left 100 3 hm]
301
+
302
+ theorem the_gas_volume_reads_back_its_moles_for_every_m :
303
+ ∀ m : Nat, molesOf (litresOf m) ≤ m ∧ m ≤ molesOf (litresOf m) + 1 := by
304
+ intro m; unfold molesOf litresOf mLperMol; exact ⟨by omega, by omega⟩
305
+
306
+
307
+ -- ── reflections, from the extra batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
308
+ -- the_atoms_read_back_from_the_mass holds on h, o < 10 and is FALSE in general: mass 5333 0 = mass 0 336.
309
+ -- The true boundary: below 5333 hydrogens the mass names the molecule, at any oxygen count.
310
+ theorem the_mass_names_the_molecule_below_5333_hydrogens :
311
+ ∀ h o h' o' : Nat, h < 5333 → h' < 5333 → mass h o = mass h' o' → h = h' ∧ o = o' := by
312
+ intro h o h' o' h1 h2 e
313
+ unfold mass mgH mgO at e
314
+ exact ⟨by omega, by omega⟩
315
+
316
+ theorem the_boundary_is_sharp : mass 5333 0 = mass 0 336 := by decide
317
+
318
+ -- the_cost_per_litre / the_energy_per_litre / hexbits rows: a floor division multiplies back within one divisor
319
+ theorem a_floor_division_multiplies_back_within_one_divisor :
320
+ ∀ a l : Nat, 0 < l → a / l * l ≤ a ∧ a < (a / l + 1) * l := by
321
+ intro a l hl
322
+ have e := Nat.div_add_mod a l
323
+ have hr := Nat.mod_lt a hl
324
+ refine ⟨Nat.div_mul_le_self a l, ?_⟩
325
+ rw [Nat.add_mul, Nat.one_mul, Nat.mul_comm (a / l) l]
326
+ generalize l * (a / l) = X at e ⊢
327
+ omega
328
+
291
329
  end Energy
@@ -645,4 +645,96 @@ theorem the_sums_of_triangular_numbers_are_the_tetrahedral_numbers_for_every_n :
645
645
  intro n
646
646
  rw [← six n, Nat.mul_div_cancel_left _ (by decide)]
647
647
 
648
+
649
+ -- ── reflections, from the easy batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
650
+ theorem choose_is_invariant_under_the_involution_k_to_n_minus_k_for_every_n :
651
+ ∀ n k : Nat, k ≤ n → choose n k = choose n (n - k) ∧ n - (n - k) = k := by
652
+ intro n k h
653
+ unfold choose
654
+ rw [Nat.sub_sub_self h, Nat.mul_comm]
655
+ exact ⟨rfl, rfl⟩
656
+
657
+
658
+ -- ── reflections, from the sums batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
659
+ -- REFLECTIONS: each closed form differences back to its term
660
+ theorem the_closed_forms_difference_back_to_the_next_power_for_every_n :
661
+ ∀ k n : Nat, 1 ≤ k → k ≤ 5 → faulhaber k (n + 1) = faulhaber k n + (n + 1) ^ k := by
662
+ intro k n h1 h5
663
+ rw [← power_sums_match_their_closed_forms_for_every_n k (n + 1) h1 h5,
664
+ ← power_sums_match_their_closed_forms_for_every_n k n h1 h5]
665
+ unfold powSum
666
+ exact a_sum_over_one_to_n_plus_one_adds_the_last_term (fun i => i ^ k) n
667
+
668
+ theorem the_tetrahedral_numbers_difference_back_to_the_triangular_numbers_for_every_n :
669
+ ∀ n : Nat, (n + 1) * (n + 1 + 1) * (n + 1 + 2) / 6 = n * (n + 1) * (n + 2) / 6 + (n + 1) * (n + 1 + 1) / 2 := by
670
+ intro n
671
+ rw [← the_sums_of_triangular_numbers_are_the_tetrahedral_numbers_for_every_n (n + 1),
672
+ ← the_sums_of_triangular_numbers_are_the_tetrahedral_numbers_for_every_n n]
673
+ exact a_sum_over_one_to_n_plus_one_adds_the_last_term (fun i => i * (i + 1) / 2) n
674
+
675
+ theorem the_powers_of_two_difference_back_to_the_next_power_for_every_n :
676
+ ∀ n : Nat, (2 ^ (n + 2) - 1) - (2 ^ (n + 1) - 1) = 2 ^ (n + 1) := by
677
+ intro n
678
+ have h : 1 ≤ 2 ^ (n + 1) := Nat.one_le_two_pow
679
+ rw [Nat.pow_succ 2 (n + 1)]
680
+ omega
681
+
682
+ theorem the_odd_numbers_difference_back_to_the_next_odd_number_for_every_n :
683
+ ∀ n : Nat, ((List.range (n + 1)).map (fun i => 2 * i + 1)).foldl (· + ·) 0 - ((List.range n).map (fun i => 2 * i + 1)).foldl (· + ·) 0 = 2 * n + 1 := by
684
+ intro n
685
+ rw [the_first_n_odd_numbers_sum_to_n_squared_for_every_n, the_first_n_odd_numbers_sum_to_n_squared_for_every_n,
686
+ square_of_successor]
687
+ omega
688
+
689
+
690
+ -- ── reflections, from the extra batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
691
+ theorem foldl_add_start : ∀ (l : List Nat) (a : Nat), l.foldl (· + ·) a = a + l.foldl (· + ·) 0 := by
692
+ intro l
693
+ induction l with
694
+ | nil => intro a; simp
695
+ | cons x xs ih =>
696
+ intro a
697
+ simp only [List.foldl]
698
+ rw [ih (a + x), ih (0 + x)]
699
+ omega
700
+
701
+ theorem the_digits_sum_to_the_number_mod_nine_when_the_fuel_covers_them :
702
+ ∀ f n : Nat, n < 10 ^ f → (digitsF f n).foldl (· + ·) 0 % 9 = n % 9 := by
703
+ intro f
704
+ induction f with
705
+ | zero =>
706
+ intro n h
707
+ have : n = 0 := by simp at h; omega
708
+ subst this
709
+ simp [digitsF]
710
+ | succ f ih =>
711
+ intro n h
712
+ cases n with
713
+ | zero => simp [digitsF]
714
+ | succ m =>
715
+ simp only [digitsF, List.foldl]
716
+ rw [foldl_add_start]
717
+ have hlt : (m + 1) / 10 < 10 ^ f := by
718
+ rw [Nat.pow_succ] at h
719
+ omega
720
+ have := ih ((m + 1) / 10) hlt
721
+ omega
722
+
723
+ theorem a_number_is_below_ten_to_its_own_successor : ∀ n : Nat, n < 10 ^ (n + 1) := by
724
+ intro n
725
+ induction n with
726
+ | zero => decide
727
+ | succ n ih =>
728
+ rw [Nat.pow_succ]
729
+ omega
730
+
731
+ -- the_digit_sum_rules_for_three_and_nine_hold_below_ten_thousand, for every n
732
+ theorem the_digit_sum_rules_for_three_and_nine_hold_for_every_n :
733
+ ∀ n : Nat, (digitSum n % 3 = 0 ↔ n % 3 = 0) ∧ (digitSum n % 9 = 0 ↔ n % 9 = 0) := by
734
+ intro n
735
+ have h := the_digits_sum_to_the_number_mod_nine_when_the_fuel_covers_them (n + 1) n (a_number_is_below_ten_to_its_own_successor n)
736
+ unfold digitSum digitsOf
737
+ generalize (digitsF (n + 1) n).foldl (· + ·) 0 = s at h ⊢
738
+ exact ⟨⟨fun a => by omega, fun a => by omega⟩, ⟨fun a => by omega, fun a => by omega⟩⟩
739
+
648
740
  end Families
@@ -51,4 +51,28 @@ theorem navier_stokes_flow_is_bounded_for_every_step :
51
51
  revert j
52
52
  decide
53
53
 
54
+
55
+ -- ── reflections, from the orbit batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
56
+ -- orbit and span are MillenniumFloor's (index.lean), opened above — not redefined here
57
+ -- REFLECTION: the reverse flow (halving, ×5) steps every state back one, at every step
58
+ theorem the_reverse_flow_undoes_every_step : ∀ k : Nat, orbit (k + 1) * 5 % 9 = orbit k := by
59
+ intro k
60
+ unfold orbit
61
+ rw [Nat.mul_mod, Nat.mod_mod, ← Nat.mul_mod, Nat.pow_succ, Nat.mul_assoc, Nat.mul_mod]
62
+ show 2 ^ k % 9 * 1 % 9 = 2 ^ k % 9
63
+ rw [Nat.mul_one, Nat.mod_mod]
64
+
65
+ -- REFLECTION of "bounded": recurrent — from every step, every state of the span returns within six steps
66
+ theorem every_state_of_the_flow_returns_within_six_steps :
67
+ ∀ k s : Nat, ∃ j, j < 6 ∧ orbit (k + j) = orbit s := by
68
+ intro k s
69
+ have key : ∀ r, r < 6 → ∀ t, t < 6 → ∃ j, j < 6 ∧ orbit ((r + j) % 6) = orbit t := by
70
+ decide
71
+ obtain ⟨j, hj, e⟩ := key (k % 6) (Nat.mod_lt _ (by decide)) (s % 6) (Nat.mod_lt _ (by decide))
72
+ refine ⟨j, hj, ?_⟩
73
+ rw [the_doubling_flow_is_its_first_six_steps (k + j), the_doubling_flow_is_its_first_six_steps s]
74
+ have hm : (k + j) % 6 = (k % 6 + j) % 6 := by omega
75
+ rw [hm]
76
+ exact e
77
+
54
78
  end Flow
@@ -113,4 +113,15 @@ theorem the_split_multiply_is_the_exact_thirty_two_bit_product :
113
113
  generalize a % 65536 * b = Q
114
114
  omega
115
115
 
116
+
117
+ -- ── reflections, from the xor batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
118
+ -- REFLECTION of the exact 32-bit multiply: multiplying by the FNV prime is undone by its inverse mod 2^32
119
+ theorem multiplying_by_the_fnv_prime_is_undone_by_its_inverse_for_every_h :
120
+ ∀ h : Nat, mul32 (mul32 h FNV_PRIME) 899433627 = h % M32 := by
121
+ intro h
122
+ unfold mul32
123
+ rw [Nat.mod_mul_mod, Nat.mul_assoc,
124
+ show FNV_PRIME * 899433627 = 1 + 3513497 * M32 by decide,
125
+ Nat.mul_add, Nat.mul_one, ← Nat.mul_assoc, Nat.add_mul_mod_self_right]
126
+
116
127
  end Fnv
@@ -155,4 +155,14 @@ theorem the_second_returns_from_the_metre_and_the_period_for_every_s :
155
155
  intro s
156
156
  exact ⟨Nat.mul_div_cancel_left s (by decide), Nat.mul_div_cancel_left s (by decide)⟩
157
157
 
158
+
159
+ -- ── reflections, from the easy batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
160
+ theorem the_metre_returns_from_the_second_for_every_whole_length :
161
+ ∀ m : Nat, m % c = 0 → travel (m / c) = m := by
162
+ intro m h; unfold travel; exact Nat.mul_div_cancel' (Nat.dvd_of_mod_eq_zero h)
163
+
164
+ theorem the_period_count_returns_from_the_second_for_every_whole_count :
165
+ ∀ p : Nat, p % dNuCs = 0 → periods (p / dNuCs) = p := by
166
+ intro p h; unfold periods; exact Nat.mul_div_cancel' (Nat.dvd_of_mod_eq_zero h)
167
+
158
168
  end Light
@@ -521,4 +521,43 @@ theorem the_moduli_dimensions_are_three_g_minus_three_and_six_g_minus_six_for_ev
521
521
  intro g
522
522
  exact ⟨by omega, by omega⟩
523
523
 
524
+
525
+ -- ── reflections, from the easy batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
526
+ theorem DR_eq : ∀ n : Nat, DR n = if n = 0 then 0 else 1 + (n - 1) % 9 := by
527
+ intro n; unfold DR; by_cases h : n = 0 <;> simp [h]
528
+
529
+ theorem halving_undoes_every_doubling_step_for_every_k : ∀ k : Nat, dbl (k + 1) / 2 = dbl k := by
530
+ intro k; show 2 * dbl k / 2 = dbl k; omega
531
+
532
+ theorem casting_out_nines_is_additive_for_every_a_b : ∀ a b : Nat, DR (a + b) = DR (DR a + DR b) := by
533
+ intro a b
534
+ simp only [DR_eq]
535
+ by_cases ha : a = 0 <;> by_cases hb : b = 0 <;> simp only [ha, hb, if_true, if_false] <;>
536
+ (repeat' split) <;> omega
537
+
538
+ theorem the_digital_root_fixes_exactly_one_to_nine : ∀ d : Nat, 1 ≤ d → d ≤ 9 → DR d = d := by
539
+ intro d h1 h9; rw [DR_eq, if_neg (by omega)]; omega
540
+
541
+ theorem the_digital_root_is_idempotent_for_every_n : ∀ n : Nat, DR (DR n) = DR n := by
542
+ intro n; simp only [DR_eq]; (repeat' split) <;> omega
543
+
544
+ theorem a_digital_root_of_nine_means_a_multiple_of_nine_for_every_n :
545
+ ∀ n : Nat, 0 < n → DR n = 9 → n % 9 = 0 := by
546
+ intro n hn h; rw [DR_eq, if_neg (by omega)] at h; omega
547
+
548
+ theorem the_hypotenuse_reads_back_from_every_three_four_five_multiple :
549
+ ∀ k c : Nat, (3 * k) ^ 2 + (4 * k) ^ 2 = c ^ 2 → c = 5 * k := by
550
+ intro k c h
551
+ rw [every_multiple_of_three_four_five_is_pythagorean] at h
552
+ rw [Nat.pow_two, Nat.pow_two] at h
553
+ rcases Nat.lt_trichotomy c (5 * k) with hl | he | hg
554
+ · have := Nat.mul_lt_mul_of_lt_of_lt hl hl; omega
555
+ · exact he
556
+ · have := Nat.mul_lt_mul_of_lt_of_lt hg hg; omega
557
+
558
+ theorem the_sixth_of_three_consecutive_integers_multiplies_back_for_every_n :
559
+ ∀ n : Nat, n * (n + 1) * (n + 2) / 6 * 6 = n * (n + 1) * (n + 2) := by
560
+ intro n
561
+ exact Nat.div_mul_cancel (Nat.dvd_of_mod_eq_zero (the_product_of_any_three_consecutive_integers_is_divisible_by_six_for_every_n n))
562
+
524
563
  end Mechanical
@@ -308,4 +308,25 @@ theorem the_nim_sum_is_a_gf2_vector_addition_for_every_a_b_c :
308
308
  exact ⟨xor_is_commutative_for_every_a_b a b, xor_is_associative_for_every_a_b_c a b c,
309
309
  xor_is_its_own_inverse_for_every_a_b a b, xor_zero_is_identity_for_every_a a⟩
310
310
 
311
+
312
+ -- ── reflections, from the xor batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
313
+ -- REFLECTIONS
314
+ theorem a_number_xored_with_itself_is_zero_for_every_a : ∀ a : Nat, xorN a a = 0 := by
315
+ intro a; unfold xorN; exact a_number_xored_with_itself_is_zero_at_every_fuel _ a
316
+
317
+ theorem xor_is_zero_only_on_equal_arguments_for_every_a_b : ∀ a b : Nat, xorN a b = 0 ↔ a = b := by
318
+ intro a b
319
+ constructor
320
+ · intro h
321
+ have := xor_is_its_own_inverse_for_every_a_b a b
322
+ rw [h, xor_is_commutative_for_every_a_b, xor_zero_is_identity_for_every_a] at this
323
+ exact this.symm
324
+ · intro h; subst h; exact a_number_xored_with_itself_is_zero_for_every_a a
325
+
326
+ theorem the_halves_and_the_low_bit_read_back_from_the_xor_for_every_a_b :
327
+ ∀ a b : Nat, xorN a b / 2 = xorN (a / 2) (b / 2) ∧ xorN a b % 2 = (a + b) % 2 := by
328
+ intro a b
329
+ have h := xor_is_the_sum_of_the_bits_plus_twice_the_xor_of_the_halves a b
330
+ constructor <;> omega
331
+
311
332
  end Nim
@@ -102,4 +102,20 @@ theorem doubling_the_domain_leaves_the_same_hole_for_every_n : ∀ n : Nat, 2 *
102
102
  intro n h
103
103
  exact Nat.lt_irrefl (2 * n) (List.mem_range.mp h)
104
104
 
105
+
106
+ -- ── reflections, from the easy batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
107
+ theorem the_successor_returns_every_positive_predecessor : ∀ n : Nat, 0 < n → (n - 1) + 1 = n := by
108
+ intro n h; omega
109
+
110
+ theorem exhaustion_reaches_everything_below_its_bound_for_every_n : ∀ n k : Nat, k < n → k ∈ List.range n := by
111
+ intro n k h; exact List.mem_range.mpr h
112
+
113
+ theorem the_predecessor_of_every_positive_bound_lies_inside : ∀ n : Nat, 0 < n → n - 1 ∈ List.range n := by
114
+ intro n h; exact List.mem_range.mpr (by omega)
115
+
116
+
117
+ -- ── reflections, from the extra batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
118
+ theorem halving_the_domain_keeps_the_half_inside_for_every_n : ∀ n : Nat, 0 < n → n ∈ List.range (2 * n) := by
119
+ intro n h; exact List.mem_range.mpr (by omega)
120
+
105
121
  end Reach
@@ -145,4 +145,258 @@ theorem reversal_keeps_the_residue_mod_nine_for_every_n :
145
145
  simp
146
146
  rw [h1, the_digit_sum_has_the_residue_of_the_number_mod_nine_for_every_n]
147
147
 
148
+
149
+ -- ── reflections, from the rev batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
150
+ -- ═══ REFLECTIONS ═══════════════════════════════════════════════════════════════════════════════════════
151
+ theorem digitsF_zero : ∀ f : Nat, digitsF f 0 = [] := by
152
+ intro f; cases f <;> rfl
153
+
154
+ theorem every_digit_is_below_ten : ∀ f n : Nat, ∀ d ∈ digitsF f n, d < 10 := by
155
+ intro f
156
+ induction f with
157
+ | zero => intro n d h; simp [digitsF] at h
158
+ | succ f ih =>
159
+ intro n d h
160
+ cases n with
161
+ | zero => simp [digitsF] at h
162
+ | succ m =>
163
+ simp only [digitsF, List.mem_cons] at h
164
+ rcases h with h | h
165
+ · omega
166
+ · exact ih _ _ h
167
+
168
+ -- the number rebuilt from its digits (reflection of the digit-sum law)
169
+ theorem the_digits_rebuild_the_number_when_the_fuel_covers_them :
170
+ ∀ f n : Nat, n < 10 ^ f → (digitsF f n).foldr (fun d a => a * 10 + d) 0 = n := by
171
+ intro f
172
+ induction f with
173
+ | zero =>
174
+ intro n h
175
+ have : n = 0 := by simp at h; omega
176
+ subst this
177
+ simp [digitsF]
178
+ | succ f ih =>
179
+ intro n h
180
+ cases n with
181
+ | zero => simp [digitsF]
182
+ | succ m =>
183
+ simp only [digitsF, List.foldr]
184
+ have hlt : (m + 1) / 10 < 10 ^ f := by
185
+ rw [Nat.pow_succ] at h
186
+ omega
187
+ rw [ih _ hlt]
188
+ omega
189
+
190
+ theorem the_number_is_rebuilt_from_its_digits_for_every_n :
191
+ ∀ n : Nat, (digits n).foldr (fun d a => a * 10 + d) 0 = n := by
192
+ intro n
193
+ unfold digits
194
+ split
195
+ · rename_i h
196
+ have : n = 0 := by simpa using h
197
+ subst this
198
+ rfl
199
+ · exact the_digits_rebuild_the_number_when_the_fuel_covers_them (n + 1) n (a_number_is_below_ten_to_its_own_successor n)
200
+
201
+ -- the sum does not see the order (reflection of foldl_add_start)
202
+ theorem a_sum_is_the_same_read_backwards : ∀ (l : List Nat), l.reverse.foldl (· + ·) 0 = l.foldl (· + ·) 0 := by
203
+ intro l
204
+ induction l with
205
+ | nil => rfl
206
+ | cons x xs ih =>
207
+ rw [List.reverse_cons, List.foldl_append, ih]
208
+ simp only [List.foldl]
209
+ rw [foldl_add_start xs (0 + x)]
210
+ omega
211
+
212
+ theorem the_top_digit_is_nonzero :
213
+ ∀ f n : Nat, 0 < n → n < 10 ^ f → ∃ L b, digitsF f n = L ++ [b] ∧ 0 < b ∧ b < 10 := by
214
+ intro f
215
+ induction f with
216
+ | zero => intro n h0 h; exfalso; simp at h; omega
217
+ | succ f ih =>
218
+ intro n h0 h
219
+ obtain ⟨m, rfl⟩ : ∃ m, n = m + 1 := ⟨n - 1, by omega⟩
220
+ simp only [digitsF]
221
+ by_cases hq : (m + 1) / 10 = 0
222
+ · refine ⟨[], (m + 1) % 10, ?_, by omega, by omega⟩
223
+ rw [hq, digitsF_zero]
224
+ rfl
225
+ · have hlt : (m + 1) / 10 < 10 ^ f := by
226
+ rw [Nat.pow_succ] at h
227
+ omega
228
+ obtain ⟨L, b, e, hb, hb10⟩ := ih ((m + 1) / 10) (by omega) hlt
229
+ exact ⟨(m + 1) % 10 :: L, b, by rw [e]; rfl, hb, hb10⟩
230
+
231
+ theorem reversal_leaves_no_trailing_zero : ∀ n : Nat, 0 < n → 0 < reverseNum n ∧ reverseNum n % 10 ≠ 0 := by
232
+ intro n hn
233
+ obtain ⟨L, b, e, hb, hb10⟩ := the_top_digit_is_nonzero (n + 1) n hn (a_number_is_below_ten_to_its_own_successor n)
234
+ have hd : digits n = L ++ [b] := by
235
+ unfold digits
236
+ rw [if_neg (by simp; omega)]
237
+ exact e
238
+ unfold reverseNum
239
+ rw [hd, List.foldl_append]
240
+ show 0 < (L.foldl (fun a d => a * 10 + d) 0) * 10 + b ∧ ((L.foldl (fun a d => a * 10 + d) 0) * 10 + b) % 10 ≠ 0
241
+ exact ⟨by omega, by omega⟩
242
+
243
+ theorem reading_a_list_back_from_the_top :
244
+ ∀ r : List Nat, r ≠ [] → (∀ d ∈ r, d < 10) → r.reverse.head? ≠ some 0 →
245
+ 0 < r.reverse.foldl (fun a d => a * 10 + d) 0 ∧ r.length ≤ r.reverse.foldl (fun a d => a * 10 + d) 0 ∧
246
+ ∀ f, r.length ≤ f → digitsF f (r.reverse.foldl (fun a d => a * 10 + d) 0) = r := by
247
+ intro r
248
+ induction r with
249
+ | nil => intro h; exact absurd rfl h
250
+ | cons b r' ih =>
251
+ intro _ hlt hhead
252
+ have hb : b < 10 := hlt b (List.mem_cons_self b r')
253
+ cases r' with
254
+ | nil =>
255
+ have hb0 : b ≠ 0 := by
256
+ intro e; apply hhead; simp [e]
257
+ simp only [List.reverse_cons, List.reverse_nil, List.nil_append, List.foldl, List.length_cons,
258
+ List.length_nil, Nat.zero_mul, Nat.zero_add]
259
+ refine ⟨by omega, by omega, ?_⟩
260
+ intro f hf
261
+ obtain ⟨f', rfl⟩ : ∃ f', f = f' + 1 := ⟨f - 1, by omega⟩
262
+ obtain ⟨b', rfl⟩ : ∃ b', b = b' + 1 := ⟨b - 1, by omega⟩
263
+ simp only [digitsF]
264
+ rw [show (b' + 1) / 10 = 0 by omega, show (b' + 1) % 10 = b' + 1 by omega, digitsF_zero]
265
+ | cons x xs =>
266
+ have hne : (x :: xs) ≠ [] := List.cons_ne_nil x xs
267
+ have hlt' : ∀ d ∈ (x :: xs), d < 10 := fun d hd => hlt d (List.mem_cons_of_mem b hd)
268
+ have hhead' : (x :: xs).reverse.head? ≠ some 0 := by
269
+ have hrev : (b :: x :: xs).reverse = (x :: xs).reverse ++ [b] := List.reverse_cons b (x :: xs)
270
+ rw [hrev] at hhead
271
+ cases h : (x :: xs).reverse with
272
+ | nil => simp at h
273
+ | cons y ys => rw [h] at hhead; exact hhead
274
+ obtain ⟨hpos, hlen, hdig⟩ := ih hne hlt' hhead'
275
+ rw [List.reverse_cons b (x :: xs), List.foldl_append]
276
+ simp only [List.foldl, List.length_cons] at hlen hdig ⊢
277
+ generalize (x :: xs).reverse.foldl (fun a d => a * 10 + d) 0 = v at hpos hlen hdig ⊢
278
+ refine ⟨by omega, by omega, ?_⟩
279
+ intro f hf
280
+ obtain ⟨f', rfl⟩ : ∃ f', f = f' + 1 := ⟨f - 1, by omega⟩
281
+ obtain ⟨w, hw⟩ : ∃ w, v * 10 + b = w + 1 := ⟨v * 10 + b - 1, by omega⟩
282
+ rw [hw]
283
+ simp only [digitsF]
284
+ rw [← hw, show (v * 10 + b) % 10 = b by omega, show (v * 10 + b) / 10 = v by omega, hdig f' (by omega)]
285
+
286
+ theorem the_digits_of_the_reversal_are_the_reversed_digits :
287
+ ∀ n : Nat, n % 10 ≠ 0 → digits (reverseNum n) = (digitsF (n + 1) n).reverse ∧ digits n = digitsF (n + 1) n := by
288
+ intro n h10
289
+ have hds : digits n = digitsF (n + 1) n := by
290
+ unfold digits
291
+ rw [if_neg (by simp; omega)]
292
+ have hne : digitsF (n + 1) n ≠ [] := by
293
+ obtain ⟨m, rfl⟩ : ∃ m, n = m + 1 := ⟨n - 1, by omega⟩
294
+ simp [digitsF]
295
+ have hhead : (digitsF (n + 1) n).head? = some (n % 10) := by
296
+ obtain ⟨m, rfl⟩ : ∃ m, n = m + 1 := ⟨n - 1, by omega⟩
297
+ simp [digitsF]
298
+ have hlt : ∀ d ∈ (digitsF (n + 1) n).reverse, d < 10 :=
299
+ fun d hd => every_digit_is_below_ten _ _ d (List.mem_reverse.mp hd)
300
+ have key := reading_a_list_back_from_the_top (digitsF (n + 1) n).reverse
301
+ (by simpa using hne) hlt
302
+ (by rw [List.reverse_reverse, hhead]; intro e; apply h10; exact Option.some.inj e)
303
+ rw [List.reverse_reverse] at key
304
+ obtain ⟨hpos, hlen, hdig⟩ := key
305
+ have hrn : reverseNum n = (digitsF (n + 1) n).foldl (fun a d => a * 10 + d) 0 := by
306
+ unfold reverseNum; rw [hds]
307
+ refine ⟨?_, hds⟩
308
+ unfold digits
309
+ rw [hrn, if_neg (by simp; omega)]
310
+ exact hdig _ (Nat.le_succ_of_le hlen)
311
+
312
+ -- reflection of reversal_keeps_the_residue_mod_nine_for_every_n: reversal undoes itself off the trailing zeros
313
+ theorem reversal_is_involutive_off_the_trailing_zeros_for_every_n :
314
+ ∀ n : Nat, n % 10 ≠ 0 → reverseNum (reverseNum n) = n := by
315
+ intro n h10
316
+ obtain ⟨hdrn, _⟩ := the_digits_of_the_reversal_are_the_reversed_digits n h10
317
+ show (digits (reverseNum n)).foldl (fun a d => a * 10 + d) 0 = n
318
+ rw [hdrn, List.foldl_reverse]
319
+ exact the_digits_rebuild_the_number_when_the_fuel_covers_them (n + 1) n (a_number_is_below_ten_to_its_own_successor n)
320
+
321
+ theorem reversal_is_involutive_exactly_off_the_trailing_zeros_for_every_n :
322
+ ∀ n : Nat, 0 < n → (reverseNum (reverseNum n) = n ↔ n % 10 ≠ 0) := by
323
+ intro n hn
324
+ constructor
325
+ · intro e h0
326
+ obtain ⟨hp, _⟩ := reversal_leaves_no_trailing_zero n hn
327
+ obtain ⟨_, hz⟩ := reversal_leaves_no_trailing_zero (reverseNum n) hp
328
+ rw [e] at hz
329
+ exact hz h0
330
+ · exact reversal_is_involutive_off_the_trailing_zeros_for_every_n n
331
+
332
+ -- more fuel changes nothing once it covers the number
333
+ theorem more_fuel_changes_no_digit : ∀ f n k : Nat, n < 10 ^ f → digitsF (f + k) n = digitsF f n := by
334
+ intro f
335
+ induction f with
336
+ | zero =>
337
+ intro n k h
338
+ have : n = 0 := by simp at h; omega
339
+ subst this
340
+ rw [digitsF_zero, digitsF_zero]
341
+ | succ f ih =>
342
+ intro n k h
343
+ cases n with
344
+ | zero => rw [digitsF_zero, digitsF_zero]
345
+ | succ m =>
346
+ rw [show f + 1 + k = (f + k) + 1 by omega]
347
+ simp only [digitsF]
348
+ have hlt : (m + 1) / 10 < 10 ^ f := by
349
+ rw [Nat.pow_succ] at h
350
+ omega
351
+ rw [ih _ k hlt]
352
+
353
+ theorem a_trailing_zero_is_a_leading_zero_of_the_digits :
354
+ ∀ m : Nat, 0 < m → digits (10 * m) = 0 :: digits m := by
355
+ intro m hm
356
+ unfold digits
357
+ rw [if_neg (by simp; omega), if_neg (by simp; omega)]
358
+ obtain ⟨p, hp⟩ : ∃ p, 10 * m = p + 1 := ⟨10 * m - 1, by omega⟩
359
+ rw [show 10 * m + 1 = (10 * m) + 1 from rfl, hp]
360
+ simp only [digitsF]
361
+ rw [← hp, show 10 * m % 10 = 0 by omega, show 10 * m / 10 = m by omega,
362
+ show 10 * m = (m + 1) + (9 * m - 1) by omega,
363
+ more_fuel_changes_no_digit (m + 1) m (9 * m - 1) (a_number_is_below_ten_to_its_own_successor m)]
364
+
365
+ -- reversal_preserves_digit_sum was decided for 1 ≤ n < 300; for every n:
366
+ theorem reversal_preserves_the_digit_sum_for_every_n : ∀ n : Nat, digitSum (reverseNum n) = digitSum n := by
367
+ intro n
368
+ induction n using Nat.strongRecOn with
369
+ | _ n ih =>
370
+ by_cases h0 : n = 0
371
+ · subst h0; rfl
372
+ by_cases h10 : n % 10 = 0
373
+ · obtain ⟨m, rfl⟩ : ∃ m, n = 10 * m := ⟨n / 10, by omega⟩
374
+ have hm : 0 < m := by omega
375
+ have hd := a_trailing_zero_is_a_leading_zero_of_the_digits m hm
376
+ have hr : reverseNum (10 * m) = reverseNum m := by
377
+ unfold reverseNum; rw [hd]; rfl
378
+ have hs : digitSum (10 * m) = digitSum m := by
379
+ unfold digitSum; rw [hd]; rfl
380
+ rw [hr, hs]
381
+ exact ih m (by omega)
382
+ · obtain ⟨hdrn, hds⟩ := the_digits_of_the_reversal_are_the_reversed_digits n h10
383
+ unfold digitSum
384
+ rw [hdrn, hds, a_sum_is_the_same_read_backwards]
385
+
386
+ -- palindromes_are_the_fixed_points counted them below 100; for every n without a trailing zero:
387
+ -- the fixed points of the reversal are exactly the numbers whose digits read the same both ways
388
+ theorem the_fixed_points_of_reversal_are_the_palindromes_for_every_n :
389
+ ∀ n : Nat, n % 10 ≠ 0 → (reverseNum n = n ↔ (digits n).reverse = digits n) := by
390
+ intro n h10
391
+ obtain ⟨hdrn, hds⟩ := the_digits_of_the_reversal_are_the_reversed_digits n h10
392
+ constructor
393
+ · intro e
394
+ have := congrArg digits e
395
+ rw [hdrn, ← hds] at this
396
+ exact this
397
+ · intro p
398
+ have hd : digits (reverseNum n) = digits n := by rw [hdrn, ← hds, p]
399
+ rw [← the_number_is_rebuilt_from_its_digits_for_every_n (reverseNum n), hd,
400
+ the_number_is_rebuilt_from_its_digits_for_every_n]
401
+
148
402
  end Reversal
@@ -216,4 +216,69 @@ theorem thue_morse_doubling_recurrence_for_every_n : ∀ n : Nat, tm (2 * n) = t
216
216
  rw [doubling_preserves_the_bit_count_for_every_n, the_odd_step_sets_exactly_one_further_bit_for_every_n]
217
217
  exact ⟨rfl, by omega⟩
218
218
 
219
+
220
+ -- ── reflections, from the bits batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
221
+ -- REFLECTION of doubling_preserves_the_bit_count / the_odd_step_sets_exactly_one_further_bit:
222
+ -- halving removes exactly the low bit, for every n
223
+ theorem halving_removes_exactly_the_low_bit_for_every_n : ∀ n : Nat, popcount n = n % 2 + popcount (n / 2) := by
224
+ intro n
225
+ cases n with
226
+ | zero => rfl
227
+ | succ m =>
228
+ unfold popcount
229
+ rw [the_bits_of_a_number_are_its_low_bit_then_the_bits_of_its_half (m + 1) (m + 1)]
230
+ have hlt := a_number_is_below_two_to_its_own_successor ((m + 1) / 2)
231
+ rw [show List.range (m + 1) = List.range ((m + 1) / 2 + 1 + (m - (m + 1) / 2)) by congr 1; omega,
232
+ bits_above_the_number_add_nothing (m - (m + 1) / 2) ((m + 1) / 2 + 1) ((m + 1) / 2) hlt]
233
+
234
+ theorem the_thue_morse_halving_recurrence_for_every_n : ∀ n : Nat, tm n = (n % 2 + tm (n / 2)) % 2 := by
235
+ intro n
236
+ unfold tm
237
+ rw [halving_removes_exactly_the_low_bit_for_every_n n]
238
+ omega
239
+
240
+ -- REFLECTION of halving_shifts_every_bit_down_by_one: doubling shifts every bit up by one
241
+ theorem doubling_shifts_every_bit_up_by_one : ∀ m i : Nat, 2 * m / 2 ^ (i + 1) = m / 2 ^ i := by
242
+ intro m i
243
+ rw [Nat.pow_succ, Nat.mul_comm (2 ^ i) 2, ← Nat.div_div_eq_div_mul, Nat.mul_div_cancel_left _ (by decide)]
244
+
245
+ -- core's Nat.mod_pow_succ carries Classical.choice, so the one step it gives is proved here by hand
246
+ theorem the_residue_below_the_next_power_adds_one_bit :
247
+ ∀ m F : Nat, m % 2 ^ (F + 1) = m % 2 ^ F + m / 2 ^ F % 2 * 2 ^ F := by
248
+ intro m F
249
+ have hP : 0 < 2 ^ F := Nat.lt_of_le_of_lt (Nat.zero_le F) (a_number_is_below_two_to_its_own_power F)
250
+ have e1 := Nat.div_add_mod m (2 ^ F)
251
+ have e2 := Nat.div_add_mod (m / 2 ^ F) 2
252
+ have hr : m % 2 ^ F < 2 ^ F := Nat.mod_lt _ hP
253
+ have hb : m / 2 ^ F % 2 < 2 := Nat.mod_lt _ (by decide)
254
+ rw [Nat.pow_succ]
255
+ generalize m / 2 ^ F / 2 = s at e2
256
+ generalize m / 2 ^ F % 2 = t at e2 hb ⊢
257
+ generalize m / 2 ^ F = q at e1 e2
258
+ generalize m % 2 ^ F = r at e1 hr ⊢
259
+ generalize 2 ^ F = P at hP e1 hr ⊢
260
+ subst e2
261
+ rw [← e1, show P * (2 * s + t) + r = (r + t * P) + P * 2 * s by
262
+ rw [Nat.mul_add, Nat.mul_comm P t, ← Nat.mul_assoc]; omega]
263
+ rw [Nat.add_mul_mod_self_left]
264
+ have htP : t * P ≤ P := by
265
+ rcases (by omega : t = 0 ∨ t = 1) with h | h <;> subst h <;> omega
266
+ exact Nat.mod_eq_of_lt (by omega)
267
+
268
+ -- REFLECTION of the_bits_of_a_number…: the number is rebuilt from its bits
269
+ theorem the_low_bits_rebuild_the_number_below_every_power :
270
+ ∀ F m : Nat, (List.range F).foldl (fun a i => a + m / 2 ^ i % 2 * 2 ^ i) 0 = m % 2 ^ F := by
271
+ intro F m
272
+ induction F with
273
+ | zero => show 0 = m % 1; rw [Nat.mod_one]
274
+ | succ F ih =>
275
+ rw [List.range_succ, List.foldl_append, ih]
276
+ simp only [List.foldl]
277
+ rw [the_residue_below_the_next_power_adds_one_bit]
278
+
279
+ theorem the_number_is_rebuilt_from_its_bits_for_every_n :
280
+ ∀ n : Nat, (List.range (n + 1)).foldl (fun a i => a + n / 2 ^ i % 2 * 2 ^ i) 0 = n := by
281
+ intro n
282
+ rw [the_low_bits_rebuild_the_number_below_every_power, Nat.mod_eq_of_lt (a_number_is_below_two_to_its_own_successor n)]
283
+
219
284
  end Sequences
@@ -149,4 +149,10 @@ theorem hexbits_are_slower_and_the_ratio_multiplies_back :
149
149
  -- encoding changes how many characters carry a value, not how many operations are performed. §7 above proves
150
150
  -- the operation-count claim; the two theorems above prove the width and the cost. Nothing was lost.
151
151
 
152
+
153
+ -- ── reflections, from the easy batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
154
+ theorem the_nanoseconds_return_from_the_microseconds_at_every_whole_count :
155
+ ∀ n : Nat, n % 1000 = 0 → n / 1000 * 1000 = n := by
156
+ intro n h; omega
157
+
152
158
  end Speed
@@ -196,4 +196,14 @@ theorem the_coin_step_and_the_coins_are_inverse_for_every_c :
196
196
  intro c
197
197
  exact ⟨Nat.mul_div_cancel_left c (by decide), Nat.mul_mod_right 3 c⟩
198
198
 
199
+
200
+ -- ── reflections, from the easy batch: each law beside its inverse (the 2×7 ↔ 1+6 wave) ──
201
+ theorem the_coins_return_from_the_coin_step_for_every_multiple_of_three :
202
+ ∀ t : Nat, t % 3 = 0 → 3 * (t / 3) = t := by
203
+ intro t h; omega
204
+
205
+ theorem paying_and_refunding_round_trips_for_every_count :
206
+ ∀ n k : Nat, k ≤ n → 3 * (n - k) + 3 * k = 3 * n := by
207
+ intro n k h; omega
208
+
199
209
  end Split