4. The E8 Lattice
There are several equivalent definitions of the E_8 lattice. Below, we
formalise two of them and prove that they are equivalent.
-
Submodule.E8[complete]
We define the E_8 lattice as a subset of \R^8 by
\Lambda_8=\{(x_i)\in\Z^8\cup(\Z+\textstyle\frac12\displaystyle )^8|\;\sum_{i=1}^8x_i\equiv 0\;(\mathrm{mod\;2})\}.
Lean code for Definition4.1●1 definition
Associated Lean declarations
-
Submodule.E8[complete]
-
Submodule.E8[complete]
-
def Submodule.E8.{u_2} (R
Type u_2: Type u_2A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`.) [FieldField.{u} (K : Type u) : Type uA `Field` is a `CommRing` with multiplicative inverses for nonzero elements. An instance of `Field K` includes maps `ratCast : ℚ → K` and `qsmul : ℚ → K → K`. Those two fields are needed to implement the `DivisionRing K → Algebra ℚ K` instance since we need to control the specific definitions for some special cases of `K` (in particular `K = ℚ` itself). See also note [forgetful inheritance]. If the field has positive characteristic `p`, our division by zero convention forces `ratCast (1 / p) = 1 / 0 = 0`.RType u_2] [NeZeroNeZero.{u_1} {R : Type u_1} [Zero R] (n : R) : PropA type-class version of `n ≠ 0`.2] : SubmoduleSubmodule.{u, v} (R : Type u) (M : Type v) [Semiring R] [AddCommMonoid M] [Module R M] : Type vA submodule of a module is one which is closed under vector operations. This is a sufficient condition for the subset of vectors in the submodule to themselves form a module.ℤInt : TypeThe integers. This type is special-cased by the compiler and overridden with an efficient implementation. The runtime has a special representation for `Int` that stores “small” signed numbers directly, while larger numbers use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit architectures).(FinFin (n : ℕ) : TypeNatural numbers less than some upper bound. In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the canonical type with `n` elements.8 → RType u_2)def Submodule.E8.{u_2} (R
Type u_2: Type u_2A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`.) [FieldField.{u} (K : Type u) : Type uA `Field` is a `CommRing` with multiplicative inverses for nonzero elements. An instance of `Field K` includes maps `ratCast : ℚ → K` and `qsmul : ℚ → K → K`. Those two fields are needed to implement the `DivisionRing K → Algebra ℚ K` instance since we need to control the specific definitions for some special cases of `K` (in particular `K = ℚ` itself). See also note [forgetful inheritance]. If the field has positive characteristic `p`, our division by zero convention forces `ratCast (1 / p) = 1 / 0 = 0`.RType u_2] [NeZeroNeZero.{u_1} {R : Type u_1} [Zero R] (n : R) : PropA type-class version of `n ≠ 0`.2] : SubmoduleSubmodule.{u, v} (R : Type u) (M : Type v) [Semiring R] [AddCommMonoid M] [Module R M] : Type vA submodule of a module is one which is closed under vector operations. This is a sufficient condition for the subset of vectors in the submodule to themselves form a module.ℤInt : TypeThe integers. This type is special-cased by the compiler and overridden with an efficient implementation. The runtime has a special representation for `Int` that stores “small” signed numbers directly, while larger numbers use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit architectures).(FinFin (n : ℕ) : TypeNatural numbers less than some upper bound. In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the canonical type with `n` elements.8 → RType u_2)
-
E8Matrix[complete]
We define the E_8 basis vectors to be the set of vectors
\B_8 =
\left\{
\begin{bmatrix}
1 \\ -1 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0
\end{bmatrix},
\begin{bmatrix}
0 \\ 1 \\ -1 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0
\end{bmatrix},
\begin{bmatrix}
0 \\ 0 \\ 1 \\ -1 \\ 0 \\ 0 \\ 0 \\ 0
\end{bmatrix},
\begin{bmatrix}
0 \\ 0 \\ 0 \\ 1 \\ -1 \\ 0 \\ 0 \\ 0
\end{bmatrix},
\begin{bmatrix}
0 \\ 0 \\ 0 \\ 0 \\ 1 \\ -1 \\ 0 \\ 0
\end{bmatrix},
\begin{bmatrix}
0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 1 \\ 1 \\ 0
\end{bmatrix},
\begin{bmatrix}
-1/2 \\ -1/2 \\ -1/2 \\ -1/2 \\ -1/2 \\ -1/2 \\ -1/2 \\ -1/2
\end{bmatrix},
\begin{bmatrix}
0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 1 \\ -1 \\ 0
\end{bmatrix}
\right\}.
Lean code for Definition4.2●1 definition
Associated Lean declarations
-
E8Matrix[complete]
-
E8Matrix[complete]
-
def E8Matrix.{u_2} (R
Type u_2: Type u_2A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`.) [FieldField.{u} (K : Type u) : Type uA `Field` is a `CommRing` with multiplicative inverses for nonzero elements. An instance of `Field K` includes maps `ratCast : ℚ → K` and `qsmul : ℚ → K → K`. Those two fields are needed to implement the `DivisionRing K → Algebra ℚ K` instance since we need to control the specific definitions for some special cases of `K` (in particular `K = ℚ` itself). See also note [forgetful inheritance]. If the field has positive characteristic `p`, our division by zero convention forces `ratCast (1 / p) = 1 / 0 = 0`.RType u_2] : MatrixMatrix.{u, u', v} (m : Type u) (n : Type u') (α : Type v) : Type (max u u' v)`Matrix m n R` is the type of matrices with entries in `R`, whose rows are indexed by `m` and whose columns are indexed by `n`.(FinFin (n : ℕ) : TypeNatural numbers less than some upper bound. In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the canonical type with `n` elements.8) (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound. In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the canonical type with `n` elements.8) RType u_2def E8Matrix.{u_2} (R
Type u_2: Type u_2A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`.) [FieldField.{u} (K : Type u) : Type uA `Field` is a `CommRing` with multiplicative inverses for nonzero elements. An instance of `Field K` includes maps `ratCast : ℚ → K` and `qsmul : ℚ → K → K`. Those two fields are needed to implement the `DivisionRing K → Algebra ℚ K` instance since we need to control the specific definitions for some special cases of `K` (in particular `K = ℚ` itself). See also note [forgetful inheritance]. If the field has positive characteristic `p`, our division by zero convention forces `ratCast (1 / p) = 1 / 0 = 0`.RType u_2] : MatrixMatrix.{u, u', v} (m : Type u) (n : Type u') (α : Type v) : Type (max u u' v)`Matrix m n R` is the type of matrices with entries in `R`, whose rows are indexed by `m` and whose columns are indexed by `n`.(FinFin (n : ℕ) : TypeNatural numbers less than some upper bound. In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the canonical type with `n` elements.8) (FinFin (n : ℕ) : TypeNatural numbers less than some upper bound. In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the canonical type with `n` elements.8) RType u_2
-
span_E8Matrix[complete]
The two definitions above coincide, i.e. \Lambda_8 = \mathrm{span}_{\Z}(\B_8).
Uses Definition 4.1 and Definition 4.2.
Lean code for Theorem4.3●1 theorem
Associated Lean declarations
-
span_E8Matrix[complete]
-
span_E8Matrix[complete]
-
theorem span_E8Matrix.{u_2} (R
Type u_2: Type u_2A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`.) [FieldField.{u} (K : Type u) : Type uA `Field` is a `CommRing` with multiplicative inverses for nonzero elements. An instance of `Field K` includes maps `ratCast : ℚ → K` and `qsmul : ℚ → K → K`. Those two fields are needed to implement the `DivisionRing K → Algebra ℚ K` instance since we need to control the specific definitions for some special cases of `K` (in particular `K = ℚ` itself). See also note [forgetful inheritance]. If the field has positive characteristic `p`, our division by zero convention forces `ratCast (1 / p) = 1 / 0 = 0`.RType u_2] [CharZeroCharZero.{u_1} (R : Type u_1) [AddMonoidWithOne R] : PropTypeclass for monoids with characteristic zero. (This is usually stated on fields but it makes sense for any additive monoid with 1.) *Warning*: for a semiring `R`, `CharZero R` and `CharP R 0` need not coincide. * `CharZero R` requires an injection `ℕ ↪ R`; * `CharP R 0` asks that only `0 : ℕ` maps to `0 : R` under the map `ℕ → R`. For instance, endowing `{0, 1}` with addition given by `max` (i.e. `1` is absorbing), shows that `CharZero {0, 1}` does not hold and yet `CharP {0, 1} 0` does. This example is formalized in `Counterexamples/CharPZeroNeCharZero.lean`.RType u_2] : Submodule.spanSubmodule.span.{u_1, u_4} (R : Type u_1) {M : Type u_4} [Semiring R] [AddCommMonoid M] [Module R M] (s : Set M) : Submodule R MThe span of a set `s ⊆ M` is the smallest submodule of M that contains `s`.ℤInt : TypeThe integers. This type is special-cased by the compiler and overridden with an efficient implementation. The runtime has a special representation for `Int` that stores “small” signed numbers directly, while larger numbers use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit architectures).(Set.rangeSet.range.{u, u_1} {α : Type u} {ι : Sort u_1} (f : ι → α) : Set αRange of a function. This function is more flexible than `f '' univ`, as the image requires that the domain is in Type and not an arbitrary Sort.(E8MatrixE8Matrix.{u_2} (R : Type u_2) [Field R] : Matrix (Fin 8) (Fin 8) RRType u_2).rowMatrix.row.{v, u_2, u_3} {m : Type u_2} {n : Type u_3} {α : Type v} (A : Matrix m n α) : m → n → αFor an `m × n` `α`-matrix `A`, `A.row i` is the `i`th row of `A` as a vector in `n → α`. `A.row` is defeq to `A`, but explicitly refers to the 'row function' of `A` while avoiding defeq abuse and noisy eta-expansions, such as in expressions like `Set.Injective A.row` and `Set.range A.row`. (Note 2025-04-07 : the identifier `Matrix.row` used to refer to a matrix with all rows equal; this is now called `Matrix.replicateRow`)) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`. We use `a = b` as notation for `Eq a b`. A fundamental property of equality is that it is an equivalence relation. ``` variable (α : Type) (a b c d : α) variable (hab : a = b) (hcb : c = b) (hcd : c = d) example : a = d := Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd ``` Equality is much more than an equivalence relation, however. It has the important property that every assertion respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value. That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`. Example: ``` example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := Eq.subst h1 h2 example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := h1 ▸ h2 ``` The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`. For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality) Conventions for notations in identifiers: * The recommended spelling of `=` in identifiers is `eq`.Submodule.E8Submodule.E8.{u_2} (R : Type u_2) [Field R] [NeZero 2] : Submodule ℤ (Fin 8 → R)RType u_2theorem span_E8Matrix.{u_2} (R
Type u_2: Type u_2A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`.) [FieldField.{u} (K : Type u) : Type uA `Field` is a `CommRing` with multiplicative inverses for nonzero elements. An instance of `Field K` includes maps `ratCast : ℚ → K` and `qsmul : ℚ → K → K`. Those two fields are needed to implement the `DivisionRing K → Algebra ℚ K` instance since we need to control the specific definitions for some special cases of `K` (in particular `K = ℚ` itself). See also note [forgetful inheritance]. If the field has positive characteristic `p`, our division by zero convention forces `ratCast (1 / p) = 1 / 0 = 0`.RType u_2] [CharZeroCharZero.{u_1} (R : Type u_1) [AddMonoidWithOne R] : PropTypeclass for monoids with characteristic zero. (This is usually stated on fields but it makes sense for any additive monoid with 1.) *Warning*: for a semiring `R`, `CharZero R` and `CharP R 0` need not coincide. * `CharZero R` requires an injection `ℕ ↪ R`; * `CharP R 0` asks that only `0 : ℕ` maps to `0 : R` under the map `ℕ → R`. For instance, endowing `{0, 1}` with addition given by `max` (i.e. `1` is absorbing), shows that `CharZero {0, 1}` does not hold and yet `CharP {0, 1} 0` does. This example is formalized in `Counterexamples/CharPZeroNeCharZero.lean`.RType u_2] : Submodule.spanSubmodule.span.{u_1, u_4} (R : Type u_1) {M : Type u_4} [Semiring R] [AddCommMonoid M] [Module R M] (s : Set M) : Submodule R MThe span of a set `s ⊆ M` is the smallest submodule of M that contains `s`.ℤInt : TypeThe integers. This type is special-cased by the compiler and overridden with an efficient implementation. The runtime has a special representation for `Int` that stores “small” signed numbers directly, while larger numbers use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit architectures).(Set.rangeSet.range.{u, u_1} {α : Type u} {ι : Sort u_1} (f : ι → α) : Set αRange of a function. This function is more flexible than `f '' univ`, as the image requires that the domain is in Type and not an arbitrary Sort.(E8MatrixE8Matrix.{u_2} (R : Type u_2) [Field R] : Matrix (Fin 8) (Fin 8) RRType u_2).rowMatrix.row.{v, u_2, u_3} {m : Type u_2} {n : Type u_3} {α : Type v} (A : Matrix m n α) : m → n → αFor an `m × n` `α`-matrix `A`, `A.row i` is the `i`th row of `A` as a vector in `n → α`. `A.row` is defeq to `A`, but explicitly refers to the 'row function' of `A` while avoiding defeq abuse and noisy eta-expansions, such as in expressions like `Set.Injective A.row` and `Set.range A.row`. (Note 2025-04-07 : the identifier `Matrix.row` used to refer to a matrix with all rows equal; this is now called `Matrix.replicateRow`)) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`. We use `a = b` as notation for `Eq a b`. A fundamental property of equality is that it is an equivalence relation. ``` variable (α : Type) (a b c d : α) variable (hab : a = b) (hcb : c = b) (hcd : c = d) example : a = d := Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd ``` Equality is much more than an equivalence relation, however. It has the important property that every assertion respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value. That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`. Example: ``` example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := Eq.subst h1 h2 example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := h1 ▸ h2 ``` The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`. For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality) Conventions for notations in identifiers: * The recommended spelling of `=` in identifiers is `eq`.Submodule.E8Submodule.E8.{u_2} (R : Type u_2) [Field R] [NeZero 2] : Submodule ℤ (Fin 8 → R)RType u_2
We prove that each side contains the other.
/- source paragraph break -/
For a vector \vec{v} \in \Lambda_8 \subseteq \R^8, we have
\sum_i \vec{v}_i \equiv 0 \pmod{2} and all coordinates are either integers
or half-integers. After some modulo arithmetic, it can be seen that
\B_8^{-1}\vec{v} has integer coordinates, so
\vec{v} \in \mathrm{span}_{\Z}(\B_8).
/- source paragraph break -/
For the opposite direction, write
\vec{v} = \sum_i c_i\B_8^i \in \mathrm{span}_{\Z}(\B_8) with the
c_i integers and \B_8^i the i-th basis vector. Expanding the
definition gives
\vec{v} = \left(c_1 - \frac{1}{2}c_7, -c_1 + c_2 - \frac{1}{2}c_7, \cdots, -\frac{1}{2}c_7\right).
Again, after some modulo arithmetic, it can be seen that
\sum_i \vec{v}_i is 0 modulo 2 and that the coordinates are all
either integers or all half-integers.
/- source paragraph break -/
This proof does not depend on \B_8 being linearly independent.
In this section, we establish basic properties of the E_8 lattice and the
\B_8 vectors.
\B_8 is an \R-basis of \R^8. This uses Definition 4.2.
Lean code for Lemma4.4●1 theorem
Associated Lean declarations
-
span_E8Matrix_eq_top[complete]
-
span_E8Matrix_eq_top[complete]
-
theorem span_E8Matrix_eq_top.{u_2} (R
Type u_2: Type u_2A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`.) [FieldField.{u} (K : Type u) : Type uA `Field` is a `CommRing` with multiplicative inverses for nonzero elements. An instance of `Field K` includes maps `ratCast : ℚ → K` and `qsmul : ℚ → K → K`. Those two fields are needed to implement the `DivisionRing K → Algebra ℚ K` instance since we need to control the specific definitions for some special cases of `K` (in particular `K = ℚ` itself). See also note [forgetful inheritance]. If the field has positive characteristic `p`, our division by zero convention forces `ratCast (1 / p) = 1 / 0 = 0`.RType u_2] [NeZeroNeZero.{u_1} {R : Type u_1} [Zero R] (n : R) : PropA type-class version of `n ≠ 0`.2] : Submodule.spanSubmodule.span.{u_1, u_4} (R : Type u_1) {M : Type u_4} [Semiring R] [AddCommMonoid M] [Module R M] (s : Set M) : Submodule R MThe span of a set `s ⊆ M` is the smallest submodule of M that contains `s`.RType u_2(Set.rangeSet.range.{u, u_1} {α : Type u} {ι : Sort u_1} (f : ι → α) : Set αRange of a function. This function is more flexible than `f '' univ`, as the image requires that the domain is in Type and not an arbitrary Sort.(E8MatrixE8Matrix.{u_2} (R : Type u_2) [Field R] : Matrix (Fin 8) (Fin 8) RRType u_2).rowMatrix.row.{v, u_2, u_3} {m : Type u_2} {n : Type u_3} {α : Type v} (A : Matrix m n α) : m → n → αFor an `m × n` `α`-matrix `A`, `A.row i` is the `i`th row of `A` as a vector in `n → α`. `A.row` is defeq to `A`, but explicitly refers to the 'row function' of `A` while avoiding defeq abuse and noisy eta-expansions, such as in expressions like `Set.Injective A.row` and `Set.range A.row`. (Note 2025-04-07 : the identifier `Matrix.row` used to refer to a matrix with all rows equal; this is now called `Matrix.replicateRow`)) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`. We use `a = b` as notation for `Eq a b`. A fundamental property of equality is that it is an equivalence relation. ``` variable (α : Type) (a b c d : α) variable (hab : a = b) (hcb : c = b) (hcd : c = d) example : a = d := Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd ``` Equality is much more than an equivalence relation, however. It has the important property that every assertion respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value. That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`. Example: ``` example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := Eq.subst h1 h2 example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := h1 ▸ h2 ``` The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`. For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality) Conventions for notations in identifiers: * The recommended spelling of `=` in identifiers is `eq`.⊤Top.top.{u_1} {α : Type u_1} [self : Top α] : αThe top (`⊤`, `\top`) element Conventions for notations in identifiers: * The recommended spelling of `⊤` in identifiers is `top`.theorem span_E8Matrix_eq_top.{u_2} (R
Type u_2: Type u_2A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`.) [FieldField.{u} (K : Type u) : Type uA `Field` is a `CommRing` with multiplicative inverses for nonzero elements. An instance of `Field K` includes maps `ratCast : ℚ → K` and `qsmul : ℚ → K → K`. Those two fields are needed to implement the `DivisionRing K → Algebra ℚ K` instance since we need to control the specific definitions for some special cases of `K` (in particular `K = ℚ` itself). See also note [forgetful inheritance]. If the field has positive characteristic `p`, our division by zero convention forces `ratCast (1 / p) = 1 / 0 = 0`.RType u_2] [NeZeroNeZero.{u_1} {R : Type u_1} [Zero R] (n : R) : PropA type-class version of `n ≠ 0`.2] : Submodule.spanSubmodule.span.{u_1, u_4} (R : Type u_1) {M : Type u_4} [Semiring R] [AddCommMonoid M] [Module R M] (s : Set M) : Submodule R MThe span of a set `s ⊆ M` is the smallest submodule of M that contains `s`.RType u_2(Set.rangeSet.range.{u, u_1} {α : Type u} {ι : Sort u_1} (f : ι → α) : Set αRange of a function. This function is more flexible than `f '' univ`, as the image requires that the domain is in Type and not an arbitrary Sort.(E8MatrixE8Matrix.{u_2} (R : Type u_2) [Field R] : Matrix (Fin 8) (Fin 8) RRType u_2).rowMatrix.row.{v, u_2, u_3} {m : Type u_2} {n : Type u_3} {α : Type v} (A : Matrix m n α) : m → n → αFor an `m × n` `α`-matrix `A`, `A.row i` is the `i`th row of `A` as a vector in `n → α`. `A.row` is defeq to `A`, but explicitly refers to the 'row function' of `A` while avoiding defeq abuse and noisy eta-expansions, such as in expressions like `Set.Injective A.row` and `Set.range A.row`. (Note 2025-04-07 : the identifier `Matrix.row` used to refer to a matrix with all rows equal; this is now called `Matrix.replicateRow`)) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`. We use `a = b` as notation for `Eq a b`. A fundamental property of equality is that it is an equivalence relation. ``` variable (α : Type) (a b c d : α) variable (hab : a = b) (hcb : c = b) (hcd : c = d) example : a = d := Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd ``` Equality is much more than an equivalence relation, however. It has the important property that every assertion respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value. That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`. Example: ``` example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := Eq.subst h1 h2 example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := h1 ▸ h2 ``` The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`. For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality) Conventions for notations in identifiers: * The recommended spelling of `=` in identifiers is `eq`.⊤Top.top.{u_1} {α : Type u_1} [self : Top α] : αThe top (`⊤`, `\top`) element Conventions for notations in identifiers: * The recommended spelling of `⊤` in identifiers is `top`.
It suffices to prove that \B_8 \in \mathrm{GL}_8(\R).
We do this by explicitly defining the inverse matrix \B_8^{-1} and
proving \B_8 \B_8^{-1} = I_8, which implies that \det(\B_8) is
nonzero. See the Lean code for more details.
\Lambda_8 is an additive subgroup of \R^8.
This uses Definition 4.1 and Theorem 4.3.
Lean code for Lemma4.5●1 definition
Associated Lean declarations
-
E8Lattice[complete]
-
E8Lattice[complete]
-
abbrev E8Lattice : Submodule
Submodule.{u, v} (R : Type u) (M : Type v) [Semiring R] [AddCommMonoid M] [Module R M] : Type vA submodule of a module is one which is closed under vector operations. This is a sufficient condition for the subset of vectors in the submodule to themselves form a module.ℤInt : TypeThe integers. This type is special-cased by the compiler and overridden with an efficient implementation. The runtime has a special representation for `Int` that stores “small” signed numbers directly, while larger numbers use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit architectures).(EuclideanSpaceEuclideanSpace.{u_7, u_8} (𝕜 : Type u_7) (n : Type u_8) : Type (max u_7 u_8)The standard real/complex Euclidean space, functions on a finite type. For an `n`-dimensional space use `EuclideanSpace 𝕜 (Fin n)`. For the case when `n = Fin _`, there is `!₂[x, y, ...]` notation for building elements of this type, analogous to `![x, y, ...]` notation.ℝReal : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational numbers.(FinFin (n : ℕ) : TypeNatural numbers less than some upper bound. In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the canonical type with `n` elements.8))abbrev E8Lattice : Submodule
Submodule.{u, v} (R : Type u) (M : Type v) [Semiring R] [AddCommMonoid M] [Module R M] : Type vA submodule of a module is one which is closed under vector operations. This is a sufficient condition for the subset of vectors in the submodule to themselves form a module.ℤInt : TypeThe integers. This type is special-cased by the compiler and overridden with an efficient implementation. The runtime has a special representation for `Int` that stores “small” signed numbers directly, while larger numbers use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)). A “small number” is an integer that can be encoded with one fewer bits than the platform's pointer size (i.e. 63 bits on 64-bit architectures and 31 bits on 32-bit architectures).(EuclideanSpaceEuclideanSpace.{u_7, u_8} (𝕜 : Type u_7) (n : Type u_8) : Type (max u_7 u_8)The standard real/complex Euclidean space, functions on a finite type. For an `n`-dimensional space use `EuclideanSpace 𝕜 (Fin n)`. For the case when `n = Fin _`, there is `!₂[x, y, ...]` notation for building elements of this type, analogous to `![x, y, ...]` notation.ℝReal : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational numbers.(FinFin (n : ℕ) : TypeNatural numbers less than some upper bound. In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the canonical type with `n` elements.8))
This follows trivially from the fact that
\Lambda_8 \subseteq \R^8 is the \Z-span of \B_8 and hence an
additive group.
All vectors in \Lambda_8 have norm of the form \sqrt{2n}, where
n is a nonnegative integer. This uses Theorem 4.3.
Lean code for Lemma4.6●1 theorem
Associated Lean declarations
-
E8_norm_eq_sqrt_even[complete]
-
E8_norm_eq_sqrt_even[complete]
-
theorem E8_norm_eq_sqrt_even (v
Fin 8 → ℝ: FinFin (n : ℕ) : TypeNatural numbers less than some upper bound. In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the canonical type with `n` elements.8 → ℝReal : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational numbers.) (hvv ∈ Submodule.E8 ℝ: vFin 8 → ℝ∈Membership.mem.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Membership α γ] : γ → α → PropThe membership relation `a ∈ s : Prop` where `a : α`, `s : γ`. Conventions for notations in identifiers: * The recommended spelling of `∈` in identifiers is `mem`.Submodule.E8Submodule.E8.{u_2} (R : Type u_2) [Field R] [NeZero 2] : Submodule ℤ (Fin 8 → R)ℝReal : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational numbers.) : ∃ nℤ, EvenEven.{u_2} {α : Type u_2} [Add α] (a : α) : PropAn element `a` of a type `α` with addition satisfies `Even a` if `a = r + r`, for some `r : α`.nℤ∧And (a b : Prop) : Prop`And a b`, or `a ∧ b`, is the conjunction of propositions. It can be constructed and destructed like a pair: if `ha : a` and `hb : b` then `⟨ha, hb⟩ : a ∧ b`, and if `h : a ∧ b` then `h.left : a` and `h.right : b`. Conventions for notations in identifiers: * The recommended spelling of `∧` in identifiers is `and`. * The recommended spelling of `/\` in identifiers is `and` (prefer `∧` over `/\`).↑nℤ=Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`. We use `a = b` as notation for `Eq a b`. A fundamental property of equality is that it is an equivalence relation. ``` variable (α : Type) (a b c d : α) variable (hab : a = b) (hcb : c = b) (hcd : c = d) example : a = d := Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd ``` Equality is much more than an equivalence relation, however. It has the important property that every assertion respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value. That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`. Example: ``` example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := Eq.subst h1 h2 example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := h1 ▸ h2 ``` The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`. For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality) Conventions for notations in identifiers: * The recommended spelling of `=` in identifiers is `eq`.‖Norm.norm.{u_8} {E : Type u_8} [self : Norm E] : E → ℝthe `ℝ`-valued norm function.WithLp.toLpWithLp.toLp.{u_1} (p : ENNReal) {V : Type u_1} (ofLp : V) : WithLp p VConverts an element of `V` to an element of `WithLp p V`.2 vFin 8 → ℝ‖Norm.norm.{u_8} {E : Type u_8} [self : Norm E] : E → ℝthe `ℝ`-valued norm function.^HPow.hPow.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HPow α β γ] : α → β → γ`a ^ b` computes `a` to the power of `b`. The meaning of this notation is type-dependent. Conventions for notations in identifiers: * The recommended spelling of `^` in identifiers is `pow`.2theorem E8_norm_eq_sqrt_even (v
Fin 8 → ℝ: FinFin (n : ℕ) : TypeNatural numbers less than some upper bound. In particular, a `Fin n` is a natural number `i` with the constraint that `i < n`. It is the canonical type with `n` elements.8 → ℝReal : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational numbers.) (hvv ∈ Submodule.E8 ℝ: vFin 8 → ℝ∈Membership.mem.{u, v} {α : outParam (Type u)} {γ : Type v} [self : Membership α γ] : γ → α → PropThe membership relation `a ∈ s : Prop` where `a : α`, `s : γ`. Conventions for notations in identifiers: * The recommended spelling of `∈` in identifiers is `mem`.Submodule.E8Submodule.E8.{u_2} (R : Type u_2) [Field R] [NeZero 2] : Submodule ℤ (Fin 8 → R)ℝReal : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational numbers.) : ∃ nℤ, EvenEven.{u_2} {α : Type u_2} [Add α] (a : α) : PropAn element `a` of a type `α` with addition satisfies `Even a` if `a = r + r`, for some `r : α`.nℤ∧And (a b : Prop) : Prop`And a b`, or `a ∧ b`, is the conjunction of propositions. It can be constructed and destructed like a pair: if `ha : a` and `hb : b` then `⟨ha, hb⟩ : a ∧ b`, and if `h : a ∧ b` then `h.left : a` and `h.right : b`. Conventions for notations in identifiers: * The recommended spelling of `∧` in identifiers is `and`. * The recommended spelling of `/\` in identifiers is `and` (prefer `∧` over `/\`).↑nℤ=Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`. We use `a = b` as notation for `Eq a b`. A fundamental property of equality is that it is an equivalence relation. ``` variable (α : Type) (a b c d : α) variable (hab : a = b) (hcb : c = b) (hcd : c = d) example : a = d := Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd ``` Equality is much more than an equivalence relation, however. It has the important property that every assertion respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value. That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`. Example: ``` example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := Eq.subst h1 h2 example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := h1 ▸ h2 ``` The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`. For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality) Conventions for notations in identifiers: * The recommended spelling of `=` in identifiers is `eq`.‖Norm.norm.{u_8} {E : Type u_8} [self : Norm E] : E → ℝthe `ℝ`-valued norm function.WithLp.toLpWithLp.toLp.{u_1} (p : ENNReal) {V : Type u_1} (ofLp : V) : WithLp p VConverts an element of `V` to an element of `WithLp p V`.2 vFin 8 → ℝ‖Norm.norm.{u_8} {E : Type u_8} [self : Norm E] : E → ℝthe `ℝ`-valued norm function.^HPow.hPow.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HPow α β γ] : α → β → γ`a ^ b` computes `a` to the power of `b`. The meaning of this notation is type-dependent. Conventions for notations in identifiers: * The recommended spelling of `^` in identifiers is `pow`.2
Writing \vec{v} = \sum_i c_i\B_8^i, we have
\|v\|^2 = \sum_i \sum_j c_ic_j (\B_8^i \cdot \B_8^j).
Computing all 64 pairs of dot products and simplifying gives a large
quadratic form in the c_i with even integer coefficients, concluding the
proof.
c\Lambda_8 is discrete, that is, the subspace topology induced by its
inclusion into \R^8 is the discrete topology.
This uses Lemma 4.6.
Lean code for Lemma4.7●1 theorem
Associated Lean declarations
-
instDiscreteE8Lattice[complete]
-
instDiscreteE8Lattice[complete]
-
theorem instDiscreteE8Lattice : DiscreteTopology
DiscreteTopology.{u_2} (α : Type u_2) [t : TopologicalSpace α] : PropA topological space is discrete if every set is open, that is, its topology equals the discrete topology `⊥`.↥E8LatticeE8Lattice : Submodule ℤ (EuclideanSpace ℝ (Fin 8))theorem instDiscreteE8Lattice : DiscreteTopology
DiscreteTopology.{u_2} (α : Type u_2) [t : TopologicalSpace α] : PropA topological space is discrete if every set is open, that is, its topology equals the discrete topology `⊥`.↥E8LatticeE8Lattice : Submodule ℤ (EuclideanSpace ℝ (Fin 8))
Since \Lambda_8 is a topological group and + is continuous, it
suffices to prove that \{0\} is open in \Lambda_8. This follows from
the existence of an open ball \B(\sqrt{2}) \subseteq \R^8 around zero
containing no other lattice points, since the shortest nonzero vector has norm
\sqrt{2}.
Lean code for Lemma4.8●1 theorem
Associated Lean declarations
-
instIsZLatticeE8Lattice[complete]
-
instIsZLatticeE8Lattice[complete]
-
theorem instIsZLatticeE8Lattice : IsZLattice
IsZLattice.{u_1, u_2} (K : Type u_1) [NormedField K] {E : Type u_2} [NormedAddCommGroup E] [NormedSpace K E] (L : Submodule ℤ E) [DiscreteTopology ↥L] : Prop`L : Submodule ℤ E` where `E` is a vector space over a normed field `K` is a `ℤ`-lattice if it is discrete and spans `E` over `K`.ℝReal : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational numbers.E8LatticeE8Lattice : Submodule ℤ (EuclideanSpace ℝ (Fin 8))theorem instIsZLatticeE8Lattice : IsZLattice
IsZLattice.{u_1, u_2} (K : Type u_1) [NormedField K] {E : Type u_2} [NormedAddCommGroup E] [NormedSpace K E] (L : Submodule ℤ E) [DiscreteTopology ↥L] : Prop`L : Submodule ℤ E` where `E` is a vector space over a normed field `K` is a `ℤ`-lattice if it is discrete and spans `E` over `K`.ℝReal : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational numbers.E8LatticeE8Lattice : Submodule ℤ (EuclideanSpace ℝ (Fin 8))
The first part is by instDiscreteE8Lattice, and the second part follows
from the fact that \B_8 is a basis (E8-is-basis) and hence linearly
independent over \R.
Prove E_8 is unimodular.
Prove E_8 is positive-definite.
Lean code for Definition4.9●1 definition
Associated Lean declarations
-
E8Packing[complete]
-
E8Packing[complete]
-
def E8Packing : PeriodicSpherePacking
PeriodicSpherePacking (d : ℕ) : Type8def E8Packing : PeriodicSpherePacking
PeriodicSpherePacking (d : ℕ) : Type8
-
E8Basis_volume[complete]
\Vol{\Lambda_8} = \mathrm{Covol}(\R^8 / \Lambda_8) = 1.
This uses Definition 4.9.
Lean code for Lemma4.10●1 theorem
Associated Lean declarations
-
E8Basis_volume[complete]
-
E8Basis_volume[complete]
-
theorem E8Basis_volume : MeasureTheory.volume
MeasureTheory.MeasureSpace.volume.{u_6} {α : Type u_6} [self : MeasureTheory.MeasureSpace α] : MeasureTheory.Measure α`volume` is the canonical measure on `α`.(ZSpan.fundamentalDomainZSpan.fundamentalDomain.{u_1, u_2, u_3} {E : Type u_1} {ι : Type u_2} {K : Type u_3} [NormedField K] [NormedAddCommGroup E] [NormedSpace K E] (b : Module.Basis ι K E) [LinearOrder K] : Set EThe fundamental domain of the ℤ-lattice spanned by `b`. See `ZSpan.isAddFundamentalDomain` for the proof that it is a fundamental domain.(E8BasisE8Basis.{u_2} (R : Type u_2) [Field R] [NeZero 2] : Module.Basis (Fin 8) R (Fin 8 → R)ℝReal : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational numbers.)) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`. We use `a = b` as notation for `Eq a b`. A fundamental property of equality is that it is an equivalence relation. ``` variable (α : Type) (a b c d : α) variable (hab : a = b) (hcb : c = b) (hcd : c = d) example : a = d := Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd ``` Equality is much more than an equivalence relation, however. It has the important property that every assertion respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value. That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`. Example: ``` example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := Eq.subst h1 h2 example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := h1 ▸ h2 ``` The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`. For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality) Conventions for notations in identifiers: * The recommended spelling of `=` in identifiers is `eq`.1theorem E8Basis_volume : MeasureTheory.volume
MeasureTheory.MeasureSpace.volume.{u_6} {α : Type u_6} [self : MeasureTheory.MeasureSpace α] : MeasureTheory.Measure α`volume` is the canonical measure on `α`.(ZSpan.fundamentalDomainZSpan.fundamentalDomain.{u_1, u_2, u_3} {E : Type u_1} {ι : Type u_2} {K : Type u_3} [NormedField K] [NormedAddCommGroup E] [NormedSpace K E] (b : Module.Basis ι K E) [LinearOrder K] : Set EThe fundamental domain of the ℤ-lattice spanned by `b`. See `ZSpan.isAddFundamentalDomain` for the proof that it is a fundamental domain.(E8BasisE8Basis.{u_2} (R : Type u_2) [Field R] [NeZero 2] : Module.Basis (Fin 8) R (Fin 8 → R)ℝReal : TypeThe type `ℝ` of real numbers constructed as equivalence classes of Cauchy sequences of rational numbers.)) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`. We use `a = b` as notation for `Eq a b`. A fundamental property of equality is that it is an equivalence relation. ``` variable (α : Type) (a b c d : α) variable (hab : a = b) (hcb : c = b) (hcd : c = d) example : a = d := Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd ``` Equality is much more than an equivalence relation, however. It has the important property that every assertion respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value. That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`. Example: ``` example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := Eq.subst h1 h2 example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := h1 ▸ h2 ``` The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`. For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality) Conventions for notations in identifiers: * The recommended spelling of `=` in identifiers is `eq`.1
TODO: In theory this should follow directly from \det(\Lambda_8) = 1, but
Lean hates me and EuclideanSpace is being annoying.
-
E8Packing_density[complete]
We have \Delta_{\mathcal{P}(E_8)} = \frac{\pi^4}{384}.
Uses Theorem 3.5 and Lemma 4.10.
Lean code for Theorem4.11●1 theorem
Associated Lean declarations
-
E8Packing_density[complete]
-
E8Packing_density[complete]
-
theorem E8Packing_density : E8Packing
E8Packing : PeriodicSpherePacking 8.densitySpherePacking.density {d : ℕ} (S : SpherePacking d) : ENNReal=Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`. We use `a = b` as notation for `Eq a b`. A fundamental property of equality is that it is an equivalence relation. ``` variable (α : Type) (a b c d : α) variable (hab : a = b) (hcb : c = b) (hcd : c = d) example : a = d := Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd ``` Equality is much more than an equivalence relation, however. It has the important property that every assertion respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value. That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`. Example: ``` example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := Eq.subst h1 h2 example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := h1 ▸ h2 ``` The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`. For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality) Conventions for notations in identifiers: * The recommended spelling of `=` in identifiers is `eq`.ENNReal.ofRealENNReal.ofReal (r : ℝ) : ENNReal`ofReal x` returns `x` if it is nonnegative, `0` otherwise.Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2], from which one can derive all its properties. For explicit bounds on π, see `Mathlib/Analysis/Real/Pi/Bounds.lean`. Denoted `π`, once the `Real` namespace is opened.^HPow.hPow.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HPow α β γ] : α → β → γ`a ^ b` computes `a` to the power of `b`. The meaning of this notation is type-dependent. Conventions for notations in identifiers: * The recommended spelling of `^` in identifiers is `pow`.4 /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`. The meaning of this notation is type-dependent. * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`. * For `Nat`, `a / b` rounds downwards. * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative. It is implemented as `Int.ediv`, the unique function satisfying `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`. Other rounding conventions are available using the functions `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding). * For `Float`, `a / 0` follows the IEEE 754 semantics for division, usually resulting in `inf` or `nan`. Conventions for notations in identifiers: * The recommended spelling of `/` in identifiers is `div`.384theorem E8Packing_density : E8Packing
E8Packing : PeriodicSpherePacking 8.densitySpherePacking.density {d : ℕ} (S : SpherePacking d) : ENNReal=Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`. We use `a = b` as notation for `Eq a b`. A fundamental property of equality is that it is an equivalence relation. ``` variable (α : Type) (a b c d : α) variable (hab : a = b) (hcb : c = b) (hcd : c = d) example : a = d := Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd ``` Equality is much more than an equivalence relation, however. It has the important property that every assertion respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value. That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`. Example: ``` example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := Eq.subst h1 h2 example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := h1 ▸ h2 ``` The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`. For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality) Conventions for notations in identifiers: * The recommended spelling of `=` in identifiers is `eq`.ENNReal.ofRealENNReal.ofReal (r : ℝ) : ENNReal`ofReal x` returns `x` if it is nonnegative, `0` otherwise.Real.piReal.pi : ℝThe number π = 3.14159265... Defined here using choice as twice a zero of cos in [1,2], from which one can derive all its properties. For explicit bounds on π, see `Mathlib/Analysis/Real/Pi/Bounds.lean`. Denoted `π`, once the `Real` namespace is opened.^HPow.hPow.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HPow α β γ] : α → β → γ`a ^ b` computes `a` to the power of `b`. The meaning of this notation is type-dependent. Conventions for notations in identifiers: * The recommended spelling of `^` in identifiers is `pow`.4 /HDiv.hDiv.{u, v, w} {α : Type u} {β : Type v} {γ : outParam (Type w)} [self : HDiv α β γ] : α → β → γ`a / b` computes the result of dividing `a` by `b`. The meaning of this notation is type-dependent. * For most types like `Nat`, `Int`, `Rat`, `Real`, `a / 0` is defined to be `0`. * For `Nat`, `a / b` rounds downwards. * For `Int`, `a / b` rounds downwards if `b` is positive or upwards if `b` is negative. It is implemented as `Int.ediv`, the unique function satisfying `a % b + b * (a / b) = a` and `0 ≤ a % b < natAbs b` for `b ≠ 0`. Other rounding conventions are available using the functions `Int.fdiv` (floor rounding) and `Int.tdiv` (truncation rounding). * For `Float`, `a / 0` follows the IEEE 754 semantics for division, usually resulting in `inf` or `nan`. Conventions for notations in identifiers: * The recommended spelling of `/` in identifiers is `div`.384
By theorem:psp-density, we have
\Delta_{\mathcal{P}(E_8)} = |E_8 / E_8| \cdot \frac{\Vol{\mathcal{B}_8(\sqrt{2} / 2)}}{\mathrm{Covol}(E_8)} = \frac{\pi^4}{384},
where the last equality follows from E8Packing-covol and the
formula for volume of a ball:
\Vol{\mathcal{B}_d(R)} = R^d \pi^{d / 2} / \Gamma\left(\frac{d}{2} + 1\right).