l3lab/ntp-mathlib huggingface dataset:
/--
Given a family of cones over the `F ⋙ Pi.eval C i`, we can assemble these together as a `Cone F`.
-/
def coneOfConeCompEval (c : ∀ i, Cone (F ⋙ Pi.eval C i)) : Cone F where
  pt i := (c i).pt
  π :=
    { app := fun j i => (c i).π.app j
      naturality := fun j j' f => by
        

Proof state:
I : Type v₁
C : I → Type u₁
inst✝¹ : (i : I) → Category.{v₁, u₁} (C i)
J : Type v₁
inst✝ : SmallCategory J
F : J ⥤ ((i : I) → C i)
c : (i : I) → Cone (F ⋙ Pi.eval C i)
j j' : J
f : j ⟶ j'
⊢ ((Functor.const J).obj fun i => (c i).pt).map f ≫ (fun j i => (c i).π.app j) j' =
    (fun j i => (c i).π.app j) j ≫ F.map f

Next tactic:
funext i
/--
Given a family of cones over the `F ⋙ Pi.eval C i`, we can assemble these together as a `Cone F`.
-/
def coneOfConeCompEval (c : ∀ i, Cone (F ⋙ Pi.eval C i)) : Cone F where
  pt i := (c i).pt
  π :=
    { app := fun j i => (c i).π.app j
      naturality := fun j j' f => by
        funext i
        

Proof state:
case h
I : Type v₁
C : I → Type u₁
inst✝¹ : (i : I) → Category.{v₁, u₁} (C i)
J : Type v₁
inst✝ : SmallCategory J
F : J ⥤ ((i : I) → C i)
c : (i : I) → Cone (F ⋙ Pi.eval C i)
j j' : J
f : j ⟶ j'
i : I
⊢ (((Functor.const J).obj fun i => (c i).pt).map f ≫ (fun j i => (c i).π.app j) j') i =
    ((fun j i => (c i).π.app j) j ≫ F.map f) i

Next tactic:
exact (c i).π.naturality f
/-- Given a family of cocones over the `F ⋙ Pi.eval C i`,
we can assemble these together as a `Cocone F`.
-/
def coconeOfCoconeCompEval (c : ∀ i, Cocone (F ⋙ Pi.eval C i)) : Cocone F where
  pt i := (c i).pt
  ι :=
    { app := fun j i => (c i).ι.app j
      naturality := fun j j' f => by
        

Proof state:
I : Type v₁
C : I → Type u₁
inst✝¹ : (i : I) → Category.{v₁, u₁} (C i)
J : Type v₁
inst✝ : SmallCategory J
F : J ⥤ ((i : I) → C i)
c : (i : I) → Cocone (F ⋙ Pi.eval C i)
j j' : J
f : j ⟶ j'
⊢ F.map f ≫ (fun j i => (c i).ι.app j) j' =
    (fun j i => (c i).ι.app j) j ≫ ((Functor.const J).obj fun i => (c i).pt).map f

Next tactic:
funext i
/-- Given a family of cocones over the `F ⋙ Pi.eval C i`,
we can assemble these together as a `Cocone F`.
-/
def coconeOfCoconeCompEval (c : ∀ i, Cocone (F ⋙ Pi.eval C i)) : Cocone F where
  pt i := (c i).pt
  ι :=
    { app := fun j i => (c i).ι.app j
      naturality := fun j j' f => by
        funext i
        

Proof state:
case h
I : Type v₁
C : I → Type u₁
inst✝¹ : (i : I) → Category.{v₁, u₁} (C i)
J : Type v₁
inst✝ : SmallCategory J
F : J ⥤ ((i : I) → C i)
c : (i : I) → Cocone (F ⋙ Pi.eval C i)
j j' : J
f : j ⟶ j'
i : I
⊢ (F.map f ≫ (fun j i => (c i).ι.app j) j') i =
    ((fun j i => (c i).ι.app j) j ≫ ((Functor.const J).obj fun i => (c i).pt).map f) i

Next tactic:
exact (c i).ι.naturality f
/-- Given a family of limit cones over the `F ⋙ Pi.eval C i`,
assembling them together as a `Cone F` produces a limit cone.
-/
def coneOfConeEvalIsLimit {c : ∀ i, Cone (F ⋙ Pi.eval C i)} (P : ∀ i, IsLimit (c i)) :
    IsLimit (coneOfConeCompEval c) where
  lift s i := (P i).lift (coneCompEval s i)
  fac s j := by
    

Proof state:
I : Type v₁
C : I → Type u₁
inst✝¹ : (i : I) → Category.{v₁, u₁} (C i)
J : Type v₁
inst✝ : SmallCategory J
F : J ⥤ ((i : I) → C i)
c : (i : I) → Cone (F ⋙ Pi.eval C i)
P : (i : I) → IsLimit (c i)
s : Cone F
j : J
⊢ (fun s i => IsLimit.lift (P i) (coneCompEval s i)) s ≫ (coneOfConeCompEval c).π.app j = s.π.app j

Next tactic:
funext i
/-- Given a family of limit cones over the `F ⋙ Pi.eval C i`,
assembling them together as a `Cone F` produces a limit cone.
-/
def coneOfConeEvalIsLimit {c : ∀ i, Cone (F ⋙ Pi.eval C i)} (P : ∀ i, IsLimit (c i)) :
    IsLimit (coneOfConeCompEval c) where
  lift s i := (P i).lift (coneCompEval s i)
  fac s j := by
    funext i
    

Proof state:
case h
I : Type v₁
C : I → Type u₁
inst✝¹ : (i : I) → Category.{v₁, u₁} (C i)
J : Type v₁
inst✝ : SmallCategory J
F : J ⥤ ((i : I) → C i)
c : (i : I) → Cone (F ⋙ Pi.eval C i)
P : (i : I) → IsLimit (c i)
s : Cone F
j : J
i : I
⊢ ((fun s i => IsLimit.lift (P i) (coneCompEval s i)) s ≫ (coneOfConeCompEval c).π.app j) i = s.π.app j i

Next tactic:
exact (P i).fac (coneCompEval s i) j
/-- Given a family of limit cones over the `F ⋙ Pi.eval C i`,
assembling them together as a `Cone F` produces a limit cone.
-/
def coneOfConeEvalIsLimit {c : ∀ i, Cone (F ⋙ Pi.eval C i)} (P : ∀ i, IsLimit (c i)) :
    IsLimit (coneOfConeCompEval c) where
  lift s i := (P i).lift (coneCompEval s i)
  fac s j := by
    funext i
    exact (P i).fac (coneCompEval s i) j
  uniq s m w := by
    

Proof state:
I : Type v₁
C : I → Type u₁
inst✝¹ : (i : I) → Category.{v₁, u₁} (C i)
J : Type v₁
inst✝ : SmallCategory J
F : J ⥤ ((i : I) → C i)
c : (i : I) → Cone (F ⋙ Pi.eval C i)
P : (i : I) → IsLimit (c i)
s : Cone F
m : s.pt ⟶ (coneOfConeCompEval c).pt
w : ∀ (j : J), m ≫ (coneOfConeCompEval c).π.app j = s.π.app j
⊢ m = (fun s i => IsLimit.lift (P i) (coneCompEval s i)) s

Next tactic:
funext i
/-- Given a family of limit cones over the `F ⋙ Pi.eval C i`,
assembling them together as a `Cone F` produces a limit cone.
-/
def coneOfConeEvalIsLimit {c : ∀ i, Cone (F ⋙ Pi.eval C i)} (P : ∀ i, IsLimit (c i)) :
    IsLimit (coneOfConeCompEval c) where
  lift s i := (P i).lift (coneCompEval s i)
  fac s j := by
    funext i
    exact (P i).fac (coneCompEval s i) j
  uniq s m w := by
    funext i
    

Proof state:
case h
I : Type v₁
C : I → Type u₁
inst✝¹ : (i : I) → Category.{v₁, u₁} (C i)
J : Type v₁
inst✝ : SmallCategory J
F : J ⥤ ((i : I) → C i)
c : (i : I) → Cone (F ⋙ Pi.eval C i)
P : (i : I) → IsLimit (c i)
s : Cone F
m : s.pt ⟶ (coneOfConeCompEval c).pt
w : ∀ (j : J), m ≫ (coneOfConeCompEval c).π.app j = s.π.app j
i : I
⊢ m i = (fun s i => IsLimit.lift (P i) (coneCompEval s i)) s i

Next tactic:
exact (P i).uniq (coneCompEval s i) (m i) fun j => congr_fun (w j) i
/-- Given a family of colimit cocones over the `F ⋙ Pi.eval C i`,
assembling them together as a `Cocone F` produces a colimit cocone.
-/
def coconeOfCoconeEvalIsColimit {c : ∀ i, Cocone (F ⋙ Pi.eval C i)} (P : ∀ i, IsColimit (c i)) :
    IsColimit (coconeOfCoconeCompEval c) where
  desc s i := (P i).desc (coconeCompEval s i)
  fac s j := by
    

Proof state:
I : Type v₁
C : I → Type u₁
inst✝¹ : (i : I) → Category.{v₁, u₁} (C i)
J : Type v₁
inst✝ : SmallCategory J
F : J ⥤ ((i : I) → C i)
c : (i : I) → Cocone (F ⋙ Pi.eval C i)
P : (i : I) → IsColimit (c i)
s : Cocone F
j : J
⊢ (coconeOfCoconeCompEval c).ι.app j ≫ (fun s i => IsColimit.desc (P i) (coconeCompEval s i)) s = s.ι.app j

Next tactic:
funext i
/-- Given a family of colimit cocones over the `F ⋙ Pi.eval C i`,
assembling them together as a `Cocone F` produces a colimit cocone.
-/
def coconeOfCoconeEvalIsColimit {c : ∀ i, Cocone (F ⋙ Pi.eval C i)} (P : ∀ i, IsColimit (c i)) :
    IsColimit (coconeOfCoconeCompEval c) where
  desc s i := (P i).desc (coconeCompEval s i)
  fac s j := by
    funext i
    

Proof state:
case h
I : Type v₁
C : I → Type u₁
inst✝¹ : (i : I) → Category.{v₁, u₁} (C i)
J : Type v₁
inst✝ : SmallCategory J
F : J ⥤ ((i : I) → C i)
c : (i : I) → Cocone (F ⋙ Pi.eval C i)
P : (i : I) → IsColimit (c i)
s : Cocone F
j : J
i : I
⊢ ((coconeOfCoconeCompEval c).ι.app j ≫ (fun s i => IsColimit.desc (P i) (coconeCompEval s i)) s) i = s.ι.app j i

Next tactic:
exact (P i).fac (coconeCompEval s i) j
/-- Given a family of colimit cocones over the `F ⋙ Pi.eval C i`,
assembling them together as a `Cocone F` produces a colimit cocone.
-/
def coconeOfCoconeEvalIsColimit {c : ∀ i, Cocone (F ⋙ Pi.eval C i)} (P : ∀ i, IsColimit (c i)) :
    IsColimit (coconeOfCoconeCompEval c) where
  desc s i := (P i).desc (coconeCompEval s i)
  fac s j := by
    funext i
    exact (P i).fac (coconeCompEval s i) j
  uniq s m w := by
    

Proof state:
I : Type v₁
C : I → Type u₁
inst✝¹ : (i : I) → Category.{v₁, u₁} (C i)
J : Type v₁
inst✝ : SmallCategory J
F : J ⥤ ((i : I) → C i)
c : (i : I) → Cocone (F ⋙ Pi.eval C i)
P : (i : I) → IsColimit (c i)
s : Cocone F
m : (coconeOfCoconeCompEval c).pt ⟶ s.pt
w : ∀ (j : J), (coconeOfCoconeCompEval c).ι.app j ≫ m = s.ι.app j
⊢ m = (fun s i => IsColimit.desc (P i) (coconeCompEval s i)) s

Next tactic:
funext i
/-- Given a family of colimit cocones over the `F ⋙ Pi.eval C i`,
assembling them together as a `Cocone F` produces a colimit cocone.
-/
def coconeOfCoconeEvalIsColimit {c : ∀ i, Cocone (F ⋙ Pi.eval C i)} (P : ∀ i, IsColimit (c i)) :
    IsColimit (coconeOfCoconeCompEval c) where
  desc s i := (P i).desc (coconeCompEval s i)
  fac s j := by
    funext i
    exact (P i).fac (coconeCompEval s i) j
  uniq s m w := by
    funext i
    

Proof state:
case h
I : Type v₁
C : I → Type u₁
inst✝¹ : (i : I) → Category.{v₁, u₁} (C i)
J : Type v₁
inst✝ : SmallCategory J
F : J ⥤ ((i : I) → C i)
c : (i : I) → Cocone (F ⋙ Pi.eval C i)
P : (i : I) → IsColimit (c i)
s : Cocone F
m : (coconeOfCoconeCompEval c).pt ⟶ s.pt
w : ∀ (j : J), (coconeOfCoconeCompEval c).ι.app j ≫ m = s.ι.app j
i : I
⊢ m i = (fun s i => IsColimit.desc (P i) (coconeCompEval s i)) s i

Next tactic:
exact (P i).uniq (coconeCompEval s i) (m i) fun j => congr_fun (w j) i
/-- The canonical linear map `M →ₗ[R] TensorAlgebra R M`.
-/
irreducible_def ι : M →ₗ[R] TensorAlgebra R M :=
  { toFun := fun m => RingQuot.mkAlgHom R _ (FreeAlgebra.ι R m)
    map_add' := fun x y => by
      

Proof state:
R : Type u_1
inst✝² : CommSemiring R
M : Type u_2
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x y : M
⊢ (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) (x + y) =
    (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) x +
      (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) y

Next tactic:
rw [← (RingQuot.mkAlgHom R (Rel R M)).map_add]
/-- The canonical linear map `M →ₗ[R] TensorAlgebra R M`.
-/
irreducible_def ι : M →ₗ[R] TensorAlgebra R M :=
  { toFun := fun m => RingQuot.mkAlgHom R _ (FreeAlgebra.ι R m)
    map_add' := fun x y => by
      rw [← (RingQuot.mkAlgHom R (Rel R M)).map_add]
      

Proof state:
R : Type u_1
inst✝² : CommSemiring R
M : Type u_2
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
x y : M
⊢ (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) (x + y) =
    (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R x + FreeAlgebra.ι R y)

Next tactic:
exact RingQuot.mkAlgHom_rel R Rel.add
/-- The canonical linear map `M →ₗ[R] TensorAlgebra R M`.
-/
irreducible_def ι : M →ₗ[R] TensorAlgebra R M :=
  { toFun := fun m => RingQuot.mkAlgHom R _ (FreeAlgebra.ι R m)
    map_add' := fun x y => by
      rw [← (RingQuot.mkAlgHom R (Rel R M)).map_add]
      exact RingQuot.mkAlgHom_rel R Rel.add
    map_smul' := fun r x => by
      

Proof state:
R : Type u_1
inst✝² : CommSemiring R
M : Type u_2
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r : R
x : M
⊢ AddHom.toFun
      { toFun := fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m),
        map_add' :=
          (_ :
            ∀ (x y : M),
              (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) (x + y) =
                (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) x +
                  (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) y) }
      (r • x) =
    (RingHom.id R) r •
      AddHom.toFun
        { toFun := fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m),
          map_add' :=
            (_ :
              ∀ (x y : M),
                (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) (x + y) =
                  (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) x +
                    (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) y) }
        x

Next tactic:
rw [← (RingQuot.mkAlgHom R (Rel R M)).map_smul]
/-- The canonical linear map `M →ₗ[R] TensorAlgebra R M`.
-/
irreducible_def ι : M →ₗ[R] TensorAlgebra R M :=
  { toFun := fun m => RingQuot.mkAlgHom R _ (FreeAlgebra.ι R m)
    map_add' := fun x y => by
      rw [← (RingQuot.mkAlgHom R (Rel R M)).map_add]
      exact RingQuot.mkAlgHom_rel R Rel.add
    map_smul' := fun r x => by
      rw [← (RingQuot.mkAlgHom R (Rel R M)).map_smul]
      

Proof state:
R : Type u_1
inst✝² : CommSemiring R
M : Type u_2
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r : R
x : M
⊢ AddHom.toFun
      { toFun := fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m),
        map_add' :=
          (_ :
            ∀ (x y : M),
              (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) (x + y) =
                (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) x +
                  (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) y) }
      (r • x) =
    (RingQuot.mkAlgHom R (Rel R M)) ((RingHom.id R) r • FreeAlgebra.ι R x)

Next tactic:
exact RingQuot.mkAlgHom_rel R Rel.smul
theorem ringQuot_mkAlgHom_freeAlgebra_ι_eq_ι (m : M) :
    RingQuot.mkAlgHom R (Rel R M) (FreeAlgebra.ι R m) = ι R m := by
  

Proof state:
R : Type u_1
inst✝² : CommSemiring R
M : Type u_2
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
m : M
⊢ (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m) = (ι R) m

Next tactic:
rw [ι]
theorem ringQuot_mkAlgHom_freeAlgebra_ι_eq_ι (m : M) :
    RingQuot.mkAlgHom R (Rel R M) (FreeAlgebra.ι R m) = ι R m := by
  rw [ι]
  

Proof state:
R : Type u_1
inst✝² : CommSemiring R
M : Type u_2
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
m : M
⊢ (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m) =
    {
        toAddHom :=
          { toFun := fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m),
            map_add' :=
              (_ :
                ∀ (x y : M),
                  (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) (x + y) =
                    (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) x +
                      (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) y) },
        map_smul' :=
          (_ :
            ∀ (r : R) (x : M),
              AddHom.toFun
                  { toFun := fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m),
                    map_add' :=
                      (_ :
                        ∀ (x y : M),
                          (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) (x + y) =
                            (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) x +
                              (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) y) }
                  (r • x) =
                (RingHom.id R) r •
                  AddHom.toFun
                    { toFun := fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m),
                      map_add' :=
                        (_ :
                          ∀ (x y : M),
                            (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) (x + y) =
                              (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) x +
                                (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) y) }
                    x) }
      m

Next tactic:
rfl
/-- Given a linear map `f : M → A` where `A` is an `R`-algebra, `lift R f` is the unique lift
of `f` to a morphism of `R`-algebras `TensorAlgebra R M → A`.
-/
@[simps symm_apply]
def lift {A : Type*} [Semiring A] [Algebra R A] : (M →ₗ[R] A) ≃ (TensorAlgebra R M →ₐ[R] A) :=
  { toFun :=
      RingQuot.liftAlgHom R ∘ fun f =>
        ⟨FreeAlgebra.lift R (⇑f), fun x y (h : Rel R M x y) => by
          

Proof state:
R : Type u_1
inst✝⁴ : CommSemiring R
M : Type u_2
inst✝³ : AddCommMonoid M
inst✝² : Module R M
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
f : M →ₗ[R] A
x y : FreeAlgebra R M
h : Rel R M x y
⊢ ((FreeAlgebra.lift R) ⇑f) x = ((FreeAlgebra.lift R) ⇑f) y

Next tactic:
induction h
/-- Given a linear map `f : M → A` where `A` is an `R`-algebra, `lift R f` is the unique lift
of `f` to a morphism of `R`-algebras `TensorAlgebra R M → A`.
-/
@[simps symm_apply]
def lift {A : Type*} [Semiring A] [Algebra R A] : (M →ₗ[R] A) ≃ (TensorAlgebra R M →ₐ[R] A) :=
  { toFun :=
      RingQuot.liftAlgHom R ∘ fun f =>
        ⟨FreeAlgebra.lift R (⇑f), fun x y (h : Rel R M x y) => by
          induction h <;>
            

Proof state:
case add
R : Type u_1
inst✝⁴ : CommSemiring R
M : Type u_2
inst✝³ : AddCommMonoid M
inst✝² : Module R M
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
f : M →ₗ[R] A
x y : FreeAlgebra R M
a✝ b✝ : M
⊢ ((FreeAlgebra.lift R) ⇑f) (FreeAlgebra.ι R (a✝ + b✝)) =
    ((FreeAlgebra.lift R) ⇑f) (FreeAlgebra.ι R a✝ + FreeAlgebra.ι R b✝)

Next tactic:
simp only [Algebra.smul_def, FreeAlgebra.lift_ι_apply, LinearMap.map_smulₛₗ,
              RingHom.id_apply, map_mul, AlgHom.commutes, map_add]
/-- Given a linear map `f : M → A` where `A` is an `R`-algebra, `lift R f` is the unique lift
of `f` to a morphism of `R`-algebras `TensorAlgebra R M → A`.
-/
@[simps symm_apply]
def lift {A : Type*} [Semiring A] [Algebra R A] : (M →ₗ[R] A) ≃ (TensorAlgebra R M →ₐ[R] A) :=
  { toFun :=
      RingQuot.liftAlgHom R ∘ fun f =>
        ⟨FreeAlgebra.lift R (⇑f), fun x y (h : Rel R M x y) => by
          induction h <;>
            

Proof state:
case smul
R : Type u_1
inst✝⁴ : CommSemiring R
M : Type u_2
inst✝³ : AddCommMonoid M
inst✝² : Module R M
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
f : M →ₗ[R] A
x y : FreeAlgebra R M
r✝ : R
a✝ : M
⊢ ((FreeAlgebra.lift R) ⇑f) (FreeAlgebra.ι R (r✝ • a✝)) =
    ((FreeAlgebra.lift R) ⇑f) ((algebraMap R (FreeAlgebra R M)) r✝ * FreeAlgebra.ι R a✝)

Next tactic:
simp only [Algebra.smul_def, FreeAlgebra.lift_ι_apply, LinearMap.map_smulₛₗ,
              RingHom.id_apply, map_mul, AlgHom.commutes, map_add]
/-- Given a linear map `f : M → A` where `A` is an `R`-algebra, `lift R f` is the unique lift
of `f` to a morphism of `R`-algebras `TensorAlgebra R M → A`.
-/
@[simps symm_apply]
def lift {A : Type*} [Semiring A] [Algebra R A] : (M →ₗ[R] A) ≃ (TensorAlgebra R M →ₐ[R] A) :=
  { toFun :=
      RingQuot.liftAlgHom R ∘ fun f =>
        ⟨FreeAlgebra.lift R (⇑f), fun x y (h : Rel R M x y) => by
          induction h <;>
            simp only [Algebra.smul_def, FreeAlgebra.lift_ι_apply, LinearMap.map_smulₛₗ,
              RingHom.id_apply, map_mul, AlgHom.commutes, map_add]⟩
    invFun := fun F => F.toLinearMap.comp (ι R)
    left_inv := fun f => by
      

Proof state:
R : Type u_1
inst✝⁴ : CommSemiring R
M : Type u_2
inst✝³ : AddCommMonoid M
inst✝² : Module R M
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
f : M →ₗ[R] A
⊢ (fun F => AlgHom.toLinearMap F ∘ₗ ι R)
      ((⇑(RingQuot.liftAlgHom R) ∘ fun f =>
          { val := (FreeAlgebra.lift R) ⇑f,
            property :=
              (_ :
                ∀ (x y : FreeAlgebra R M), Rel R M x y → ((FreeAlgebra.lift R) ⇑f) x = ((FreeAlgebra.lift R) ⇑f) y) })
        f) =
    f

Next tactic:
rw [ι]
/-- Given a linear map `f : M → A` where `A` is an `R`-algebra, `lift R f` is the unique lift
of `f` to a morphism of `R`-algebras `TensorAlgebra R M → A`.
-/
@[simps symm_apply]
def lift {A : Type*} [Semiring A] [Algebra R A] : (M →ₗ[R] A) ≃ (TensorAlgebra R M →ₐ[R] A) :=
  { toFun :=
      RingQuot.liftAlgHom R ∘ fun f =>
        ⟨FreeAlgebra.lift R (⇑f), fun x y (h : Rel R M x y) => by
          induction h <;>
            simp only [Algebra.smul_def, FreeAlgebra.lift_ι_apply, LinearMap.map_smulₛₗ,
              RingHom.id_apply, map_mul, AlgHom.commutes, map_add]⟩
    invFun := fun F => F.toLinearMap.comp (ι R)
    left_inv := fun f => by
      rw [ι]
      

Proof state:
R : Type u_1
inst✝⁴ : CommSemiring R
M : Type u_2
inst✝³ : AddCommMonoid M
inst✝² : Module R M
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
f : M →ₗ[R] A
⊢ (fun F =>
        AlgHom.toLinearMap F ∘ₗ
          {
            toAddHom :=
              { toFun := fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m),
                map_add' :=
                  (_ :
                    ∀ (x y : M),
                      (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) (x + y) =
                        (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) x +
                          (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) y) },
            map_smul' :=
              (_ :
                ∀ (r : R) (x : M),
                  AddHom.toFun
                      { toFun := fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m),
                        map_add' :=
                          (_ :
                            ∀ (x y : M),
                              (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) (x + y) =
                                (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) x +
                                  (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) y) }
                      (r • x) =
                    (RingHom.id R) r •
                      AddHom.toFun
                        { toFun := fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m),
                          map_add' :=
                            (_ :
                              ∀ (x y : M),
                                (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) (x + y) =
                                  (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) x +
                                    (fun m => (RingQuot.mkAlgHom R (Rel R M)) (FreeAlgebra.ι R m)) y) }
                        x) })
      ((⇑(RingQuot.liftAlgHom R) ∘ fun f =>
          { val := (FreeAlgebra.lift R) ⇑f,
            property :=
              (_ :
                ∀ (x y : FreeAlgebra R M), Rel R M x y → ((FreeAlgebra.lift R) ⇑f) x = ((FreeAlgebra.lift R) ⇑f) y) })
        f) =
    f

Next tactic:
ext1 x