File: Mathlib/LinearAlgebra/PiTensorProduct.lean

full_name: PiTensorProduct.Eqv.of_add
code: /-- The relation on `FreeAddMonoid (R × Π i, s i)` that generates a congruence whose quotient is
the tensor product. -/
inductive Eqv : FreeAddMonoid (R × Π i, s i) → FreeAddMonoid (R × Π i, s i) → Prop
  | of_zero : ∀ (r : R) (f : Π i, s i) (i : ι) (_ : f i = 0), Eqv (FreeAddMonoid.of (r, f)) 0
  | of_zero_scalar : ∀ f : Π i, s i, Eqv (FreeAddMonoid.of (0, f)) 0
  | of_add : ∀ (_ : DecidableEq ι) (r : R) (f : Π i, s i) (i : ι) (m₁ m₂ : s i),
      Eqv (FreeAddMonoid.of (r, update f i m₁) + FreeAddMonoid.of (r, update f i m₂))
        (FreeAddMonoid.of (r, update f i (m₁ + m₂)))
  | of_add_scalar : ∀ (r r' : R) (f : Π i, s i),
      Eqv (FreeAddMonoid.of (r, f) + FreeAddMonoid.of (r', f)) (FreeAddMonoid.of (r + r', f))
  | of_smul : ∀ (_ : DecidableEq ι) (r : R) (f : Π i, s i) (i : ι) (r' : R),
      Eqv (FreeAddMonoid.of (r, update f i (r' • f i))) (FreeAddMonoid.of (r' * r, f))
  | add_comm : ∀ x y, Eqv (x + y) (y + x)
goal: ∀ (x : DecidableEq ι) (r : R) (f : (i : ι) → s i) (i : ι) (m₁ m₂ : s i),
  PiTensorProduct.Eqv R s (FreeAddMonoid.of (r, Function.update f i m₁) + FreeAddMonoid.of (r, Function.update f i m₂))
    (FreeAddMonoid.of (r, Function.update f i (m₁ + m₂)))

full_name: PiTensorProduct.Eqv.of_zero
code: /-- The relation on `FreeAddMonoid (R × Π i, s i)` that generates a congruence whose quotient is
the tensor product. -/
inductive Eqv : FreeAddMonoid (R × Π i, s i) → FreeAddMonoid (R × Π i, s i) → Prop
  | of_zero : ∀ (r : R) (f : Π i, s i) (i : ι) (_ : f i = 0), Eqv (FreeAddMonoid.of (r, f)) 0
  | of_zero_scalar : ∀ f : Π i, s i, Eqv (FreeAddMonoid.of (0, f)) 0
  | of_add : ∀ (_ : DecidableEq ι) (r : R) (f : Π i, s i) (i : ι) (m₁ m₂ : s i),
      Eqv (FreeAddMonoid.of (r, update f i m₁) + FreeAddMonoid.of (r, update f i m₂))
        (FreeAddMonoid.of (r, update f i (m₁ + m₂)))
  | of_add_scalar : ∀ (r r' : R) (f : Π i, s i),
      Eqv (FreeAddMonoid.of (r, f) + FreeAddMonoid.of (r', f)) (FreeAddMonoid.of (r + r', f))
  | of_smul : ∀ (_ : DecidableEq ι) (r : R) (f : Π i, s i) (i : ι) (r' : R),
      Eqv (FreeAddMonoid.of (r, update f i (r' • f i))) (FreeAddMonoid.of (r' * r, f))
  | add_comm : ∀ x y, Eqv (x + y) (y + x)
goal: f i = 0 → PiTensorProduct.Eqv R s (FreeAddMonoid.of (r, f)) 0

full_name: PiTensorProduct.Eqv.of_smul
code: /-- The relation on `FreeAddMonoid (R × Π i, s i)` that generates a congruence whose quotient is
the tensor product. -/
inductive Eqv : FreeAddMonoid (R × Π i, s i) → FreeAddMonoid (R × Π i, s i) → Prop
  | of_zero : ∀ (r : R) (f : Π i, s i) (i : ι) (_ : f i = 0), Eqv (FreeAddMonoid.of (r, f)) 0
  | of_zero_scalar : ∀ f : Π i, s i, Eqv (FreeAddMonoid.of (0, f)) 0
  | of_add : ∀ (_ : DecidableEq ι) (r : R) (f : Π i, s i) (i : ι) (m₁ m₂ : s i),
      Eqv (FreeAddMonoid.of (r, update f i m₁) + FreeAddMonoid.of (r, update f i m₂))
        (FreeAddMonoid.of (r, update f i (m₁ + m₂)))
  | of_add_scalar : ∀ (r r' : R) (f : Π i, s i),
      Eqv (FreeAddMonoid.of (r, f) + FreeAddMonoid.of (r', f)) (FreeAddMonoid.of (r + r', f))
  | of_smul : ∀ (_ : DecidableEq ι) (r : R) (f : Π i, s i) (i : ι) (r' : R),
      Eqv (FreeAddMonoid.of (r, update f i (r' • f i))) (FreeAddMonoid.of (r' * r, f))
  | add_comm : ∀ x y, Eqv (x + y) (y + x)
goal: ∀ (x : DecidableEq ι) (r : R) (f : (i : ι) → s i) (i : ι) (r' : R),
  PiTensorProduct.Eqv R s (FreeAddMonoid.of (r, Function.update f i (r' • f i))) (FreeAddMonoid.of (r' * r, f))

full_name: PiTensorProduct.Eqv.of_zero_scalar
code: /-- The relation on `FreeAddMonoid (R × Π i, s i)` that generates a congruence whose quotient is
the tensor product. -/
inductive Eqv : FreeAddMonoid (R × Π i, s i) → FreeAddMonoid (R × Π i, s i) → Prop
  | of_zero : ∀ (r : R) (f : Π i, s i) (i : ι) (_ : f i = 0), Eqv (FreeAddMonoid.of (r, f)) 0
  | of_zero_scalar : ∀ f : Π i, s i, Eqv (FreeAddMonoid.of (0, f)) 0
  | of_add : ∀ (_ : DecidableEq ι) (r : R) (f : Π i, s i) (i : ι) (m₁ m₂ : s i),
      Eqv (FreeAddMonoid.of (r, update f i m₁) + FreeAddMonoid.of (r, update f i m₂))
        (FreeAddMonoid.of (r, update f i (m₁ + m₂)))
  | of_add_scalar : ∀ (r r' : R) (f : Π i, s i),
      Eqv (FreeAddMonoid.of (r, f) + FreeAddMonoid.of (r', f)) (FreeAddMonoid.of (r + r', f))
  | of_smul : ∀ (_ : DecidableEq ι) (r : R) (f : Π i, s i) (i : ι) (r' : R),
      Eqv (FreeAddMonoid.of (r, update f i (r' • f i))) (FreeAddMonoid.of (r' * r, f))
  | add_comm : ∀ x y, Eqv (x + y) (y + x)
goal: PiTensorProduct.Eqv R s (FreeAddMonoid.of (0, f)) 0

full_name: PiTensorProduct.Eqv
code: /-- The relation on `FreeAddMonoid (R × Π i, s i)` that generates a congruence whose quotient is
the tensor product. -/
inductive Eqv : FreeAddMonoid (R × Π i, s i) → FreeAddMonoid (R × Π i, s i) → Prop
  | of_zero : ∀ (r : R) (f : Π i, s i) (i : ι) (_ : f i = 0), Eqv (FreeAddMonoid.of (r, f)) 0
  | of_zero_scalar : ∀ f : Π i, s i, Eqv (FreeAddMonoid.of (0, f)) 0
  | of_add : ∀ (_ : DecidableEq ι) (r : R) (f : Π i, s i) (i : ι) (m₁ m₂ : s i),
      Eqv (FreeAddMonoid.of (r, update f i m₁) + FreeAddMonoid.of (r, update f i m₂))
        (FreeAddMonoid.of (r, update f i (m₁ + m₂)))
  | of_add_scalar : ∀ (r r' : R) (f : Π i, s i),
      Eqv (FreeAddMonoid.of (r, f) + FreeAddMonoid.of (r', f)) (FreeAddMonoid.of (r + r', f))
  | of_smul : ∀ (_ : DecidableEq ι) (r : R) (f : Π i, s i) (i : ι) (r' : R),
      Eqv (FreeAddMonoid.of (r, update f i (r' • f i))) (FreeAddMonoid.of (r' * r, f))
  | add_comm : ∀ x y, Eqv (x + y) (y + x)
goal: FreeAddMonoid (R × ((i : ι) → s i)) → FreeAddMonoid (R × ((i : ι) → s i)) → Prop

full_name: PiTensorProduct.Eqv.of_add_scalar
code: /-- The relation on `FreeAddMonoid (R × Π i, s i)` that generates a congruence whose quotient is
the tensor product. -/
inductive Eqv : FreeAddMonoid (R × Π i, s i) → FreeAddMonoid (R × Π i, s i) → Prop
  | of_zero : ∀ (r : R) (f : Π i, s i) (i : ι) (_ : f i = 0), Eqv (FreeAddMonoid.of (r, f)) 0
  | of_zero_scalar : ∀ f : Π i, s i, Eqv (FreeAddMonoid.of (0, f)) 0
  | of_add : ∀ (_ : DecidableEq ι) (r : R) (f : Π i, s i) (i : ι) (m₁ m₂ : s i),
      Eqv (FreeAddMonoid.of (r, update f i m₁) + FreeAddMonoid.of (r, update f i m₂))
        (FreeAddMonoid.of (r, update f i (m₁ + m₂)))
  | of_add_scalar : ∀ (r r' : R) (f : Π i, s i),
      Eqv (FreeAddMonoid.of (r, f) + FreeAddMonoid.of (r', f)) (FreeAddMonoid.of (r + r', f))
  | of_smul : ∀ (_ : DecidableEq ι) (r : R) (f : Π i, s i) (i : ι) (r' : R),
      Eqv (FreeAddMonoid.of (r, update f i (r' • f i))) (FreeAddMonoid.of (r' * r, f))
  | add_comm : ∀ x y, Eqv (x + y) (y + x)
goal: PiTensorProduct.Eqv R s (FreeAddMonoid.of (r, f) + FreeAddMonoid.of (r', f)) (FreeAddMonoid.of (r + r', f))

full_name: PiTensorProduct.Eqv.add_comm
code: /-- The relation on `FreeAddMonoid (R × Π i, s i)` that generates a congruence whose quotient is
the tensor product. -/
inductive Eqv : FreeAddMonoid (R × Π i, s i) → FreeAddMonoid (R × Π i, s i) → Prop
  | of_zero : ∀ (r : R) (f : Π i, s i) (i : ι) (_ : f i = 0), Eqv (FreeAddMonoid.of (r, f)) 0
  | of_zero_scalar : ∀ f : Π i, s i, Eqv (FreeAddMonoid.of (0, f)) 0
  | of_add : ∀ (_ : DecidableEq ι) (r : R) (f : Π i, s i) (i : ι) (m₁ m₂ : s i),
      Eqv (FreeAddMonoid.of (r, update f i m₁) + FreeAddMonoid.of (r, update f i m₂))
        (FreeAddMonoid.of (r, update f i (m₁ + m₂)))
  | of_add_scalar : ∀ (r r' : R) (f : Π i, s i),
      Eqv (FreeAddMonoid.of (r, f) + FreeAddMonoid.of (r', f)) (FreeAddMonoid.of (r + r', f))
  | of_smul : ∀ (_ : DecidableEq ι) (r : R) (f : Π i, s i) (i : ι) (r' : R),
      Eqv (FreeAddMonoid.of (r, update f i (r' • f i))) (FreeAddMonoid.of (r' * r, f))
  | add_comm : ∀ x y, Eqv (x + y) (y + x)
goal: PiTensorProduct.Eqv R s (x + y) (y + x)

full_name: PiTensorProduct
code: /-- `PiTensorProduct R s` with `R` a commutative semiring and `s : ι → Type*` is the tensor
  product of all the `s i`'s. This is denoted by `⨂[R] i, s i`. -/
def PiTensorProduct : Type _ 
goal: Type (max (max u_1 u_4) u_7)

full_name: TensorProduct.«_aux_Mathlib_LinearAlgebra_PiTensorProduct___macroRules_TensorProduct_term⨂[_]_,__1»
code: /-- This enables the notation `⨂[R] i : ι, s i` for the pi tensor product `PiTensorProduct`,
given an indexed family of types `s : ι → Type*`. -/
scoped[TensorProduct] notation3:100"⨂["R"] "(...)", "r:(scoped f => PiTensorProduct R f) => r
goal: Lean.Macro

full_name: PiTensorProduct.instAddCommMonoid
code: instance : AddCommMonoid (⨂[R] i, s i) 
goal: AddCommMonoid (PiTensorProduct R fun i => s i)

full_name: PiTensorProduct.instInhabited
code: instance : Inhabited (⨂[R] i, s i) 
goal: Inhabited (PiTensorProduct R fun i => s i)

full_name: PiTensorProduct.tprodCoeff
code: /-- `tprodCoeff R r f` with `r : R` and `f : Π i, s i` is the tensor product of the vectors `f i`
over all `i : ι`, multiplied by the coefficient `r`. Note that this is meant as an auxiliary
definition for this file alone, and that one should use `tprod` defined below for most purposes. -/
def tprodCoeff (r : R) (f : Π i, s i) : ⨂[R] i, s i 
goal: PiTensorProduct R fun i => s i

full_name: PiTensorProduct.zero_tprodCoeff
code: theorem zero_tprodCoeff (f : Π i, s i) : tprodCoeff R 0 f = 0 
goal: PiTensorProduct.tprodCoeff R 0 f = 0

full_name: PiTensorProduct.zero_tprodCoeff'
code: theorem zero_tprodCoeff' (z : R) (f : Π i, s i) (i : ι) (hf : f i = 0) : tprodCoeff R z f = 0 
goal: PiTensorProduct.tprodCoeff R z f = 0

full_name: PiTensorProduct.add_tprodCoeff
code: theorem add_tprodCoeff [DecidableEq ι] (z : R) (f : Π i, s i) (i : ι) (m₁ m₂ : s i) :
    tprodCoeff R z (update f i m₁) + tprodCoeff R z (update f i m₂) =
      tprodCoeff R z (update f i (m₁ + m₂)) 
goal: PiTensorProduct.tprodCoeff R z (Function.update f i m₁) + PiTensorProduct.tprodCoeff R z (Function.update f i m₂) =
  PiTensorProduct.tprodCoeff R z (Function.update f i (m₁ + m₂))

full_name: PiTensorProduct.add_tprodCoeff'
code: theorem add_tprodCoeff' (z₁ z₂ : R) (f : Π i, s i) :
    tprodCoeff R z₁ f + tprodCoeff R z₂ f = tprodCoeff R (z₁ + z₂) f 
goal: PiTensorProduct.tprodCoeff R z₁ f + PiTensorProduct.tprodCoeff R z₂ f = PiTensorProduct.tprodCoeff R (z₁ + z₂) f

full_name: PiTensorProduct.smul_tprodCoeff_aux
code: theorem smul_tprodCoeff_aux [DecidableEq ι] (z : R) (f : Π i, s i) (i : ι) (r : R) :
    tprodCoeff R z (update f i (r • f i)) = tprodCoeff R (r * z) f 
goal: PiTensorProduct.tprodCoeff R z (Function.update f i (r • f i)) = PiTensorProduct.tprodCoeff R (r * z) f

full_name: PiTensorProduct.smul_tprodCoeff
code: theorem smul_tprodCoeff [DecidableEq ι] (z : R) (f : Π i, s i) (i : ι) (r : R₁) [SMul R₁ R]
    [IsScalarTower R₁ R R] [SMul R₁ (s i)] [IsScalarTower R₁ R (s i)] :
    tprodCoeff R z (update f i (r • f i)) = tprodCoeff R (r • z) f 
goal: PiTensorProduct.tprodCoeff R z (Function.update f i (r • f i)) = PiTensorProduct.tprodCoeff R (r • z) f

full_name: PiTensorProduct.liftAddHom
code: /-- Construct an `AddMonoidHom` from `(⨂[R] i, s i)` to some space `F` from a function
`φ : (R × Π i, s i) → F` with the appropriate properties. -/
def liftAddHom (φ : (R × Π i, s i) → F)
    (C0 : ∀ (r : R) (f : Π i, s i) (i : ι) (_ : f i = 0), φ (r, f) = 0)
    (C0' : ∀ f : Π i, s i, φ (0, f) = 0)
    (C_add : ∀ [DecidableEq ι] (r : R) (f : Π i, s i) (i : ι) (m₁ m₂ : s i),
      φ (r, update f i m₁) + φ (r, update f i m₂) = φ (r, update f i (m₁ + m₂)))
    (C_add_scalar : ∀ (r r' : R) (f : Π i, s i), φ (r, f) + φ (r', f) = φ (r + r', f))
    (C_smul : ∀ [DecidableEq ι] (r : R) (f : Π i, s i) (i : ι) (r' : R),
      φ (r, update f i (r' • f i)) = φ (r' * r, f)) :
    (⨂[R] i, s i) →+ F 
goal: (PiTensorProduct R fun i => s i) →+ F

full_name: PiTensorProduct.induction_on'
code: /-- Induct using `tprodCoeff` -/
@[elab_as_elim]
protected theorem induction_on' {motive : (⨂[R] i, s i) → Prop} (z : ⨂[R] i, s i)
    (tprodCoeff : ∀ (r : R) (f : Π i, s i), motive (tprodCoeff R r f))
    (add : ∀ x y, motive x → motive y → motive (x + y)) :
    motive z 
goal: motive z

full_name: PiTensorProduct.hasSMul'
code: instance hasSMul' : SMul R₁ (⨂[R] i, s i) 
goal: SMul R₁ (PiTensorProduct R fun i => s i)

full_name: PiTensorProduct.instSMul
code: instance : SMul R (⨂[R] i, s i) 
goal: SMul R (PiTensorProduct R fun i => s i)

full_name: PiTensorProduct.smul_tprodCoeff'
code: theorem smul_tprodCoeff' (r : R₁) (z : R) (f : Π i, s i) :
    r • tprodCoeff R z f = tprodCoeff R (r • z) f 
goal: r • PiTensorProduct.tprodCoeff R z f = PiTensorProduct.tprodCoeff R (r • z) f

full_name: PiTensorProduct.smul_add
code: protected theorem smul_add (r : R₁) (x y : ⨂[R] i, s i) : r • (x + y) = r • x + r • y 
goal: r • (x + y) = r • x + r • y

full_name: PiTensorProduct.distribMulAction'
code: instance distribMulAction' : DistribMulAction R₁ (⨂[R] i, s i) 
goal: DistribMulAction R₁ (PiTensorProduct R fun i => s i)

full_name: PiTensorProduct.smulCommClass'
code: instance smulCommClass' [SMulCommClass R₁ R₂ R] : SMulCommClass R₁ R₂ (⨂[R] i, s i) 
goal: SMulCommClass R₁ R₂ (PiTensorProduct R fun i => s i)

full_name: PiTensorProduct.isScalarTower'
code: instance isScalarTower' [SMul R₁ R₂] [IsScalarTower R₁ R₂ R] :
    IsScalarTower R₁ R₂ (⨂[R] i, s i) 
goal: IsScalarTower R₁ R₂ (PiTensorProduct R fun i => s i)

full_name: PiTensorProduct.module'
code: instance module' [Semiring R₁] [Module R₁ R] [SMulCommClass R₁ R R] : Module R₁ (⨂[R] i, s i) 
goal: Module R₁ (PiTensorProduct R fun i => s i)

full_name: PiTensorProduct.instModule
code: instance : Module R (⨂[R] i, s i) 
goal: Module R (PiTensorProduct R fun i => s i)

full_name: PiTensorProduct.instSMulCommClass
code: instance : SMulCommClass R R (⨂[R] i, s i) 
goal: SMulCommClass R R (PiTensorProduct R fun i => s i)

full_name: PiTensorProduct.instIsScalarTower
code: instance : IsScalarTower R R (⨂[R] i, s i) 
goal: IsScalarTower R R (PiTensorProduct R fun i => s i)

full_name: PiTensorProduct.tprod
code: /-- The canonical `MultilinearMap R s (⨂[R] i, s i)`.

`tprod R fun i => f i` has notation `⨂ₜ[R] i, f i`. -/
def tprod : MultilinearMap R s (⨂[R] i, s i) 
goal: MultilinearMap R s (PiTensorProduct R fun i => s i)

full_name: PiTensorProduct.«_aux_Mathlib_LinearAlgebra_PiTensorProduct___macroRules_PiTensorProduct_term⨂ₜ[_]_,__1»
code: @[inherit_doc tprod]
notation3:100 "⨂ₜ["R"] "(...)", "r:(scoped f => tprod R f) => r
goal: Lean.Macro

full_name: PiTensorProduct.tprod_eq_tprodCoeff_one
code: theorem tprod_eq_tprodCoeff_one :
    ⇑(tprod R : MultilinearMap R s (⨂[R] i, s i)) = tprodCoeff R 1 
goal: ⇑(PiTensorProduct.tprod R) = PiTensorProduct.tprodCoeff R 1

full_name: PiTensorProduct.tprodCoeff_eq_smul_tprod
code: @[simp]
theorem tprodCoeff_eq_smul_tprod (z : R) (f : Π i, s i) : tprodCoeff R z f = z • tprod R f 
goal: PiTensorProduct.tprodCoeff R z f = z • (PiTensorProduct.tprod R) f

full_name: FreeAddMonoid.toPiTensorProduct
code: /-- The image of an element `p` of `FreeAddMonoid (R × Π i, s i)` in the `PiTensorProduct` is
equal to the sum of `a • ⨂ₜ[R] i, m i` over all the entries `(a, m)` of `p`.
-/
lemma _root_.FreeAddMonoid.toPiTensorProduct (p : FreeAddMonoid (R × Π i, s i)) :
    AddCon.toQuotient (c := addConGen (PiTensorProduct.Eqv R s)) p =
    List.sum (List.map (fun x ↦ x.1 • ⨂ₜ[R] i, x.2 i) p) 
goal: ↑p = (List.map (fun x => x.1 • ⨂ₜ[R] (i : ι), x.2 i) p).sum

full_name: PiTensorProduct.lifts
code: /-- The set of lifts of an element `x` of `⨂[R] i, s i` in `FreeAddMonoid (R × Π i, s i)`. -/
def lifts (x : ⨂[R] i, s i) : Set (FreeAddMonoid (R × Π i, s i)) 
goal: Set (FreeAddMonoid (R × ((i : ι) → s i)))

full_name: PiTensorProduct.mem_lifts_iff
code: /-- An element `p` of `FreeAddMonoid (R × Π i, s i)` lifts an element `x` of `⨂[R] i, s i`
if and only if `x` is equal to to the sum of `a • ⨂ₜ[R] i, m i` over all the entries
`(a, m)` of `p`.
-/
lemma mem_lifts_iff (x : ⨂[R] i, s i) (p : FreeAddMonoid (R × Π i, s i)) :
    p ∈ lifts x ↔ List.sum (List.map (fun x ↦ x.1 • ⨂ₜ[R] i, x.2 i) p) = x 
goal: p ∈ x.lifts ↔ (List.map (fun x => x.1 • ⨂ₜ[R] (i : ι), x.2 i) p).sum = x

full_name: PiTensorProduct.nonempty_lifts
code: /-- Every element of `⨂[R] i, s i` has a lift in `FreeAddMonoid (R × Π i, s i)`.
-/
lemma nonempty_lifts (x : ⨂[R] i, s i) : Set.Nonempty (lifts x) 
goal: x.lifts.Nonempty

full_name: PiTensorProduct.lifts_zero
code: /-- The empty list lifts the element `0` of `⨂[R] i, s i`.
-/
lemma lifts_zero : 0 ∈ lifts (0 : ⨂[R] i, s i) 
goal: 0 ∈ PiTensorProduct.lifts 0

full_name: PiTensorProduct.lifts_add
code: /-- If elements `p,q` of `FreeAddMonoid (R × Π i, s i)` lift elements `x,y` of `⨂[R] i, s i`
respectively, then `p + q` lifts `x + y`.
-/
lemma lifts_add {x y : ⨂[R] i, s i} {p q : FreeAddMonoid (R × Π i, s i)}
    (hp : p ∈ lifts x) (hq : q ∈ lifts y) : p + q ∈ lifts (x + y) 
goal: p + q ∈ (x + y).lifts

full_name: PiTensorProduct.lifts_smul
code: /-- If an element `p` of `FreeAddMonoid (R × Π i, s i)` lifts an element `x` of `⨂[R] i, s i`,
and if `a` is an element of `R`, then the list obtained by multiplying the first entry of each
element of `p` by `a` lifts `a • x`.
-/
lemma lifts_smul {x : ⨂[R] i, s i} {p : FreeAddMonoid (R × Π i, s i)} (h : p ∈ lifts x) (a : R) :
    List.map (fun (y : R × Π i, s i) ↦ (a * y.1, y.2)) p ∈ lifts (a • x) 
goal: List.map (fun y => (a * y.1, y.2)) p ∈ (a • x).lifts

full_name: PiTensorProduct.induction_on
code: /-- Induct using scaled versions of `PiTensorProduct.tprod`. -/
@[elab_as_elim]
protected theorem induction_on {motive : (⨂[R] i, s i) → Prop} (z : ⨂[R] i, s i)
    (smul_tprod : ∀ (r : R) (f : Π i, s i), motive (r • tprod R f))
    (add : ∀ x y, motive x → motive y → motive (x + y)) :
    motive z 
goal: motive z

full_name: PiTensorProduct.ext
code: @[ext]
theorem ext {φ₁ φ₂ : (⨂[R] i, s i) →ₗ[R] E}
    (H : φ₁.compMultilinearMap (tprod R) = φ₂.compMultilinearMap (tprod R)) : φ₁ = φ₂ 
goal: φ₁ = φ₂

full_name: PiTensorProduct.span_tprod_eq_top
code: /-- The pure tensors (i.e. the elements of the image of `PiTensorProduct.tprod`) span
the tensor product. -/
theorem span_tprod_eq_top :
    Submodule.span R (Set.range (tprod R)) = (⊤ : Submodule R (⨂[R] i, s i)) 
goal: Submodule.span R (Set.range ⇑(PiTensorProduct.tprod R)) = ⊤

full_name: PiTensorProduct.liftAux
code: /-- Auxiliary function to constructing a linear map `(⨂[R] i, s i) → E` given a
`MultilinearMap R s E` with the property that its composition with the canonical
`MultilinearMap R s (⨂[R] i, s i)` is the given multilinear map. -/
def liftAux (φ : MultilinearMap R s E) : (⨂[R] i, s i) →+ E 
goal: (PiTensorProduct R fun i => s i) →+ E

full_name: PiTensorProduct.liftAux_tprod
code: theorem liftAux_tprod (φ : MultilinearMap R s E) (f : Π i, s i) : liftAux φ (tprod R f) = φ f 
goal: (PiTensorProduct.liftAux φ) ((PiTensorProduct.tprod R) f) = φ f

full_name: PiTensorProduct.liftAux_tprodCoeff
code: theorem liftAux_tprodCoeff (φ : MultilinearMap R s E) (z : R) (f : Π i, s i) :
    liftAux φ (tprodCoeff R z f) = z • φ f 
goal: (PiTensorProduct.liftAux φ) (PiTensorProduct.tprodCoeff R z f) = z • φ f

full_name: PiTensorProduct.liftAux.smul
code: theorem liftAux.smul {φ : MultilinearMap R s E} (r : R) (x : ⨂[R] i, s i) :
    liftAux φ (r • x) = r • liftAux φ x 
goal: (PiTensorProduct.liftAux φ) (r • x) = r • (PiTensorProduct.liftAux φ) x

full_name: PiTensorProduct.lift
code: /-- Constructing a linear map `(⨂[R] i, s i) → E` given a `MultilinearMap R s E` with the
property that its composition with the canonical `MultilinearMap R s E` is
the given multilinear map `φ`. -/
def lift : MultilinearMap R s E ≃ₗ[R] (⨂[R] i, s i) →ₗ[R] E 
goal: MultilinearMap R s E ≃ₗ[R] (PiTensorProduct R fun i => s i) →ₗ[R] E

full_name: PiTensorProduct.lift.tprod
code: @[simp]
theorem lift.tprod (f : Π i, s i) : lift φ (tprod R f) = φ f 
goal: (PiTensorProduct.lift φ) ((PiTensorProduct.tprod R) f) = φ f

full_name: PiTensorProduct.lift.unique'
code: theorem lift.unique' {φ' : (⨂[R] i, s i) →ₗ[R] E}
    (H : φ'.compMultilinearMap (PiTensorProduct.tprod R) = φ) : φ' = lift φ 
goal: φ' = PiTensorProduct.lift φ

full_name: PiTensorProduct.lift.unique
code: theorem lift.unique {φ' : (⨂[R] i, s i) →ₗ[R] E} (H : ∀ f, φ' (PiTensorProduct.tprod R f) = φ f) :
    φ' = lift φ 
goal: φ' = PiTensorProduct.lift φ

full_name: PiTensorProduct.lift_symm
code: @[simp]
theorem lift_symm (φ' : (⨂[R] i, s i) →ₗ[R] E) : lift.symm φ' = φ'.compMultilinearMap (tprod R) 
goal: PiTensorProduct.lift.symm φ' = φ'.compMultilinearMap (PiTensorProduct.tprod R)

full_name: PiTensorProduct.lift_tprod
code: @[simp]
theorem lift_tprod : lift (tprod R : MultilinearMap R s _) = LinearMap.id 
goal: PiTensorProduct.lift (PiTensorProduct.tprod R) = LinearMap.id

full_name: PiTensorProduct.map
code: /--
Let `sᵢ` and `tᵢ` be two families of `R`-modules.
Let `f` be a family of `R`-linear maps between `sᵢ` and `tᵢ`, i.e. `f : Πᵢ sᵢ → tᵢ`,
then there is an induced map `⨂ᵢ sᵢ → ⨂ᵢ tᵢ` by `⨂ aᵢ ↦ ⨂ fᵢ aᵢ`.

This is `TensorProduct.map` for an arbitrary family of modules.
-/
def map : (⨂[R] i, s i) →ₗ[R] ⨂[R] i, t i 
goal: (PiTensorProduct R fun i => s i) →ₗ[R] PiTensorProduct R fun i => t i

full_name: PiTensorProduct.map_tprod
code: @[simp] lemma map_tprod (x : Π i, s i) :
    map f (tprod R x) = tprod R fun i ↦ f i (x i) 
goal: (PiTensorProduct.map f) ((PiTensorProduct.tprod R) x) = ⨂ₜ[R] (i : ι), (f i) (x i)

full_name: PiTensorProduct.map_range_eq_span_tprod
code: theorem map_range_eq_span_tprod :
    LinearMap.range (map f) =
      Submodule.span R {t | ∃ (m : Π i, s i), tprod R (fun i ↦ f i (m i)) = t} 
goal: LinearMap.range (PiTensorProduct.map f) = Submodule.span R {t_1 | ∃ m, (⨂ₜ[R] (i : ι), (f i) (m i)) = t_1}

full_name: PiTensorProduct.mapIncl
code: /-- Given submodules `p i ⊆ s i`, this is the natural map: `⨂[R] i, p i → ⨂[R] i, s i`.
This is `TensorProduct.mapIncl` for an arbitrary family of modules.
-/
@[simp]
def mapIncl (p : Π i, Submodule R (s i)) : (⨂[R] i, p i) →ₗ[R] ⨂[R] i, s i 
goal: (PiTensorProduct R fun i => ↥(p i)) →ₗ[R] PiTensorProduct R fun i => s i

full_name: PiTensorProduct.map_comp
code: theorem map_comp : map (fun (i : ι) ↦ g i ∘ₗ f i) = map g ∘ₗ map f 
goal: (PiTensorProduct.map fun i => g i ∘ₗ f i) = PiTensorProduct.map g ∘ₗ PiTensorProduct.map f

full_name: PiTensorProduct.lift_comp_map
code: theorem lift_comp_map (h : MultilinearMap R t E) :
    lift h ∘ₗ map f = lift (h.compLinearMap f) 
goal: PiTensorProduct.lift h ∘ₗ PiTensorProduct.map f = PiTensorProduct.lift (h.compLinearMap f)

full_name: PiTensorProduct.map_id
code: @[simp]
theorem map_id : map (fun i ↦ (LinearMap.id : s i →ₗ[R] s i)) = .id 
goal: (PiTensorProduct.map fun i => LinearMap.id) = LinearMap.id

full_name: PiTensorProduct.map_one
code: @[simp]
theorem map_one : map (fun (i : ι) ↦ (1 : s i →ₗ[R] s i)) = 1 
goal: (PiTensorProduct.map fun i => 1) = 1

full_name: PiTensorProduct.map_mul
code: theorem map_mul (f₁ f₂ : Π i, s i →ₗ[R] s i) :
    map (fun i ↦ f₁ i * f₂ i) = map f₁ * map f₂ 
goal: (PiTensorProduct.map fun i => f₁ i * f₂ i) = PiTensorProduct.map f₁ * PiTensorProduct.map f₂

full_name: PiTensorProduct.mapMonoidHom
code: /-- Upgrading `PiTensorProduct.map` to a `MonoidHom` when `s = t`. -/
@[simps]
def mapMonoidHom : (Π i, s i →ₗ[R] s i) →* ((⨂[R] i, s i) →ₗ[R] ⨂[R] i, s i) 
goal: ((i : ι) → s i →ₗ[R] s i) →* (PiTensorProduct R fun i => s i) →ₗ[R] PiTensorProduct R fun i => s i

full_name: PiTensorProduct.mapMonoidHom_apply
code: /-- Upgrading `PiTensorProduct.map` to a `MonoidHom` when `s = t`. -/
@[simps]
def mapMonoidHom : (Π i, s i →ₗ[R] s i) →* ((⨂[R] i, s i) →ₗ[R] ⨂[R] i, s i) 
goal: PiTensorProduct.mapMonoidHom f = PiTensorProduct.map f

full_name: PiTensorProduct.map_pow
code: @[simp]
protected theorem map_pow (f : Π i, s i →ₗ[R] s i) (n : ℕ) :
    map (f ^ n) = map f ^ n 
goal: PiTensorProduct.map (f ^ n) = PiTensorProduct.map f ^ n

full_name: _private.Mathlib.LinearAlgebra.PiTensorProduct.0.PiTensorProduct.map_add_smul_aux
code: private theorem map_add_smul_aux [DecidableEq ι] (i : ι) (x : Π i, s i) (u : s i →ₗ[R] t i) :
    (fun j ↦ update f i u j (x j)) = update (fun j ↦ (f j) (x j)) i (u (x i)) 
goal: (fun j => (Function.update f i u j) (x j)) = Function.update (fun j => (f j) (x j)) i (u (x i))

full_name: PiTensorProduct.map_add
code: protected theorem map_add [DecidableEq ι] (i : ι) (u v : s i →ₗ[R] t i) :
    map (update f i (u + v)) = map (update f i u) + map (update f i v) 
goal: PiTensorProduct.map (Function.update f i (u + v)) =
  PiTensorProduct.map (Function.update f i u) + PiTensorProduct.map (Function.update f i v)

full_name: PiTensorProduct.map_smul
code: protected theorem map_smul [DecidableEq ι] (i : ι) (c : R) (u : s i →ₗ[R] t i) :
    map (update f i (c • u)) = c • map (update f i u) 
goal: PiTensorProduct.map (Function.update f i (c • u)) = c • PiTensorProduct.map (Function.update f i u)

full_name: PiTensorProduct.mapMultilinear_apply
code: /-- The tensor of a family of linear maps from `sᵢ` to `tᵢ`, as a multilinear map of
the family.
-/
@[simps]
noncomputable def mapMultilinear :
    MultilinearMap R (fun (i : ι) ↦ s i →ₗ[R] t i) ((⨂[R] i, s i) →ₗ[R] ⨂[R] i, t i) 
goal: (PiTensorProduct.mapMultilinear R s t) f = PiTensorProduct.map f

full_name: PiTensorProduct.mapMultilinear
code: /-- The tensor of a family of linear maps from `sᵢ` to `tᵢ`, as a multilinear map of
the family.
-/
@[simps]
noncomputable def mapMultilinear :
    MultilinearMap R (fun (i : ι) ↦ s i →ₗ[R] t i) ((⨂[R] i, s i) →ₗ[R] ⨂[R] i, t i) 
goal: MultilinearMap R (fun i => s i →ₗ[R] t i) ((PiTensorProduct R fun i => s i) →ₗ[R] PiTensorProduct R fun i => t i)

full_name: PiTensorProduct.piTensorHomMap
code: /--
Let `sᵢ` and `tᵢ` be families of `R`-modules.
Then there is an `R`-linear map between `⨂ᵢ Hom(sᵢ, tᵢ)` and `Hom(⨂ᵢ sᵢ, ⨂ tᵢ)` defined by
`⨂ᵢ fᵢ ↦ ⨂ᵢ aᵢ ↦ ⨂ᵢ fᵢ aᵢ`.

This is `TensorProduct.homTensorHomMap` for an arbitrary family of modules.

Note that `PiTensorProduct.piTensorHomMap (tprod R f)` is equal to `PiTensorProduct.map f`.
-/
def piTensorHomMap : (⨂[R] i, s i →ₗ[R] t i) →ₗ[R] (⨂[R] i, s i) →ₗ[R] ⨂[R] i, t i 
goal: (PiTensorProduct R fun i => s i →ₗ[R] t i) →ₗ[R] (PiTensorProduct R fun i => s i) →ₗ[R] PiTensorProduct R fun i => t i

full_name: PiTensorProduct.piTensorHomMap_tprod_tprod
code: @[simp] lemma piTensorHomMap_tprod_tprod (f : Π i, s i →ₗ[R] t i) (x : Π i, s i) :
    piTensorHomMap (tprod R f) (tprod R x) = tprod R fun i ↦ f i (x i) 
goal: (PiTensorProduct.piTensorHomMap ((PiTensorProduct.tprod R) f)) ((PiTensorProduct.tprod R) x) =
  ⨂ₜ[R] (i : ι), (f i) (x i)

full_name: PiTensorProduct.piTensorHomMap_tprod_eq_map
code: lemma piTensorHomMap_tprod_eq_map (f : Π i, s i →ₗ[R] t i) :
    piTensorHomMap (tprod R f) = map f 
goal: PiTensorProduct.piTensorHomMap ((PiTensorProduct.tprod R) f) = PiTensorProduct.map f

full_name: PiTensorProduct.congr
code: /-- If `s i` and `t i` are linearly equivalent for every `i` in `ι`, then `⨂[R] i, s i` and
`⨂[R] i, t i` are linearly equivalent.

This is the n-ary version of `TensorProduct.congr`
-/
noncomputable def congr (f : Π i, s i ≃ₗ[R] t i) :
    (⨂[R] i, s i) ≃ₗ[R] ⨂[R] i, t i 
goal: (PiTensorProduct R fun i => s i) ≃ₗ[R] PiTensorProduct R fun i => t i

full_name: PiTensorProduct.congr_tprod
code: @[simp]
theorem congr_tprod (f : Π i, s i ≃ₗ[R] t i) (m : Π i, s i) :
    congr f (tprod R m) = tprod R (fun (i : ι) ↦ (f i) (m i)) 
goal: (PiTensorProduct.congr f) ((PiTensorProduct.tprod R) m) = ⨂ₜ[R] (i : ι), (f i) (m i)

full_name: PiTensorProduct.congr_symm_tprod
code: @[simp]
theorem congr_symm_tprod (f : Π i, s i ≃ₗ[R] t i) (p : Π i, t i) :
    (congr f).symm (tprod R p) = tprod R (fun (i : ι) ↦ (f i).symm (p i)) 
goal: (PiTensorProduct.congr f).symm ((PiTensorProduct.tprod R) p) = ⨂ₜ[R] (i : ι), (f i).symm (p i)

full_name: PiTensorProduct.map₂
code: /--
Let `sᵢ`, `tᵢ` and `t'ᵢ` be families of `R`-modules, then `f : Πᵢ sᵢ → tᵢ → t'ᵢ` induces an
element of `Hom(⨂ᵢ sᵢ, Hom(⨂ tᵢ, ⨂ᵢ t'ᵢ))` defined by `⨂ᵢ aᵢ ↦ ⨂ᵢ bᵢ ↦ ⨂ᵢ fᵢ aᵢ bᵢ`.

This is `PiTensorProduct.map` for two arbitrary families of modules.
This is `TensorProduct.map₂` for families of modules.
-/
def map₂ (f : Π i, s i →ₗ[R] t i →ₗ[R] t' i) :
    (⨂[R] i, s i) →ₗ[R] (⨂[R] i, t i) →ₗ[R] ⨂[R] i, t' i 
goal: (PiTensorProduct R fun i => s i) →ₗ[R] (PiTensorProduct R fun i => t i) →ₗ[R] PiTensorProduct R fun i => t' i

full_name: PiTensorProduct.map₂_tprod_tprod
code: lemma map₂_tprod_tprod (f : Π i, s i →ₗ[R] t i →ₗ[R] t' i) (x : Π i, s i) (y : Π i, t i) :
    map₂ f (tprod R x) (tprod R y) = tprod R fun i ↦ f i (x i) (y i) 
goal: ((PiTensorProduct.map₂ f) ((PiTensorProduct.tprod R) x)) ((PiTensorProduct.tprod R) y) =
  ⨂ₜ[R] (i : ι), ((f i) (x i)) (y i)

full_name: PiTensorProduct.piTensorHomMapFun₂
code: /--
Let `sᵢ`, `tᵢ` and `t'ᵢ` be families of `R`-modules.
Then there is a function from `⨂ᵢ Hom(sᵢ, Hom(tᵢ, t'ᵢ))` to `Hom(⨂ᵢ sᵢ, Hom(⨂ tᵢ, ⨂ᵢ t'ᵢ))`
defined by `⨂ᵢ fᵢ ↦ ⨂ᵢ aᵢ ↦ ⨂ᵢ bᵢ ↦ ⨂ᵢ fᵢ aᵢ bᵢ`. -/
def piTensorHomMapFun₂ : (⨂[R] i, s i →ₗ[R] t i →ₗ[R] t' i) →
    (⨂[R] i, s i) →ₗ[R] (⨂[R] i, t i) →ₗ[R] (⨂[R] i, t' i) 
goal: (PiTensorProduct R fun i => s i →ₗ[R] t i →ₗ[R] t' i) →
  (PiTensorProduct R fun i => s i) →ₗ[R] (PiTensorProduct R fun i => t i) →ₗ[R] PiTensorProduct R fun i => t' i

full_name: PiTensorProduct.piTensorHomMapFun₂_add
code: theorem piTensorHomMapFun₂_add (φ ψ : ⨂[R] i, s i →ₗ[R] t i →ₗ[R] t' i) :
    piTensorHomMapFun₂ (φ + ψ) = piTensorHomMapFun₂ φ + piTensorHomMapFun₂ ψ 
goal: (φ + ψ).piTensorHomMapFun₂ = φ.piTensorHomMapFun₂ + ψ.piTensorHomMapFun₂

full_name: PiTensorProduct.piTensorHomMapFun₂_smul
code: theorem piTensorHomMapFun₂_smul (r : R) (φ : ⨂[R] i, s i →ₗ[R] t i →ₗ[R] t' i) :
    piTensorHomMapFun₂ (r • φ) = r • piTensorHomMapFun₂ φ 
goal: (r • φ).piTensorHomMapFun₂ = r • φ.piTensorHomMapFun₂

full_name: PiTensorProduct.piTensorHomMap₂
code: /--
Let `sᵢ`, `tᵢ` and `t'ᵢ` be families of `R`-modules.
Then there is an linear map from `⨂ᵢ Hom(sᵢ, Hom(tᵢ, t'ᵢ))` to `Hom(⨂ᵢ sᵢ, Hom(⨂ tᵢ, ⨂ᵢ t'ᵢ))`
defined by `⨂ᵢ fᵢ ↦ ⨂ᵢ aᵢ ↦ ⨂ᵢ bᵢ ↦ ⨂ᵢ fᵢ aᵢ bᵢ`.

This is `TensorProduct.homTensorHomMap` for two arbitrary families of modules.
-/
def piTensorHomMap₂ : (⨂[R] i, s i →ₗ[R] t i →ₗ[R] t' i) →ₗ[R]
    (⨂[R] i, s i) →ₗ[R] (⨂[R] i, t i) →ₗ[R] (⨂[R] i, t' i) 
goal: (PiTensorProduct R fun i => s i →ₗ[R] t i →ₗ[R] t' i) →ₗ[R]
  (PiTensorProduct R fun i => s i) →ₗ[R] (PiTensorProduct R fun i => t i) →ₗ[R] PiTensorProduct R fun i => t' i

full_name: PiTensorProduct.piTensorHomMap₂_tprod_tprod_tprod
code: @[simp] lemma piTensorHomMap₂_tprod_tprod_tprod
    (f : ∀ i, s i →ₗ[R] t i →ₗ[R] t' i) (a : ∀ i, s i) (b : ∀ i, t i) :
    piTensorHomMap₂ (tprod R f) (tprod R a) (tprod R b) = tprod R (fun i ↦ f i (a i) (b i)) 
goal: ((PiTensorProduct.piTensorHomMap₂ ((PiTensorProduct.tprod R) f)) ((PiTensorProduct.tprod R) a))
    ((PiTensorProduct.tprod R) b) =
  ⨂ₜ[R] (i : ι), ((f i) (a i)) (b i)

full_name: PiTensorProduct.reindex
code: /-- Re-index the components of the tensor power by `e`. -/
def reindex (e : ι ≃ ι₂) : (⨂[R] i : ι, s i) ≃ₗ[R] ⨂[R] i : ι₂, s (e.symm i) 
goal: (PiTensorProduct R fun i => s i) ≃ₗ[R] PiTensorProduct R fun i => s (e.symm i)

full_name: PiTensorProduct.reindex_tprod
code: @[simp]
theorem reindex_tprod (e : ι ≃ ι₂) (f : Π i, s i) :
    reindex R s e (tprod R f) = tprod R fun i ↦ f (e.symm i) 
goal: (PiTensorProduct.reindex R s e) ((PiTensorProduct.tprod R) f) = (PiTensorProduct.tprod R) fun i => f (e.symm i)

full_name: PiTensorProduct.reindex_comp_tprod
code: @[simp]
theorem reindex_comp_tprod (e : ι ≃ ι₂) :
    (reindex R s e).compMultilinearMap (tprod R) =
    (domDomCongrLinearEquiv' R R s _ e).symm (tprod R) 
goal: (↑(PiTensorProduct.reindex R s e)).compMultilinearMap (PiTensorProduct.tprod R) =
  (MultilinearMap.domDomCongrLinearEquiv' R R s (PiTensorProduct R fun i => s (e.symm i)) e).symm
    (PiTensorProduct.tprod R)

full_name: PiTensorProduct.lift_comp_reindex
code: theorem lift_comp_reindex (e : ι ≃ ι₂) (φ : MultilinearMap R (fun i ↦ s (e.symm i)) E) :
    lift φ ∘ₗ (reindex R s e) = lift ((domDomCongrLinearEquiv' R R s _ e).symm φ) 
goal: PiTensorProduct.lift φ ∘ₗ ↑(PiTensorProduct.reindex R s e) =
  PiTensorProduct.lift ((MultilinearMap.domDomCongrLinearEquiv' R R s E e).symm φ)

full_name: PiTensorProduct.lift_comp_reindex_symm
code: @[simp]
theorem lift_comp_reindex_symm (e : ι ≃ ι₂) (φ : MultilinearMap R s E) :
    lift φ ∘ₗ (reindex R s e).symm = lift (domDomCongrLinearEquiv' R R s _ e φ) 
goal: PiTensorProduct.lift φ ∘ₗ ↑(PiTensorProduct.reindex R s e).symm =
  PiTensorProduct.lift ((MultilinearMap.domDomCongrLinearEquiv' R R s E e) φ)

full_name: PiTensorProduct.lift_reindex
code: theorem lift_reindex
    (e : ι ≃ ι₂) (φ : MultilinearMap R (fun i ↦ s (e.symm i)) E) (x : ⨂[R] i, s i) :
    lift φ (reindex R s e x) = lift ((domDomCongrLinearEquiv' R R s _ e).symm φ) x 
goal: (PiTensorProduct.lift φ) ((PiTensorProduct.reindex R s e) x) =
  (PiTensorProduct.lift ((MultilinearMap.domDomCongrLinearEquiv' R R s E e).symm φ)) x

full_name: PiTensorProduct.lift_reindex_symm
code: @[simp]
theorem lift_reindex_symm
    (e : ι ≃ ι₂) (φ : MultilinearMap R s E) (x : ⨂[R] i, s (e.symm i)) :
    lift φ (reindex R s e |>.symm x) = lift (domDomCongrLinearEquiv' R R s _ e φ) x 
goal: (PiTensorProduct.lift φ) ((PiTensorProduct.reindex R s e).symm x) =
  (PiTensorProduct.lift ((MultilinearMap.domDomCongrLinearEquiv' R R s E e) φ)) x

full_name: PiTensorProduct.reindex_trans
code: @[simp]
theorem reindex_trans (e : ι ≃ ι₂) (e' : ι₂ ≃ ι₃) :
    (reindex R s e).trans (reindex R _ e') = reindex R s (e.trans e') 
goal: PiTensorProduct.reindex R s e ≪≫ₗ PiTensorProduct.reindex R (fun i => s (e.symm i)) e' =
  PiTensorProduct.reindex R s (e.trans e')

full_name: PiTensorProduct.reindex_reindex
code: theorem reindex_reindex (e : ι ≃ ι₂) (e' : ι₂ ≃ ι₃) (x : ⨂[R] i, s i) :
    reindex R _ e' (reindex R s e x) = reindex R s (e.trans e') x 
goal: (PiTensorProduct.reindex R (fun i => s (e.symm i)) e') ((PiTensorProduct.reindex R s e) x) =
  (PiTensorProduct.reindex R s (e.trans e')) x

full_name: PiTensorProduct.reindex_symm
code: /-- This lemma is impractical to state in the dependent case. -/
@[simp]
theorem reindex_symm (e : ι ≃ ι₂) :
    (reindex R (fun _ ↦ M) e).symm = reindex R (fun _ ↦ M) e.symm 
goal: (PiTensorProduct.reindex R (fun x => M) e).symm = PiTensorProduct.reindex R (fun x => M) e.symm

full_name: PiTensorProduct.reindex_refl
code: @[simp]
theorem reindex_refl : reindex R s (Equiv.refl ι) = LinearEquiv.refl R _ 
goal: PiTensorProduct.reindex R s (Equiv.refl ι) = LinearEquiv.refl R (PiTensorProduct R fun i => s i)

full_name: PiTensorProduct.map_comp_reindex_eq
code: /-- Re-indexing the components of the tensor product by an equivalence `e` is compatible
with `PiTensorProduct.map`. -/
theorem map_comp_reindex_eq (f : Π i, s i →ₗ[R] t i) (e : ι ≃ ι₂) :
    map (fun i ↦ f (e.symm i)) ∘ₗ reindex R s e = reindex R t e ∘ₗ map f 
goal: (PiTensorProduct.map fun i => f (e.symm i)) ∘ₗ ↑(PiTensorProduct.reindex R s e) =
  ↑(PiTensorProduct.reindex R t e) ∘ₗ PiTensorProduct.map f

full_name: PiTensorProduct.map_reindex
code: theorem map_reindex (f : Π i, s i →ₗ[R] t i) (e : ι ≃ ι₂) (x : ⨂[R] i, s i) :
    map (fun i ↦ f (e.symm i)) (reindex R s e x) = reindex R t e (map f x) 
goal: (PiTensorProduct.map fun i => f (e.symm i)) ((PiTensorProduct.reindex R s e) x) =
  (PiTensorProduct.reindex R t e) ((PiTensorProduct.map f) x)

full_name: PiTensorProduct.map_comp_reindex_symm
code: theorem map_comp_reindex_symm (f : Π i, s i →ₗ[R] t i) (e : ι ≃ ι₂) :
    map f ∘ₗ (reindex R s e).symm = (reindex R t e).symm ∘ₗ map (fun i => f (e.symm i)) 
goal: PiTensorProduct.map f ∘ₗ ↑(PiTensorProduct.reindex R s e).symm =
  ↑(PiTensorProduct.reindex R t e).symm ∘ₗ PiTensorProduct.map fun i => f (e.symm i)

full_name: PiTensorProduct.map_reindex_symm
code: theorem map_reindex_symm (f : Π i, s i →ₗ[R] t i) (e : ι ≃ ι₂) (x : ⨂[R] i, s (e.symm i)) :
    map f ((reindex R s e).symm x) = (reindex R t e).symm (map (fun i ↦ f (e.symm i)) x) 
goal: (PiTensorProduct.map f) ((PiTensorProduct.reindex R s e).symm x) =
  (PiTensorProduct.reindex R t e).symm ((PiTensorProduct.map fun i => f (e.symm i)) x)

full_name: PiTensorProduct.isEmptyEquiv_symm_apply
code: /-- The tensor product over an empty index type `ι` is isomorphic to the base ring. -/
@[simps symm_apply]
def isEmptyEquiv [IsEmpty ι] : (⨂[R] i : ι, s i) ≃ₗ[R] R 
goal: (PiTensorProduct.isEmptyEquiv ι).symm r = r • (PiTensorProduct.tprod R) isEmptyElim

full_name: PiTensorProduct.isEmptyEquiv
code: /-- The tensor product over an empty index type `ι` is isomorphic to the base ring. -/
@[simps symm_apply]
def isEmptyEquiv [IsEmpty ι] : (⨂[R] i : ι, s i) ≃ₗ[R] R 
goal: (PiTensorProduct R fun i => s i) ≃ₗ[R] R

full_name: PiTensorProduct.isEmptyEquiv_apply_tprod
code: @[simp]
theorem isEmptyEquiv_apply_tprod [IsEmpty ι] (f : Π i, s i) :
    isEmptyEquiv ι (tprod R f) = 1 
goal: (PiTensorProduct.isEmptyEquiv ι) ((PiTensorProduct.tprod R) f) = 1

full_name: PiTensorProduct.subsingletonEquiv
code: /--
Tensor product of `M` over a singleton set is equivalent to `M`
-/
@[simps symm_apply]
def subsingletonEquiv [Subsingleton ι] (i₀ : ι) : (⨂[R] _ : ι, M) ≃ₗ[R] M 
goal: (PiTensorProduct R fun x => M) ≃ₗ[R] M

full_name: PiTensorProduct.subsingletonEquiv_symm_apply
code: /--
Tensor product of `M` over a singleton set is equivalent to `M`
-/
@[simps symm_apply]
def subsingletonEquiv [Subsingleton ι] (i₀ : ι) : (⨂[R] _ : ι, M) ≃ₗ[R] M 
goal: (PiTensorProduct.subsingletonEquiv i₀).symm m = (PiTensorProduct.tprod R) fun x => m

full_name: PiTensorProduct.subsingletonEquiv_apply_tprod
code: @[simp]
theorem subsingletonEquiv_apply_tprod [Subsingleton ι] (i : ι) (f : ι → M) :
    subsingletonEquiv i (tprod R f) = f i 
goal: (PiTensorProduct.subsingletonEquiv i) ((PiTensorProduct.tprod R) f) = f i

full_name: _private.Mathlib.LinearAlgebra.PiTensorProduct.0.PiTensorProduct.tmul
code: /-- Collapse a `TensorProduct` of `PiTensorProduct`s. -/
private def tmul : ((⨂[R] _ : ι, M) ⊗[R] ⨂[R] _ : ι₂, M) →ₗ[R] ⨂[R] _ : ι ⊕ ι₂, M 
goal: TensorProduct R (PiTensorProduct R fun x => M) (PiTensorProduct R fun x => M) →ₗ[R] PiTensorProduct R fun x => M

full_name: _private.Mathlib.LinearAlgebra.PiTensorProduct.0.PiTensorProduct.tmul_apply
code: private theorem tmul_apply (a : ι → M) (b : ι₂ → M) :
    tmul ((⨂ₜ[R] i, a i) ⊗ₜ[R] ⨂ₜ[R] i, b i) = ⨂ₜ[R] i, Sum.elim a b i 
goal: PiTensorProduct.tmul (((PiTensorProduct.tprod R) fun i => a i) ⊗ₜ[R] (PiTensorProduct.tprod R) fun i => b i) =
  (PiTensorProduct.tprod R) fun i => Sum.elim a b i

full_name: _private.Mathlib.LinearAlgebra.PiTensorProduct.0.PiTensorProduct.tmulSymm
code: /-- Expand `PiTensorProduct` into a `TensorProduct` of two factors. -/
private def tmulSymm : (⨂[R] _ : ι ⊕ ι₂, M) →ₗ[R] (⨂[R] _ : ι, M) ⊗[R] ⨂[R] _ : ι₂, M 
goal: (PiTensorProduct R fun x => M) →ₗ[R] TensorProduct R (PiTensorProduct R fun x => M) (PiTensorProduct R fun x => M)

full_name: _private.Mathlib.LinearAlgebra.PiTensorProduct.0.PiTensorProduct.tmulSymm_apply
code: private theorem tmulSymm_apply (a : ι ⊕ ι₂ → M) :
    tmulSymm (⨂ₜ[R] i, a i) = (⨂ₜ[R] i, a (Sum.inl i)) ⊗ₜ[R] ⨂ₜ[R] i, a (Sum.inr i) 
goal: PiTensorProduct.tmulSymm ((PiTensorProduct.tprod R) fun i => a i) =
  ((PiTensorProduct.tprod R) fun i => a (Sum.inl i)) ⊗ₜ[R] (PiTensorProduct.tprod R) fun i => a (Sum.inr i)

full_name: PiTensorProduct.tmulEquiv
code: /-- Equivalence between a `TensorProduct` of `PiTensorProduct`s and a single
`PiTensorProduct` indexed by a `Sum` type.

For simplicity, this is defined only for homogeneously- (rather than dependently-) typed components.
-/
def tmulEquiv : ((⨂[R] _ : ι, M) ⊗[R] ⨂[R] _ : ι₂, M) ≃ₗ[R] ⨂[R] _ : ι ⊕ ι₂, M 
goal: TensorProduct R (PiTensorProduct R fun x => M) (PiTensorProduct R fun x => M) ≃ₗ[R] PiTensorProduct R fun x => M

full_name: PiTensorProduct.tmulEquiv_apply
code: @[simp]
theorem tmulEquiv_apply (a : ι → M) (b : ι₂ → M) :
    tmulEquiv (ι := ι) (ι₂ := ι₂) R M ((⨂ₜ[R] i, a i) ⊗ₜ[R] ⨂ₜ[R] i, b i) =
    ⨂ₜ[R] i, Sum.elim a b i 
goal: (PiTensorProduct.tmulEquiv R M)
    (((PiTensorProduct.tprod R) fun i => a i) ⊗ₜ[R] (PiTensorProduct.tprod R) fun i => b i) =
  (PiTensorProduct.tprod R) fun i => Sum.elim a b i

full_name: PiTensorProduct.tmulEquiv_symm_apply
code: @[simp]
theorem tmulEquiv_symm_apply (a : ι ⊕ ι₂ → M) :
    (tmulEquiv (ι := ι) (ι₂ := ι₂) R M).symm (⨂ₜ[R] i, a i) =
    (⨂ₜ[R] i, a (Sum.inl i)) ⊗ₜ[R] ⨂ₜ[R] i, a (Sum.inr i) 
goal: (PiTensorProduct.tmulEquiv R M).symm ((PiTensorProduct.tprod R) fun i => a i) =
  ((PiTensorProduct.tprod R) fun i => a (Sum.inl i)) ⊗ₜ[R] (PiTensorProduct.tprod R) fun i => a (Sum.inr i)

full_name: PiTensorProduct.instAddCommGroup
code: instance : AddCommGroup (⨂[R] i, s i) 
goal: AddCommGroup (PiTensorProduct R fun i => s i)