/- Copyright 2025 The Formal Conjectures Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -/ import FormalConjecturesUtil

Hadamard's conjecture

References:

namespace Hadamard

A square matrix $M$ with $±1$-entries that satisfies the equality $|M| ≤ n^\frac{n}{2}$ is called a Hadamard matrix.

def IsHadamard {n : } (M : Matrix (Fin n) (Fin n) ) : Prop := ( (i j : Fin n), M i j ({1, -1} : Finset )) |M.det| = n ^ ((n : ) / 2)

Equivalently, a square matrix $M$ with $±1$-entries $|A| ≤ n^\frac{n}{2}.$ if it satisfies the equality $M^TM = n \cdot 1$, where $1$ denotes the unit matrix.

def IsHadamard' {n : } (M : Matrix (Fin n) (Fin n) ) : Prop := ( (i j : Fin n), M i j ({1, -1} : Finset )) M.transpose * M = n

Both definitions are equivalent.

TOOD(firsching): complete and golf the proof

@[category test, AMS 15] theorem declaration uses 'sorry'isHadamard_equiv_isHadamard' (n : ) (M : Matrix (Fin n) (Fin n) ) : IsHadamard' M IsHadamard M := n:M:Matrix (Fin n) (Fin n) IsHadamard' M IsHadamard M n:M:Matrix (Fin n) (Fin n) (∀ (i j : Fin n), M i j = 1 M i j = -1) (M.transpose * M = n |M.det| = n ^ (n / 2)) n:M:Matrix (Fin n) (Fin n) h: (i j : Fin n), M i j = 1 M i j = -1M.transpose * M = n |M.det| = n ^ (n / 2) n:M:Matrix (Fin n) (Fin n) h: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * MM.transpose * M = n |M.det| = n ^ (n / 2) n:M:Matrix (Fin n) (Fin n) h: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * MM.transpose * M = n |M.det| = n ^ (n / 2)n:M:Matrix (Fin n) (Fin n) h: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * M|M.det| = n ^ (n / 2) M.transpose * M = n n:M:Matrix (Fin n) (Fin n) h: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * MM.transpose * M = n |M.det| = n ^ (n / 2) n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = n|M.det| = n ^ (n / 2) have h_det : (M.transpose * M).det = n^((n : )) := n:M:Matrix (Fin n) (Fin n) IsHadamard' M IsHadamard M have : Matrix.diagonal (fun x : Fin n => (n : )) = (n : Matrix (Fin n) (Fin n) ) := n:M:Matrix (Fin n) (Fin n) IsHadamard' M IsHadamard M All goals completed! 🐙 n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nthis:(Matrix.diagonal fun x => n) = n := Eq.refl (Matrix.diagonal fun x => n)(Matrix.diagonal fun x => n).det = n ^ n All goals completed! 🐙 n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ n|M.det| = n ^ (n / 2) n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ n(n ^ n) = n ^ (n / 2) have : (n ^ (n : )) = (n ^ (n : )) ^ ((1 : )/2) := n:M:Matrix (Fin n) (Fin n) IsHadamard' M IsHadamard M n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ n(n ^ n) = (n ^ n) ^ 1n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ n0 n ^ n n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ n(n ^ n) = (n ^ n) ^ 1 All goals completed! 🐙 n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ n0 n ^ n All goals completed! 🐙 n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ nthis:(n ^ n) = (n ^ n) ^ (1 / 2) := Eq.mpr (id (congrArg (fun _a => (n ^ n) = _a) (Real.rpow_div_two_eq_sqrt 1 (of_eq_true (Eq.trans (congrArg (LE.le 0) (Real.rpow_natCast (↑n) n)) (isHadamard_equiv_isHadamard'._simp_4 (of_eq_true (isHadamard_equiv_isHadamard'._simp_3 n)) n)))))) (of_eq_true (Eq.trans (congr (congrArg (fun x => Eq x) (Real.rpow_natCast (↑n) n)) (Eq.trans (congrArg (fun x => x ^ 1) (Real.rpow_natCast (↑n) n)) (Real.rpow_one (n ^ n)))) (eq_self (n ^ n))))(n ^ n) ^ (1 / 2) = n ^ (n / 2) n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ nthis:(n ^ n) = (n ^ n) ^ (1 / 2) := Eq.mpr (id (congrArg (fun _a => (n ^ n) = _a) (Real.rpow_div_two_eq_sqrt 1 (of_eq_true (Eq.trans (congrArg (LE.le 0) (Real.rpow_natCast (↑n) n)) (isHadamard_equiv_isHadamard'._simp_4 (of_eq_true (isHadamard_equiv_isHadamard'._simp_3 n)) n)))))) (of_eq_true (Eq.trans (congr (congrArg (fun x => Eq x) (Real.rpow_natCast (↑n) n)) (Eq.trans (congrArg (fun x => x ^ 1) (Real.rpow_natCast (↑n) n)) (Real.rpow_one (n ^ n)))) (eq_self (n ^ n))))(n ^ n) ^ 2⁻¹ = n ^ (n / 2) n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ nthis:(n ^ n) = (n ^ n) ^ (1 / 2) := Eq.mpr (id (congrArg (fun _a => (n ^ n) = _a) (Real.rpow_div_two_eq_sqrt 1 (of_eq_true (Eq.trans (congrArg (LE.le 0) (Real.rpow_natCast (↑n) n)) (isHadamard_equiv_isHadamard'._simp_4 (of_eq_true (isHadamard_equiv_isHadamard'._simp_3 n)) n)))))) (of_eq_true (Eq.trans (congr (congrArg (fun x => Eq x) (Real.rpow_natCast (↑n) n)) (Eq.trans (congrArg (fun x => x ^ 1) (Real.rpow_natCast (↑n) n)) (Real.rpow_one (n ^ n)))) (eq_self (n ^ n))))0 n ^ (n / 2)n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ nthis:(n ^ n) = (n ^ n) ^ (1 / 2) := Eq.mpr (id (congrArg (fun _a => (n ^ n) = _a) (Real.rpow_div_two_eq_sqrt 1 (of_eq_true (Eq.trans (congrArg (LE.le 0) (Real.rpow_natCast (↑n) n)) (isHadamard_equiv_isHadamard'._simp_4 (of_eq_true (isHadamard_equiv_isHadamard'._simp_3 n)) n)))))) (of_eq_true (Eq.trans (congr (congrArg (fun x => Eq x) (Real.rpow_natCast (↑n) n)) (Eq.trans (congrArg (fun x => x ^ 1) (Real.rpow_natCast (↑n) n)) (Real.rpow_one (n ^ n)))) (eq_self (n ^ n))))0 n ^ nn:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ nthis:(n ^ n) = (n ^ n) ^ (1 / 2) := Eq.mpr (id (congrArg (fun _a => (n ^ n) = _a) (Real.rpow_div_two_eq_sqrt 1 (of_eq_true (Eq.trans (congrArg (LE.le 0) (Real.rpow_natCast (↑n) n)) (isHadamard_equiv_isHadamard'._simp_4 (of_eq_true (isHadamard_equiv_isHadamard'._simp_3 n)) n)))))) (of_eq_true (Eq.trans (congr (congrArg (fun x => Eq x) (Real.rpow_natCast (↑n) n)) (Eq.trans (congrArg (fun x => x ^ 1) (Real.rpow_natCast (↑n) n)) (Real.rpow_one (n ^ n)))) (eq_self (n ^ n))))2 0n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ nthis:(n ^ n) = (n ^ n) ^ (1 / 2) := Eq.mpr (id (congrArg (fun _a => (n ^ n) = _a) (Real.rpow_div_two_eq_sqrt 1 (of_eq_true (Eq.trans (congrArg (LE.le 0) (Real.rpow_natCast (↑n) n)) (isHadamard_equiv_isHadamard'._simp_4 (of_eq_true (isHadamard_equiv_isHadamard'._simp_3 n)) n)))))) (of_eq_true (Eq.trans (congr (congrArg (fun x => Eq x) (Real.rpow_natCast (↑n) n)) (Eq.trans (congrArg (fun x => x ^ 1) (Real.rpow_natCast (↑n) n)) (Real.rpow_one (n ^ n)))) (eq_self (n ^ n))))(n ^ (n / 2)) ^ 2 = n ^ n n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ nthis:(n ^ n) = (n ^ n) ^ (1 / 2) := Eq.mpr (id (congrArg (fun _a => (n ^ n) = _a) (Real.rpow_div_two_eq_sqrt 1 (of_eq_true (Eq.trans (congrArg (LE.le 0) (Real.rpow_natCast (↑n) n)) (isHadamard_equiv_isHadamard'._simp_4 (of_eq_true (isHadamard_equiv_isHadamard'._simp_3 n)) n)))))) (of_eq_true (Eq.trans (congr (congrArg (fun x => Eq x) (Real.rpow_natCast (↑n) n)) (Eq.trans (congrArg (fun x => x ^ 1) (Real.rpow_natCast (↑n) n)) (Real.rpow_one (n ^ n)))) (eq_self (n ^ n))))0 n ^ (n / 2) All goals completed! 🐙 n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ nthis:(n ^ n) = (n ^ n) ^ (1 / 2) := Eq.mpr (id (congrArg (fun _a => (n ^ n) = _a) (Real.rpow_div_two_eq_sqrt 1 (of_eq_true (Eq.trans (congrArg (LE.le 0) (Real.rpow_natCast (↑n) n)) (isHadamard_equiv_isHadamard'._simp_4 (of_eq_true (isHadamard_equiv_isHadamard'._simp_3 n)) n)))))) (of_eq_true (Eq.trans (congr (congrArg (fun x => Eq x) (Real.rpow_natCast (↑n) n)) (Eq.trans (congrArg (fun x => x ^ 1) (Real.rpow_natCast (↑n) n)) (Real.rpow_one (n ^ n)))) (eq_self (n ^ n))))0 n ^ n All goals completed! 🐙 n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ nthis:(n ^ n) = (n ^ n) ^ (1 / 2) := Eq.mpr (id (congrArg (fun _a => (n ^ n) = _a) (Real.rpow_div_two_eq_sqrt 1 (of_eq_true (Eq.trans (congrArg (LE.le 0) (Real.rpow_natCast (↑n) n)) (isHadamard_equiv_isHadamard'._simp_4 (of_eq_true (isHadamard_equiv_isHadamard'._simp_3 n)) n)))))) (of_eq_true (Eq.trans (congr (congrArg (fun x => Eq x) (Real.rpow_natCast (↑n) n)) (Eq.trans (congrArg (fun x => x ^ 1) (Real.rpow_natCast (↑n) n)) (Real.rpow_one (n ^ n)))) (eq_self (n ^ n))))2 0 All goals completed! 🐙 n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ nthis:(n ^ n) = (n ^ n) ^ (1 / 2) := Eq.mpr (id (congrArg (fun _a => (n ^ n) = _a) (Real.rpow_div_two_eq_sqrt 1 (of_eq_true (Eq.trans (congrArg (LE.le 0) (Real.rpow_natCast (↑n) n)) (isHadamard_equiv_isHadamard'._simp_4 (of_eq_true (isHadamard_equiv_isHadamard'._simp_3 n)) n)))))) (of_eq_true (Eq.trans (congr (congrArg (fun x => Eq x) (Real.rpow_natCast (↑n) n)) (Eq.trans (congrArg (fun x => x ^ 1) (Real.rpow_natCast (↑n) n)) (Real.rpow_one (n ^ n)))) (eq_self (n ^ n))))(n ^ (n / 2)) ^ 2 = n ^ n n:M:Matrix (Fin n) (Fin n) h✝: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * Mh:M.transpose * M = nh_det:M.det * M.det = n ^ nthis:(n ^ n) = (n ^ n) ^ (1 / 2) := Eq.mpr (id (congrArg (fun _a => (n ^ n) = _a) (Real.rpow_div_two_eq_sqrt 1 (of_eq_true (Eq.trans (congrArg (LE.le 0) (Real.rpow_natCast (↑n) n)) (isHadamard_equiv_isHadamard'._simp_4 (of_eq_true (isHadamard_equiv_isHadamard'._simp_3 n)) n)))))) (of_eq_true (Eq.trans (congr (congrArg (fun x => Eq x) (Real.rpow_natCast (↑n) n)) (Eq.trans (congrArg (fun x => x ^ 1) (Real.rpow_natCast (↑n) n)) (Real.rpow_one (n ^ n)))) (eq_self (n ^ n))))n ^ (n / 2 * 2) = n ^ n All goals completed! 🐙 n:M:Matrix (Fin n) (Fin n) h: (i j : Fin n), M i j = 1 M i j = -1N:Matrix (Fin n) (Fin n) := M.transpose * M|M.det| = n ^ (n / 2) M.transpose * M = n All goals completed! 🐙

There exists a Hadamard matrix for all $n = 4k$.

@[category research open, AMS 15] theorem declaration uses 'sorry'HadamardConjecture (k : ) : M, IsHadamard (n := 4 * k) M := k: M, IsHadamard M All goals completed! 🐙 @[category test, AMS 15] theorem exists_hadamard_zero : M, IsHadamard (n := 0) M := M, IsHadamard M IsHadamard 0 All goals completed! 🐙

Hadamard constructs a 12 x 12 matrix ...

def H12 : Matrix (Fin 12) (Fin 12) := !![ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1; 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1; 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1; 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1; 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1; 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1; 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1; 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1; 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1; 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1; 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1; 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1 ]

which satisifies the condition.

@[category test, AMS 15] theorem declaration uses 'sorry'isHadamard_H12 : IsHadamard H12 := IsHadamard H12 All goals completed! 🐙

For all $k ≤ 166$, it is known there that there is a Hadamard matrix of size $4 * k$.

@[category research solved, AMS 15] theorem declaration uses 'sorry'HadamardConjecture.variants.first_cases (k : ) (h : k 166) : M, IsHadamard (n := 4 * k) M := k:h:k 166 M, IsHadamard M All goals completed! 🐙

The smallest order for which no Hadamard matrix is presently known is $668 = 4 * 167$.

@[category research open, AMS 15] theorem declaration uses 'sorry'HadamardConjecture.variants.«167» : M, IsHadamard (n := 4 * 167) M := M, IsHadamard M All goals completed! 🐙 end Hadamard