l3lab/ntp-mathlib huggingface dataset:
theorem ker_unitGroupToResidueFieldUnits :
    A.unitGroupToResidueFieldUnits.ker = A.principalUnitGroup.comap A.unitGroup.subtype := by
  ext
  -- Porting note: simp fails but rw works
  -- See https://github.com/leanprover-community/mathlib4/issues/5026
  -- simp [Subgroup.mem_comap, Subgroup.coeSubtype, coe_mem_principalUnitGroup_iff]
  rw [Subgroup.mem_comap, Subgroup.coeSubtype, coe_mem_principalUnitGroup_iff]
  

Proof state:
case h
K : Type u
inst✝ : Field K
A : ValuationSubring K
x✝ : ↥(unitGroup A)
⊢ x✝ ∈ MonoidHom.ker (unitGroupToResidueFieldUnits A) ↔
    (unitGroupMulEquiv A) x✝ ∈ MonoidHom.ker (Units.map ↑(LocalRing.residue ↥A))

Next tactic:
rfl
/-- The action on a valuation subring corresponding to applying the action to every element.

This is available as an instance in the `Pointwise` locale. -/
def pointwiseHasSMul : SMul G (ValuationSubring K) where
  smul g S :=-- TODO: if we add `ValuationSubring.map` at a later date, we should use it here
    { g • S.toSubring with
      mem_or_inv_mem' := fun x =>
        (mem_or_inv_mem S (g⁻¹ • x)).imp Subring.mem_pointwise_smul_iff_inv_smul_mem.mpr fun h =>
          Subring.mem_pointwise_smul_iff_inv_smul_mem.mpr <| by 

Proof state:
K : Type u
inst✝² : Field K
A : ValuationSubring K
G : Type u_1
inst✝¹ : Group G
inst✝ : MulSemiringAction G K
g : G
S : ValuationSubring K
src✝ : Subring K := g • S.toSubring
x : K
h : (g⁻¹ • x)⁻¹ ∈ S
⊢ g⁻¹ • x⁻¹ ∈ S.toSubring

Next tactic:
rwa [smul_inv'']
/-- The pullback of a valuation subring `A` along a ring homomorphism `K →+* L`. -/
def comap (A : ValuationSubring L) (f : K →+* L) : ValuationSubring K :=
  { A.toSubring.comap f with mem_or_inv_mem' := fun k => by 

Proof state:
K : Type u
inst✝² : Field K
A✝ : ValuationSubring K
L : Type u_1
J : Type u_2
inst✝¹ : Field L
inst✝ : Field J
A : ValuationSubring L
f : K →+* L
src✝ : Subring K := Subring.comap f A.toSubring
k : K
⊢ k ∈
      { toSubsemiring := src✝.toSubsemiring,
                neg_mem' :=
                  (_ :
                    ∀ {x : K},
                      x ∈ src✝.carrier → -x ∈ src✝.carrier) }.toSubsemiring.toSubmonoid.toSubsemigroup.carrier ∨
    k⁻¹ ∈
      { toSubsemiring := src✝.toSubsemiring,
                neg_mem' :=
                  (_ :
                    ∀ {x : K}, x ∈ src✝.carrier → -x ∈ src✝.carrier) }.toSubsemiring.toSubmonoid.toSubsemigroup.carrier

Next tactic:
simp [ValuationSubring.mem_or_inv_mem]
@[simp] theorem bind_singleton' (l : List α) : (l.bind fun x => [x]) = l := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
⊢ (List.bind l fun x => [x]) = l

Next tactic:
induction l
@[simp] theorem bind_singleton' (l : List α) : (l.bind fun x => [x]) = l := by
  induction l <;> 

Proof state:
case nil
α : Type u
β : Type v
γ : Type w
⊢ (List.bind [] fun x => [x]) = []

Next tactic:
simp [*]
@[simp] theorem bind_singleton' (l : List α) : (l.bind fun x => [x]) = l := by
  induction l <;> 

Proof state:
case cons
α : Type u
β : Type v
γ : Type w
head✝ : α
tail✝ : List α
tail_ih✝ : (List.bind tail✝ fun x => [x]) = tail✝
⊢ (List.bind (head✝ :: tail✝) fun x => [x]) = head✝ :: tail✝

Next tactic:
simp [*]
theorem map_eq_bind {α β} (f : α → β) (l : List α) : map f l = l.bind fun x => [f x] := by
  

Proof state:
α✝ : Type u
β✝ : Type v
γ : Type w
α : Type u_1
β : Type u_2
f : α → β
l : List α
⊢ map f l = List.bind l fun x => [f x]

Next tactic:
simp only [← map_singleton]
theorem map_eq_bind {α β} (f : α → β) (l : List α) : map f l = l.bind fun x => [f x] := by
  simp only [← map_singleton]
  

Proof state:
α✝ : Type u
β✝ : Type v
γ : Type w
α : Type u_1
β : Type u_2
f : α → β
l : List α
⊢ map f l = List.bind l fun x => map f [x]

Next tactic:
rw [← bind_singleton' l, bind_map, bind_singleton']
theorem bind_assoc {α β} (l : List α) (f : α → List β) (g : β → List γ) :
    (l.bind f).bind g = l.bind fun x => (f x).bind g := by 

Proof state:
α✝ : Type u
β✝ : Type v
γ : Type w
α : Type u_1
β : Type u_2
l : List α
f : α → List β
g : β → List γ
⊢ List.bind (List.bind l f) g = List.bind l fun x => List.bind (f x) g

Next tactic:
induction l
theorem bind_assoc {α β} (l : List α) (f : α → List β) (g : β → List γ) :
    (l.bind f).bind g = l.bind fun x => (f x).bind g := by induction l <;> 

Proof state:
case nil
α✝ : Type u
β✝ : Type v
γ : Type w
α : Type u_1
β : Type u_2
f : α → List β
g : β → List γ
⊢ List.bind (List.bind [] f) g = List.bind [] fun x => List.bind (f x) g

Next tactic:
simp [*]
theorem bind_assoc {α β} (l : List α) (f : α → List β) (g : β → List γ) :
    (l.bind f).bind g = l.bind fun x => (f x).bind g := by induction l <;> 

Proof state:
case cons
α✝ : Type u
β✝ : Type v
γ : Type w
α : Type u_1
β : Type u_2
f : α → List β
g : β → List γ
head✝ : α
tail✝ : List α
tail_ih✝ : List.bind (List.bind tail✝ f) g = List.bind tail✝ fun x => List.bind (f x) g
⊢ List.bind (List.bind (head✝ :: tail✝) f) g = List.bind (head✝ :: tail✝) fun x => List.bind (f x) g

Next tactic:
simp [*]
instance decidableBex : ∀ (l : List α), Decidable (∃ x ∈ l, p x)
  | []    => isFalse (by 

Proof state:
α✝ : Type u
β : Type v
γ : Type w
α : Type u
p : α → Prop
inst✝ : DecidablePred p
⊢ ¬∃ x, x ∈ [] ∧ p x

Next tactic:
simp
instance decidableBex : ∀ (l : List α), Decidable (∃ x ∈ l, p x)
  | []    => isFalse (by simp)
  | x::xs =>
    match ‹DecidablePred p› x with
    | isTrue h₁ => isTrue ⟨x, mem_cons_self _ _, h₁⟩
    | isFalse h₁ => match decidableBex xs with
      | isTrue h₂  => isTrue <| by
        

Proof state:
α✝ : Type u
β : Type v
γ : Type w
α : Type u
p : α → Prop
inst✝ : DecidablePred p
x : α
xs : List α
h₁ : ¬p x
h₂ : ∃ x, x ∈ xs ∧ p x
⊢ ∃ x_1, x_1 ∈ x :: xs ∧ p x_1

Next tactic:
cases' h₂ with y h
instance decidableBex : ∀ (l : List α), Decidable (∃ x ∈ l, p x)
  | []    => isFalse (by simp)
  | x::xs =>
    match ‹DecidablePred p› x with
    | isTrue h₁ => isTrue ⟨x, mem_cons_self _ _, h₁⟩
    | isFalse h₁ => match decidableBex xs with
      | isTrue h₂  => isTrue <| by
        cases' h₂ with y h; 

Proof state:
case intro
α✝ : Type u
β : Type v
γ : Type w
α : Type u
p : α → Prop
inst✝ : DecidablePred p
x : α
xs : List α
h₁ : ¬p x
y : α
h : y ∈ xs ∧ p y
⊢ ∃ x_1, x_1 ∈ x :: xs ∧ p x_1

Next tactic:
cases' h with hm hp
instance decidableBex : ∀ (l : List α), Decidable (∃ x ∈ l, p x)
  | []    => isFalse (by simp)
  | x::xs =>
    match ‹DecidablePred p› x with
    | isTrue h₁ => isTrue ⟨x, mem_cons_self _ _, h₁⟩
    | isFalse h₁ => match decidableBex xs with
      | isTrue h₂  => isTrue <| by
        cases' h₂ with y h; cases' h with hm hp
        

Proof state:
case intro.intro
α✝ : Type u
β : Type v
γ : Type w
α : Type u
p : α → Prop
inst✝ : DecidablePred p
x : α
xs : List α
h₁ : ¬p x
y : α
hm : y ∈ xs
hp : p y
⊢ ∃ x_1, x_1 ∈ x :: xs ∧ p x_1

Next tactic:
exact ⟨y, mem_cons_of_mem _ hm, hp⟩
instance decidableBex : ∀ (l : List α), Decidable (∃ x ∈ l, p x)
  | []    => isFalse (by simp)
  | x::xs =>
    match ‹DecidablePred p› x with
    | isTrue h₁ => isTrue ⟨x, mem_cons_self _ _, h₁⟩
    | isFalse h₁ => match decidableBex xs with
      | isTrue h₂  => isTrue <| by
        cases' h₂ with y h; cases' h with hm hp
        exact ⟨y, mem_cons_of_mem _ hm, hp⟩
      | isFalse h₂ => isFalse <| by
        

Proof state:
α✝ : Type u
β : Type v
γ : Type w
α : Type u
p : α → Prop
inst✝ : DecidablePred p
x : α
xs : List α
h₁ : ¬p x
h₂ : ¬∃ x, x ∈ xs ∧ p x
⊢ ¬∃ x_1, x_1 ∈ x :: xs ∧ p x_1

Next tactic:
intro h
instance decidableBex : ∀ (l : List α), Decidable (∃ x ∈ l, p x)
  | []    => isFalse (by simp)
  | x::xs =>
    match ‹DecidablePred p› x with
    | isTrue h₁ => isTrue ⟨x, mem_cons_self _ _, h₁⟩
    | isFalse h₁ => match decidableBex xs with
      | isTrue h₂  => isTrue <| by
        cases' h₂ with y h; cases' h with hm hp
        exact ⟨y, mem_cons_of_mem _ hm, hp⟩
      | isFalse h₂ => isFalse <| by
        intro h; 

Proof state:
α✝ : Type u
β : Type v
γ : Type w
α : Type u
p : α → Prop
inst✝ : DecidablePred p
x : α
xs : List α
h₁ : ¬p x
h₂ : ¬∃ x, x ∈ xs ∧ p x
h : ∃ x_1, x_1 ∈ x :: xs ∧ p x_1
⊢ False

Next tactic:
cases' h with y h
instance decidableBex : ∀ (l : List α), Decidable (∃ x ∈ l, p x)
  | []    => isFalse (by simp)
  | x::xs =>
    match ‹DecidablePred p› x with
    | isTrue h₁ => isTrue ⟨x, mem_cons_self _ _, h₁⟩
    | isFalse h₁ => match decidableBex xs with
      | isTrue h₂  => isTrue <| by
        cases' h₂ with y h; cases' h with hm hp
        exact ⟨y, mem_cons_of_mem _ hm, hp⟩
      | isFalse h₂ => isFalse <| by
        intro h; cases' h with y h; 

Proof state:
case intro
α✝ : Type u
β : Type v
γ : Type w
α : Type u
p : α → Prop
inst✝ : DecidablePred p
x : α
xs : List α
h₁ : ¬p x
h₂ : ¬∃ x, x ∈ xs ∧ p x
y : α
h : y ∈ x :: xs ∧ p y
⊢ False

Next tactic:
cases' h with hm hp
instance decidableBex : ∀ (l : List α), Decidable (∃ x ∈ l, p x)
  | []    => isFalse (by simp)
  | x::xs =>
    match ‹DecidablePred p› x with
    | isTrue h₁ => isTrue ⟨x, mem_cons_self _ _, h₁⟩
    | isFalse h₁ => match decidableBex xs with
      | isTrue h₂  => isTrue <| by
        cases' h₂ with y h; cases' h with hm hp
        exact ⟨y, mem_cons_of_mem _ hm, hp⟩
      | isFalse h₂ => isFalse <| by
        intro h; cases' h with y h; cases' h with hm hp
        

Proof state:
case intro.intro
α✝ : Type u
β : Type v
γ : Type w
α : Type u
p : α → Prop
inst✝ : DecidablePred p
x : α
xs : List α
h₁ : ¬p x
h₂ : ¬∃ x, x ∈ xs ∧ p x
y : α
hm : y ∈ x :: xs
hp : p y
⊢ False

Next tactic:
cases' mem_cons.1 hm with h h
instance decidableBex : ∀ (l : List α), Decidable (∃ x ∈ l, p x)
  | []    => isFalse (by simp)
  | x::xs =>
    match ‹DecidablePred p› x with
    | isTrue h₁ => isTrue ⟨x, mem_cons_self _ _, h₁⟩
    | isFalse h₁ => match decidableBex xs with
      | isTrue h₂  => isTrue <| by
        cases' h₂ with y h; cases' h with hm hp
        exact ⟨y, mem_cons_of_mem _ hm, hp⟩
      | isFalse h₂ => isFalse <| by
        intro h; cases' h with y h; cases' h with hm hp
        cases' mem_cons.1 hm with h h
        · 

Proof state:
case intro.intro.inl
α✝ : Type u
β : Type v
γ : Type w
α : Type u
p : α → Prop
inst✝ : DecidablePred p
x : α
xs : List α
h₁ : ¬p x
h₂ : ¬∃ x, x ∈ xs ∧ p x
y : α
hm : y ∈ x :: xs
hp : p y
h : y = x
⊢ False

Next tactic:
rw [h] at hp
instance decidableBex : ∀ (l : List α), Decidable (∃ x ∈ l, p x)
  | []    => isFalse (by simp)
  | x::xs =>
    match ‹DecidablePred p› x with
    | isTrue h₁ => isTrue ⟨x, mem_cons_self _ _, h₁⟩
    | isFalse h₁ => match decidableBex xs with
      | isTrue h₂  => isTrue <| by
        cases' h₂ with y h; cases' h with hm hp
        exact ⟨y, mem_cons_of_mem _ hm, hp⟩
      | isFalse h₂ => isFalse <| by
        intro h; cases' h with y h; cases' h with hm hp
        cases' mem_cons.1 hm with h h
        · rw [h] at hp; 

Proof state:
case intro.intro.inl
α✝ : Type u
β : Type v
γ : Type w
α : Type u
p : α → Prop
inst✝ : DecidablePred p
x : α
xs : List α
h₁ : ¬p x
h₂ : ¬∃ x, x ∈ xs ∧ p x
y : α
hm : y ∈ x :: xs
hp : p x
h : y = x
⊢ False

Next tactic:
contradiction
instance decidableBex : ∀ (l : List α), Decidable (∃ x ∈ l, p x)
  | []    => isFalse (by simp)
  | x::xs =>
    match ‹DecidablePred p› x with
    | isTrue h₁ => isTrue ⟨x, mem_cons_self _ _, h₁⟩
    | isFalse h₁ => match decidableBex xs with
      | isTrue h₂  => isTrue <| by
        cases' h₂ with y h; cases' h with hm hp
        exact ⟨y, mem_cons_of_mem _ hm, hp⟩
      | isFalse h₂ => isFalse <| by
        intro h; cases' h with y h; cases' h with hm hp
        cases' mem_cons.1 hm with h h
        · rw [h] at hp; contradiction
        · 

Proof state:
case intro.intro.inr
α✝ : Type u
β : Type v
γ : Type w
α : Type u
p : α → Prop
inst✝ : DecidablePred p
x : α
xs : List α
h₁ : ¬p x
h₂ : ¬∃ x, x ∈ xs ∧ p x
y : α
hm : y ∈ x :: xs
hp : p y
h : y ∈ xs
⊢ False

Next tactic:
exact absurd ⟨y, h, hp⟩ h₂
@[simp]
theorem toTensorAlgebra_gMul {i j} (a : (⨂[R]^i) M) (b : (⨂[R]^j) M) :
    TensorPower.toTensorAlgebra (@GradedMonoid.GMul.mul _ (fun n => (⨂[R]^n) M) _ _ _ _ a b) =
      TensorPower.toTensorAlgebra a * TensorPower.toTensorAlgebra b := by
  -- change `a` and `b` to `tprod R a` and `tprod R b`
  

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a : (⨂[R]^i) M
b : (⨂[R]^j) M
⊢ toTensorAlgebra (GradedMonoid.GMul.mul a b) = toTensorAlgebra a * toTensorAlgebra b

Next tactic:
rw [TensorPower.gMul_eq_coe_linearMap, ← LinearMap.compr₂_apply, ← @LinearMap.mul_apply' R, ←
    LinearMap.compl₂_apply, ← LinearMap.comp_apply]
@[simp]
theorem toTensorAlgebra_gMul {i j} (a : (⨂[R]^i) M) (b : (⨂[R]^j) M) :
    TensorPower.toTensorAlgebra (@GradedMonoid.GMul.mul _ (fun n => (⨂[R]^n) M) _ _ _ _ a b) =
      TensorPower.toTensorAlgebra a * TensorPower.toTensorAlgebra b := by
  -- change `a` and `b` to `tprod R a` and `tprod R b`
  rw [TensorPower.gMul_eq_coe_linearMap, ← LinearMap.compr₂_apply, ← @LinearMap.mul_apply' R, ←
    LinearMap.compl₂_apply, ← LinearMap.comp_apply]
  

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a : (⨂[R]^i) M
b : (⨂[R]^j) M
⊢ ((LinearMap.compr₂ (LinearMap.compr₂ (TensorProduct.mk R ((⨂[R]^i) M) ((⨂[R]^j) M)) ↑mulEquiv) toTensorAlgebra) a) b =
    ((LinearMap.compl₂ (LinearMap.mul R (TensorAlgebra R M)) toTensorAlgebra ∘ₗ toTensorAlgebra) a) b

Next tactic:
refine' LinearMap.congr_fun (LinearMap.congr_fun _ a) b
@[simp]
theorem toTensorAlgebra_gMul {i j} (a : (⨂[R]^i) M) (b : (⨂[R]^j) M) :
    TensorPower.toTensorAlgebra (@GradedMonoid.GMul.mul _ (fun n => (⨂[R]^n) M) _ _ _ _ a b) =
      TensorPower.toTensorAlgebra a * TensorPower.toTensorAlgebra b := by
  -- change `a` and `b` to `tprod R a` and `tprod R b`
  rw [TensorPower.gMul_eq_coe_linearMap, ← LinearMap.compr₂_apply, ← @LinearMap.mul_apply' R, ←
    LinearMap.compl₂_apply, ← LinearMap.comp_apply]
  refine' LinearMap.congr_fun (LinearMap.congr_fun _ a) b
  

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a : (⨂[R]^i) M
b : (⨂[R]^j) M
⊢ LinearMap.compr₂ (LinearMap.compr₂ (TensorProduct.mk R ((⨂[R]^i) M) ((⨂[R]^j) M)) ↑mulEquiv) toTensorAlgebra =
    LinearMap.compl₂ (LinearMap.mul R (TensorAlgebra R M)) toTensorAlgebra ∘ₗ toTensorAlgebra

Next tactic:
clear! a b
@[simp]
theorem toTensorAlgebra_gMul {i j} (a : (⨂[R]^i) M) (b : (⨂[R]^j) M) :
    TensorPower.toTensorAlgebra (@GradedMonoid.GMul.mul _ (fun n => (⨂[R]^n) M) _ _ _ _ a b) =
      TensorPower.toTensorAlgebra a * TensorPower.toTensorAlgebra b := by
  -- change `a` and `b` to `tprod R a` and `tprod R b`
  rw [TensorPower.gMul_eq_coe_linearMap, ← LinearMap.compr₂_apply, ← @LinearMap.mul_apply' R, ←
    LinearMap.compl₂_apply, ← LinearMap.comp_apply]
  refine' LinearMap.congr_fun (LinearMap.congr_fun _ a) b
  clear! a b
  

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
⊢ LinearMap.compr₂ (LinearMap.compr₂ (TensorProduct.mk R ((⨂[R]^i) M) ((⨂[R]^j) M)) ↑mulEquiv) toTensorAlgebra =
    LinearMap.compl₂ (LinearMap.mul R (TensorAlgebra R M)) toTensorAlgebra ∘ₗ toTensorAlgebra

Next tactic:
ext (a b)
@[simp]
theorem toTensorAlgebra_gMul {i j} (a : (⨂[R]^i) M) (b : (⨂[R]^j) M) :
    TensorPower.toTensorAlgebra (@GradedMonoid.GMul.mul _ (fun n => (⨂[R]^n) M) _ _ _ _ a b) =
      TensorPower.toTensorAlgebra a * TensorPower.toTensorAlgebra b := by
  -- change `a` and `b` to `tprod R a` and `tprod R b`
  rw [TensorPower.gMul_eq_coe_linearMap, ← LinearMap.compr₂_apply, ← @LinearMap.mul_apply' R, ←
    LinearMap.compl₂_apply, ← LinearMap.comp_apply]
  refine' LinearMap.congr_fun (LinearMap.congr_fun _ a) b
  clear! a b
  ext (a b)
  -- Porting note: pulled the next two lines out of the long `simp only` below.
  

Proof state:
case H.H.H.H
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a : Fin i → M
b : Fin j → M
⊢ (LinearMap.compMultilinearMap
        ((LinearMap.compMultilinearMap
            (LinearMap.compr₂ (LinearMap.compr₂ (TensorProduct.mk R ((⨂[R]^i) M) ((⨂[R]^j) M)) ↑mulEquiv)
              toTensorAlgebra)
            (PiTensorProduct.tprod R))
          a)
        (PiTensorProduct.tprod R))
      b =
    (LinearMap.compMultilinearMap
        ((LinearMap.compMultilinearMap
            (LinearMap.compl₂ (LinearMap.mul R (TensorAlgebra R M)) toTensorAlgebra ∘ₗ toTensorAlgebra)
            (PiTensorProduct.tprod R))
          a)
        (PiTensorProduct.tprod R))
      b

Next tactic:
simp only [LinearMap.compMultilinearMap_apply]
@[simp]
theorem toTensorAlgebra_gMul {i j} (a : (⨂[R]^i) M) (b : (⨂[R]^j) M) :
    TensorPower.toTensorAlgebra (@GradedMonoid.GMul.mul _ (fun n => (⨂[R]^n) M) _ _ _ _ a b) =
      TensorPower.toTensorAlgebra a * TensorPower.toTensorAlgebra b := by
  -- change `a` and `b` to `tprod R a` and `tprod R b`
  rw [TensorPower.gMul_eq_coe_linearMap, ← LinearMap.compr₂_apply, ← @LinearMap.mul_apply' R, ←
    LinearMap.compl₂_apply, ← LinearMap.comp_apply]
  refine' LinearMap.congr_fun (LinearMap.congr_fun _ a) b
  clear! a b
  ext (a b)
  -- Porting note: pulled the next two lines out of the long `simp only` below.
  simp only [LinearMap.compMultilinearMap_apply]
  

Proof state:
case H.H.H.H
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a : Fin i → M
b : Fin j → M
⊢ ((LinearMap.compr₂ (LinearMap.compr₂ (TensorProduct.mk R ((⨂[R]^i) M) ((⨂[R]^j) M)) ↑mulEquiv) toTensorAlgebra)
        ((PiTensorProduct.tprod R) a))
      ((PiTensorProduct.tprod R) b) =
    ((LinearMap.compl₂ (LinearMap.mul R (TensorAlgebra R M)) toTensorAlgebra ∘ₗ toTensorAlgebra)
        ((PiTensorProduct.tprod R) a))
      ((PiTensorProduct.tprod R) b)

Next tactic:
rw [LinearMap.compr₂_apply, ← gMul_eq_coe_linearMap]
@[simp]
theorem toTensorAlgebra_gMul {i j} (a : (⨂[R]^i) M) (b : (⨂[R]^j) M) :
    TensorPower.toTensorAlgebra (@GradedMonoid.GMul.mul _ (fun n => (⨂[R]^n) M) _ _ _ _ a b) =
      TensorPower.toTensorAlgebra a * TensorPower.toTensorAlgebra b := by
  -- change `a` and `b` to `tprod R a` and `tprod R b`
  rw [TensorPower.gMul_eq_coe_linearMap, ← LinearMap.compr₂_apply, ← @LinearMap.mul_apply' R, ←
    LinearMap.compl₂_apply, ← LinearMap.comp_apply]
  refine' LinearMap.congr_fun (LinearMap.congr_fun _ a) b
  clear! a b
  ext (a b)
  -- Porting note: pulled the next two lines out of the long `simp only` below.
  simp only [LinearMap.compMultilinearMap_apply]
  rw [LinearMap.compr₂_apply, ← gMul_eq_coe_linearMap]
  

Proof state:
case H.H.H.H
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a : Fin i → M
b : Fin j → M
⊢ toTensorAlgebra (GradedMonoid.GMul.mul ((PiTensorProduct.tprod R) a) ((PiTensorProduct.tprod R) b)) =
    ((LinearMap.compl₂ (LinearMap.mul R (TensorAlgebra R M)) toTensorAlgebra ∘ₗ toTensorAlgebra)
        ((PiTensorProduct.tprod R) a))
      ((PiTensorProduct.tprod R) b)

Next tactic:
simp only [LinearMap.compr₂_apply, LinearMap.mul_apply', LinearMap.compl₂_apply,
    LinearMap.comp_apply, LinearMap.compMultilinearMap_apply, PiTensorProduct.lift.tprod,
    TensorPower.tprod_mul_tprod, TensorPower.toTensorAlgebra_tprod, TensorAlgebra.tprod_apply, ←
    gMul_eq_coe_linearMap]
@[simp]
theorem toTensorAlgebra_gMul {i j} (a : (⨂[R]^i) M) (b : (⨂[R]^j) M) :
    TensorPower.toTensorAlgebra (@GradedMonoid.GMul.mul _ (fun n => (⨂[R]^n) M) _ _ _ _ a b) =
      TensorPower.toTensorAlgebra a * TensorPower.toTensorAlgebra b := by
  -- change `a` and `b` to `tprod R a` and `tprod R b`
  rw [TensorPower.gMul_eq_coe_linearMap, ← LinearMap.compr₂_apply, ← @LinearMap.mul_apply' R, ←
    LinearMap.compl₂_apply, ← LinearMap.comp_apply]
  refine' LinearMap.congr_fun (LinearMap.congr_fun _ a) b
  clear! a b
  ext (a b)
  -- Porting note: pulled the next two lines out of the long `simp only` below.
  simp only [LinearMap.compMultilinearMap_apply]
  rw [LinearMap.compr₂_apply, ← gMul_eq_coe_linearMap]
  simp only [LinearMap.compr₂_apply, LinearMap.mul_apply', LinearMap.compl₂_apply,
    LinearMap.comp_apply, LinearMap.compMultilinearMap_apply, PiTensorProduct.lift.tprod,
    TensorPower.tprod_mul_tprod, TensorPower.toTensorAlgebra_tprod, TensorAlgebra.tprod_apply, ←
    gMul_eq_coe_linearMap]
  

Proof state:
case H.H.H.H
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a : Fin i → M
b : Fin j → M
⊢ List.prod (List.ofFn fun i_1 => (TensorAlgebra.ι R) (Fin.append a b i_1)) =
    List.prod (List.ofFn fun i => (TensorAlgebra.ι R) (a i)) * List.prod (List.ofFn fun i => (TensorAlgebra.ι R) (b i))

Next tactic:
refine' Eq.trans _ List.prod_append
@[simp]
theorem toTensorAlgebra_gMul {i j} (a : (⨂[R]^i) M) (b : (⨂[R]^j) M) :
    TensorPower.toTensorAlgebra (@GradedMonoid.GMul.mul _ (fun n => (⨂[R]^n) M) _ _ _ _ a b) =
      TensorPower.toTensorAlgebra a * TensorPower.toTensorAlgebra b := by
  -- change `a` and `b` to `tprod R a` and `tprod R b`
  rw [TensorPower.gMul_eq_coe_linearMap, ← LinearMap.compr₂_apply, ← @LinearMap.mul_apply' R, ←
    LinearMap.compl₂_apply, ← LinearMap.comp_apply]
  refine' LinearMap.congr_fun (LinearMap.congr_fun _ a) b
  clear! a b
  ext (a b)
  -- Porting note: pulled the next two lines out of the long `simp only` below.
  simp only [LinearMap.compMultilinearMap_apply]
  rw [LinearMap.compr₂_apply, ← gMul_eq_coe_linearMap]
  simp only [LinearMap.compr₂_apply, LinearMap.mul_apply', LinearMap.compl₂_apply,
    LinearMap.comp_apply, LinearMap.compMultilinearMap_apply, PiTensorProduct.lift.tprod,
    TensorPower.tprod_mul_tprod, TensorPower.toTensorAlgebra_tprod, TensorAlgebra.tprod_apply, ←
    gMul_eq_coe_linearMap]
  refine' Eq.trans _ List.prod_append
  -- Porting note: was `congr`
  

Proof state:
case H.H.H.H
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a : Fin i → M
b : Fin j → M
⊢ List.prod (List.ofFn fun i_1 => (TensorAlgebra.ι R) (Fin.append a b i_1)) =
    List.prod ((List.ofFn fun i => (TensorAlgebra.ι R) (a i)) ++ List.ofFn fun i => (TensorAlgebra.ι R) (b i))

Next tactic:
apply congr_arg
@[simp]
theorem toTensorAlgebra_gMul {i j} (a : (⨂[R]^i) M) (b : (⨂[R]^j) M) :
    TensorPower.toTensorAlgebra (@GradedMonoid.GMul.mul _ (fun n => (⨂[R]^n) M) _ _ _ _ a b) =
      TensorPower.toTensorAlgebra a * TensorPower.toTensorAlgebra b := by
  -- change `a` and `b` to `tprod R a` and `tprod R b`
  rw [TensorPower.gMul_eq_coe_linearMap, ← LinearMap.compr₂_apply, ← @LinearMap.mul_apply' R, ←
    LinearMap.compl₂_apply, ← LinearMap.comp_apply]
  refine' LinearMap.congr_fun (LinearMap.congr_fun _ a) b
  clear! a b
  ext (a b)
  -- Porting note: pulled the next two lines out of the long `simp only` below.
  simp only [LinearMap.compMultilinearMap_apply]
  rw [LinearMap.compr₂_apply, ← gMul_eq_coe_linearMap]
  simp only [LinearMap.compr₂_apply, LinearMap.mul_apply', LinearMap.compl₂_apply,
    LinearMap.comp_apply, LinearMap.compMultilinearMap_apply, PiTensorProduct.lift.tprod,
    TensorPower.tprod_mul_tprod, TensorPower.toTensorAlgebra_tprod, TensorAlgebra.tprod_apply, ←
    gMul_eq_coe_linearMap]
  refine' Eq.trans _ List.prod_append
  -- Porting note: was `congr`
  apply congr_arg
  -- Porting note: `erw` for `Function.comp`
  

Proof state:
case H.H.H.H.h
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
i j : ℕ
a : Fin i → M
b : Fin j → M
⊢ (List.ofFn fun i_1 => (TensorAlgebra.ι R) (Fin.append a b i_1)) =
    (List.ofFn fun i => (TensorAlgebra.ι R) (a i)) ++ List.ofFn fun i => (TensorAlgebra.ι R) (b i)

Next tactic:
erw [← List.map_ofFn _ (TensorAlgebra.ι R), ← List.map_ofFn _ (TensorAlgebra.ι R), ←
    List.map_ofFn _ (TensorAlgebra.ι R), ← List.map_append, List.ofFn_fin_append]
@[simp]
theorem toTensorAlgebra_galgebra_toFun (r : R) :
    TensorPower.toTensorAlgebra (DirectSum.GAlgebra.toFun (R := R) (A := fun n => (⨂[R]^n) M) r) =
      algebraMap _ _ r := by
  

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommSemiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r : R
⊢ toTensorAlgebra (DirectSum.GAlgebra.toFun r) = (algebraMap R (TensorAlgebra R M)) r

Next tactic:
rw [TensorPower.galgebra_toFun_def, TensorPower.algebraMap₀_eq_smul_one, LinearMap.map_smul,
    TensorPower.toTensorAlgebra_gOne, Algebra.algebraMap_eq_smul_one]