The proof
Green's open problem 40 - f two eq one
It is not known whether f(2) = 1 [Gr24]Source
Main.lean · 1028 lines · 39.1 kB
/-!
# Green 40: binary linear covering density at radius two
Complete Conjectures.io submission body. The challenge supplies the imports
`FormalConjectures.GreensOpenProblems.«40»`, `TaskSupport`, and the surrounding
`namespace Bounty`. Submit this entire file as the proof body.
Pinned formal-conjectures commit: 8432eac998110a563e03df65a28c117e97c8c142.
Lean: 4.33.1. Mathlib: 0df444a360eaa60ab8c11dca51a86af692955474.
This follows the supplied proof's quadratic-map induction, graph repair, and
parity-check construction. Two equivalent simplifications are used:
* Finite interpolation uses the F-linear operator
`D(t)(r,j) = r*t(r,j) + sum_s t(s,j)` on `F -> Coord(H) -> F`.
The equation `(D + rho)t = inc(h)` forces `t` to be supported at `rho`,
with value `h` in binary coordinates. Thus projection away from coordinate
zero gives exactly the interpolation identity required by the induction.
This replaces multiplication by delta in an extension field and has the
same binary dimension as that extension-field construction.
* The induction starts one step earlier, with a one-dimensional binary
domain and zero-dimensional codomain. The first doubling gives the
two-dimensional quadratic map with polar determinant. Codes include a
zero column, and union cardinalities are bounded above. The resulting
bound `1 + 10 / 2^(c/2)` suffices for the same limit.
The sphere-covering lower bound is included from the published contribution:
https://github.com/conjectures-io/conjectures-contribution/tree/main/contributions/green-40-f-two-eq-one/61648655993994f3bfd0ae9b44322f5541653c3d63d5c284213e49162addebe5
-/
/- Binary quadratic maps and a finite interpolation operator for Green 40. -/
noncomputable section
open Filter Finset
open scoped ENNReal Pointwise
namespace Green40Proof
abbrev B := ZMod 2
theorem binary_cases (a : B) : a = 0 ∨ a = 1 := by
fin_cases a
· exact Or.inl rfl
· exact Or.inr rfl
section Binary
variable {M : Type*} [AddCommGroup M] [Module B M]
theorem twice (x : M) : x + x = 0 := by
have h : (2 : B) = 0 := by decide
simpa only [two_smul, zero_smul] using congrArg (fun a : B => a • x) h
theorem neg_binary (x : M) : -x = x := by
apply neg_eq_of_add_eq_zero_left
exact twice x
theorem sub_binary (x y : M) : x - y = x + y := by simp [neg_binary, sub_eq_add_neg]
end Binary
section Polar
variable {V H : Type*} [AddCommGroup V] [Module B V]
[AddCommGroup H] [Module B H]
def bp (Q : V → H) (a x : V) : H := Q (a + x) + Q a + Q x
theorem bp_comm (Q : V → H) (a x : V) : bp Q a x = bp Q x a := by
unfold bp
rw [add_comm a x]
abel
theorem bp_zero (Q : V → H) (h0 : Q 0 = 0) (a : V) : bp Q a 0 = 0 := by
simp [twice, bp, h0]
theorem bp_self (Q : V → H) (h0 : Q 0 = 0) (a : V) : bp Q a a = 0 := by
simp [twice, bp, h0]
def IsQuadratic (Q : V → H) : Prop :=
Q 0 = 0 ∧ ∀ a x y, bp Q a (x + y) = bp Q a x + bp Q a y
def derivative (Q : V → H) (hq : IsQuadratic Q) (a : V) : V →ₗ[B] H :=
AddMonoidHom.toZModLinearMap 2
{ toFun := bp Q a
map_zero' := bp_zero Q hq.1 a
map_add' := hq.2 a }
theorem derivative_apply (Q : V → H) (hq : IsQuadratic Q) (a x : V) :
derivative Q hq a x = bp Q a x := rfl
variable {V' : Type*} [AddCommGroup V'] [Module B V']
theorem bp_comp (Q : V → H) (E : V' →ₗ[B] V) (a x : V') :
bp (fun y => Q (E y)) a x = bp Q (E a) (E x) := by
simp [bp]
theorem quadratic_comp (Q : V → H) (hq : IsQuadratic Q) (E : V' →ₗ[B] V) :
IsQuadratic (fun y => Q (E y)) := by
exact ⟨by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply] using hq.1, by intros; simp only [bp_comp, map_add, hq.2]⟩
end Polar
section Interpolation
variable (F : Type*) [Field F] [Algebra B F] [Fintype F] [DecidableEq F]
(H : Type*) [AddCommGroup H] [Module B H] [Finite H]
abbrev Coord := Fin (Module.finrank B H)
abbrev Z := F → Coord H → F
noncomputable def coords : H ≃ₗ[B] (Coord H → B) :=
(Module.finBasis B H).equivFun
noncomputable def inc : H →ₗ[B] Z F H :=
{ toFun := fun h _ j => algebraMap B F (coords H h j)
map_add' := by intros; ext; simp
map_smul' := by intros; ext; simp [Algebra.smul_def] }
noncomputable def delta : Z F H →ₗ[F] Z F H :=
{ toFun := fun t r j => r * t r j + ∑ s, t s j
map_add' := by intros; ext; simp [mul_add, Finset.sum_add_distrib]; ring
map_smul' := by
intro m t
ext r j
change r * (m * t r j) + (∑ s, m * t s j) = m * (r * t r j + ∑ s, t s j)
rw [mul_add, Finset.mul_sum]
ring }
noncomputable def project (l : F →ₗ[B] B) : Z F H →ₗ[B] H :=
(coords H).symm.toLinearMap.comp
({
toFun := fun t j => l (∑ r ∈ Finset.univ.erase 0, t r j)
map_add' := by intros; ext; simp [Finset.sum_add_distrib]
map_smul' := by
intro a t
ext j
change l (∑ r ∈ Finset.univ.erase 0, a • t r j) =
a • l (∑ r ∈ Finset.univ.erase 0, t r j)
rw [← Finset.smul_sum]
exact l.map_smul a _ } : Z F H →ₗ[B] (Coord H → B))
theorem interp_support (r : F) (t : Z F H) (h : H)
(heq : delta F H t + r • t = inc F H h) :
t = fun s j => if s = r then algebraMap B F (coords H h j) else 0 := by
classical
have hsum (j : Coord H) : (∑ s, t s j) = algebraMap B F (coords H h j) := by
have := congrFun (congrFun heq r) j
dsimp [delta, inc] at this
have hz : r * t r j + r * t r j = 0 := twice _
linear_combination this - hz
have hout (s : F) (hs : s ≠ r) (j : Coord H) : t s j = 0 := by
have hh := congrFun (congrFun heq s) j
dsimp [delta, inc] at hh
rw [hsum] at hh
have hz : (s + r) * t s j = 0 := by linear_combination hh
exact (mul_eq_zero.mp hz).resolve_left (by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, ← sub_binary] using sub_ne_zero.mpr hs)
ext s j
split_ifs with hs
· subst s
have hh := hsum j
rw [Finset.sum_eq_single r] at hh
· exact hh
· intro b _ hb
exact hout b hb j
· simp
· exact hout s hs j
theorem interp_project (l : F →ₗ[B] B) (hl : l 1 = 1)
(r : F) (t : Z F H) (h : H)
(heq : delta F H t + r • t = inc F H h) :
project F H l t = if r = 0 then 0 else h := by
classical
have hlift (b : B) : l (algebraMap B F b) = b := by
have := l.map_smul b (1 : F)
simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, Algebra.smul_def, hl] using this
rw [interp_support F H r t h heq]
apply (coords H).injective
ext j
simp only [project, LinearMap.comp_apply, LinearEquiv.coe_coe,
LinearEquiv.apply_symm_apply]
by_cases hr : r = 0
· subst r
simp [apply_ite, hlift]
· simp [apply_ite, hr, Ne.symm hr, hlift]
theorem interp_injective (r : F) (t : Z F H)
(heq : delta F H t + r • t = 0) : t = 0 := by
have hh := interp_support F H r t 0 (by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply] using heq)
rw [hh]
ext s j
simp
end Interpolation
end Green40Proof
end
/- The doubling construction for binary quadratic maps. -/
noncomputable section
namespace Green40Proof
section Lift
variable {F K H T : Type*} [Field F] [Algebra B F] [DecidableEq F]
[AddCommGroup K] [Module B K]
[AddCommGroup H] [Module B H]
[AddCommGroup T] [Module F T] [Module B T] [IsScalarTower B F T]
variable (Q : F × K → H) (I : H →ₗ[B] T) (P : T →ₗ[B] H) (D : T →ₗ[F] T)
def liftQ (x : (F × F) × (K × T)) : F × (H × T) :=
(x.1.1 * x.1.2,
(Q (x.1.1, x.2.1) + Q (x.1.2, x.2.1) + P (x.1.2 • x.2.2),
x.1.1 • x.2.2 + D (x.1.2 • x.2.2) + I (Q (x.1.2, x.2.1))))
theorem lift_polar (a b u v : F) (z w : K) (s t : T) :
bp (liftQ Q I P D) ((a,b),(z,s)) ((u,v),(w,t)) =
(a*v+b*u,
(bp Q (a,z) (u,w) + bp Q (b,z) (v,w) + P (b • t + v • s),
a • t + u • s + D (b • t + v • s) + I (bp Q (b,z) (v,w)))) := by
unfold bp liftQ
simp only [Prod.fst_add, Prod.snd_add, Prod.mk_add_mk,
add_smul, smul_add, map_add]
apply Prod.ext
· dsimp
have hchar : (2 : F) = 0 := by
simpa only [one_add_one_eq_two] using twice (1 : F)
linear_combination (a*b+u*v)*hchar
· apply Prod.ext
· dsimp
abel_nf
simp only [two_smul ℤ, twice, zero_add, add_zero]
· dsimp
abel_nf
simp only [two_smul ℤ, twice, zero_add, add_zero]
theorem lift_zero (hzero : ∀ z, Q (0,z) = 0) (z : K) (t : T) :
liftQ Q I P D ((0,0),(z,t)) = 0 := by
simp [twice, liftQ, hzero]
theorem lift_quadratic (hq : IsQuadratic Q) : IsQuadratic (liftQ Q I P D) := by
constructor
· simp [twice, liftQ, show Q (0,0) = 0 from hq.1]
· rintro ⟨⟨a,b⟩,z,s⟩ ⟨⟨u,v⟩,w,t⟩ ⟨⟨u',v'⟩,w',t'⟩
have hq1 := hq.2 (a,z) (u,w) (u',w')
have hq2 := hq.2 (b,z) (v,w) (v',w')
simp only [Prod.mk_add_mk] at hq1 hq2
simp only [Prod.mk_add_mk, lift_polar, hq1, hq2,
add_smul, smul_add, map_add, mul_add, add_mul]
apply Prod.ext
· dsimp; ring
· apply Prod.ext <;> dsimp <;> abel
variable (hzero : ∀ z, Q (0,z) = 0)
(hgood : ∀ a z u w, a ≠ 0 → bp Q (a,z) (u,w) = 0 →
(u,w) = 0 ∨ (u,w) = (a,z))
(hinterp : ∀ (r : F) (t : T) (h : H), D t + r • t = I h →
P t = if r = 0 then 0 else h)
(hinj : ∀ (r : F) (t : T), D t + r • t = 0 → t = 0)
include hzero hgood hinterp hinj
theorem lift_kernel (a b u v : F) (z w : K) (s t : T)
(hab : a ≠ 0 ∨ b ≠ 0)
(h : bp (liftQ Q I P D) ((a,b),(z,s)) ((u,v),(w,t)) = 0) :
((u,v),(w,t)) = 0 ∨ ((u,v),(w,t)) = ((a,b),(z,s)) := by
rw [lift_polar] at h
have h1 : a*v+b*u = 0 := congrArg Prod.fst h
have h2 : bp Q (a,z) (u,w) + bp Q (b,z) (v,w) + P (b • t + v • s) = 0 :=
congrArg (fun x => x.2.1) h
have h3 : a • t + u • s + D (b • t + v • s) + I (bp Q (b,z) (v,w)) = 0 :=
congrArg (fun x => x.2.2) h
have hq0 : Q 0 = 0 := hzero 0
by_cases hb : b = 0
· subst b
have ha := hab.resolve_right (by simp)
have hv : v = 0 := (mul_eq_zero.mp (by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply] using h1)).resolve_left ha
subst v
have hY : bp Q (0,z) (0,w) = 0 := by simp [twice, bp, hzero]
have hX : bp Q (a,z) (u,w) = 0 := by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, hY] using h2
rcases hgood a z u w ha hX with hh | hh
· have hu : u = 0 := congrArg Prod.fst hh
have hw : w = 0 := congrArg Prod.snd hh
subst u; subst w
have ht : t = 0 := (smul_eq_zero.mp (by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, hY] using h3)).resolve_left ha
simp [ht]
· have hu : u = a := congrArg Prod.fst hh
have hw : w = z := congrArg Prod.snd hh
subst u; subst w
have ht : t = s := by
have hs : a • (t + s) = 0 := by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, smul_add, hY] using h3
have := (smul_eq_zero.mp hs).resolve_left ha
simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply] using (eq_neg_of_add_eq_zero_left this)
simp [ht]
· have hu : u = (a / b) * v := by
have hh : b*u = a*v := by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply] using eq_neg_of_add_eq_zero_right h1
field_simp
linear_combination hh
have hR : D (b • t + v • s) + (a / b) • (b • t + v • s) =
I (bp Q (b,z) (v,w)) := by
have hh := eq_neg_of_add_eq_zero_left h3
simp only [neg_binary] at hh
rw [smul_add, ← mul_smul, div_mul_cancel₀ _ hb, ← mul_smul, ← hu]
simpa only [add_comm, add_left_comm, add_assoc] using hh
have hPR := hinterp (a / b) (b • t + v • s) (bp Q (b,z) (v,w)) hR
have hcases : ((u,w) = 0 ∨ (u,w) = (a,z)) ∧ a ≠ 0 ∨
((v,w) = 0 ∨ (v,w) = (b,z)) ∧ a = 0 := by
by_cases ha : a = 0
· right
have hu0 : u = 0 := by simp [ha] at hu; exact hu
have hX : bp Q (a,z) (u,w) = 0 := by simp [twice, ha, hu0, bp, hzero]
have hY : bp Q (b,z) (v,w) = 0 := by
rw [hX, hPR] at h2
simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, ha] using h2
exact ⟨hgood b z v w hb hY, ha⟩
· left
have hX : bp Q (a,z) (u,w) = 0 := by
simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, hPR, div_ne_zero ha hb, add_assoc] using h2
exact ⟨hgood a z u w ha hX, ha⟩
have huv : (u = 0 ∧ v = 0 ∧ w = 0) ∨ (u = a ∧ v = b ∧ w = z) := by
rcases hcases with ⟨hh,ha⟩ | ⟨hh,ha⟩
· rcases hh with hh | hh
· have hu0 : u = 0 := congrArg Prod.fst hh
have hw : w = 0 := congrArg Prod.snd hh
have hv : v = 0 := (mul_eq_zero.mp (by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, hu0] using h1)).resolve_left ha
exact Or.inl ⟨hu0,hv,hw⟩
· have hua : u = a := congrArg Prod.fst hh
have hw : w = z := congrArg Prod.snd hh
have hv : v = b := by
have he : a * (v + b) = 0 := by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, mul_add, hua, mul_comm b a] using h1
simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply] using eq_neg_of_add_eq_zero_left ((mul_eq_zero.mp he).resolve_left ha)
exact Or.inr ⟨hua,hv,hw⟩
· rcases hh with hh | hh
· have hv : v = 0 := congrArg Prod.fst hh
have hw : w = 0 := congrArg Prod.snd hh
exact Or.inl ⟨by simp [hv] at hu; exact hu, hv, hw⟩
· have hv : v = b := congrArg Prod.fst hh
have hw : w = z := congrArg Prod.snd hh
exact Or.inr ⟨by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, hv, hb] using hu, hv, hw⟩
clear hu
rcases huv with ⟨hu0,hv0,hw0⟩ | ⟨hua,hvb,hwz⟩
· subst u; subst v; subst w
have hRt : b • t = 0 := hinj (a/b) (b • t) (by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, bp, hzero] using hR)
have ht : t = 0 := (smul_eq_zero.mp hRt).resolve_left hb
simp [ht]
· subst u; subst v; subst w
have hRt : b • t + b • s = 0 := hinj (a/b) (b • t + b • s)
(by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, bp_self Q hq0] using hR)
have ht : t = s := by
rw [← smul_add] at hRt
simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply] using eq_neg_of_add_eq_zero_left ((smul_eq_zero.mp hRt).resolve_left hb)
simp [ht]
end Lift
end Green40Proof
end
/- Iterating the doubling construction. -/
noncomputable section
namespace Green40Proof
abbrev GF (c : ℕ) := GaloisField 2 c
abbrev BV (n : ℕ) := Fin n → B
structure Model (c : ℕ) where
K : Type
H : Type
[addK : AddCommGroup K]
[modK : Module B K]
[finK : Finite K]
[addH : AddCommGroup H]
[modH : Module B H]
[finH : Finite H]
Q : GF c × K → H
quadratic : IsQuadratic Q
zero : ∀ z, Q (0,z) = 0
good : ∀ a z u w, a ≠ 0 → bp Q (a,z) (u,w) = 0 →
(u,w) = 0 ∨ (u,w) = (a,z)
dim : Module.finrank B H + 1 = c + Module.finrank B K
def Model.step {c : ℕ} (hc : c ≠ 0) (M : Model c) : Model (c+c) := by
letI := M.addK
letI := M.modK
letI := M.finK
letI := M.addH
letI := M.modH
letI := M.finH
letI : DecidableEq (GF c) := Classical.decEq _
letI : Fintype (GF c) := Fintype.ofFinite _
let E : GF (c+c) ≃ₗ[B] (GF c × GF c) :=
LinearEquiv.ofFinrankEq _ _ (by
rw [GaloisField.finrank 2 (by omega), Module.finrank_prod,
GaloisField.finrank 2 hc])
have hex := Module.Projective.exists_dual_eq_one B (one_ne_zero : (1 : GF c) ≠ 0)
let l := Classical.choose hex
have hl := Classical.choose_spec hex
let I := inc (GF c) M.H
let P := project (GF c) M.H l
let D := delta (GF c) M.H
let R := liftQ M.Q I P D
let L : (GF (c+c) × (M.K × Z (GF c) M.H)) ≃ₗ[B]
((GF c × GF c) × (M.K × Z (GF c) M.H)) :=
E.prodCongr (LinearEquiv.refl B _)
refine {
K := M.K × Z (GF c) M.H
H := GF c × (M.H × Z (GF c) M.H)
Q := fun x => R (L x)
quadratic := quadratic_comp R (lift_quadratic M.Q I P D M.quadratic) L.toLinearMap
zero := ?_
good := ?_
dim := ?_ }
· rintro ⟨z,t⟩
change liftQ M.Q I P D ((E 0),(z,t)) = 0
rw [map_zero]
exact lift_zero M.Q I P D M.zero z t
· rintro a ⟨z,s⟩ u ⟨w,t⟩ ha hh
have he : (E a).1 ≠ 0 ∨ (E a).2 ≠ 0 := by
by_contra hn
push Not at hn
apply ha
apply E.injective
exact (Prod.ext hn.1 hn.2).trans (map_zero E).symm
have hh' : bp R ((E a),(z,s)) ((E u),(w,t)) = 0 := by
change bp (fun x => R (L.toLinearMap x)) (a,(z,s)) (u,(w,t)) = 0 at hh
rw [bp_comp] at hh
exact hh
have hk := lift_kernel M.Q I P D M.zero M.good
(interp_project (GF c) M.H l hl) (interp_injective (GF c) M.H)
(E a).1 (E a).2 (E u).1 (E u).2 z w s t he hh'
rcases hk with hk | hk
· left
apply L.injective
simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, L] using hk
· right
apply L.injective
simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, L] using hk
· simp only [Module.finrank_prod, GaloisField.finrank 2 hc]
have := M.dim
omega
def baseModel : Model 1 := by
let E : GF 1 ≃ₗ[B] B := LinearEquiv.ofFinrankEq _ _ (by
simp [GaloisField.finrank])
refine {
K := BV 0
H := BV 0
Q := fun _ => 0
quadratic := by constructor <;> simp [twice, bp]
zero := by simp
good := ?_
dim := by simp [BV] }
intro a z u w ha _
have he : E a = 1 := (binary_cases (E a)).resolve_left (by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply] using ha)
rcases binary_cases (E u) with hu | hu
· left
apply Prod.ext
· exact E.injective (by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply] using hu)
· exact Subsingleton.elim _ _
· right
apply Prod.ext
· exact E.injective (hu.trans he.symm)
· exact Subsingleton.elim _ _
def models : (r : ℕ) → Model (2 ^ r)
| 0 => baseModel
| r+1 => by
simpa only [pow_succ, mul_two] using (models r).step (by positivity)
end Green40Proof
end
/- A sum basis gives a binary linear covering code, with an explicit density bound. -/
noncomputable section
open Finset
open scoped ENNReal Pointwise
namespace Green40Proof
theorem binary_support_injective (n : ℕ) :
Function.Injective (fun x : 𝔽₂ n => Finset.univ.filter (fun i => x i ≠ 0)) := by
intro x y h
funext i
have hi : x i = 0 ↔ y i = 0 := by
have := Finset.ext_iff.mp h i
simpa only [mem_filter, mem_univ, true_and, not_iff_not] using this
have bx : x i = 0 ∨ x i = 1 := binary_cases (x i)
have by' : y i = 0 ∨ y i = 1 := binary_cases (y i)
rcases bx with hx | hx <;> rcases by' with hy | hy <;> simp_all
theorem hammingBall_card_bound (n : ℕ) :
2 * Nat.card (Green40.hammingBall n 2) ≤ n*n+n+2 := by
let A : Finset (Finset (Fin n)) :=
(Finset.univ.powersetCard 0 ∪ Finset.univ.powersetCard 1) ∪ Finset.univ.powersetCard 2
have hsupport (x : Green40.hammingBall n 2) :
Finset.univ.filter (fun i => x.1 i ≠ 0) ∈ A := by
have hx := x.2
change (Finset.univ.filter (fun i => x.1 i ≠ 0)).card ≤ 2 at hx
simp only [A, mem_union, mem_powersetCard, subset_univ, true_and]
omega
let f : Green40.hammingBall n 2 → A :=
fun x => ⟨Finset.univ.filter (fun i => x.1 i ≠ 0), hsupport x⟩
have hinj : Function.Injective f := by
intro x y h
apply Subtype.ext
exact binary_support_injective n (congrArg Subtype.val h)
have h1 : Nat.card (Green40.hammingBall n 2) ≤ A.card := by
simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply] using Nat.card_le_card_of_injective f hinj
have h2 : A.card ≤ 1+n+n.choose 2 := by
have hh := (Finset.card_union_le (α := Finset (Fin n))
(Finset.univ.powersetCard 0 ∪ Finset.univ.powersetCard 1)
(Finset.univ.powersetCard 2)).trans
(Nat.add_le_add_right (Finset.card_union_le
(Finset.univ.powersetCard 0) (Finset.univ.powersetCard 1)) _)
simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, A] using hh
have h3 : 2 * n.choose 2 ≤ n * (n-1) := by
rw [Nat.choose_two_right]
omega
have h4 : n * (n-1) + n = n*n := by
cases n with
| zero => simp
| succ k => simp; ring
omega
theorem hammingNorm_add_le {n : ℕ} (x y : 𝔽₂ n) :
hammingNorm (x+y) ≤ hammingNorm x + hammingNorm y := by
apply (Finset.card_le_card (s := Finset.univ.filter (fun i => (x+y) i ≠ 0))
(t := (Finset.univ.filter (fun i => x i ≠ 0)) ∪
(Finset.univ.filter (fun i => y i ≠ 0))) ?_).trans (Finset.card_union_le _ _)
intro i hi
simp only [mem_filter, mem_univ, true_and, mem_union, Pi.add_apply] at *
by_contra hn
push Not at hn
simp [twice, hn] at hi
theorem hammingNorm_single_le {n : ℕ} (i : Fin n) :
hammingNorm (Pi.single i (1 : B) : 𝔽₂ n) ≤ 1 := by
unfold hammingNorm
calc
(Finset.univ.filter (fun j => (Pi.single i (1 : B) : 𝔽₂ n) j ≠ 0)).card
≤ ({i} : Finset (Fin n)).card := Finset.card_le_card (by
intro j hj
simp only [mem_filter, mem_univ, true_and] at hj
by_contra hn
have hji : j ≠ i := by simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply] using hn
simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, Pi.single_apply, hji, Ne.symm hji] using hj)
_ = 1 := by simp
section Code
variable {G : Type*} [AddCommGroup G] [Module B G] [Finite G]
(S : Finset G)
(hS : ∀ g : G, ∃ a ∈ S, ∃ b ∈ S, a+b=g)
def columns : Fin S.card → G :=
fun i => ((Fintype.equivFinOfCardEq (by simp : Fintype.card S = S.card)).symm i).1
theorem columns_surjective (a : S) : ∃ i, columns S i = a.1 := by
use (Fintype.equivFinOfCardEq (by simp : Fintype.card S = S.card)) a
simp [columns]
def parity : 𝔽₂ S.card →ₗ[B] G :=
{ toFun := fun x => ∑ i, x i • columns S i
map_add' := by intros; simp [add_smul, Finset.sum_add_distrib]
map_smul' := by intros; simp [Finset.smul_sum, smul_smul] }
theorem parity_single (i : Fin S.card) :
parity S (Pi.single i (1 : B)) = columns S i := by
simp [parity, Pi.single_apply, ite_smul]
include hS
theorem syndrome_small (g : G) : ∃ x : 𝔽₂ S.card,
hammingNorm x ≤ 2 ∧ parity S x = g := by
obtain ⟨a,ha,b,hb,hab⟩ := hS g
obtain ⟨i,hi⟩ := columns_surjective S ⟨a,ha⟩
obtain ⟨j,hj⟩ := columns_surjective S ⟨b,hb⟩
refine ⟨Pi.single i 1 + Pi.single j 1, ?_, ?_⟩
· exact (hammingNorm_add_le _ _).trans (by
have := hammingNorm_single_le i
have := hammingNorm_single_le j
omega)
· simp [parity_single, hi,hj,hab]
theorem parity_surjective : Function.Surjective (parity S) := by
intro g
obtain ⟨x,_,hx⟩ := syndrome_small S hS g
exact ⟨x,hx⟩
theorem parity_cover : Green40.IsCoveringSubspace S.card 2 (parity S).ker := by
apply Set.eq_univ_of_forall
intro x
obtain ⟨e,he,hxe⟩ := syndrome_small S hS (parity S x)
refine ⟨x-e, ?_, e, he, sub_add_cancel _ _⟩
change parity S (x-e) = 0
simp [hxe]
theorem parity_card : Nat.card (parity S).ker * Nat.card G = 2 ^ S.card := by
have hr := (parity S).finrank_range_add_finrank_ker
rw [LinearMap.range_eq_top.mpr (parity_surjective S hS), finrank_top] at hr
have hn : Module.finrank B (𝔽₂ S.card) = S.card := by simp
rw [hn] at hr
rw [Module.natCard_eq_pow_finrank (K := B) (V := (parity S).ker),
Module.natCard_eq_pow_finrank (K := B) (V := G), Nat.card_zmod]
rw [← pow_add, add_comm, hr]
theorem minDensity_le_sum_basis :
Green40.minDensity S.card 2 ≤
(Nat.card (Green40.hammingBall S.card 2) : ℝ≥0∞) / (Nat.card G : ℝ≥0∞) := by
refine (iInf₂_le (parity S).ker (parity_cover S hS)).trans_eq ?_
have hcard : (Nat.card (parity S).ker : ℝ≥0∞) * (Nat.card G : ℝ≥0∞) = 2 ^ S.card := by
exact_mod_cast parity_card S hS
rw [← hcard]
exact ENNReal.mul_div_mul_left _ _
(by exact_mod_cast (Nat.card_pos (α := (parity S).ker)).ne') (by simp)
end Code
end Green40Proof
end
/- Repairing the graph and obtaining small sum bases. -/
noncomputable section
open Finset
open scoped ENNReal Pointwise
namespace Green40Proof
theorem derivative_surj {V H : Type*} [AddCommGroup V] [Module B V] [Finite V]
[AddCommGroup H] [Module B H] [Finite H]
(Q : V → H) (hq : IsQuadratic Q)
(hdim : Module.finrank B V = Module.finrank B H + 1)
(a : V) (ha : a ≠ 0)
(hk : ∀ x, bp Q a x = 0 → x = 0 ∨ x = a) :
Function.Surjective (derivative Q hq a) := by
let D := derivative Q hq a
have hker : D.ker ≤ Submodule.span B {a} := by
intro x hx
rcases hk x hx with rfl | rfl
· exact Submodule.zero_mem _
· exact Submodule.subset_span (by simp)
have hkdim : Module.finrank B D.ker ≤ 1 := by
simpa only [finrank_span_singleton ha] using Submodule.finrank_mono hker
have hr := D.finrank_range_add_finrank_ker
have hrle := Submodule.finrank_le D.range
apply LinearMap.range_eq_top.mp
apply Submodule.eq_top_of_finrank_eq
change Module.finrank B D.range = Module.finrank B H
omega
theorem Model.graph_sums {c : ℕ} (hc : c ≠ 0) (M : Model c)
(a : GF c) (z : M.K) (h : M.H) (ha : a ≠ 0) :
letI := M.addK
letI := M.modK
letI := M.finK
letI := M.addH
letI := M.modH
letI := M.finH
∃ x y : GF c × M.K, x+y=(a,z) ∧ M.Q x + M.Q y = h := by
letI := M.addK
letI := M.modK
letI := M.finK
letI := M.addH
letI := M.modH
letI := M.finH
have hs := derivative_surj M.Q M.quadratic (by
rw [Module.finrank_prod, GaloisField.finrank 2 hc]
exact M.dim.symm)
(a,z) (by intro hh; exact ha (congrArg Prod.fst hh))
(fun x hx => M.good a z x.1 x.2 ha hx)
obtain ⟨x,hx⟩ := hs (h + M.Q (a,z))
refine ⟨x,(a,z)+x,?_,?_⟩
· have hh := twice x
calc x + ((a,z)+x) = (a,z)+(x+x) := by abel
_ = (a,z) := by rw [hh,add_zero]
· change M.Q ((a,z)+x) + M.Q (a,z) + M.Q x = h + M.Q (a,z) at hx
apply add_right_cancel (b := M.Q (a,z))
simpa only [add_comm,add_left_comm,add_assoc] using hx
def vertical {c : ℕ} (M : Model c) :
letI := M.addK
letI := M.modK
letI := M.finK
letI := M.addH
letI := M.modH
letI := M.finH
(M.K × M.H) →ₗ[B] ((GF c × M.K) × M.H) := by
letI := M.addK
letI := M.modK
letI := M.finK
letI := M.addH
letI := M.modH
letI := M.finH
exact
{ toFun := fun x => ((0,x.1),x.2)
map_add' := by intros; rfl
map_smul' := by intros; ext <;> simp }
theorem Model.exists_sum_basis {p : ℕ} (hp : 0 < p) (M : Model (2*p)) :
letI := M.addK
letI := M.modK
letI := M.finK
letI := M.addH
letI := M.modH
letI := M.finH
let n := 2*p + Module.finrank B M.K
∃ (S : Finset ((GF (2*p) × M.K) × M.H)),
(∀ g, ∃ a ∈ S, ∃ b ∈ S, a+b=g) ∧
2^n ≤ S.card ∧ S.card ≤ 2^n + 2^(n-p+1) := by
classical
letI := M.addK
letI := M.modK
letI := M.finK
letI := M.addH
letI := M.modH
letI := M.finH
letI : Fintype M.K := Fintype.ofFinite _
letI : Fintype M.H := Fintype.ofFinite _
letI : Fintype (GF (2*p)) := Fintype.ofFinite _
let n := 2*p + Module.finrank B M.K
let d := p + Module.finrank B M.K
have hd : 0 < d := by dsimp [d]; omega
let E : (BV d × BV (d-1)) ≃ₗ[B] (M.K × M.H) :=
LinearEquiv.ofFinrankEq _ _ (by
simp only [Module.finrank_prod, Module.finrank_pi, Module.finrank_self,
Fintype.card_fin, smul_eq_mul, mul_one]
have hm := M.dim
dsimp [d]
omega)
let C : Finset ((GF (2*p) × M.K) × M.H) :=
Finset.univ.image (fun x => (x,M.Q x))
let A : Finset ((GF (2*p) × M.K) × M.H) :=
Finset.univ.image (fun x : BV d => vertical M (E (x,0)))
let A' : Finset ((GF (2*p) × M.K) × M.H) :=
Finset.univ.image (fun x : BV (d-1) => vertical M (E (0,x)))
let S := C ∪ A ∪ A'
have hCS : C ⊆ S := Finset.subset_union_left.trans Finset.subset_union_left
have hAS : A ⊆ S := Finset.subset_union_right.trans Finset.subset_union_left
have hBS : A' ⊆ S := Finset.subset_union_right
have hcardV : Fintype.card (GF (2*p) × M.K) = 2^n := by
rw [← Nat.card_eq_fintype_card, Module.natCard_eq_pow_finrank (K := B)]
simp only [Nat.card_zmod, Module.finrank_prod,
GaloisField.finrank 2 (n := 2*p) (by omega)]
rfl
have hcardC : C.card = 2^n := by
dsimp only [C]
rw [Finset.card_image_of_injective _ (by
intro x y h
exact congrArg Prod.fst h), Finset.card_univ, hcardV]
have hcardA : A.card ≤ 2^d := by
simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, BV, B] using (Finset.card_image_le (s := (Finset.univ : Finset (BV d)))
(f := fun x => vertical M (E (x,0))))
have hcardB : A'.card ≤ 2^(d-1) := by
simpa [twice, neg_binary, bp_zero, bp_self, derivative_apply, BV, B] using (Finset.card_image_le (s := (Finset.univ : Finset (BV (d-1))))
(f := fun x => vertical M (E (0,x))))
refine ⟨S,?_,?_,?_⟩
· rintro ⟨⟨a,z⟩,h⟩
by_cases ha : a = 0
· subst a
let x := (E.symm (z,h)).1
let y := (E.symm (z,h)).2
refine ⟨vertical M (E (x,0)), hAS (by simp [A]),
vertical M (E (0,y)), hBS (by simp [A']), ?_⟩
rw [← map_add, ← map_add]
simp only [Prod.mk_add_mk, add_zero, zero_add]
change vertical M (E (E.symm (z,h))) = ((0,z),h)
rw [LinearEquiv.apply_symm_apply]
rfl
· obtain ⟨x,y,hxy,hQ⟩ := M.graph_sums (by omega) a z h ha
refine ⟨(x,M.Q x), hCS (by simp [C]), (y,M.Q y), hCS (by simp [C]), ?_⟩
simp [Prod.mk_add_mk,hxy,hQ]
· rw [← hcardC]
exact Finset.card_le_card hCS
· have hbound := (Finset.card_union_le (C∪A) A').trans
(Nat.add_le_add_right (Finset.card_union_le C A) A'.card)
have hpow : 2^(d-1) ≤ 2^d := Nat.pow_le_pow_right (by decide) (by omega)
have hnd : n-p+1 = d+1 := by dsimp [n,d]; omega
change S.card ≤ 2^n + 2^(n-p+1)
rw [hnd,pow_succ]
rw [hcardC] at hbound
change S.card ≤ 2^n + A.card + A'.card at hbound
omega
theorem Model.exists_code {p : ℕ} (hp : 0 < p) (M : Model (2*p)) :
∃ n N : ℕ, 2*p ≤ n ∧ 2^n ≤ N ∧ N ≤ 2^n+2^(n-p+1) ∧
Green40.minDensity N 2 ≤
(Nat.card (Green40.hammingBall N 2) : ℝ≥0∞) / 2^(2*n-1) := by
letI := M.addK
letI := M.modK
letI := M.finK
letI := M.addH
letI := M.modH
letI := M.finH
obtain ⟨S,hcov,hlo,hhi⟩ := M.exists_sum_basis hp
let n := 2*p + Module.finrank B M.K
have hcard : Nat.card ((GF (2*p) × M.K) × M.H) = 2^(2*n-1) := by
rw [Module.natCard_eq_pow_finrank (K := B)]
simp only [Nat.card_zmod, Module.finrank_prod,
GaloisField.finrank 2 (n := 2*p) (by omega)]
congr 1
have hm := M.dim
dsimp [n]
omega
refine ⟨n,S.card,by dsimp [n]; omega,hlo,hhi,?_⟩
simpa only [hcard, Nat.cast_pow, Nat.cast_ofNat] using minDensity_le_sum_basis S hcov
end Green40Proof
end
/- Uniform density estimates for the repaired graphs. -/
open Filter
open scoped ENNReal Pointwise
namespace Green40Proof
theorem numeric_estimate (v q N b d : ℝ)
(hq : 2 ≤ q) (hv : q ≤ v) (hNlo : v ≤ N)
(hNhi : N*q ≤ v*(q+2)) (hb : 2*b ≤ N*N+N+2)
(hd : 2*d = v*v) : b / d ≤ 1 + 10 / q := by
have hqpos : 0 < q := by linarith
have hvpos : 0 < v := by linarith
have hNpos : 0 < N := by linarith
have hdpos : 0 < d := by nlinarith [sq_pos_of_pos hvpos]
have hNtwo : N ≤ 2*v := by
have hh := mul_nonneg (sub_nonneg.mpr hNlo) (sub_nonneg.mpr hq)
nlinarith
have hmain : q*(N*N-v*v) ≤ 6*v*v := by
have hh := mul_nonneg (show 0 ≤ 2*v-q*(N-v) by nlinarith) (show 0 ≤ N+v by linarith)
have hh' := mul_nonneg (show 0 ≤ 2*v-N by linarith) (show 0 ≤ 2*v by linarith)
nlinarith
have hsmall : q*(N+2) ≤ 4*v*v := by
have hh := mul_nonneg (show 0 ≤ v-q by linarith) (show 0 ≤ N+2 by linarith)
have hh' := mul_nonneg (show 0 ≤ v by linarith) (show 0 ≤ 4*v-(N+2) by linarith)
nlinarith
have htotal : 2*b*q ≤ (q+10)*v*v := by
have hh := mul_le_mul_of_nonneg_right hb (le_of_lt hqpos)
nlinarith
rw [div_le_iff₀ hdpos]
apply (mul_le_mul_iff_left₀ hqpos).mp
have heq : (1+10/q)*d*q = (q+10)*d := by field_simp
rw [heq]
nlinarith [congrArg (fun x : ℝ => (q+10)*x) hd]
theorem density_estimate {p n N : ℕ} (hp : 0 < p) (hpn : 2*p ≤ n)
(hlo : 2^n ≤ N) (hhi : N ≤ 2^n+2^(n-p+1)) :
(Nat.card (Green40.hammingBall N 2) : ℝ≥0∞) / 2^(2*n-1) ≤
ENNReal.ofReal (1+10/(2:ℝ)^p) := by
have hreal : (Nat.card (Green40.hammingBall N 2) : ℝ) / (2:ℝ)^(2*n-1) ≤
1+10/(2:ℝ)^p := by
apply numeric_estimate ((2:ℝ)^n) ((2:ℝ)^p) N _ _
· calc (2:ℝ) = 2^1 := by norm_num
_ ≤ 2^p := pow_le_pow_right₀ (by norm_num) hp
· exact pow_le_pow_right₀ (by norm_num) (by omega)
· exact_mod_cast hlo
· have hc : (N:ℝ) ≤ (2:ℝ)^n+2^(n-p+1) := by exact_mod_cast hhi
have hh := mul_le_mul_of_nonneg_right hc (by positivity : (0:ℝ) ≤ 2^p)
have hpow : (2:ℝ)^(n-p+1)*2^p = 2^n*2 := by
rw [← pow_add, ← pow_succ]
congr 1
omega
nlinarith
· exact_mod_cast hammingBall_card_bound N
· rw [mul_comm, ← pow_succ, ← pow_add]
congr 1
omega
convert ENNReal.ofReal_le_ofReal hreal using 1
rw [ENNReal.ofReal_div_of_pos (by positivity)]
simp
end Green40Proof
/-
# Green 40 sphere-covering lower bounds
The elementary counting lower bound is the fixed half of the conjectured
equality `Green40.f 2 = 1`. These lemmas isolate that half so a later solver
only has to construct a subsequence of covering subspaces with density at most
one.
-/
namespace Contribution.Green40FTwoEqOne
open Filter Set
open scoped ENNReal Pointwise
/-- A finite sumset that covers the ambient type has at most as many points as
the product of the two source sets. This is the counting map used by the
sphere-covering bound. -/
theorem card_le_card_mul_of_add_eq_univ {α : Type*} [Add α] [Finite α]
(A B : Set α) (hcover : A + B = Set.univ) :
Nat.card α ≤ Nat.card A * Nat.card B := by
let addMap : A × B → α := fun p => p.1.1 + p.2.1
have hsurj : Function.Surjective addMap := by
intro x
have hx : x ∈ A + B := by rw [hcover]; exact Set.mem_univ x
rcases hx with ⟨a, ha, b, hb, hab⟩
exact ⟨(⟨a, ha⟩, ⟨b, hb⟩), hab⟩
simpa [Nat.card_prod] using Nat.card_le_card_of_surjective addMap hsurj
/-- Every covering subspace obeys the sphere-covering cardinality bound. -/
theorem coveringSubspace_card_bound (n r : ℕ)
(V : Submodule (ZMod 2) (𝔽₂ n)) (hV : Green40.IsCoveringSubspace n r V) :
2 ^ n ≤ Nat.card V * Nat.card (Green40.hammingBall n r) := by
have h := card_le_card_mul_of_add_eq_univ
(A := (V : Set (𝔽₂ n))) (B := Green40.hammingBall n r) hV
simpa [Nat.card_eq_fintype_card] using h
/-- The density of each individual covering subspace is at least one. -/
theorem one_le_coveringSubspace_density (n r : ℕ)
(V : Submodule (ZMod 2) (𝔽₂ n)) (hV : Green40.IsCoveringSubspace n r V) :
(1 : ℝ≥0∞) ≤
(Nat.card V : ℝ≥0∞) * (Nat.card (Green40.hammingBall n r) : ℝ≥0∞) /
(2 ^ n : ℝ≥0∞) := by
rw [ENNReal.le_div_iff_mul_le (Or.inl (by simp)) (Or.inl (by simp))]
simp only [one_mul]
exact_mod_cast coveringSubspace_card_bound n r V hV
/-- The minimum density at every finite length is at least one. -/
theorem one_le_minDensity (n r : ℕ) : (1 : ℝ≥0∞) ≤ Green40.minDensity n r := by
rw [Green40.minDensity]
refine le_iInf fun V => ?_
refine le_iInf fun hV => ?_
exact one_le_coveringSubspace_density n r V hV
/-- The sphere-covering lower bound survives the liminf defining `Green40.f`. -/
theorem one_le_f (r : ℕ) : (1 : ℝ≥0∞) ≤ Green40.f r := by
rw [Green40.f]
calc
(1 : ℝ≥0∞) ≤ ⨅ n, Green40.minDensity n r := le_iInf fun n => one_le_minDensity n r
_ ≤ liminf (fun n => Green40.minDensity n r) atTop := iInf_le_liminf
/-- Green 40 at radius two is therefore reduced to the matching upper bound. -/
theorem f_two_eq_one_iff_le_one : Green40.f 2 = 1 ↔ Green40.f 2 ≤ 1 := by
constructor
· intro h
exact h.le
· intro h
exact le_antisymm h (one_le_f 2)
end Contribution.Green40FTwoEqOne
/- The asymptotic upper bound and the exact challenge target. -/
noncomputable section
open Filter Topology
open scoped ENNReal Pointwise
namespace Green40Proof
theorem f_two_le_one : Green40.f 2 ≤ 1 := by
have hex (r : ℕ) : ∃ n N : ℕ, 2*(2^r) ≤ n ∧ 2^n ≤ N ∧
N ≤ 2^n+2^(n-2^r+1) ∧
Green40.minDensity N 2 ≤
(Nat.card (Green40.hammingBall N 2) : ℝ≥0∞) / 2^(2*n-1) := by
let M : Model (2*(2^r)) := by
simpa only [pow_succ, mul_comm] using models (r+1)
exact M.exists_code (by positivity)
choose n N hpn hlo hhi hmd using hex
have hNgrowth : Tendsto N atTop atTop := by
apply tendsto_atTop_mono (fun r => ?_) tendsto_id
change r ≤ N r
have h1 : r < 2^r := Nat.lt_two_pow_self
have h2 : n r < 2^(n r) := Nat.lt_two_pow_self
have := hpn r
have := hlo r
omega
have hupper (r : ℕ) : Green40.minDensity (N r) 2 ≤
ENNReal.ofReal (1+10/(2:ℝ)^(2^r)) :=
(hmd r).trans (density_estimate (by positivity) (hpn r) (hlo r) (hhi r))
have hpgrowth : Tendsto (fun r : ℕ => 2^r) atTop atTop := by
exact tendsto_atTop_mono (fun r => (show r < 2^r from Nat.lt_two_pow_self).le) tendsto_id
have hden : Tendsto (fun r : ℕ => (2:ℝ)^(2^r)) atTop atTop :=
(tendsto_pow_atTop_atTop_of_one_lt (by norm_num : (1:ℝ)<2)).comp hpgrowth
have hreal : Tendsto (fun r : ℕ => 1+10/(2:ℝ)^(2^r)) atTop (𝓝 1) := by
have hc1 : Tendsto (fun _ : ℕ => (1:ℝ)) atTop (𝓝 1) := tendsto_const_nhds
have hc10 : Tendsto (fun _ : ℕ => (10:ℝ)) atTop (𝓝 10) := tendsto_const_nhds
have hh := hc1.add (hc10.mul (tendsto_inv_atTop_zero.comp hden))
simpa only [Function.comp_def, div_eq_mul_inv, mul_zero, add_zero] using hh
have hlimit : Tendsto (fun r : ℕ => ENNReal.ofReal (1+10/(2:ℝ)^(2^r)))
atTop (𝓝 (1:ℝ≥0∞)) := by
simpa only [Function.comp_def, ENNReal.ofReal_one] using
(ENNReal.continuous_ofReal.tendsto (1:ℝ)).comp hreal
calc
Green40.f 2 ≤ liminf (fun r => Green40.minDensity (N r) 2) atTop :=
hNgrowth.liminf_le_liminf_comp
_ ≤ liminf (fun r => ENNReal.ofReal (1+10/(2:ℝ)^(2^r))) atTop :=
Filter.liminf_le_liminf (Filter.Eventually.of_forall hupper)
_ = 1 := hlimit.liminf_eq
theorem density_two_eq_one : Green40.f 2 = 1 :=
le_antisymm f_two_le_one (Contribution.Green40FTwoEqOne.one_le_f 2)
end Green40Proof
theorem target : fcTypeOfName% "Green40.green_40.f_two_eq_one" := by
exact ⟨fun _ => Green40Proof.density_two_eq_one, fun _ => True.intro⟩
end
Provenance
- Proof SHA-256
- sha256:3ce2c4e59100ad65a74ce35e457a1c0a8d8afe731b58e476c67ba609c7636be5
- Solver
- JenW1N
- Attribution
- conjectures.io