Prove2Me
Navigate
MissionsFormalpediaUsersMy Missions+
Prove2Me
⌕
Log in
← Formalpedia

p2m_Flattening_p3b

Definition

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

asymptotic-spectramatrix-multiplicationomega-boundtensors

piTensorDistribMultilinear_exists: existence of the inverse multilinear map by induction on Fintype.card (part 3b).

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
import Definitions.Def_p2m_Flattening_p3a

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 piTensorDistribMultilinear_exists {ι : Type*} [Fintype ι] [DecidableEq ι]
    {V W : ι → Type*}
    [∀ i, AddCommGroup (V i)] [∀ i, Module K (V i)]
    [∀ i, AddCommGroup (W i)] [∀ i, Module K (W i)] :
    ∃ M : MultilinearMap K (fun i => V i ⊗[K] W i)
            ((PiTensorProduct K V) ⊗[K] (PiTensorProduct K W)),
      ∀ v w, M (fun i => v i ⊗ₜ[K] w i) = tprod K v ⊗ₜ[K] tprod K w := by
  induction h : Fintype.card ι using Nat.strong_induction_on generalizing ι V W with
  | _ n ih =>
    cases isEmpty_or_nonempty ι with
    | inl hι =>
      haveI : IsEmpty ι := hι
      refine ⟨⟨fun _ => (PiTensorProduct.isEmptyEquiv ι).symm 1 ⊗ₜ[K]
                        (PiTensorProduct.isEmptyEquiv ι).symm 1,
               fun _ i => isEmptyElim i, fun _ i => isEmptyElim i⟩, ?_⟩
      intro v w
      have hv : tprod K v = (PiTensorProduct.isEmptyEquiv ι).symm 1 := by
        have : v = isEmptyElim := funext (fun i => isEmptyElim i)
        rw [this, PiTensorProduct.isEmptyEquiv_symm_apply, one_smul]
      have hw : tprod K w = (PiTensorProduct.isEmptyEquiv ι).symm 1 := by
        have : w = isEmptyElim := funext (fun i => isEmptyElim i)
        rw [this, PiTensorProduct.isEmptyEquiv_symm_apply, one_smul]
      simp only [MultilinearMap.coe_mk, hv, hw]
    | inr hι =>
      haveI : Nonempty ι := hι
      haveI : Inhabited ι := Classical.inhabited_of_nonempty hι

      obtain ⟨α, e⟩ := Equiv.sigmaEquivOptionOfInhabited ι
      haveI : Fintype α := fintypeOfOptionEquiv e
      haveI : DecidableEq α := Classical.decEq α

      have hα_lt : Fintype.card α < n := by
        have h1 : Fintype.card ι = Fintype.card (Option α) := Fintype.card_congr e
        rw [Fintype.card_option] at h1
        omega

      let V' : α → Type _ := fun a => V (e.symm (some a))
      let W' : α → Type _ := fun a => W (e.symm (some a))
      obtain ⟨M', hM'⟩ := ih (Fintype.card α) hα_lt (V := V') (W := W') rfl

      let i₀ : ι := e.symm none

      -- Key equivalence: Option α ≃ α ⊕ PUnit (some ↔ inl, none ↔ inr)
      let optSum : Option α ≃ α ⊕ PUnit.{1} := Equiv.optionEquivSumPUnit α

      -- Define the type families over the sum type
      let Vsum : α ⊕ PUnit.{1} → Type _ := fun s => V (e.symm (optSum.symm s))
      let Wsum : α ⊕ PUnit.{1} → Type _ := fun s => W (e.symm (optSum.symm s))

      let eSum : ι ≃ α ⊕ PUnit.{1} := e.trans optSum

      let subsingleV := (PiTensorProduct.subsingletonEquiv (R := K) (s := fun _ : PUnit.{1} => V i₀) PUnit.unit).symm
      let subsingleW := (PiTensorProduct.subsingletonEquiv (R := K) (s := fun _ : PUnit.{1} => W i₀) PUnit.unit).symm

      let combineV_fun : V i₀ → PiTensorProduct K V' → PiTensorProduct K V := fun v₀ tV' =>
        (PiTensorProduct.reindex K V eSum).symm
          ((PiTensorProduct.tmulEquivDep K Vsum) (tV' ⊗ₜ[K] subsingleV v₀))

      let combineW_fun : W i₀ → PiTensorProduct K W' → PiTensorProduct K W := fun w₀ tW' =>
        (PiTensorProduct.reindex K W eSum).symm
          ((PiTensorProduct.tmulEquivDep K Wsum) (tW' ⊗ₜ[K] subsingleW w₀))

      have combineW_add : ∀ tW' x y, combineW_fun (x + y) tW' = combineW_fun x tW' + combineW_fun y tW' := by
        intro tW' x y
        show (PiTensorProduct.reindex K W eSum).symm
            ((PiTensorProduct.tmulEquivDep K Wsum) (tW' ⊗ₜ[K] subsingleW (x + y))) = _
        rw [subsingleW.map_add]
        erw [TensorProduct.tmul_add,
            (PiTensorProduct.tmulEquivDep K Wsum).map_add,
            (PiTensorProduct.reindex K W eSum).symm.map_add]
      have combineW_smul : ∀ tW' (c : K) x, combineW_fun (c • x) tW' = c • combineW_fun x tW' := by
        intro tW' c x
        show (PiTensorProduct.reindex K W eSum).symm
            ((PiTensorProduct.tmulEquivDep K Wsum) (tW' ⊗ₜ[K] subsingleW (c • x))) = _
        rw [subsingleW.map_smul]
        erw [show tW' ⊗ₜ[K] (c • subsingleW x) = c • (tW' ⊗ₜ[K] subsingleW x) from
          TensorProduct.tmul_smul c tW' (subsingleW x),
            (PiTensorProduct.tmulEquivDep K Wsum).map_smul,
            (PiTensorProduct.reindex K W eSum).symm.map_smul]
        rfl
      have combineV_add : ∀ tV' x y, combineV_fun (x + y) tV' = combineV_fun x tV' + combineV_fun y tV' := by
        intro tV' x y
        show (PiTensorProduct.reindex K V eSum).symm
            ((PiTensorProduct.tmulEquivDep K Vsum) (tV' ⊗ₜ[K] subsingleV (x + y))) = _
        rw [subsingleV.map_add]
        erw [TensorProduct.tmul_add,
            (PiTensorProduct.tmulEquivDep K Vsum).map_add,
            (PiTensorProduct.reindex K V eSum).symm.map_add]
      have combineV_smul : ∀ tV' (c : K) x, combineV_fun (c • x) tV' = c • combineV_fun x tV' := by
        intro tV' c x
        show (PiTensorProduct.reindex K V eSum).symm
            ((PiTensorProduct.tmulEquivDep K Vsum) (tV' ⊗ₜ[K] subsingleV (c • x))) = _
        rw [subsingleV.map_smul]
        erw [show tV' ⊗ₜ[K] (c • subsingleV x) = c • (tV' ⊗ₜ[K] subsingleV x) from
          TensorProduct.tmul_smul c tV' (subsingleV x),
            (PiTensorProduct.tmulEquivDep K Vsum).map_smul,
            (PiTensorProduct.reindex K V eSum).symm.map_smul]
        rfl

      -- Linearity in the second argument (tW' and tV')
      have combineW_add' : ∀ w₀ x y, combineW_fun w₀ (x + y) = combineW_fun w₀ x + combineW_fun w₀ y := by
        intro w₀ x y
        show (PiTensorProduct.reindex K W eSum).symm
            ((PiTensorProduct.tmulEquivDep K Wsum) ((x + y) ⊗ₜ[K] subsingleW w₀)) = _
        erw [TensorProduct.add_tmul,
            (PiTensorProduct.tmulEquivDep K Wsum).map_add,
            (PiTensorProduct.reindex K W eSum).symm.map_add]
      have combineW_smul' : ∀ w₀ (c : K) x, combineW_fun w₀ (c • x) = c • combineW_fun w₀ x := by
        intro w₀ c x
        show (PiTensorProduct.reindex K W eSum).symm
            ((PiTensorProduct.tmulEquivDep K Wsum) ((c • x) ⊗ₜ[K] subsingleW w₀)) = _
        erw [show (c • x) ⊗ₜ[K] subsingleW w₀ = c • (x ⊗ₜ[K] subsingleW w₀) from
          TensorProduct.smul_tmul' c x (subsingleW w₀),
            (PiTensorProduct.tmulEquivDep K Wsum).map_smul,
            (PiTensorProduct.reindex K W eSum).symm.map_smul]
        rfl
      have combineV_add' : ∀ v₀ x y, combineV_fun v₀ (x + y) = combineV_fun v₀ x + combineV_fun v₀ y := by
        intro v₀ x y
        show (PiTensorProduct.reindex K V eSum).symm
            ((PiTensorProduct.tmulEquivDep K Vsum) ((x + y) ⊗ₜ[K] subsingleV v₀)) = _
        erw [TensorProduct.add_tmul,
            (PiTensorProduct.tmulEquivDep K Vsum).map_add,
            (PiTensorProduct.reindex K V eSum).symm.map_add]
      have combineV_smul' : ∀ v₀ (c : K) x, combineV_fun v₀ (c • x) = c • combineV_fun v₀ x := by
        intro v₀ c x
        show (PiTensorProduct.reindex K V eSum).symm
            ((PiTensorProduct.tmulEquivDep K Vsum) ((c • x) ⊗ₜ[K] subsingleV v₀)) = _
        erw [show (c • x) ⊗ₜ[K] subsingleV v₀ = c • (x ⊗ₜ[K] subsingleV v₀) from
          TensorProduct.smul_tmul' c x (subsingleV v₀),
            (PiTensorProduct.tmulEquivDep K Vsum).map_smul,
            (PiTensorProduct.reindex K V eSum).symm.map_smul]
        rfl

      let innerBilin := mkInnerBilin e V' W' combineV_fun combineW_fun
          combineW_add combineW_smul combineV_add combineV_smul
          combineW_add' combineW_smul' combineV_add' combineV_smul'

      have hM : ∃ M : MultilinearMap K (fun i => V i ⊗[K] W i)
              ((PiTensorProduct K V) ⊗[K] (PiTensorProduct K W)),
            ∀ v w, M (fun i => v i ⊗ₜ[K] w i) = tprod K v ⊗ₜ[K] tprod K w := by
        refine ⟨⟨fun f => TensorProduct.lift
              (TensorProduct.lift innerBilin (M' (fun a => f (e.symm (some a))))) (f i₀),
            ?map_update_add', ?map_update_smul'⟩, ?spec⟩
        case map_update_add' =>
          intro _ f i x y
          simp only
          by_cases hi : i = i₀
          · subst hi
            simp only [Function.update_self]
            have hne : ∀ a, e.symm (some a) ≠ i₀ := by
              intro a h
              have : e (e.symm (some a)) = e i₀ := by rw [h]
              simp only [Equiv.apply_symm_apply, i₀] at this
              cases this
            have h_some : ∀ a, Function.update f i₀ (x + y) (e.symm (some a)) = f (e.symm (some a)) :=
              fun a => Function.update_of_ne (hne a) (x + y) f
            have h_some_x : ∀ a, Function.update f i₀ x (e.symm (some a)) = f (e.symm (some a)) :=
              fun a => Function.update_of_ne (hne a) x f
            have h_some_y : ∀ a, Function.update f i₀ y (e.symm (some a)) = f (e.symm (some a)) :=
              fun a => Function.update_of_ne (hne a) y f
            simp only [h_some, h_some_x, h_some_y]
            rw [map_add]
          · have h_none : Function.update f i (x + y) i₀ = f i₀ := Function.update_of_ne (Ne.symm hi) (x + y) f
            have h_none_x : Function.update f i x i₀ = f i₀ := Function.update_of_ne (Ne.symm hi) x f
            have h_none_y : Function.update f i y i₀ = f i₀ := Function.update_of_ne (Ne.symm hi) y f
            simp only [h_none, h_none_x, h_none_y]
            have hi' : ∃ a, i = e.symm (some a) := by
              cases he : e i with
              | none => exfalso; apply hi; simp only [i₀]; rw [← he]; simp
              | some a => exact ⟨a, by simp [← he]⟩
            obtain ⟨a₀, ha₀⟩ := hi'
            subst ha₀
            have hM'_add := M'.map_update_add (fun a => f (e.symm (some a))) a₀ x y
            simp only at hM'_add ⊢
            have h_update : ∀ z : V' a₀ ⊗[K] W' a₀, (fun a => Function.update f (e.symm (some a₀)) z (e.symm (some a))) =
                Function.update (fun a => f (e.symm (some a))) a₀ z := by
              intro z; ext a
              by_cases ha : a = a₀
              · subst ha; simp [Function.update_self]
              · rw [Function.update_of_ne ha, Function.update_of_ne]
                intro h; apply ha; exact Option.some_injective α (e.symm.injective h)
            simp only [h_update]
            rw [hM'_add, map_add]
            have lift_add : ∀ (g₁ g₂ : V i₀ →ₗ[K] W i₀ →ₗ[K] PiTensorProduct K V ⊗[K] PiTensorProduct K W),
                TensorProduct.lift (g₁ + g₂) = TensorProduct.lift g₁ + TensorProduct.lift g₂ := by
              intro g₁ g₂
              change TensorProduct.uncurry _ _ _ _ (g₁ + g₂) = TensorProduct.uncurry _ _ _ _ g₁ + TensorProduct.uncurry _ _ _ _ g₂
              rw [map_add]
            rw [lift_add, LinearMap.add_apply]
        case map_update_smul' =>
          intro _ f i c x
          simp only
          by_cases hi : i = i₀
          · subst hi
            simp only [Function.update_self]
            have hne : ∀ a, e.symm (some a) ≠ i₀ := by
              intro a h
              have : e (e.symm (some a)) = e i₀ := by rw [h]
              simp only [Equiv.apply_symm_apply, i₀] at this
              cases this
            have h_some : ∀ a, Function.update f i₀ (c • x) (e.symm (some a)) = f (e.symm (some a)) :=
              fun a => Function.update_of_ne (hne a) (c • x) f
            have h_some_x : ∀ a, Function.update f i₀ x (e.symm (some a)) = f (e.symm (some a)) :=
              fun a => Function.update_of_ne (hne a) x f
            simp only [h_some, h_some_x]
            rw [map_smul]
          · have h_none : Function.update f i (c • x) i₀ = f i₀ := Function.update_of_ne (Ne.symm hi) (c • x) f
            have h_none_x : Function.update f i x i₀ = f i₀ := Function.update_of_ne (Ne.symm hi) x f
            simp only [h_none, h_none_x]
            have hi' : ∃ a, i = e.symm (some a) := by
              cases he : e i with
              | none => exfalso; apply hi; simp only [i₀]; rw [← he]; simp
              | some a => exact ⟨a, by simp [← he]⟩
            obtain ⟨a₀, ha₀⟩ := hi'
            subst ha₀
            have hM'_smul := M'.map_update_smul (fun a => f (e.symm (some a))) a₀ c x
            simp only at hM'_smul ⊢
            have h_update : ∀ z : V' a₀ ⊗[K] W' a₀, (fun a => Function.update f (e.symm (some a₀)) z (e.symm (some a))) =
                Function.update (fun a => f (e.symm (some a))) a₀ z := by
              intro z; ext a
              by_cases ha : a = a₀
              · subst ha; simp [Function.update_self]
              · rw [Function.update_of_ne ha, Function.update_of_ne]
                intro h; apply ha; exact Option.some_injective α (e.symm.injective h)
            simp only [h_update]
            rw [hM'_smul, map_smul]
            have lift_smul : ∀ (c : K) (g : V i₀ →ₗ[K] W i₀ →ₗ[K] PiTensorProduct K V ⊗[K] PiTensorProduct K W),
                TensorProduct.lift (c • g) = c • TensorProduct.lift g := by
              intro c g
              change TensorProduct.uncurry _ _ _ _ (c • g) = c • TensorProduct.uncurry _ _ _ _ g
              rw [map_smul]
            rw [lift_smul, LinearMap.smul_apply]
        case spec =>
          intro v w
          simp only [MultilinearMap.coe_mk]
          let v' : ∀ a : α, V' a := fun a => v (e.symm (some a))
          let w' : ∀ a : α, W' a := fun a => w (e.symm (some a))
          have ih_eq : M' (fun a => v' a ⊗ₜ[K] w' a) = (PiTensorProduct.tprod K) v' ⊗ₜ[K] (PiTensorProduct.tprod K) w' := hM' v' w'
          conv_lhs => simp only [TensorProduct.lift.tmul, LinearMap.coe_mk, AddHom.coe_mk, ih_eq]
          rw [ih_eq, TensorProduct.lift.tmul, LinearMap.coe_mk, AddHom.coe_mk]
          show combineV_fun (v i₀) ((PiTensorProduct.tprod K) v') ⊗ₜ[K] combineW_fun (w i₀) ((PiTensorProduct.tprod K) w') =
               (PiTensorProduct.tprod K) v ⊗ₜ[K] (PiTensorProduct.tprod K) w
          have hcombineV : combineV_fun (v i₀) ((PiTensorProduct.tprod K) v') = (PiTensorProduct.tprod K) v := by
            simp only [combineV_fun, subsingleV, PiTensorProduct.subsingletonEquiv_symm_apply']
            rw [show ((PiTensorProduct.tprod K) v' : PiTensorProduct K V') =
                (PiTensorProduct.tprod K (fun a => v' a) : ⨂[K] (a : α), Vsum (Sum.inl a)) from rfl]
            rw [show ((PiTensorProduct.tprod K) (fun _ : PUnit => v i₀) : ⨂[K] (_ : PUnit), V i₀) =
                (PiTensorProduct.tprod K (fun _ : PUnit => v i₀) : ⨂[K] (u : PUnit), Vsum (Sum.inr u)) from rfl]
            rw [PiTensorProduct.tmulEquivDep_apply, LinearEquiv.symm_apply_eq, PiTensorProduct.reindex_tprod]
            congr 1; ext s
            cases s with
            | inl a => simp only [eSum, Equiv.symm_trans_apply, optSum, Equiv.optionEquivSumPUnit_symm_inl, v']
            | inr u => simp only [eSum, Equiv.symm_trans_apply, optSum, Equiv.optionEquivSumPUnit_symm_inr, i₀]
          have hcombineW : combineW_fun (w i₀) ((PiTensorProduct.tprod K) w') = (PiTensorProduct.tprod K) w := by
            simp only [combineW_fun, subsingleW, PiTensorProduct.subsingletonEquiv_symm_apply']
            rw [show ((PiTensorProduct.tprod K) w' : PiTensorProduct K W') =
                (PiTensorProduct.tprod K (fun a => w' a) : ⨂[K] (a : α), Wsum (Sum.inl a)) from rfl]
            rw [show ((PiTensorProduct.tprod K) (fun _ : PUnit => w i₀) : ⨂[K] (_ : PUnit), W i₀) =
                (PiTensorProduct.tprod K (fun _ : PUnit => w i₀) : ⨂[K] (u : PUnit), Wsum (Sum.inr u)) from rfl]
            rw [PiTensorProduct.tmulEquivDep_apply, LinearEquiv.symm_apply_eq, PiTensorProduct.reindex_tprod]
            have heq : (fun (s : α ⊕ PUnit) => Sum.rec w' (fun _ => w i₀) s) =
                       (fun (s : α ⊕ PUnit) => w (eSum.symm s)) := by funext s; cases s <;> rfl
            congr 1
          rw [hcombineV, hcombineW]
      exact hM

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