Imports
/-
Copyright (c) 2026 Robert Sneiderman. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Robert Sneiderman
-/
module
public import Physlib.Relativity.Tensors.RealTensor.Basic
public import Physlib.Relativity.Tensors.UnitTensor
public import Physlib.Meta.Sorry
public import Physlib.Relativity.Tensors.OfInt
public import Physlib.Mathematics.KroneckerDelta.BasicThe Levi-Civita tensor as a real Lorentz tensor
i. Overview
This file defines the rank-four Levi-Civita tensor εᵘᵛᵖᵟ as a real Lorentz tensor in
d = 3 spatial dimensions, with ε⁰¹²³ = 1, and proves its antisymmetry under each
adjacent transposition of indices.
The component on a multi-index f is the generalized Kronecker delta of f against the
identity, i.e. the sign of f when f is a permutation and 0 otherwise. The integer
components are carried by TensorSpecies.Tensor.TensorInt.toTensor.
ii. Key results
leviCivita : the rank-four Levi-Civita tensor ε4, with ε⁰¹²³ = 1.
leviCivita_basis_repr_apply : its standard-basis components as a generalized Kronecker delta.
leviCivita_antisymm, leviCivita_antisymm_mid, leviCivita_antisymm_last : antisymmetry
under each adjacent transposition of the indices.
iii. Table of contents
A. Definition
B. Components in the standard basis
C. Antisymmetry
iv. References
@[expose] public sectionA. Definition
The Levi-Civita tensor εᵘᵛᵖᵟ as a real Lorentz tensor.
scoped[realLorentzTensor] notation "ε4" => leviCivita
The TensorInt.toTensor form of the Levi-Civita tensor.
lemma leviCivita_eq_ofInt : ε4 =
TensorInt.toTensor (S := realLorentzTensor 3)
(c := ![Color.up, Color.up, Color.up, Color.up]) fun f =>
generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) (id : Fin 4 → Fin 4) :=
rfl
The Euclidean Levi-Civita symbol ε_{ijkl} in dimension 4.
def _root_.euclidLeviCivita (g : Fin 4 → Fin 4) : ℝ :=
generalizedKroneckerDelta g (id : Fin 4 → Fin 4)B. Components in the standard basis
The components of the Levi-Civita tensor in the standard basis are the generalized Kronecker delta of the multi-index against the identity.
All goals completed! 🐙
The Levi-Civita tensor vanishes on any multi-index with a repeated value: if two distinct
index positions i ≠ j carry the same basis index, the component is zero.
lemma leviCivita_basis_repr_eq_zero_of_eq
{b : ComponentIdx (S := realLorentzTensor 3) ![Color.up, Color.up, Color.up, Color.up]}
{i j : Fin 4} (hij : i ≠ j) (h : b i = b j) :
(Tensor.basis _).repr ε4 b = 0 := by b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b j⊢ ((basis ![Color.up, Color.up, Color.up, Color.up]).repr ε4) b = 0
rw [leviCivita_basis_repr_apply b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b j⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) = 0 b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b j⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) = 0] b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b j⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) = 0
have hdet : generalizedKroneckerDelta (fun i => finSumFinEquiv (b i))
(id : Fin 4 → Fin 4) = 0 := by b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b j⊢ ((basis ![Color.up, Color.up, Color.up, Color.up]).repr ε4) b = 0 b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b jhdet:generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id = 0⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) = 0
rw [show generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) (id : Fin 4 → Fin 4)
= Matrix.det (fun a c => ((kroneckerDelta (finSumFinEquiv (b a)) (id c) : ℕ) : ℤ))
from rfl b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b j⊢ (det fun a c => ↑δ[finSumFinEquiv (b a),id c]) = 0 b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b j⊢ (det fun a c => ↑δ[finSumFinEquiv (b a),id c]) = 0 b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b jhdet:generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id = 0⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) = 0] b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b j⊢ (det fun a c => ↑δ[finSumFinEquiv (b a),id c]) = 0 b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b jhdet:generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id = 0⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) = 0
refine Matrix.det_zero_of_row_eq hij (funext fun c => ?_) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b jc:Fin (Nat.succ 0).succ.succ.succ⊢ ↑δ[finSumFinEquiv (b i),id c] = ↑δ[finSumFinEquiv (b j),id c] b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b jhdet:generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id = 0⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) = 0
rw [congrArg (⇑finSumFinEquiv) h b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b jc:Fin (Nat.succ 0).succ.succ.succ⊢ ↑δ[finSumFinEquiv (b j),id c] = ↑δ[finSumFinEquiv (b j),id c] b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b jhdet:generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id = 0⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) = 0] b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b jhdet:generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id = 0⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) = 0 b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b jhdet:generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id = 0⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) = 0
rw [hdet, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b jhdet:generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id = 0⊢ ↑0 = 0 All goals completed! 🐙 Int.cast_zero b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin 4j:Fin 4hij:i ≠ jh:b i = b jhdet:generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id = 0⊢ 0 = 0 All goals completed! 🐙] All goals completed! 🐙C. Antisymmetry
The Levi-Civita tensor is antisymmetric in its first two indices
{ε4 | μ ν ρ σ = - ε4 | ν μ ρ σ}ᵀ.
lemma leviCivita_antisymm : {ε4 | μ ν ρ σ = - (ε4 | ν μ ρ σ)}ᵀ := by ⊢ ε4 = (permT ![1, 0, 2, 3] ⋯) (-ε4)
apply (Tensor.basis _).repr.injective ⊢ (basis ![Color.up, Color.up, Color.up, Color.up]).repr ε4 =
(basis ![Color.up, Color.up, Color.up, Color.up]).repr ((permT ![1, 0, 2, 3] ⋯) (-ε4))
ext b b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ((basis ![Color.up, Color.up, Color.up, Color.up]).repr ε4) b =
((basis ![Color.up, Color.up, Color.up, Color.up]).repr ((permT ![1, 0, 2, 3] ⋯) (-ε4))) b
rw [permT_basis_repr_symm_apply, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ((basis ![Color.up, Color.up, Color.up, Color.up]).repr ε4) b =
((basis ![Color.up, Color.up, Color.up, Color.up]).repr (-ε4)) fun i =>
(basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) id) leviCivita_eq_ofInt, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ((basis ![Color.up, Color.up, Color.up, Color.up]).repr
(TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
b =
((basis ![Color.up, Color.up, Color.up, Color.up]).repr
(-TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) id) TensorInt.basis_repr_apply, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
((basis ![Color.up, Color.up, Color.up, Color.up]).repr
(-TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) id)
map_neg, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
(-(basis ![Color.up, Color.up, Color.up, Color.up]).repr
(TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) id) Finsupp.neg_apply, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
-((basis ![Color.up, Color.up, Color.up, Color.up]).repr
(TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) id) TensorInt.basis_repr_apply, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
-↑(generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) id) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) id) ← Int.cast_neg b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) id) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) id)] b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) id)
congr 1 b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id =
-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) id
rw [← generalizedKroneckerDelta_swap _ _ (Fin.zero_ne_one (n := 2)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id =
generalizedKroneckerDelta
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 0 1))
id b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id =
generalizedKroneckerDelta
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 0 1))
id] b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id =
generalizedKroneckerDelta
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 0 1))
id
congr 1 e_μ b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ (fun i => finSumFinEquiv (b i)) =
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 0 1)
funext i e_μ b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin (Nat.succ 0).succ.succ.succ⊢ finSumFinEquiv (b i) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 0 1))
i
fin_cases i e_μ.«0» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨0, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 0 1))
((fun i => i) ⟨0, ⋯⟩)e_μ.«1» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨1, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 0 1))
((fun i => i) ⟨1, ⋯⟩)e_μ.«2» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨2, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 0 1))
((fun i => i) ⟨2, ⋯⟩)e_μ.«3» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨3, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 0 1))
((fun i => i) ⟨3, ⋯⟩) <;> e_μ.«0» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨0, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 0 1))
((fun i => i) ⟨0, ⋯⟩)e_μ.«1» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨1, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 0 1))
((fun i => i) ⟨1, ⋯⟩)e_μ.«2» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨2, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 0 1))
((fun i => i) ⟨2, ⋯⟩)e_μ.«3» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨3, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![1, 0, 2, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 0 1))
((fun i => i) ⟨3, ⋯⟩) rfl All goals completed! 🐙
The Levi-Civita tensor is antisymmetric in its middle two indices
{ε4 | μ ν ρ σ = - ε4 | μ ρ ν σ}ᵀ.
lemma leviCivita_antisymm_mid : {ε4 | μ ν ρ σ = - (ε4 | μ ρ ν σ)}ᵀ := by ⊢ ε4 = (permT ![0, 2, 1, 3] ⋯) (-ε4)
apply (Tensor.basis _).repr.injective ⊢ (basis ![Color.up, Color.up, Color.up, Color.up]).repr ε4 =
(basis ![Color.up, Color.up, Color.up, Color.up]).repr ((permT ![0, 2, 1, 3] ⋯) (-ε4))
ext b b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ((basis ![Color.up, Color.up, Color.up, Color.up]).repr ε4) b =
((basis ![Color.up, Color.up, Color.up, Color.up]).repr ((permT ![0, 2, 1, 3] ⋯) (-ε4))) b
rw [permT_basis_repr_symm_apply, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ((basis ![Color.up, Color.up, Color.up, Color.up]).repr ε4) b =
((basis ![Color.up, Color.up, Color.up, Color.up]).repr (-ε4)) fun i =>
(basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) id) leviCivita_eq_ofInt, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ((basis ![Color.up, Color.up, Color.up, Color.up]).repr
(TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
b =
((basis ![Color.up, Color.up, Color.up, Color.up]).repr
(-TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) id) TensorInt.basis_repr_apply, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
((basis ![Color.up, Color.up, Color.up, Color.up]).repr
(-TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) id)
map_neg, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
(-(basis ![Color.up, Color.up, Color.up, Color.up]).repr
(TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) id) Finsupp.neg_apply, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
-((basis ![Color.up, Color.up, Color.up, Color.up]).repr
(TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) id) TensorInt.basis_repr_apply, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
-↑(generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) id) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) id) ← Int.cast_neg b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) id) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) id)] b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) id)
congr 1 b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id =
-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) id
rw [← generalizedKroneckerDelta_swap _ _ (show (1 : Fin 4) ≠ 2 by ⊢ ε4 = (permT ![0, 2, 1, 3] ⋯) (-ε4) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id =
generalizedKroneckerDelta
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 1 2))
id decide All goals completed! 🐙 b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id =
generalizedKroneckerDelta
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 1 2))
id)] b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id =
generalizedKroneckerDelta
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 1 2))
id
congr 1 e_μ b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ (fun i => finSumFinEquiv (b i)) =
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 1 2)
funext i e_μ b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin (Nat.succ 0).succ.succ.succ⊢ finSumFinEquiv (b i) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 1 2))
i
fin_cases i e_μ.«0» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨0, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 1 2))
((fun i => i) ⟨0, ⋯⟩)e_μ.«1» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨1, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 1 2))
((fun i => i) ⟨1, ⋯⟩)e_μ.«2» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨2, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 1 2))
((fun i => i) ⟨2, ⋯⟩)e_μ.«3» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨3, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 1 2))
((fun i => i) ⟨3, ⋯⟩) <;> e_μ.«0» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨0, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 1 2))
((fun i => i) ⟨0, ⋯⟩)e_μ.«1» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨1, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 1 2))
((fun i => i) ⟨1, ⋯⟩)e_μ.«2» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨2, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 1 2))
((fun i => i) ⟨2, ⋯⟩)e_μ.«3» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨3, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 2, 1, 3] ⋯ i))) i)) ∘
⇑(Equiv.swap 1 2))
((fun i => i) ⟨3, ⋯⟩) rfl All goals completed! 🐙
The Levi-Civita tensor is antisymmetric in its last two indices
{ε4 | μ ν ρ σ = - ε4 | μ ν σ ρ}ᵀ.
lemma leviCivita_antisymm_last : {ε4 | μ ν ρ σ = - (ε4 | μ ν σ ρ)}ᵀ := by ⊢ ε4 = (permT ![0, 1, 3, 2] ⋯) (-ε4)
apply (Tensor.basis _).repr.injective ⊢ (basis ![Color.up, Color.up, Color.up, Color.up]).repr ε4 =
(basis ![Color.up, Color.up, Color.up, Color.up]).repr ((permT ![0, 1, 3, 2] ⋯) (-ε4))
ext b b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ((basis ![Color.up, Color.up, Color.up, Color.up]).repr ε4) b =
((basis ![Color.up, Color.up, Color.up, Color.up]).repr ((permT ![0, 1, 3, 2] ⋯) (-ε4))) b
rw [permT_basis_repr_symm_apply, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ((basis ![Color.up, Color.up, Color.up, Color.up]).repr ε4) b =
((basis ![Color.up, Color.up, Color.up, Color.up]).repr (-ε4)) fun i =>
(basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) id) leviCivita_eq_ofInt, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ((basis ![Color.up, Color.up, Color.up, Color.up]).repr
(TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
b =
((basis ![Color.up, Color.up, Color.up, Color.up]).repr
(-TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) id) TensorInt.basis_repr_apply, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
((basis ![Color.up, Color.up, Color.up, Color.up]).repr
(-TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) id)
map_neg, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
(-(basis ![Color.up, Color.up, Color.up, Color.up]).repr
(TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) id) Finsupp.neg_apply, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
-((basis ![Color.up, Color.up, Color.up, Color.up]).repr
(TensorInt.toTensor fun f => generalizedKroneckerDelta (fun i => finSumFinEquiv (f i)) id))
fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i)) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) id) TensorInt.basis_repr_apply, b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
-↑(generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) id) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) id) ← Int.cast_neg b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) id) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) id)] b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ ↑(generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id) =
↑(-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) id)
congr 1 b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id =
-generalizedKroneckerDelta
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) id
rw [← generalizedKroneckerDelta_swap _ _ (show (2 : Fin 4) ≠ 3 by ⊢ ε4 = (permT ![0, 1, 3, 2] ⋯) (-ε4) b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id =
generalizedKroneckerDelta
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) ∘
⇑(Equiv.swap 2 3))
id decide All goals completed! 🐙 b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id =
generalizedKroneckerDelta
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) ∘
⇑(Equiv.swap 2 3))
id)] b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ generalizedKroneckerDelta (fun i => finSumFinEquiv (b i)) id =
generalizedKroneckerDelta
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) ∘
⇑(Equiv.swap 2 3))
id
congr 1 e_μ b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ (fun i => finSumFinEquiv (b i)) =
(fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) ∘
⇑(Equiv.swap 2 3)
funext i e_μ b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]i:Fin (Nat.succ 0).succ.succ.succ⊢ finSumFinEquiv (b i) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) ∘
⇑(Equiv.swap 2 3))
i
fin_cases i e_μ.«0» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨0, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) ∘
⇑(Equiv.swap 2 3))
((fun i => i) ⟨0, ⋯⟩)e_μ.«1» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨1, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) ∘
⇑(Equiv.swap 2 3))
((fun i => i) ⟨1, ⋯⟩)e_μ.«2» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨2, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) ∘
⇑(Equiv.swap 2 3))
((fun i => i) ⟨2, ⋯⟩)e_μ.«3» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨3, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) ∘
⇑(Equiv.swap 2 3))
((fun i => i) ⟨3, ⋯⟩) <;> e_μ.«0» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨0, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) ∘
⇑(Equiv.swap 2 3))
((fun i => i) ⟨0, ⋯⟩)e_μ.«1» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨1, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) ∘
⇑(Equiv.swap 2 3))
((fun i => i) ⟨1, ⋯⟩)e_μ.«2» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨2, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) ∘
⇑(Equiv.swap 2 3))
((fun i => i) ⟨2, ⋯⟩)e_μ.«3» b:ComponentIdx ![Color.up, Color.up, Color.up, Color.up]⊢ finSumFinEquiv (b ((fun i => i) ⟨3, ⋯⟩)) =
((fun i => finSumFinEquiv ((fun i => (basisIdxCongr ⋯) (b (IsReindexing.inv ![0, 1, 3, 2] ⋯ i))) i)) ∘
⇑(Equiv.swap 2 3))
((fun i => i) ⟨3, ⋯⟩) rfl All goals completed! 🐙@[sorryful]
lemma leviCivita_contract_three : {ε4 | μ ν ρ σ ⊗ ε4 | τ(μ) τ(ν) τ(ρ) τ(τ) =
(-6) • unitTensor (S := realLorentzTensor) Color.down | σ τ }ᵀ := by ⊢ (contrT 2 0 2 ⋯)
((contrT 4 1 4 ⋯)
((contrT 6 2 6 ⋯)
((prodT ε4) ((toDualMapAtIndex 3) ((toDualMapAtIndex 2) ((toDualMapAtIndex 1) ((toDualMapAtIndex 0) ε4))))))) =
(permT ![0, 1] ⋯) (-6 • unitTensor Color.down)
sorry All goals completed! 🐙-- `checkType` linter: under the v4.32.0 toolchain, whnf on this tensor-notation
-- statement exceeds the linter's 200k-heartbeat budget (it did not on v4.31.0).
-- Statement unchanged; see the v4.32.0 bump commit message.
@[sorryful, nolint checkType]
lemma leviCivita_contract_self :
{ε4 | μ ν ρ σ ⊗ ε4 | τ(μ) τ(ν) τ(ρ) τ(σ)}ᵀ.toField = - 24 := by ⊢ toField
((contrT 0 0 1 ⋯)
((contrT 2 1 3 ⋯)
((contrT 4 2 5 ⋯)
((contrT 6 3 7 ⋯)
((prodT ε4)
((toDualMapAtIndex 3) ((toDualMapAtIndex 2) ((toDualMapAtIndex 1) ((toDualMapAtIndex 0) ε4))))))))) =
-24
sorry All goals completed! 🐙