Sphere Packing in R^8

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.

Definition4.1
Group: Equivalent models of the E8 lattice. (2)
Hover another entry in this group to preview it.
Preview
Definition 4.2
Loading preview
Hover a group entry to preview it.
L∃∀N
Used by 2
Hover a use site to preview it.
Preview
Theorem 4.3
Loading preview
Hover a use site to preview it.

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.11 definition
  • def Submodule.E8.{u_2} (RType 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} (RType 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)
    complete
Definition4.2
Group: Equivalent models of the E8 lattice. (2)
Hover another entry in this group to preview it.
Preview
Definition 4.1
Loading preview
Hover a group entry to preview it.
L∃∀N
Used by 2
Hover a use site to preview it.
Preview
Theorem 4.3
Loading preview
Hover a use site to preview it.

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.21 definition
  • def E8Matrix.{u_2} (RType 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
    def E8Matrix.{u_2} (RType 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
    complete
Theorem4.3
Group: Equivalent models of the E8 lattice. (2)
Hover another entry in this group to preview it.
Preview
Definition 4.1
Loading preview
Hover a group entry to preview it.
L∃∀N
Used by 2
Hover a use site to preview it.
Preview
Lemma 4.5
Loading preview
Hover a use site to preview it.

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.31 theorem
  • theorem span_E8Matrix.{u_2} (RType 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) R RType 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
    theorem span_E8Matrix.{u_2} (RType 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) R RType 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
    complete
Proof

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.

Lemma4.4
Group: Basic structural and arithmetic properties of E8. (4)
Hover another entry in this group to preview it.
Preview
Lemma 4.5
Loading preview
Hover a group entry to preview it.
L∃∀Nused by 1

\B_8 is an \R-basis of \R^8. This uses Definition 4.2.

Lean code for Lemma4.41 theorem
  • theorem span_E8Matrix_eq_top.{u_2} (RType 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) R RType 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} (RType 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) R RType 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`.
    complete
Proof

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.

Lemma4.5
Group: Basic structural and arithmetic properties of E8. (4)
Hover another entry in this group to preview it.
Preview
Lemma 4.4
Loading preview
Hover a group entry to preview it.
L∃∀N
Used by 2
Hover a use site to preview it.
Preview
Theorem 2.15
Loading preview
Hover a use site to preview it.

\Lambda_8 is an additive subgroup of \R^8. This uses Definition 4.1 and Theorem 4.3.

Lean code for Lemma4.51 definition
  • abbrev E8Lattice : 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).
     (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 :
      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).
     (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))
    complete
Proof

This follows trivially from the fact that \Lambda_8 \subseteq \R^8 is the \Z-span of \B_8 and hence an additive group.

Lemma4.6
Group: Basic structural and arithmetic properties of E8. (4)
Hover another entry in this group to preview it.
Preview
Lemma 4.4
Loading preview
Hover a group entry to preview it.
L∃∀N
Used by 2
Hover a use site to preview it.
Preview
Lemma 4.7
Loading preview
Hover a use site to preview it.

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.61 theorem
  • theorem E8_norm_eq_sqrt_even (vFin 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
    theorem E8_norm_eq_sqrt_even (vFin 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
    complete
Proof

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.

Lemma4.7
Group: Basic structural and arithmetic properties of E8. (4)
Hover another entry in this group to preview it.
Preview
Lemma 4.4
Loading preview
Hover a group entry to preview it.
L∃∀Nused by 1

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.71 theorem
  • theorem instDiscreteE8Lattice : DiscreteTopologyDiscreteTopology.{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 :
      DiscreteTopologyDiscreteTopology.{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))
    complete
Proof

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}.

Lemma4.8
Group: Basic structural and arithmetic properties of E8. (4)
Hover another entry in this group to preview it.
Preview
Lemma 4.4
Loading preview
Hover a group entry to preview it.
L∃∀Nused by 0

c\Lambda_8 is a \Z-lattice, that is, it is discrete and spans \R^8 over \R. This uses Lemma 4.7 and Lemma 4.4.

Lean code for Lemma4.81 theorem
  • theorem instIsZLatticeE8Lattice : IsZLatticeIsZLattice.{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 :
      IsZLatticeIsZLattice.{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))
    complete
Proof

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.

Definition4.9
Group: Definition and density computation of the E8 sphere packing. (2)
Hover another entry in this group to preview it.
Preview
Lemma 4.10
Loading preview
Hover a group entry to preview it.
L∃∀Nused by 1

The E_8 sphere packing is the (periodic) sphere packing with separation \sqrt{2}, whose set of centres is \Lambda_8. Uses Lemma 4.5 and Lemma 4.6.

Lean code for Definition4.91 definition
  • def E8Packing : PeriodicSpherePackingPeriodicSpherePacking (d : ℕ) : Type 8
    def E8Packing : PeriodicSpherePackingPeriodicSpherePacking (d : ℕ) : Type 8
    complete
Lemma4.10
Group: Definition and density computation of the E8 sphere packing. (2)
Hover another entry in this group to preview it.
Preview
Definition 4.9
Loading preview
Hover a group entry to preview it.
L∃∀Nused by 1

\Vol{\Lambda_8} = \mathrm{Covol}(\R^8 / \Lambda_8) = 1. This uses Definition 4.9.

Lean code for Lemma4.101 theorem
  • theorem E8Basis_volume :
      MeasureTheory.volumeMeasureTheory.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
    theorem E8Basis_volume :
      MeasureTheory.volumeMeasureTheory.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
    complete
Proof

TODO: In theory this should follow directly from \det(\Lambda_8) = 1, but Lean hates me and EuclideanSpace is being annoying.

Theorem4.11
Group: Definition and density computation of the E8 sphere packing. (2)
Hover another entry in this group to preview it.
Preview
Definition 4.9
Loading preview
Hover a group entry to preview it.
L∃∀Nused by 1

We have \Delta_{\mathcal{P}(E_8)} = \frac{\pi^4}{384}. Uses Theorem 3.5 and Lemma 4.10.

Lean code for Theorem4.111 theorem
  • theorem E8Packing_density : E8PackingE8Packing : 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
    theorem E8Packing_density :
      E8PackingE8Packing : 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
    complete
Proof

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).