Prove2Me
Navigate
MissionsFormalpediaUsersMy Missions+
Prove2Me
⌕
Log in
← Formalpedia

p2m_TensorObj_p1

Definition

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

asymptotic-spectramatrix-multiplicationomega-boundtensors

TensorObj K d: concrete order-d tensors over a field K; addition, multiplication via interchange contraction, Restrict preorder, isomorphism equivalence (part 1).

Definition code
import Mathlib.LinearAlgebra.PiTensorProduct
import Mathlib.LinearAlgebra.FiniteDimensional.Basic
import Mathlib.RingTheory.TensorProduct.Finite
import Mathlib.LinearAlgebra.TensorProduct.Finiteness
import Mathlib.Logic.Basic
import Mathlib.Algebra.Module.ULift
import Mathlib.LinearAlgebra.Prod
import Mathlib.Algebra.Module.PUnit
import Mathlib.LinearAlgebra.TensorProduct.Prod
import Mathlib.LinearAlgebra.TensorProduct.Tower

universe u v w

open BigOperators TensorProduct
open PiTensorProduct

set_option maxHeartbeats 1000000


open BigOperators TensorProduct

-- We open PiTensorProduct, but distinct names prevent clashes with the type
open PiTensorProduct

/-- `TensorObj` represents a single concrete (d)-th order tensor
  t ∈ V₁ ⊗ V₂ ⊗ ⋯ ⊗ V_d over a field K.

  Unlike a coordinate representation, this structure stores the vector spaces
  themselves and an element of their iterated tensor product.

  Arguments:
  * `K`: The base field.
  * `d`: The order of the tensor (must be greater than 1). -/
structure TensorObj (K : Type u) [Field K] (d : ℕ) [Fact (1 < d)] where
  /-- The family of vector spaces involved in the tensor product. -/
  V : Fin d → Type v
  /-- Each space must be an additive commutative group. -/
  [addCommGroup : ∀ i, AddCommGroup (V i)]
  /-- Each space must be a module over K. -/
  [module : ∀ i, Module K (V i)]
  /-- Each space must be finite-dimensional over K. -/
  [finiteDimensional : ∀ i, FiniteDimensional K (V i)]
  /-- The concrete tensor element in the iterated tensor product of the V i. -/
  t : PiTensorProduct K V

attribute [instance] TensorObj.addCommGroup TensorObj.module TensorObj.finiteDimensional

namespace TensorObj


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

noncomputable section

/-- Helper for product of LinearEquivs. -/
def prodEquiv {M M' N N' : Type*} [AddCommMonoid M] [AddCommMonoid M'] [AddCommMonoid N] [AddCommMonoid N']
    [Module K M] [Module K M'] [Module K N] [Module K N']
    (e1 : M ≃ₗ[K] M') (e2 : N ≃ₗ[K] N') : (M × N) ≃ₗ[K] (M' × N') :=
  { toFun := Prod.map e1 e2
    invFun := Prod.map e1.symm e2.symm
    left_inv := fun ⟨x, y⟩ => by simp
    right_inv := fun ⟨x, y⟩ => by simp
    map_add' := fun x y => by
      cases x; cases y
      dsimp [Prod.map]
      simp only [map_add]
    map_smul' := fun c x => by
      cases x
      dsimp [Prod.map]
      simp only [map_smul] }

/-- Helper for commutativity. -/
def prodComm {M N : Type*} [AddCommMonoid M] [AddCommMonoid N] [Module K M] [Module K N] :
    (M × N) ≃ₗ[K] (N × M) :=
  { toFun := Prod.swap
    invFun := Prod.swap
    left_inv := fun ⟨x, y⟩ => by simp
    right_inv := fun ⟨x, y⟩ => by simp
    map_add' := fun x y => by simp
    map_smul' := fun c x => by simp }

/-- Helper for associativity. -/
def prodAssoc {M N P : Type*} [AddCommMonoid M] [AddCommMonoid N] [AddCommMonoid P]
    [Module K M] [Module K N] [Module K P] : ((M × N) × P) ≃ₗ[K] (M × (N × P)) :=
  { toFun := fun ⟨⟨m, n⟩, p⟩ => (m, (n, p))
    invFun := fun ⟨m, ⟨n, p⟩⟩ => ((m, n), p)
    left_inv := fun ⟨⟨m, n⟩, p⟩ => rfl
    right_inv := fun ⟨m, ⟨n, p⟩⟩ => rfl
    map_add' := fun x y => by simp
    map_smul' := fun c x => by simp }

/-- Helper for zero unit. -/
def prodZero {M : Type*} [AddCommMonoid M] [Module K M] : (PUnit × M) ≃ₗ[K] M :=
  { toFun := fun ⟨_, m⟩ => m
    invFun := fun m => (PUnit.unit, m)
    left_inv := fun ⟨u, m⟩ => by simp
    right_inv := fun m => rfl
    map_add' := fun x y => rfl
    map_smul' := fun c x => rfl }

/-- Helper for ULift equivalence. -/
def uliftEquiv : ULift.{v} K ≃ₗ[K] K :=
  { toFun := ULift.down
    invFun := ULift.up
    left_inv := fun _ => rfl
    right_inv := fun _ => rfl
    map_add' := fun _ _ => rfl
    map_smul' := fun _ _ => rfl }

/-- Helper for tensor unit. -/
def tensorOne {V : Type*} [AddCommGroup V] [Module K V] : (ULift.{v} K) ⊗[K] V ≃ₗ[K] V :=
  LinearEquiv.trans (TensorProduct.congr (uliftEquiv) (LinearEquiv.refl K V)) (TensorProduct.lid K V)

/-- Helper for tensor zero. -/
def tensorZero {V : Type*} [AddCommGroup V] [Module K V] : PUnit ⊗[K] V ≃ₗ[K] PUnit :=
  { toFun := fun _ => PUnit.unit
    invFun := fun _ => 0
    left_inv := fun x => by
       -- 0 ⊗ v = 0 = PUnit.unit from iso perspective?
       -- x : PUnit ⊗ V. PUnit is zero module. x=0.
       rw [Subsingleton.elim x 0]

    right_inv := fun x => rfl
    map_add' := fun x y => rfl
    map_smul' := fun c x => rfl }

/-- Helper for left distributivity: M ⊗ (N × P) ≃ (M ⊗ N) × (M ⊗ P). -/
def distribLeft {M N P : Type*} [AddCommGroup M] [AddCommGroup N] [AddCommGroup P]
    [Module K M] [Module K N] [Module K P] : M ⊗[K] (N × P) ≃ₗ[K] (M ⊗[K] N) × (M ⊗[K] P) :=
  TensorProduct.prodRight K K M N P

/-- Helper for right distributivity: (N × P) ⊗ M ≃ (N ⊗ M) × (P ⊗ M). -/
def distribRight {M N P : Type*} [AddCommGroup M] [AddCommGroup N] [AddCommGroup P]
    [Module K M] [Module K N] [Module K P] : (N × P) ⊗[K] M ≃ₗ[K] (N ⊗[K] M) × (P ⊗[K] M) :=
  TensorProduct.prodLeft K K N P M

/-- Functoriality of PiTensorProduct: a family of linear maps induces a map on the tensor product.
    Renamed to `liftMap` to avoid namespace conflicts. -/
def liftMap {ι : Type*} [Fintype ι] {V W : ι → Type*}
    [∀ i, AddCommGroup (V i)] [∀ i, Module K (V i)]
    [∀ i, AddCommGroup (W i)] [∀ i, Module K (W i)]
    (f : ∀ i, V i →ₗ[K] W i) : PiTensorProduct K V →ₗ[K] PiTensorProduct K W :=
  lift <| (tprod K).compLinearMap f

/-- Functoriality of PiTensorProduct: identity map. -/
@[simp]
theorem liftMap_id (X : TensorObj K d) : liftMap (fun _ => LinearMap.id) X.t = X.t := by
  have : liftMap (fun (i : Fin d) => (LinearMap.id : X.V i →ₗ[K] X.V i)) = LinearMap.id := by
    apply PiTensorProduct.ext
    apply MultilinearMap.ext; intro v
    simp [liftMap]
  rw [this]; rfl

/-- Functoriality of PiTensorProduct: composition. -/
theorem liftMap_comp {ι : Type*} [Fintype ι] {V₁ V₂ V₃ : ι → Type*}
    [∀ i, AddCommGroup (V₁ i)] [∀ i, Module K (V₁ i)]
    [∀ i, AddCommGroup (V₂ i)] [∀ i, Module K (V₂ i)]
    [∀ i, AddCommGroup (V₃ i)] [∀ i, Module K (V₃ i)]
    (f : ∀ i, V₂ i →ₗ[K] V₃ i) (g : ∀ i, V₁ i →ₗ[K] V₂ i) (t : PiTensorProduct K V₁) :
    liftMap f (liftMap g t) = liftMap (fun i => (f i).comp (g i)) t := by
  have : liftMap f ∘ₗ liftMap g = liftMap (fun i => (f i).comp (g i)) := by
    apply PiTensorProduct.ext
    apply MultilinearMap.ext; intro v
    simp [liftMap]
  rw [← LinearMap.comp_apply, this]

/-- liftMap on a pure tensor is a pure tensor with each component mapped. -/
theorem liftMap_tprod {ι : Type*} [Fintype ι] {V W : ι → Type*}
    [∀ i, AddCommGroup (V i)] [∀ i, Module K (V i)]
    [∀ i, AddCommGroup (W i)] [∀ i, Module K (W i)]
    (f : ∀ i, V i →ₗ[K] W i) (v : ∀ i, V i) :
    liftMap f (tprod K v) = tprod K (fun i => f i (v i)) := by
  simp only [liftMap, PiTensorProduct.lift.tprod, MultilinearMap.compLinearMap_apply]

/-- Helper to construct interchange map definition -/
def interchangeAux {ι : Type*} [Fintype ι] [DecidableEq ι] {V W : ι → Type*}
    [∀ i, AddCommGroup (V i)] [∀ i, Module K (V i)]
    [∀ i, AddCommGroup (W i)] [∀ i, Module K (W i)]
    (v : ∀ i, V i) : MultilinearMap K W (PiTensorProduct K (fun i => V i ⊗[K] W i)) where
    toFun w := tprod K fun i => v i ⊗ₜ[K] w i
    map_update_add' w i x y := by
      -- h1: Align LHS to a Function.update that matches (tprod K).map_add input
      have h1 : (fun j => v j ⊗ₜ[K] Function.update w i (x + y) j) =
                Function.update (fun j => v j ⊗ₜ[K] w j) i (v i ⊗ₜ[K] (x + y)) := by
        ext j; by_cases h : j = i
        · subst h; simp
        · simp [h]

      -- h2: Break down the updated value
      have h2 : Function.update (fun j => v j ⊗ₜ[K] w j) i (v i ⊗ₜ[K] (x + y)) =
                Function.update (fun j => v j ⊗ₜ[K] w j) i (v i ⊗ₜ[K] x + v i ⊗ₜ[K] y) := by
        simp [TensorProduct.tmul_add]

      -- h3: Align RHS term 1
      have h3 : Function.update (fun j => v j ⊗ₜ[K] w j) i (v i ⊗ₜ[K] x) =
                (fun j => v j ⊗ₜ[K] Function.update w i x j) := by
        ext j; by_cases h : j = i
        · subst h; simp
        · simp [h]

      -- h4: Align RHS term 2
      have h4 : Function.update (fun j => v j ⊗ₜ[K] w j) i (v i ⊗ₜ[K] y) =
                (fun j => v j ⊗ₜ[K] Function.update w i y j) := by
        ext j; by_cases h : j = i
        · subst h; simp
        · simp [h]

      calc
        (tprod K) (fun j => v j ⊗ₜ[K] (Function.update w i (x + y)) j)
        _ = (tprod K) (Function.update (fun j => v j ⊗ₜ[K] w j) i (v i ⊗ₜ[K] (x + y))) := by rw [h1]
        _ = (tprod K) (Function.update (fun j => v j ⊗ₜ[K] w j) i (v i ⊗ₜ[K] x + v i ⊗ₜ[K] y)) := by rw [h2]
        _ = (tprod K) (Function.update (fun j => v j ⊗ₜ[K] w j) i (v i ⊗ₜ[K] x)) +
            (tprod K) (Function.update (fun j => v j ⊗ₜ[K] w j) i (v i ⊗ₜ[K] y)) := by
            rw [MultilinearMap.map_update_add (tprod K) (fun j => v j ⊗ₜ[K] w j) i (v i ⊗ₜ[K] x) (v i ⊗ₜ[K] y)]
        _ = (tprod K) (fun j => v j ⊗ₜ[K] (Function.update w i x) j) +
            (tprod K) (fun j => v j ⊗ₜ[K] (Function.update w i y) j) := by rw [h3, h4]

    map_update_smul' w i c x := by
      have h1 : (fun j => v j ⊗ₜ[K] Function.update w i (c • x) j) =
                Function.update (fun j => v j ⊗ₜ[K] w j) i (v i ⊗ₜ[K] (c • x)) := by
        ext j; by_cases h : j = i
        · subst h; simp
        · simp [h]

      have h2 : Function.update (fun j => v j ⊗ₜ[K] w j) i (v i ⊗ₜ[K] (c • x)) =
                Function.update (fun j => v j ⊗ₜ[K] w j) i (c • (v i ⊗ₜ[K] x)) := by
        simp [TensorProduct.tmul_smul]

      calc
        (tprod K) (fun j => v j ⊗ₜ[K] (Function.update w i (c • x)) j)
        _ = (tprod K) (Function.update (fun j => v j ⊗ₜ[K] w j) i (v i ⊗ₜ[K] (c • x))) := by rw [h1]
        _ = (tprod K) (Function.update (fun j => v j ⊗ₜ[K] w j) i (c • (v i ⊗ₜ[K] x))) := by rw [h2]
        _ = c • (tprod K) (Function.update (fun j => v j ⊗ₜ[K] w j) i (v i ⊗ₜ[K] x)) := by
            rw [MultilinearMap.map_update_smul (tprod K) (fun j => v j ⊗ₜ[K] w j) i c (v i ⊗ₜ[K] x)]
        _ = c • (tprod K) (fun j => v j ⊗ₜ[K] (Function.update w i x) j) := by
            -- Explicitly use map_smul effect on function instead of bad lemma h3
            congr 1; congr; ext j; by_cases h : j = i
            · subst h; simp
            · simp [h]

noncomputable def interchangeMap {ι : 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 (PiTensorProduct K W →ₗ[K] PiTensorProduct K (fun i => V i ⊗[K] W i)) where
    toFun v := lift (interchangeAux v)
    map_update_add' v i x y := by
      apply _root_.PiTensorProduct.ext
      apply MultilinearMap.ext; intro m
      simp only [LinearMap.add_apply, LinearMap.compMultilinearMap_apply]

      simp only [_root_.PiTensorProduct.lift.tprod]
      dsimp [interchangeAux, MultilinearMap.coe_mk]

      have h1 : (fun j => Function.update v i (x + y) j ⊗ₜ[K] m j) =
                Function.update (fun j => v j ⊗ₜ[K] m j) i ((x + y) ⊗ₜ[K] m i) := by
        ext j; by_cases h : j = i
        · subst h; simp
        · simp [h]

      have h2 : Function.update (fun j => v j ⊗ₜ[K] m j) i ((x + y) ⊗ₜ[K] m i) =
                Function.update (fun j => v j ⊗ₜ[K] m j) i (x ⊗ₜ[K] m i + y ⊗ₜ[K] m i) := by
        simp [TensorProduct.add_tmul]

      have h3 : Function.update (fun j => v j ⊗ₜ[K] m j) i (x ⊗ₜ[K] m i) =
                (fun j => Function.update v i x j ⊗ₜ[K] m j) := by
        ext j; by_cases h : j = i
        · subst h; simp
        · simp [h]

      have h4 : Function.update (fun j => v j ⊗ₜ[K] m j) i (y ⊗ₜ[K] m i) =
                (fun j => Function.update v i y j ⊗ₜ[K] m j) := by
        ext j; by_cases h : j = i
        · subst h; simp
        · simp [h]

      calc
        (tprod K) (fun j => (Function.update v i (x + y)) j ⊗ₜ[K] m j)
        _ = (tprod K) (Function.update (fun j => v j ⊗ₜ[K] m j) i ((x + y) ⊗ₜ[K] m i)) := by rw [h1]
        _ = (tprod K) (Function.update (fun j => v j ⊗ₜ[K] m j) i (x ⊗ₜ[K] m i + y ⊗ₜ[K] m i)) := by rw [h2]
        _ = (tprod K) (Function.update (fun j => v j ⊗ₜ[K] m j) i (x ⊗ₜ[K] m i)) +
            (tprod K) (Function.update (fun j => v j ⊗ₜ[K] m j) i (y ⊗ₜ[K] m i)) := by
            rw [MultilinearMap.map_update_add (tprod K) (fun j => v j ⊗ₜ[K] m j) i (x ⊗ₜ[K] m i) (y ⊗ₜ[K] m i)]
        _ = (tprod K) (fun j => (Function.update v i x) j ⊗ₜ[K] m j) +
            (tprod K) (fun j => (Function.update v i y) j ⊗ₜ[K] m j) := by rw [h3, h4]

    map_update_smul' v i c x := by
      apply _root_.PiTensorProduct.ext
      apply MultilinearMap.ext; intro m
      simp only [LinearMap.smul_apply, LinearMap.compMultilinearMap_apply]

      simp only [_root_.PiTensorProduct.lift.tprod]
      dsimp [interchangeAux, MultilinearMap.coe_mk]

      have h1 : (fun j => Function.update v i (c • x) j ⊗ₜ[K] m j) =
                Function.update (fun j => v j ⊗ₜ[K] m j) i ((c • x) ⊗ₜ[K] m i) := by
        ext j; by_cases h : j = i
        · subst h; simp
        · simp [h]

      have h2 : Function.update (fun j => v j ⊗ₜ[K] m j) i ((c • x) ⊗ₜ[K] m i) =
                Function.update (fun j => v j ⊗ₜ[K] m j) i (c • (x ⊗ₜ[K] m i)) := by
         simp [TensorProduct.smul_tmul]

      calc
        (tprod K) (fun j => (Function.update v i (c • x)) j ⊗ₜ[K] m j)
        _ = (tprod K) (Function.update (fun j => v j ⊗ₜ[K] m j) i ((c • x) ⊗ₜ[K] m i)) := by rw [h1]
        _ = (tprod K) (Function.update (fun j => v j ⊗ₜ[K] m j) i (c • (x ⊗ₜ[K] m i))) := by rw [h2]
        _ = c • (tprod K) (Function.update (fun j => v j ⊗ₜ[K] m j) i (x ⊗ₜ[K] m i)) := by
            rw [MultilinearMap.map_update_smul (tprod K) (fun j => v j ⊗ₜ[K] m j) i c (x ⊗ₜ[K] m i)]
        _ = c • (tprod K) (fun j => (Function.update v i x) j ⊗ₜ[K] m j) := by
            congr 1; congr; ext j; by_cases h : j = i
            · subst h; simp
            · simp [h]


def interchange {ι : Type*} [Fintype ι] [DecidableEq ι] {V W : ι → Type*}
    [∀ i, AddCommGroup (V i)] [∀ i, Module K (V i)]
    [∀ i, AddCommGroup (W i)] [∀ i, Module K (W i)] :
    PiTensorProduct K V →ₗ[K] PiTensorProduct K W →ₗ[K] PiTensorProduct K (fun i => V i ⊗[K] W i) :=
  lift interchangeMap

/-- Naturality of the interchange map. -/
@[simp]
theorem liftMap_interchange {ι : Type*} [Fintype ι] [DecidableEq ι]
    {V₁ V₂ V₃ V₄ : ι → Type*}
    [∀ i, AddCommGroup (V₁ i)] [∀ i, Module K (V₁ i)]
    [∀ i, AddCommGroup (V₂ i)] [∀ i, Module K (V₂ i)]
    [∀ i, AddCommGroup (V₃ i)] [∀ i, Module K (V₃ i)]
    [∀ i, AddCommGroup (V₄ i)] [∀ i, Module K (V₄ i)]
    (f : ∀ i, V₁ i →ₗ[K] V₃ i) (g : ∀ i, V₂ i →ₗ[K] V₄ i)
    (t₁ : PiTensorProduct K V₁) (t₂ : PiTensorProduct K V₂) :
    liftMap (fun i => TensorProduct.map (f i) (g i)) (interchange t₁ t₂) =
    interchange (liftMap f t₁) (liftMap g t₂) := by
  induction t₁ using PiTensorProduct.induction_on with
  | smul_tprod c v =>
    simp only [map_smul]
    induction t₂ using PiTensorProduct.induction_on with
    | smul_tprod c' v' =>
      simp only [map_smul]
      simp only [interchange, interchangeMap, liftMap, interchangeAux]
      simp [TensorProduct.map_tmul]
    | add x y ih1 ih2 =>
      simp only [map_add, ih1, ih2]
  | add x y ih1 ih2 =>
    simp only [map_add, LinearMap.add_apply, ih1, ih2]

/-- interchange on pure tensors gives a pure tensor of tensor products. -/
theorem interchange_tprod_K {ι : Type*} [Fintype ι] [DecidableEq ι] {V W : ι → Type*}
    [∀ i, AddCommGroup (V i)] [∀ i, Module K (V i)]
    [∀ i, AddCommGroup (W i)] [∀ i, Module K (W i)]
    (v : ∀ i, V i) (w : ∀ i, W i) :
    interchange (tprod K v) (tprod K w) = tprod K (fun i => v i ⊗ₜ[K] w i) := by
  dsimp [interchange]
  rw [PiTensorProduct.lift.tprod]
  dsimp [interchangeMap]
  rw [PiTensorProduct.lift.tprod]
  rfl

/-- Direct sum of two tensor objects. -/
def add (X Y : TensorObj K d) : TensorObj K d where
  V := fun i => X.V i × Y.V i
  t := liftMap (fun i => LinearMap.inl K (X.V i) (Y.V i)) X.t +
       liftMap (fun i => LinearMap.inr K (X.V i) (Y.V i)) Y.t

/-- Tensor product of two tensor objects. -/
def mul (X Y : TensorObj K d) : TensorObj K d where
  V := fun i => X.V i ⊗[K] Y.V i
  t := interchange X.t Y.t

instance : Add (TensorObj K d) := ⟨add⟩
instance : Mul (TensorObj K d) := ⟨mul⟩

@[simp] theorem add_t (X Y : TensorObj K d) : (X + Y).t =
    liftMap (fun i => LinearMap.inl K (X.V i) (Y.V i)) X.t +
    liftMap (fun i => LinearMap.inr K (X.V i) (Y.V i)) Y.t := rfl

@[simp] theorem mul_t (X Y : TensorObj K d) : (X * Y).t = interchange X.t Y.t := rfl

end

end TensorObj

namespace TensorObj

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

/-- X is a restriction of Y (X ≤ Y) if there exists a family of linear maps f_i : Y.V_i → X.V_i
    such that the induced map on the tensor product sends Y.t to X.t. -/
def Restrict (X Y : TensorObj K d) : Prop :=
  ∃ f : ∀ i, Y.V i →ₗ[K] X.V i, liftMap f Y.t = X.t

theorem restrict_refl (X : TensorObj K d) : Restrict X X :=
  ⟨fun _ => LinearMap.id, liftMap_id X⟩

theorem restrict_trans {X Y Z : TensorObj K d} : Restrict X Y → Restrict Y Z → Restrict X Z := by
  rintro ⟨f, hf⟩ ⟨g, hg⟩
  exact ⟨fun i => (f i).comp (g i), by rw [← liftMap_comp, hg, hf]⟩

end TensorObj

/-- An isomorphism between two `TensorObj` K d consists of:
    1. A family of linear equivalences `equiv : X.V i ≃ₗ[K] Y.V i` for each `i`.
    2. A compatibility condition `map_t` stating that the induced map on the tensor product
       sends `X.t` to `Y.t`. -/
structure TensorIso {K : Type u} [Field K] {d : ℕ} [Fact (1 < d)]
    (X Y : TensorObj K d) where
  equiv : ∀ i : Fin d, X.V i ≃ₗ[K] Y.V i
  /-- The induced map on the tensor product must send X.t to Y.t. -/
  map_t : TensorObj.liftMap (fun i => (equiv i).toLinearMap) X.t = Y.t

namespace TensorObj

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

/-- The zero tensor object. -/
noncomputable def zeroObj : TensorObj.{u, v} K d where
  V := fun _ => PUnit
  t := 0

/-- The unit tensor object (1 ⊗ ⋯ ⊗ 1). -/
noncomputable def oneObj : TensorObj.{u, max u v} K d where
  V := fun _ => ULift.{v} K
  t := tprod K (fun _ => ULift.up 1)

/-- The equivalence relation: two tensor objects are isomorphic if there exists a `TensorIso`. -/
def Isomorphic (X Y : TensorObj K d) : Prop := Nonempty (TensorIso X Y)

/-- The isomorphism relation is an equivalence relation. -/
private theorem isomorphic_refl (X : TensorObj K d) : Isomorphic X X := by
  refine ⟨{ equiv := fun i => LinearEquiv.refl _ _, map_t := ?_ }⟩
  simp only [LinearEquiv.refl_toLinearMap]
  exact liftMap_id X

private theorem isomorphic_symm {X Y : TensorObj K d} : Isomorphic X Y → Isomorphic Y X := by
  rintro ⟨iso⟩
  refine ⟨{ equiv := fun i => (iso.equiv i).symm, map_t := ?_ }⟩
  rw [← iso.map_t, liftMap_comp]
  convert liftMap_id X using 2
  apply PiTensorProduct.ext
  apply MultilinearMap.ext; intro v
  simp

private theorem isomorphic_trans {X Y Z : TensorObj K d} : Isomorphic X Y → Isomorphic Y Z → Isomorphic X Z := by
  rintro ⟨iXY⟩ ⟨iYZ⟩
  refine ⟨{ equiv := fun i => (iXY.equiv i).trans (iYZ.equiv i), map_t := ?_ }⟩
  simp only [LinearEquiv.coe_trans]
  rw [← liftMap_comp, iXY.map_t, iYZ.map_t]

/-- The setoid structure on `TensorObj` defined by mutual restriction (X ~ Y iff X ≤ Y and Y ≤ X). -/
def tensorSetoid (K : Type u) [Field K] (d : ℕ) [Fact (1 < d)] : Setoid (TensorObj.{u, max u v} K d) where
  r X Y := TensorObj.Restrict X Y ∧ TensorObj.Restrict Y X
  iseqv := {
    refl  := fun X => ⟨restrict_refl X, restrict_refl X⟩
    symm  := fun ⟨h1, h2⟩ => ⟨h2, h1⟩
    trans := fun ⟨h1, h2⟩ ⟨h3, h4⟩ => ⟨restrict_trans h1 h3, restrict_trans h4 h2⟩
  }
end TensorObj
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