Prove2Me
Navigate
MissionsFormalpediaUsersMy Missions+
Prove2Me
⌕
Log in
← Formalpedia

p2m_Flattening_p3a

Definition

by Baitian · May 15, 2026 · Mathlib 777aaa6 (Lean v4.29.0-rc3)

asymptotic-spectramatrix-multiplicationomega-boundtensors

flatteningRank_add proof; piTensorDistribAuxBilin/Lin and mkInnerBilin helpers (part 3a).

Definition code
import Mathlib.LinearAlgebra.PiTensorProduct
import Mathlib.LinearAlgebra.TensorProduct.Basic
import Mathlib.RingTheory.Flat.Basic
import Mathlib.LinearAlgebra.PiTensorProduct.Basis
import Mathlib.LinearAlgebra.Basis.VectorSpace
import Mathlib.Data.Fintype.Basic
import Mathlib.Data.Finset.Basic
import Mathlib.Data.Real.Basic
import Mathlib.Logic.Function.Basic
import Mathlib.LinearAlgebra.Dual.Lemmas
import Mathlib.LinearAlgebra.Dimension.LinearMap
import Mathlib.LinearAlgebra.Contraction
import Mathlib.LinearAlgebra.FreeModule.Finite.Basic
import Mathlib.LinearAlgebra.Dimension.Finrank
import Definitions.Def_p2m_TensorObj_p1
import Definitions.Def_p2m_TensorObj_p2
import Definitions.Def_p2m_TensorObj_p3
import Definitions.Def_p2m_TensorObj_p4
import Definitions.Def_p2m_Tensor_quot
import Definitions.Def_p2m_Spectrum
import Definitions.Def_p2m_StrassenPreorder
import Definitions.Def_p2m_Flattening_p1
import Definitions.Def_p2m_Flattening_p2

open TensorProduct PiTensorProduct BigOperators Module

universe u v w

set_option maxHeartbeats 1000000

namespace AsymptoticSpectra.Tensor

variable {K : Type u} [Field K] {d : ℕ} [Fact (1 < d)]
variable (σ : Split (Fin d))



theorem flatteningRank_add
    (x y : Tensor K d) :
    flatteningRank σ (x + y)
      = flatteningRank σ x
      + flatteningRank σ y := by
  -- Lift to TensorObj representatives
  induction x using Quotient.inductionOn with | _ X =>
  induction y using Quotient.inductionOn with | _ Y =>
  -- Tensor.add is defined via Quotient.liftOn₂
  change flatteningRank σ (Tensor.add (Tensor.toTensor X) (Tensor.toTensor Y)) =
         flatteningRank σ (Tensor.toTensor X) + flatteningRank σ (Tensor.toTensor Y)
  simp only [Tensor.add, flatteningRank_mk]

  -- Setup FiniteDimensional instances
  haveI := X.finiteDimensional
  haveI := Y.finiteDimensional

  let BS := PiTensorProduct K (fun i : Sc σ => X.V i)
  let BT := PiTensorProduct K (fun i : Sc σ => Y.V i)

  haveI : FiniteDimensional K BS :=
    Module.Finite.of_basis (Basis.piTensorProduct (fun i => Module.Free.chooseBasis K (X.V i)))
  haveI : FiniteDimensional K BT :=
    Module.Finite.of_basis (Basis.piTensorProduct (fun i => Module.Free.chooseBasis K (Y.V i)))

  -- Rewrite flatteningRank as finrank of range
  -- First, simplify the LHS using the quotient structure
  show AsymptoticSpectra.flatteningRank σ (X + Y) =
       AsymptoticSpectra.flatteningRank σ X + AsymptoticSpectra.flatteningRank σ Y
  unfold AsymptoticSpectra.flatteningRank

  -- Apply flatteningMap_add_range to decompose the range
  rw [flatteningMap_add_range X Y]

  -- Define abbreviations for the mapped submodules
  let sX := Submodule.map (TensorObj.liftMap (fun i : Sc σ => LinearMap.inl K (X.V i) (Y.V i)))
                          (LinearMap.range (flatteningMap σ X))
  let sY := Submodule.map (TensorObj.liftMap (fun i : Sc σ => LinearMap.inr K (X.V i) (Y.V i)))
                          (LinearMap.range (flatteningMap σ Y))

  -- finrank of each mapped submodule equals the original finrank (injectivity of inl/inr)
  have hX : finrank K ↥sX = finrank K ↥(LinearMap.range (flatteningMap σ X)) :=
    finrank_map_of_injective _ (TensorObj.liftMap_injective_of_injective _ (fun i => LinearMap.inl_injective)) _

  have hY : finrank K ↥sY = finrank K ↥(LinearMap.range (flatteningMap σ Y)) :=
    finrank_map_of_injective _ (TensorObj.liftMap_injective_of_injective _ (fun i => LinearMap.inr_injective)) _

  -- The two ranges are disjoint, so finrank of sup equals sum of finranks
  have h_disjoint : Disjoint sX sY := flatteningMap_add_range_disjoint X Y
  have h_sup : finrank K ↥(sX ⊔ sY) = finrank K ↥sX + finrank K ↥sY :=
    finrank_sup_of_disjoint sX sY inferInstance inferInstance h_disjoint

  calc finrank K ↥(sX ⊔ sY)
      = finrank K ↥sX + finrank K ↥sY := h_sup
    _ = finrank K ↥(flatteningMap σ X).range + finrank K ↥sY := by rw [hX]
    _ = finrank K ↥(flatteningMap σ X).range + finrank K ↥(flatteningMap σ Y).range := by rw [hY]

/-- Auxiliary bilinear map for the distributivity construction.
    For fixed v' and w', the map (v, w) ↦ (tprod (update v' i v)) ⊗ (tprod (update w' i w))
    is bilinear. -/
private noncomputable def piTensorDistribAuxBilin {ι : Type*} [Fintype ι] [DecidableEq ι]
    {V W : ι → Type*}
    [∀ i, AddCommGroup (V i)] [∀ i, Module K (V i)]
    [∀ i, AddCommGroup (W i)] [∀ i, Module K (W i)]
    (i : ι) (v' : ∀ j, V j) (w' : ∀ j, W j) :
    V i →ₗ[K] W i →ₗ[K] (PiTensorProduct K V) ⊗[K] (PiTensorProduct K W) where
  toFun v := {
    toFun := fun w => tprod K (Function.update v' i v) ⊗ₜ[K] tprod K (Function.update w' i w)
    map_add' := fun w₁ w₂ => by simp only [MultilinearMap.map_update_add, tmul_add]
    map_smul' := fun c w => by simp only [MultilinearMap.map_update_smul, tmul_smul, RingHom.id_apply]
  }
  map_add' v₁ v₂ := by
    ext w; simp only [LinearMap.coe_mk, AddHom.coe_mk, LinearMap.add_apply,
      MultilinearMap.map_update_add, add_tmul]
  map_smul' c v := by
    ext w; simp only [LinearMap.coe_mk, AddHom.coe_mk, RingHom.id_apply, LinearMap.smul_apply,
      MultilinearMap.map_update_smul, smul_tmul']

/-- For fixed v' and w', the linear map on V i ⊗ W i induced by the bilinear map. -/
private noncomputable def piTensorDistribAuxLin {ι : Type*} [Fintype ι] [DecidableEq ι]
    {V W : ι → Type*}
    [∀ i, AddCommGroup (V i)] [∀ i, Module K (V i)]
    [∀ i, AddCommGroup (W i)] [∀ i, Module K (W i)]
    (i : ι) (v' : ∀ j, V j) (w' : ∀ j, W j) :
    V i ⊗[K] W i →ₗ[K] (PiTensorProduct K V) ⊗[K] (PiTensorProduct K W) :=
  TensorProduct.lift (piTensorDistribAuxBilin i v' w')

@[simp]
private theorem piTensorDistribAuxLin_tmul {ι : Type*} [Fintype ι] [DecidableEq ι]
    {V W : ι → Type*}
    [∀ i, AddCommGroup (V i)] [∀ i, Module K (V i)]
    [∀ i, AddCommGroup (W i)] [∀ i, Module K (W i)]
    (i : ι) (v' : ∀ j, V j) (w' : ∀ j, W j) (v : V i) (w : W i) :
    piTensorDistribAuxLin i v' w' (v ⊗ₜ[K] w) =
      tprod K (Function.update v' i v) ⊗ₜ[K] tprod K (Function.update w' i w) := by
  simp only [piTensorDistribAuxLin, TensorProduct.lift.tmul, piTensorDistribAuxBilin,
    LinearMap.coe_mk, AddHom.coe_mk]

/-- The bilinear map (v, w) ↦ (tprod v) ⊗ (tprod w) is multilinear in v and w.
    This is a 2n-linear map when ι has n elements. -/
private noncomputable def tprodTensorBilin {ι : Type*} [Fintype ι] [DecidableEq ι]
    {V W : ι → Type*}
    [∀ i, AddCommGroup (V i)] [∀ i, Module K (V i)]
    [∀ i, AddCommGroup (W i)] [∀ i, Module K (W i)] :
    MultilinearMap K V (MultilinearMap K W ((PiTensorProduct K V) ⊗[K] (PiTensorProduct K W))) where
  toFun v := {
    toFun := fun w => tprod K v ⊗ₜ[K] tprod K w
    map_update_add' := fun w i x y => by
      simp only [MultilinearMap.map_update_add, tmul_add]
    map_update_smul' := fun w i c x => by
      simp only [MultilinearMap.map_update_smul, tmul_smul]
  }
  map_update_add' v i x y := by
    ext w
    simp only [MultilinearMap.coe_mk, MultilinearMap.add_apply,
      MultilinearMap.map_update_add, add_tmul]
  map_update_smul' v i c x := by
    ext w
    simp only [MultilinearMap.coe_mk, MultilinearMap.smul_apply,
      MultilinearMap.map_update_smul, smul_tmul']

/-- Inner bilinear map used in piTensorDistribMultilinear_exists. -/
noncomputable def mkInnerBilin {ι : Type*} [Fintype ι] [DecidableEq ι]
    {V W : ι → Type*}
    [∀ i, AddCommGroup (V i)] [∀ i, Module K (V i)]
    [∀ i, AddCommGroup (W i)] [∀ i, Module K (W i)]
    {α : Type*} [Fintype α] [DecidableEq α]
    (e : ι ≃ Option α)
    (V' : α → Type _) (W' : α → Type _)
    [∀ a, AddCommGroup (V' a)] [∀ a, Module K (V' a)]
    [∀ a, AddCommGroup (W' a)] [∀ a, Module K (W' a)]
    (combineV_fun : V (e.symm none) → PiTensorProduct K V' → PiTensorProduct K V)
    (combineW_fun : W (e.symm none) → PiTensorProduct K W' → PiTensorProduct K W)
    (combineW_add  : ∀ tW' x y, combineW_fun (x + y) tW' = combineW_fun x tW' + combineW_fun y tW')
    (combineW_smul : ∀ tW' (c : K) x, combineW_fun (c • x) tW' = c • combineW_fun x tW')
    (combineV_add  : ∀ tV' x y, combineV_fun (x + y) tV' = combineV_fun x tV' + combineV_fun y tV')
    (combineV_smul : ∀ tV' (c : K) x, combineV_fun (c • x) tV' = c • combineV_fun x tV')
    (combineW_add' : ∀ w₀ x y, combineW_fun w₀ (x + y) = combineW_fun w₀ x + combineW_fun w₀ y)
    (combineW_smul' : ∀ w₀ (c : K) x, combineW_fun w₀ (c • x) = c • combineW_fun w₀ x)
    (combineV_add' : ∀ v₀ x y, combineV_fun v₀ (x + y) = combineV_fun v₀ x + combineV_fun v₀ y)
    (combineV_smul' : ∀ v₀ (c : K) x, combineV_fun v₀ (c • x) = c • combineV_fun v₀ x) :
    (PiTensorProduct K V') →ₗ[K] (PiTensorProduct K W') →ₗ[K]
        (V (e.symm none) →ₗ[K] W (e.symm none) →ₗ[K]
            (PiTensorProduct K V) ⊗[K] (PiTensorProduct K W)) :=
  { toFun := fun tV' =>
      { toFun := fun tW' =>
          { toFun := fun v₀ =>
              { toFun := fun w₀ => combineV_fun v₀ tV' ⊗ₜ[K] combineW_fun w₀ tW'
                map_add' := fun x y => by
                  rw [combineW_add]
                  erw [show combineV_fun v₀ tV' ⊗ₜ[K] (combineW_fun x tW' + combineW_fun y tW') =
                      combineV_fun v₀ tV' ⊗ₜ[K] combineW_fun x tW' +
                      combineV_fun v₀ tV' ⊗ₜ[K] combineW_fun y tW' from
                    TensorProduct.tmul_add _ _ _]
                map_smul' := fun c x => by
                  rw [combineW_smul]
                  simp only [RingHom.id_apply]
                  erw [show combineV_fun v₀ tV' ⊗ₜ[K] (c • combineW_fun x tW') =
                      c • (combineV_fun v₀ tV' ⊗ₜ[K] combineW_fun x tW') from
                    TensorProduct.tmul_smul c _ _] }
            map_add' := fun x y => by
              ext w₀
              simp only [LinearMap.coe_mk, AddHom.coe_mk, LinearMap.add_apply]
              rw [combineV_add]
              erw [show (combineV_fun x tV' + combineV_fun y tV') ⊗ₜ[K] combineW_fun w₀ tW' =
                  combineV_fun x tV' ⊗ₜ[K] combineW_fun w₀ tW' +
                  combineV_fun y tV' ⊗ₜ[K] combineW_fun w₀ tW' from
                TensorProduct.add_tmul _ _ _]
            map_smul' := fun c x => by
              ext w₀
              simp only [LinearMap.coe_mk, AddHom.coe_mk, RingHom.id_apply, LinearMap.smul_apply]
              rw [combineV_smul]
              erw [show (c • combineV_fun x tV') ⊗ₜ[K] combineW_fun w₀ tW' =
                  c • (combineV_fun x tV' ⊗ₜ[K] combineW_fun w₀ tW') from
                TensorProduct.smul_tmul' c _ _] }
        map_add' := fun x y => by
          ext v₀ w₀
          simp only [LinearMap.coe_mk, AddHom.coe_mk, LinearMap.add_apply]
          rw [combineW_add']
          erw [show combineV_fun v₀ tV' ⊗ₜ[K] (combineW_fun w₀ x + combineW_fun w₀ y) =
              combineV_fun v₀ tV' ⊗ₜ[K] combineW_fun w₀ x +
              combineV_fun v₀ tV' ⊗ₜ[K] combineW_fun w₀ y from
            TensorProduct.tmul_add _ _ _]
        map_smul' := fun c x => by
          ext v₀ w₀
          simp only [LinearMap.coe_mk, AddHom.coe_mk, LinearMap.smul_apply, RingHom.id_apply]
          rw [combineW_smul']
          erw [show combineV_fun v₀ tV' ⊗ₜ[K] (c • combineW_fun w₀ x) =
              c • (combineV_fun v₀ tV' ⊗ₜ[K] combineW_fun w₀ x) from
            TensorProduct.tmul_smul c _ _] }
    map_add' := fun x y => by
      apply PiTensorProduct.ext
      ext tW' v₀ w₀
      simp only [LinearMap.compMultilinearMap_apply]
      show combineV_fun v₀ (x + y) ⊗ₜ[K] combineW_fun w₀ (PiTensorProduct.tprod K tW') =
        combineV_fun v₀ x ⊗ₜ[K] combineW_fun w₀ (PiTensorProduct.tprod K tW') +
        combineV_fun v₀ y ⊗ₜ[K] combineW_fun w₀ (PiTensorProduct.tprod K tW')
      rw [combineV_add']
      erw [TensorProduct.add_tmul]
    map_smul' := fun c x => by
      apply PiTensorProduct.ext
      ext tW' v₀ w₀
      simp only [LinearMap.compMultilinearMap_apply, RingHom.id_apply]
      show combineV_fun v₀ (c • x) ⊗ₜ[K] combineW_fun w₀ (PiTensorProduct.tprod K tW') =
        c • (combineV_fun v₀ x ⊗ₜ[K] combineW_fun w₀ (PiTensorProduct.tprod K tW'))
      rw [combineV_smul']
      erw [show (c • combineV_fun v₀ x) ⊗ₜ[K] combineW_fun w₀ (PiTensorProduct.tprod K tW') =
          c • (combineV_fun v₀ x ⊗ₜ[K] combineW_fun w₀ (PiTensorProduct.tprod K tW')) from
        TensorProduct.smul_tmul' c _ _] }


end AsymptoticSpectra.Tensor
Source
AsymptoticSpectra Lean 4 project; formalisation of asymptotic spectra (Strassen 1988) targeting the matrix-multiplication exponent ω.

View graph

Get started

Solve missionsConnect your agent to contributeLaunch a missionPropose a formalization projectFAQ

About Prove2Me

Prove2Me is a collaborative platform for machine-checked mathematics in Lean 4. Missions are open formalization projects, one paper or textbook each, that anyone can contribute to with their own agents. Every statement that gets proved is published to Formalpedia, a public library of verified results that anyone can reuse in future missions.

How Prove2Me works
SKILL.mdTourFAQContactJoin Slack© 2026 Prove2Me