l3lab/ntp-mathlib huggingface dataset:
/-- An equivalence of sets induces a linear equivalence of `Finsupp`s supported on those sets. -/
noncomputable def congr {α' : Type*} (s : Set α) (t : Set α') (e : s ≃ t) :
    supported M R s ≃ₗ[R] supported M R t := by
  

Proof state:
α : Type u_1
M : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝⁷ : Semiring R
inst✝⁶ : Semiring S
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α' : Type u_7
s : Set α
t : Set α'
e : ↑s ≃ ↑t
⊢ ↥(supported M R s) ≃ₗ[R] ↥(supported M R t)

Next tactic:
haveI := Classical.decPred fun x => x ∈ s
/-- An equivalence of sets induces a linear equivalence of `Finsupp`s supported on those sets. -/
noncomputable def congr {α' : Type*} (s : Set α) (t : Set α') (e : s ≃ t) :
    supported M R s ≃ₗ[R] supported M R t := by
  haveI := Classical.decPred fun x => x ∈ s
  

Proof state:
α : Type u_1
M : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝⁷ : Semiring R
inst✝⁶ : Semiring S
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α' : Type u_7
s : Set α
t : Set α'
e : ↑s ≃ ↑t
this : DecidablePred fun x => x ∈ s
⊢ ↥(supported M R s) ≃ₗ[R] ↥(supported M R t)

Next tactic:
haveI := Classical.decPred fun x => x ∈ t
/-- An equivalence of sets induces a linear equivalence of `Finsupp`s supported on those sets. -/
noncomputable def congr {α' : Type*} (s : Set α) (t : Set α') (e : s ≃ t) :
    supported M R s ≃ₗ[R] supported M R t := by
  haveI := Classical.decPred fun x => x ∈ s
  haveI := Classical.decPred fun x => x ∈ t
  

Proof state:
α : Type u_1
M : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝⁷ : Semiring R
inst✝⁶ : Semiring S
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α' : Type u_7
s : Set α
t : Set α'
e : ↑s ≃ ↑t
this✝ : DecidablePred fun x => x ∈ s
this : DecidablePred fun x => x ∈ t
⊢ ↥(supported M R s) ≃ₗ[R] ↥(supported M R t)

Next tactic:
exact Finsupp.supportedEquivFinsupp s ≪≫ₗ
    (Finsupp.domLCongr e ≪≫ₗ (Finsupp.supportedEquivFinsupp t).symm)
@[simp]
theorem lcongr_single {ι κ : Sort _} (e₁ : ι ≃ κ) (e₂ : M ≃ₗ[R] N) (i : ι) (m : M) :
    lcongr e₁ e₂ (Finsupp.single i m) = Finsupp.single (e₁ i) (e₂ m) := by 

Proof state:
α : Type u_1
M : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝⁷ : Semiring R
inst✝⁶ : Semiring S
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
ι : Type u_7
κ : Type u_8
e₁ : ι ≃ κ
e₂ : M ≃ₗ[R] N
i : ι
m : M
⊢ ((lcongr e₁ e₂) fun₀ | i => m) = fun₀ | e₁ i => e₂ m

Next tactic:
simp [lcongr]
theorem lcongr_symm_single {ι κ : Sort _} (e₁ : ι ≃ κ) (e₂ : M ≃ₗ[R] N) (k : κ) (n : N) :
    (lcongr e₁ e₂).symm (Finsupp.single k n) = Finsupp.single (e₁.symm k) (e₂.symm n) := by
  

Proof state:
α : Type u_1
M : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝⁷ : Semiring R
inst✝⁶ : Semiring S
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
ι : Type u_7
κ : Type u_8
e₁ : ι ≃ κ
e₂ : M ≃ₗ[R] N
k : κ
n : N
⊢ ((LinearEquiv.symm (lcongr e₁ e₂)) fun₀ | k => n) = fun₀ | e₁.symm k => (LinearEquiv.symm e₂) n

Next tactic:
apply_fun (lcongr e₁ e₂ : (ι →₀ M) → (κ →₀ N)) using (lcongr e₁ e₂).injective
theorem lcongr_symm_single {ι κ : Sort _} (e₁ : ι ≃ κ) (e₂ : M ≃ₗ[R] N) (k : κ) (n : N) :
    (lcongr e₁ e₂).symm (Finsupp.single k n) = Finsupp.single (e₁.symm k) (e₂.symm n) := by
  apply_fun (lcongr e₁ e₂ : (ι →₀ M) → (κ →₀ N)) using (lcongr e₁ e₂).injective
  

Proof state:
α : Type u_1
M : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝⁷ : Semiring R
inst✝⁶ : Semiring S
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
ι : Type u_7
κ : Type u_8
e₁ : ι ≃ κ
e₂ : M ≃ₗ[R] N
k : κ
n : N
⊢ (lcongr e₁ e₂) ((LinearEquiv.symm (lcongr e₁ e₂)) fun₀ | k => n) =
    (lcongr e₁ e₂) fun₀ | e₁.symm k => (LinearEquiv.symm e₂) n

Next tactic:
simp
@[simp]
theorem lcongr_symm {ι κ : Sort _} (e₁ : ι ≃ κ) (e₂ : M ≃ₗ[R] N) :
    (lcongr e₁ e₂).symm = lcongr e₁.symm e₂.symm := by
  

Proof state:
α : Type u_1
M : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝⁷ : Semiring R
inst✝⁶ : Semiring S
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
ι : Type u_7
κ : Type u_8
e₁ : ι ≃ κ
e₂ : M ≃ₗ[R] N
⊢ LinearEquiv.symm (lcongr e₁ e₂) = lcongr e₁.symm (LinearEquiv.symm e₂)

Next tactic:
ext
@[simp]
theorem lcongr_symm {ι κ : Sort _} (e₁ : ι ≃ κ) (e₂ : M ≃ₗ[R] N) :
    (lcongr e₁ e₂).symm = lcongr e₁.symm e₂.symm := by
  ext
  

Proof state:
case h.h
α : Type u_1
M : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝⁷ : Semiring R
inst✝⁶ : Semiring S
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
ι : Type u_7
κ : Type u_8
e₁ : ι ≃ κ
e₂ : M ≃ₗ[R] N
x✝ : κ →₀ N
a✝ : ι
⊢ ((LinearEquiv.symm (lcongr e₁ e₂)) x✝) a✝ = ((lcongr e₁.symm (LinearEquiv.symm e₂)) x✝) a✝

Next tactic:
rfl
/-- The linear equivalence between `(α ⊕ β) →₀ M` and `(α →₀ M) × (β →₀ M)`.

This is the `LinearEquiv` version of `Finsupp.sumFinsuppEquivProdFinsupp`. -/
@[simps apply symm_apply]
def sumFinsuppLEquivProdFinsupp {α β : Type*} : (Sum α β →₀ M) ≃ₗ[R] (α →₀ M) × (β →₀ M) :=
  { sumFinsuppAddEquivProdFinsupp with
    map_smul' := by
      

Proof state:
α✝ : Type u_1
M : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝⁷ : Semiring R
inst✝⁶ : Semiring S
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_7
β : Type u_8
src✝ : (α ⊕ β →₀ M) ≃+ (α →₀ M) × (β →₀ M) := sumFinsuppAddEquivProdFinsupp
⊢ ∀ (r : R) (x : α ⊕ β →₀ M),
    AddHom.toFun
        { toFun := src✝.toFun,
          map_add' :=
            (_ :
              ∀ (x y : α ⊕ β →₀ M),
                Equiv.toFun src✝.toEquiv (x + y) = Equiv.toFun src✝.toEquiv x + Equiv.toFun src✝.toEquiv y) }
        (r • x) =
      (RingHom.id R) r •
        AddHom.toFun
          { toFun := src✝.toFun,
            map_add' :=
              (_ :
                ∀ (x y : α ⊕ β →₀ M),
                  Equiv.toFun src✝.toEquiv (x + y) = Equiv.toFun src✝.toEquiv x + Equiv.toFun src✝.toEquiv y) }
          x

Next tactic:
intros
/-- The linear equivalence between `(α ⊕ β) →₀ M` and `(α →₀ M) × (β →₀ M)`.

This is the `LinearEquiv` version of `Finsupp.sumFinsuppEquivProdFinsupp`. -/
@[simps apply symm_apply]
def sumFinsuppLEquivProdFinsupp {α β : Type*} : (Sum α β →₀ M) ≃ₗ[R] (α →₀ M) × (β →₀ M) :=
  { sumFinsuppAddEquivProdFinsupp with
    map_smul' := by
      intros
      

Proof state:
α✝ : Type u_1
M : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝⁷ : Semiring R
inst✝⁶ : Semiring S
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_7
β : Type u_8
src✝ : (α ⊕ β →₀ M) ≃+ (α →₀ M) × (β →₀ M) := sumFinsuppAddEquivProdFinsupp
r✝ : R
x✝ : α ⊕ β →₀ M
⊢ AddHom.toFun
      { toFun := src✝.toFun,
        map_add' :=
          (_ :
            ∀ (x y : α ⊕ β →₀ M),
              Equiv.toFun src✝.toEquiv (x + y) = Equiv.toFun src✝.toEquiv x + Equiv.toFun src✝.toEquiv y) }
      (r✝ • x✝) =
    (RingHom.id R) r✝ •
      AddHom.toFun
        { toFun := src✝.toFun,
          map_add' :=
            (_ :
              ∀ (x y : α ⊕ β →₀ M),
                Equiv.toFun src✝.toEquiv (x + y) = Equiv.toFun src✝.toEquiv x + Equiv.toFun src✝.toEquiv y) }
        x✝

Next tactic:
ext
/-- The linear equivalence between `(α ⊕ β) →₀ M` and `(α →₀ M) × (β →₀ M)`.

This is the `LinearEquiv` version of `Finsupp.sumFinsuppEquivProdFinsupp`. -/
@[simps apply symm_apply]
def sumFinsuppLEquivProdFinsupp {α β : Type*} : (Sum α β →₀ M) ≃ₗ[R] (α →₀ M) × (β →₀ M) :=
  { sumFinsuppAddEquivProdFinsupp with
    map_smul' := by
      intros
      ext <;>
        -- Porting note: `add_equiv.to_fun_eq_coe` →
        --               `Equiv.toFun_as_coe` & `AddEquiv.toEquiv_eq_coe` & `AddEquiv.coe_toEquiv`
        

Proof state:
case a.h
α✝ : Type u_1
M : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝⁷ : Semiring R
inst✝⁶ : Semiring S
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_7
β : Type u_8
src✝ : (α ⊕ β →₀ M) ≃+ (α →₀ M) × (β →₀ M) := sumFinsuppAddEquivProdFinsupp
r✝ : R
x✝ : α ⊕ β →₀ M
a✝ : α
⊢ (AddHom.toFun
          { toFun := src✝.toFun,
            map_add' :=
              (_ :
                ∀ (x y : α ⊕ β →₀ M),
                  Equiv.toFun src✝.toEquiv (x + y) = Equiv.toFun src✝.toEquiv x + Equiv.toFun src✝.toEquiv y) }
          (r✝ • x✝)).1
      a✝ =
    ((RingHom.id R) r✝ •
          AddHom.toFun
            { toFun := src✝.toFun,
              map_add' :=
                (_ :
                  ∀ (x y : α ⊕ β →₀ M),
                    Equiv.toFun src✝.toEquiv (x + y) = Equiv.toFun src✝.toEquiv x + Equiv.toFun src✝.toEquiv y) }
            x✝).1
      a✝

Next tactic:
simp only [Equiv.toFun_as_coe, AddEquiv.toEquiv_eq_coe, AddEquiv.coe_toEquiv, Prod.smul_fst,
          Prod.smul_snd, smul_apply,
          snd_sumFinsuppAddEquivProdFinsupp, fst_sumFinsuppAddEquivProdFinsupp,
          RingHom.id_apply]
/-- The linear equivalence between `(α ⊕ β) →₀ M` and `(α →₀ M) × (β →₀ M)`.

This is the `LinearEquiv` version of `Finsupp.sumFinsuppEquivProdFinsupp`. -/
@[simps apply symm_apply]
def sumFinsuppLEquivProdFinsupp {α β : Type*} : (Sum α β →₀ M) ≃ₗ[R] (α →₀ M) × (β →₀ M) :=
  { sumFinsuppAddEquivProdFinsupp with
    map_smul' := by
      intros
      ext <;>
        -- Porting note: `add_equiv.to_fun_eq_coe` →
        --               `Equiv.toFun_as_coe` & `AddEquiv.toEquiv_eq_coe` & `AddEquiv.coe_toEquiv`
        

Proof state:
case a.h
α✝ : Type u_1
M : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝⁷ : Semiring R
inst✝⁶ : Semiring S
inst✝⁵ : AddCommMonoid M
inst✝⁴ : Module R M
inst✝³ : AddCommMonoid N
inst✝² : Module R N
inst✝¹ : AddCommMonoid P
inst✝ : Module R P
α : Type u_7
β : Type u_8
src✝ : (α ⊕ β →₀ M) ≃+ (α →₀ M) × (β →₀ M) := sumFinsuppAddEquivProdFinsupp
r✝ : R
x✝ : α ⊕ β →₀ M
a✝ : β
⊢ (AddHom.toFun
          { toFun := src✝.toFun,
            map_add' :=
              (_ :
                ∀ (x y : α ⊕ β →₀ M),
                  Equiv.toFun src✝.toEquiv (x + y) = Equiv.toFun src✝.toEquiv x + Equiv.toFun src✝.toEquiv y) }
          (r✝ • x✝)).2
      a✝ =
    ((RingHom.id R) r✝ •
          AddHom.toFun
            { toFun := src✝.toFun,
              map_add' :=
                (_ :
                  ∀ (x y : α ⊕ β →₀ M),
                    Equiv.toFun src✝.toEquiv (x + y) = Equiv.toFun src✝.toEquiv x + Equiv.toFun src✝.toEquiv y) }
            x✝).2
      a✝

Next tactic:
simp only [Equiv.toFun_as_coe, AddEquiv.toEquiv_eq_coe, AddEquiv.coe_toEquiv, Prod.smul_fst,
          Prod.smul_snd, smul_apply,
          snd_sumFinsuppAddEquivProdFinsupp, fst_sumFinsuppAddEquivProdFinsupp,
          RingHom.id_apply]
/-- On a `Fintype η`, `Finsupp.split` is a linear equivalence between
`(Σ (j : η), ιs j) →₀ M` and `(j : η) → (ιs j →₀ M)`.

This is the `LinearEquiv` version of `Finsupp.sigmaFinsuppAddEquivPiFinsupp`. -/
noncomputable def sigmaFinsuppLEquivPiFinsupp {M : Type*} {ιs : η → Type*} [AddCommMonoid M]
    [Module R M] : ((Σ j, ιs j) →₀ M) ≃ₗ[R] (j : _) → (ιs j →₀ M) :=
  -- Porting note: `ιs` should be specified.
  { sigmaFinsuppAddEquivPiFinsupp (ιs := ιs) with
    map_smul' := fun c f => by
      

Proof state:
α : Type u_1
M✝ : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝¹¹ : Semiring R
inst✝¹⁰ : Semiring S
inst✝⁹ : AddCommMonoid M✝
inst✝⁸ : Module R M✝
inst✝⁷ : AddCommMonoid N
inst✝⁶ : Module R N
inst✝⁵ : AddCommMonoid P
inst✝⁴ : Module R P
η : Type u_7
inst✝³ : Fintype η
ιs✝ : η → Type u_8
inst✝² : Zero α
M : Type u_9
ιs : η → Type u_10
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
src✝ : ((j : η) × ιs j →₀ M) ≃+ ((j : η) → ιs j →₀ M) := sigmaFinsuppAddEquivPiFinsupp
c : R
f : (j : η) × ιs j →₀ M
⊢ AddHom.toFun
      { toFun := src✝.toFun,
        map_add' :=
          (_ :
            ∀ (x y : (j : η) × ιs j →₀ M),
              Equiv.toFun src✝.toEquiv (x + y) = Equiv.toFun src✝.toEquiv x + Equiv.toFun src✝.toEquiv y) }
      (c • f) =
    (RingHom.id R) c •
      AddHom.toFun
        { toFun := src✝.toFun,
          map_add' :=
            (_ :
              ∀ (x y : (j : η) × ιs j →₀ M),
                Equiv.toFun src✝.toEquiv (x + y) = Equiv.toFun src✝.toEquiv x + Equiv.toFun src✝.toEquiv y) }
        f

Next tactic:
ext
/-- On a `Fintype η`, `Finsupp.split` is a linear equivalence between
`(Σ (j : η), ιs j) →₀ M` and `(j : η) → (ιs j →₀ M)`.

This is the `LinearEquiv` version of `Finsupp.sigmaFinsuppAddEquivPiFinsupp`. -/
noncomputable def sigmaFinsuppLEquivPiFinsupp {M : Type*} {ιs : η → Type*} [AddCommMonoid M]
    [Module R M] : ((Σ j, ιs j) →₀ M) ≃ₗ[R] (j : _) → (ιs j →₀ M) :=
  -- Porting note: `ιs` should be specified.
  { sigmaFinsuppAddEquivPiFinsupp (ιs := ιs) with
    map_smul' := fun c f => by
      ext
      

Proof state:
case h.h
α : Type u_1
M✝ : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝¹¹ : Semiring R
inst✝¹⁰ : Semiring S
inst✝⁹ : AddCommMonoid M✝
inst✝⁸ : Module R M✝
inst✝⁷ : AddCommMonoid N
inst✝⁶ : Module R N
inst✝⁵ : AddCommMonoid P
inst✝⁴ : Module R P
η : Type u_7
inst✝³ : Fintype η
ιs✝ : η → Type u_8
inst✝² : Zero α
M : Type u_9
ιs : η → Type u_10
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
src✝ : ((j : η) × ιs j →₀ M) ≃+ ((j : η) → ιs j →₀ M) := sigmaFinsuppAddEquivPiFinsupp
c : R
f : (j : η) × ιs j →₀ M
x✝ : η
a✝ : ιs x✝
⊢ (AddHom.toFun
        { toFun := src✝.toFun,
          map_add' :=
            (_ :
              ∀ (x y : (j : η) × ιs j →₀ M),
                Equiv.toFun src✝.toEquiv (x + y) = Equiv.toFun src✝.toEquiv x + Equiv.toFun src✝.toEquiv y) }
        (c • f) x✝)
      a✝ =
    (((RingHom.id R) c •
          AddHom.toFun
            { toFun := src✝.toFun,
              map_add' :=
                (_ :
                  ∀ (x y : (j : η) × ιs j →₀ M),
                    Equiv.toFun src✝.toEquiv (x + y) = Equiv.toFun src✝.toEquiv x + Equiv.toFun src✝.toEquiv y) }
            f)
        x✝)
      a✝

Next tactic:
simp
/-- The linear equivalence between `α × β →₀ M` and `α →₀ β →₀ M`.

This is the `LinearEquiv` version of `Finsupp.finsuppProdEquiv`. -/
noncomputable def finsuppProdLEquiv {α β : Type*} (R : Type*) {M : Type*} [Semiring R]
    [AddCommMonoid M] [Module R M] : (α × β →₀ M) ≃ₗ[R] α →₀ β →₀ M :=
  { finsuppProdEquiv with
    map_add' := fun f g => by
      

Proof state:
α✝ : Type u_1
M✝ : Type u_2
N : Type u_3
P : Type u_4
R✝ : Type u_5
S : Type u_6
inst✝¹⁰ : Semiring R✝
inst✝⁹ : Semiring S
inst✝⁸ : AddCommMonoid M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommMonoid N
inst✝⁵ : Module R✝ N
inst✝⁴ : AddCommMonoid P
inst✝³ : Module R✝ P
α : Type u_7
β : Type u_8
R : Type u_9
M : Type u_10
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
src✝ : (α × β →₀ M) ≃ (α →₀ β →₀ M) := finsuppProdEquiv
f g : α × β →₀ M
⊢ Equiv.toFun src✝ (f + g) = Equiv.toFun src✝ f + Equiv.toFun src✝ g

Next tactic:
ext
/-- The linear equivalence between `α × β →₀ M` and `α →₀ β →₀ M`.

This is the `LinearEquiv` version of `Finsupp.finsuppProdEquiv`. -/
noncomputable def finsuppProdLEquiv {α β : Type*} (R : Type*) {M : Type*} [Semiring R]
    [AddCommMonoid M] [Module R M] : (α × β →₀ M) ≃ₗ[R] α →₀ β →₀ M :=
  { finsuppProdEquiv with
    map_add' := fun f g => by
      ext
      

Proof state:
case h.h
α✝ : Type u_1
M✝ : Type u_2
N : Type u_3
P : Type u_4
R✝ : Type u_5
S : Type u_6
inst✝¹⁰ : Semiring R✝
inst✝⁹ : Semiring S
inst✝⁸ : AddCommMonoid M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommMonoid N
inst✝⁵ : Module R✝ N
inst✝⁴ : AddCommMonoid P
inst✝³ : Module R✝ P
α : Type u_7
β : Type u_8
R : Type u_9
M : Type u_10
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
src✝ : (α × β →₀ M) ≃ (α →₀ β →₀ M) := finsuppProdEquiv
f g : α × β →₀ M
a✝¹ : α
a✝ : β
⊢ ((Equiv.toFun src✝ (f + g)) a✝¹) a✝ = ((Equiv.toFun src✝ f + Equiv.toFun src✝ g) a✝¹) a✝

Next tactic:
simp [finsuppProdEquiv, curry_apply]
/-- The linear equivalence between `α × β →₀ M` and `α →₀ β →₀ M`.

This is the `LinearEquiv` version of `Finsupp.finsuppProdEquiv`. -/
noncomputable def finsuppProdLEquiv {α β : Type*} (R : Type*) {M : Type*} [Semiring R]
    [AddCommMonoid M] [Module R M] : (α × β →₀ M) ≃ₗ[R] α →₀ β →₀ M :=
  { finsuppProdEquiv with
    map_add' := fun f g => by
      ext
      simp [finsuppProdEquiv, curry_apply]
    map_smul' := fun c f => by
      

Proof state:
α✝ : Type u_1
M✝ : Type u_2
N : Type u_3
P : Type u_4
R✝ : Type u_5
S : Type u_6
inst✝¹⁰ : Semiring R✝
inst✝⁹ : Semiring S
inst✝⁸ : AddCommMonoid M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommMonoid N
inst✝⁵ : Module R✝ N
inst✝⁴ : AddCommMonoid P
inst✝³ : Module R✝ P
α : Type u_7
β : Type u_8
R : Type u_9
M : Type u_10
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
src✝ : (α × β →₀ M) ≃ (α →₀ β →₀ M) := finsuppProdEquiv
c : R
f : α × β →₀ M
⊢ AddHom.toFun
      { toFun := src✝.toFun,
        map_add' := (_ : ∀ (f g : α × β →₀ M), Equiv.toFun src✝ (f + g) = Equiv.toFun src✝ f + Equiv.toFun src✝ g) }
      (c • f) =
    (RingHom.id R) c •
      AddHom.toFun
        { toFun := src✝.toFun,
          map_add' := (_ : ∀ (f g : α × β →₀ M), Equiv.toFun src✝ (f + g) = Equiv.toFun src✝ f + Equiv.toFun src✝ g) }
        f

Next tactic:
ext
/-- The linear equivalence between `α × β →₀ M` and `α →₀ β →₀ M`.

This is the `LinearEquiv` version of `Finsupp.finsuppProdEquiv`. -/
noncomputable def finsuppProdLEquiv {α β : Type*} (R : Type*) {M : Type*} [Semiring R]
    [AddCommMonoid M] [Module R M] : (α × β →₀ M) ≃ₗ[R] α →₀ β →₀ M :=
  { finsuppProdEquiv with
    map_add' := fun f g => by
      ext
      simp [finsuppProdEquiv, curry_apply]
    map_smul' := fun c f => by
      ext
      

Proof state:
case h.h
α✝ : Type u_1
M✝ : Type u_2
N : Type u_3
P : Type u_4
R✝ : Type u_5
S : Type u_6
inst✝¹⁰ : Semiring R✝
inst✝⁹ : Semiring S
inst✝⁸ : AddCommMonoid M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommMonoid N
inst✝⁵ : Module R✝ N
inst✝⁴ : AddCommMonoid P
inst✝³ : Module R✝ P
α : Type u_7
β : Type u_8
R : Type u_9
M : Type u_10
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
src✝ : (α × β →₀ M) ≃ (α →₀ β →₀ M) := finsuppProdEquiv
c : R
f : α × β →₀ M
a✝¹ : α
a✝ : β
⊢ ((AddHom.toFun
          { toFun := src✝.toFun,
            map_add' := (_ : ∀ (f g : α × β →₀ M), Equiv.toFun src✝ (f + g) = Equiv.toFun src✝ f + Equiv.toFun src✝ g) }
          (c • f))
        a✝¹)
      a✝ =
    (((RingHom.id R) c •
          AddHom.toFun
            { toFun := src✝.toFun,
              map_add' :=
                (_ : ∀ (f g : α × β →₀ M), Equiv.toFun src✝ (f + g) = Equiv.toFun src✝ f + Equiv.toFun src✝ g) }
            f)
        a✝¹)
      a✝

Next tactic:
simp [finsuppProdEquiv, curry_apply]
@[simp]
theorem finsuppProdLEquiv_apply {α β R M : Type*} [Semiring R] [AddCommMonoid M] [Module R M]
    (f : α × β →₀ M) (x y) : finsuppProdLEquiv R f x y = f (x, y) := by
  

Proof state:
α✝ : Type u_1
M✝ : Type u_2
N : Type u_3
P : Type u_4
R✝ : Type u_5
S : Type u_6
inst✝¹⁰ : Semiring R✝
inst✝⁹ : Semiring S
inst✝⁸ : AddCommMonoid M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommMonoid N
inst✝⁵ : Module R✝ N
inst✝⁴ : AddCommMonoid P
inst✝³ : Module R✝ P
α : Type u_7
β : Type u_8
R : Type u_9
M : Type u_10
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f : α × β →₀ M
x : α
y : β
⊢ (((finsuppProdLEquiv R) f) x) y = f (x, y)

Next tactic:
rw [finsuppProdLEquiv, LinearEquiv.coe_mk, finsuppProdEquiv, Finsupp.curry_apply]
@[simp]
theorem finsuppProdLEquiv_symm_apply {α β R M : Type*} [Semiring R] [AddCommMonoid M] [Module R M]
    (f : α →₀ β →₀ M) (xy) : (finsuppProdLEquiv R).symm f xy = f xy.1 xy.2 := by
  

Proof state:
α✝ : Type u_1
M✝ : Type u_2
N : Type u_3
P : Type u_4
R✝ : Type u_5
S : Type u_6
inst✝¹⁰ : Semiring R✝
inst✝⁹ : Semiring S
inst✝⁸ : AddCommMonoid M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommMonoid N
inst✝⁵ : Module R✝ N
inst✝⁴ : AddCommMonoid P
inst✝³ : Module R✝ P
α : Type u_7
β : Type u_8
R : Type u_9
M : Type u_10
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f : α →₀ β →₀ M
xy : α × β
⊢ ((LinearEquiv.symm (finsuppProdLEquiv R)) f) xy = (f xy.1) xy.2

Next tactic:
conv_rhs =>
    rw [← (finsuppProdLEquiv R).apply_symm_apply f, finsuppProdLEquiv_apply]
@[simp]
theorem finsuppProdLEquiv_symm_apply {α β R M : Type*} [Semiring R] [AddCommMonoid M] [Module R M]
    (f : α →₀ β →₀ M) (xy) : (finsuppProdLEquiv R).symm f xy = f xy.1 xy.2 := by
  conv_rhs =>
    

Proof state:
α✝ : Type u_1
M✝ : Type u_2
N : Type u_3
P : Type u_4
R✝ : Type u_5
S : Type u_6
inst✝¹⁰ : Semiring R✝
inst✝⁹ : Semiring S
inst✝⁸ : AddCommMonoid M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommMonoid N
inst✝⁵ : Module R✝ N
inst✝⁴ : AddCommMonoid P
inst✝³ : Module R✝ P
α : Type u_7
β : Type u_8
R : Type u_9
M : Type u_10
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f : α →₀ β →₀ M
xy : α × β
| (f xy.1) xy.2

Next tactic:
rw [← (finsuppProdLEquiv R).apply_symm_apply f, finsuppProdLEquiv_apply]
/-- If `R` is countable, then any `R`-submodule spanned by a countable family of vectors is
countable. -/
instance {ι : Type*} [Countable R] [Countable ι] (v : ι → M) :
    Countable (Submodule.span R (Set.range v)) := by
  

Proof state:
α : Type u_1
M : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝⁹ : Semiring R
inst✝⁸ : Semiring S
inst✝⁷ : AddCommMonoid M
inst✝⁶ : Module R M
inst✝⁵ : AddCommMonoid N
inst✝⁴ : Module R N
inst✝³ : AddCommMonoid P
inst✝² : Module R P
ι : Type u_7
inst✝¹ : Countable R
inst✝ : Countable ι
v : ι → M
⊢ Countable ↥(span R (Set.range v))

Next tactic:
refine Set.countable_coe_iff.mpr (Set.Countable.mono ?_ (Set.countable_range
      (fun c : (ι →₀ R) => c.sum fun i _ => (c i) • v i)))
/-- If `R` is countable, then any `R`-submodule spanned by a countable family of vectors is
countable. -/
instance {ι : Type*} [Countable R] [Countable ι] (v : ι → M) :
    Countable (Submodule.span R (Set.range v)) := by
  refine Set.countable_coe_iff.mpr (Set.Countable.mono ?_ (Set.countable_range
      (fun c : (ι →₀ R) => c.sum fun i _ => (c i) • v i)))
  

Proof state:
α : Type u_1
M : Type u_2
N : Type u_3
P : Type u_4
R : Type u_5
S : Type u_6
inst✝⁹ : Semiring R
inst✝⁸ : Semiring S
inst✝⁷ : AddCommMonoid M
inst✝⁶ : Module R M
inst✝⁵ : AddCommMonoid N
inst✝⁴ : Module R N
inst✝³ : AddCommMonoid P
inst✝² : Module R P
ι : Type u_7
inst✝¹ : Countable R
inst✝ : Countable ι
v : ι → M
⊢ ↑(span R (Set.range v)) ⊆ Set.range fun c => sum c fun i x => c i • v i

Next tactic:
exact fun _ h => Finsupp.mem_span_range_iff_exists_finsupp.mp (SetLike.mem_coe.mp h)
/-- `Fintype.total R S v f` is the linear combination of vectors in `v` with weights in `f`.
This variant of `Finsupp.total` is defined on fintype indexed vectors.

This map is linear in `v` if `R` is commutative, and always linear in `f`.
See note [bundled maps over different rings] for why separate `R` and `S` semirings are used.
-/
protected def Fintype.total : (α → M) →ₗ[S] (α → R) →ₗ[R] M where
  toFun v :=
    { toFun := fun f => ∑ i, f i • v i
      map_add' := fun f g => by 

Proof state:
α : Type u_1
M : Type u_2
R : Type u_3
inst✝⁶ : Fintype α
inst✝⁵ : Semiring R
inst✝⁴ : AddCommMonoid M
inst✝³ : Module R M
S : Type u_4
inst✝² : Semiring S
inst✝¹ : Module S M
inst✝ : SMulCommClass R S M
v✝ v : α → M
f g : α → R
⊢ (fun f => ∑ i : α, f i • v i) (f + g) = (fun f => ∑ i : α, f i • v i) f + (fun f => ∑ i : α, f i • v i) g

Next tactic:
simp_rw [← Finset.sum_add_distrib, ← add_smul]