l3lab/ntp-mathlib huggingface dataset:
/-- 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 [ι]
      ext1 x
      

Proof state:
case h
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 : M
⊢ ((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))
      x =
    f x

Next tactic:
exact (RingQuot.liftAlgHom_mkAlgHom_apply _ _ _ _).trans (FreeAlgebra.lift_ι_apply f x)
/-- 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 [ι]
      ext1 x
      exact (RingQuot.liftAlgHom_mkAlgHom_apply _ _ _ _).trans (FreeAlgebra.lift_ι_apply f x)
    right_inv := fun F =>
      RingQuot.ringQuot_ext' _ _ _ <|
        FreeAlgebra.hom_ext <|
          funext fun x => 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 : TensorAlgebra R M →ₐ[R] A
x : M
⊢ (⇑(AlgHom.comp
            ((⇑(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) })
              ((fun F => AlgHom.toLinearMap F ∘ₗ ι R) F))
            (RingQuot.mkAlgHom R (Rel R M))) ∘
        FreeAlgebra.ι R)
      x =
    (⇑(AlgHom.comp F (RingQuot.mkAlgHom R (Rel R M))) ∘ FreeAlgebra.ι R) x

Next tactic:
rw [ι]
@[simp]
theorem ι_comp_lift {A : Type*} [Semiring A] [Algebra R A] (f : M →ₗ[R] A) :
    (lift R f).toLinearMap.comp (ι R) = 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
⊢ AlgHom.toLinearMap ((lift R) f) ∘ₗ ι R = f

Next tactic:
convert (lift R).symm_apply_apply f
@[simp]
theorem lift_ι_apply {A : Type*} [Semiring A] [Algebra R A] (f : M →ₗ[R] A) (x) :
    lift R f (ι R x) = f x := 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 : M
⊢ ((lift R) f) ((ι R) x) = f x

Next tactic:
conv_rhs => rw [← ι_comp_lift f]
@[simp]
theorem lift_ι_apply {A : Type*} [Semiring A] [Algebra R A] (f : M →ₗ[R] A) (x) :
    lift R f (ι R x) = f x := by
  conv_rhs => 

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 : M
| f x

Next tactic:
rw [← ι_comp_lift f]
@[simp]
theorem lift_unique {A : Type*} [Semiring A] [Algebra R A] (f : M →ₗ[R] A)
    (g : TensorAlgebra R M →ₐ[R] A) : g.toLinearMap.comp (ι R) = f ↔ g = lift R 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
g : TensorAlgebra R M →ₐ[R] A
⊢ AlgHom.toLinearMap g ∘ₗ ι R = f ↔ g = (lift R) f

Next tactic:
rw [← (lift R).symm_apply_eq]
@[simp]
theorem lift_unique {A : Type*} [Semiring A] [Algebra R A] (f : M →ₗ[R] A)
    (g : TensorAlgebra R M →ₐ[R] A) : g.toLinearMap.comp (ι R) = f ↔ g = lift R f := by
  rw [← (lift R).symm_apply_eq]
  

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
g : TensorAlgebra R M →ₐ[R] A
⊢ AlgHom.toLinearMap g ∘ₗ ι R = f ↔ (lift R).symm g = f

Next tactic:
simp only [lift, Equiv.coe_fn_symm_mk]
@[simp]
theorem lift_comp_ι {A : Type*} [Semiring A] [Algebra R A] (g : TensorAlgebra R M →ₐ[R] A) :
    lift R (g.toLinearMap.comp (ι R)) = g := 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
g : TensorAlgebra R M →ₐ[R] A
⊢ (lift R) (AlgHom.toLinearMap g ∘ₗ ι R) = g

Next tactic:
rw [← lift_symm_apply]
@[simp]
theorem lift_comp_ι {A : Type*} [Semiring A] [Algebra R A] (g : TensorAlgebra R M →ₐ[R] A) :
    lift R (g.toLinearMap.comp (ι R)) = g := by
  rw [← lift_symm_apply]
  

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
g : TensorAlgebra R M →ₐ[R] A
⊢ (lift R) ((lift R).symm g) = g

Next tactic:
exact (lift R).apply_symm_apply g
/-- See note [partially-applied ext lemmas]. -/
@[ext]
theorem hom_ext {A : Type*} [Semiring A] [Algebra R A] {f g : TensorAlgebra R M →ₐ[R] A}
    (w : f.toLinearMap.comp (ι R) = g.toLinearMap.comp (ι R)) : f = g := 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 g : TensorAlgebra R M →ₐ[R] A
w : AlgHom.toLinearMap f ∘ₗ ι R = AlgHom.toLinearMap g ∘ₗ ι R
⊢ f = g

Next tactic:
rw [← lift_symm_apply, ← lift_symm_apply] at w
/-- See note [partially-applied ext lemmas]. -/
@[ext]
theorem hom_ext {A : Type*} [Semiring A] [Algebra R A] {f g : TensorAlgebra R M →ₐ[R] A}
    (w : f.toLinearMap.comp (ι R) = g.toLinearMap.comp (ι R)) : f = g := by
  rw [← lift_symm_apply, ← lift_symm_apply] at w
  

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 g : TensorAlgebra R M →ₐ[R] A
w : (lift R).symm f = (lift R).symm g
⊢ f = g

Next tactic:
exact (lift R).symm.injective w
/-- If `C` holds for the `algebraMap` of `r : R` into `TensorAlgebra R M`, the `ι` of `x : M`,
and is preserved under addition and muliplication, then it holds for all of `TensorAlgebra R M`.
-/
@[elab_as_elim]
theorem induction {C : TensorAlgebra R M → Prop}
    (h_grade0 : ∀ r, C (algebraMap R (TensorAlgebra R M) r)) (h_grade1 : ∀ x, C (ι R x))
    (h_mul : ∀ a b, C a → C b → C (a * b)) (h_add : ∀ a b, C a → C b → C (a + b))
    (a : TensorAlgebra R M) : C a := by
  -- the arguments are enough to construct a subalgebra, and a mapping into it from M
  

Proof state:
R : Type u_1
inst✝² : CommSemiring R
M : Type u_2
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
C : TensorAlgebra R M → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (TensorAlgebra R M)) r)
h_grade1 : ∀ (x : M), C ((ι R) x)
h_mul : ∀ (a b : TensorAlgebra R M), C a → C b → C (a * b)
h_add : ∀ (a b : TensorAlgebra R M), C a → C b → C (a + b)
a : TensorAlgebra R M
⊢ C a

Next tactic:
let s : Subalgebra R (TensorAlgebra R M) :=
    { carrier := C
      mul_mem' := @h_mul
      add_mem' := @h_add
      algebraMap_mem' := h_grade0 }
/-- If `C` holds for the `algebraMap` of `r : R` into `TensorAlgebra R M`, the `ι` of `x : M`,
and is preserved under addition and muliplication, then it holds for all of `TensorAlgebra R M`.
-/
@[elab_as_elim]
theorem induction {C : TensorAlgebra R M → Prop}
    (h_grade0 : ∀ r, C (algebraMap R (TensorAlgebra R M) r)) (h_grade1 : ∀ x, C (ι R x))
    (h_mul : ∀ a b, C a → C b → C (a * b)) (h_add : ∀ a b, C a → C b → C (a + b))
    (a : TensorAlgebra R M) : C a := by
  -- the arguments are enough to construct a subalgebra, and a mapping into it from M
  let s : Subalgebra R (TensorAlgebra R M) :=
    { carrier := C
      mul_mem' := @h_mul
      add_mem' := @h_add
      algebraMap_mem' := h_grade0 }
  -- porting note: Added `h`. `h` is needed for `of`.
  

Proof state:
R : Type u_1
inst✝² : CommSemiring R
M : Type u_2
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
C : TensorAlgebra R M → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (TensorAlgebra R M)) r)
h_grade1 : ∀ (x : M), C ((ι R) x)
h_mul : ∀ (a b : TensorAlgebra R M), C a → C b → C (a * b)
h_add : ∀ (a b : TensorAlgebra R M), C a → C b → C (a + b)
a : TensorAlgebra R M
s : Subalgebra R (TensorAlgebra R M) :=
  {
    toSubsemiring :=
      { toSubmonoid := { toSubsemigroup := { carrier := C, mul_mem' := h_mul }, one_mem' := (_ : 1 ∈ C) },
        add_mem' := h_add, zero_mem' := (_ : 0 ∈ C) },
    algebraMap_mem' := h_grade0 }
⊢ C a

Next tactic:
let h : AddCommMonoid s := inferInstanceAs (AddCommMonoid (Subalgebra.toSubmodule s))
/-- If `C` holds for the `algebraMap` of `r : R` into `TensorAlgebra R M`, the `ι` of `x : M`,
and is preserved under addition and muliplication, then it holds for all of `TensorAlgebra R M`.
-/
@[elab_as_elim]
theorem induction {C : TensorAlgebra R M → Prop}
    (h_grade0 : ∀ r, C (algebraMap R (TensorAlgebra R M) r)) (h_grade1 : ∀ x, C (ι R x))
    (h_mul : ∀ a b, C a → C b → C (a * b)) (h_add : ∀ a b, C a → C b → C (a + b))
    (a : TensorAlgebra R M) : C a := by
  -- the arguments are enough to construct a subalgebra, and a mapping into it from M
  let s : Subalgebra R (TensorAlgebra R M) :=
    { carrier := C
      mul_mem' := @h_mul
      add_mem' := @h_add
      algebraMap_mem' := h_grade0 }
  -- porting note: Added `h`. `h` is needed for `of`.
  let h : AddCommMonoid s := inferInstanceAs (AddCommMonoid (Subalgebra.toSubmodule s))
  

Proof state:
R : Type u_1
inst✝² : CommSemiring R
M : Type u_2
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
C : TensorAlgebra R M → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (TensorAlgebra R M)) r)
h_grade1 : ∀ (x : M), C ((ι R) x)
h_mul : ∀ (a b : TensorAlgebra R M), C a → C b → C (a * b)
h_add : ∀ (a b : TensorAlgebra R M), C a → C b → C (a + b)
a : TensorAlgebra R M
s : Subalgebra R (TensorAlgebra R M) :=
  {
    toSubsemiring :=
      { toSubmonoid := { toSubsemigroup := { carrier := C, mul_mem' := h_mul }, one_mem' := (_ : 1 ∈ C) },
        add_mem' := h_add, zero_mem' := (_ : 0 ∈ C) },
    algebraMap_mem' := h_grade0 }
h : AddCommMonoid ↥s := inferInstanceAs (AddCommMonoid ↥(Subalgebra.toSubmodule s))
⊢ C a

Next tactic:
let of : M →ₗ[R] s := (ι R).codRestrict (Subalgebra.toSubmodule s) h_grade1
/-- If `C` holds for the `algebraMap` of `r : R` into `TensorAlgebra R M`, the `ι` of `x : M`,
and is preserved under addition and muliplication, then it holds for all of `TensorAlgebra R M`.
-/
@[elab_as_elim]
theorem induction {C : TensorAlgebra R M → Prop}
    (h_grade0 : ∀ r, C (algebraMap R (TensorAlgebra R M) r)) (h_grade1 : ∀ x, C (ι R x))
    (h_mul : ∀ a b, C a → C b → C (a * b)) (h_add : ∀ a b, C a → C b → C (a + b))
    (a : TensorAlgebra R M) : C a := by
  -- the arguments are enough to construct a subalgebra, and a mapping into it from M
  let s : Subalgebra R (TensorAlgebra R M) :=
    { carrier := C
      mul_mem' := @h_mul
      add_mem' := @h_add
      algebraMap_mem' := h_grade0 }
  -- porting note: Added `h`. `h` is needed for `of`.
  let h : AddCommMonoid s := inferInstanceAs (AddCommMonoid (Subalgebra.toSubmodule s))
  let of : M →ₗ[R] s := (ι R).codRestrict (Subalgebra.toSubmodule s) h_grade1
  -- the mapping through the subalgebra is the identity
  

Proof state:
R : Type u_1
inst✝² : CommSemiring R
M : Type u_2
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
C : TensorAlgebra R M → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (TensorAlgebra R M)) r)
h_grade1 : ∀ (x : M), C ((ι R) x)
h_mul : ∀ (a b : TensorAlgebra R M), C a → C b → C (a * b)
h_add : ∀ (a b : TensorAlgebra R M), C a → C b → C (a + b)
a : TensorAlgebra R M
s : Subalgebra R (TensorAlgebra R M) :=
  {
    toSubsemiring :=
      { toSubmonoid := { toSubsemigroup := { carrier := C, mul_mem' := h_mul }, one_mem' := (_ : 1 ∈ C) },
        add_mem' := h_add, zero_mem' := (_ : 0 ∈ C) },
    algebraMap_mem' := h_grade0 }
h : AddCommMonoid ↥s := inferInstanceAs (AddCommMonoid ↥(Subalgebra.toSubmodule s))
of : M →ₗ[R] ↥s := LinearMap.codRestrict (Subalgebra.toSubmodule s) (ι R) h_grade1
⊢ C a

Next tactic:
have of_id : AlgHom.id R (TensorAlgebra R M) = s.val.comp (lift R of) := by
    ext
    simp only [AlgHom.toLinearMap_id, LinearMap.id_comp, AlgHom.comp_toLinearMap,
      LinearMap.coe_comp, Function.comp_apply, AlgHom.toLinearMap_apply, lift_ι_apply,
      Subalgebra.coe_val]
    erw [LinearMap.codRestrict_apply]
/-- If `C` holds for the `algebraMap` of `r : R` into `TensorAlgebra R M`, the `ι` of `x : M`,
and is preserved under addition and muliplication, then it holds for all of `TensorAlgebra R M`.
-/
@[elab_as_elim]
theorem induction {C : TensorAlgebra R M → Prop}
    (h_grade0 : ∀ r, C (algebraMap R (TensorAlgebra R M) r)) (h_grade1 : ∀ x, C (ι R x))
    (h_mul : ∀ a b, C a → C b → C (a * b)) (h_add : ∀ a b, C a → C b → C (a + b))
    (a : TensorAlgebra R M) : C a := by
  -- the arguments are enough to construct a subalgebra, and a mapping into it from M
  let s : Subalgebra R (TensorAlgebra R M) :=
    { carrier := C
      mul_mem' := @h_mul
      add_mem' := @h_add
      algebraMap_mem' := h_grade0 }
  -- porting note: Added `h`. `h` is needed for `of`.
  let h : AddCommMonoid s := inferInstanceAs (AddCommMonoid (Subalgebra.toSubmodule s))
  let of : M →ₗ[R] s := (ι R).codRestrict (Subalgebra.toSubmodule s) h_grade1
  -- the mapping through the subalgebra is the identity
  have of_id : AlgHom.id R (TensorAlgebra R M) = s.val.comp (lift R of) := by
    

Proof state:
R : Type u_1
inst✝² : CommSemiring R
M : Type u_2
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
C : TensorAlgebra R M → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (TensorAlgebra R M)) r)
h_grade1 : ∀ (x : M), C ((ι R) x)
h_mul : ∀ (a b : TensorAlgebra R M), C a → C b → C (a * b)
h_add : ∀ (a b : TensorAlgebra R M), C a → C b → C (a + b)
a : TensorAlgebra R M
s : Subalgebra R (TensorAlgebra R M) :=
  {
    toSubsemiring :=
      { toSubmonoid := { toSubsemigroup := { carrier := C, mul_mem' := h_mul }, one_mem' := (_ : 1 ∈ C) },
        add_mem' := h_add, zero_mem' := (_ : 0 ∈ C) },
    algebraMap_mem' := h_grade0 }
h : AddCommMonoid ↥s := inferInstanceAs (AddCommMonoid ↥(Subalgebra.toSubmodule s))
of : M →ₗ[R] ↥s := LinearMap.codRestrict (Subalgebra.toSubmodule s) (ι R) h_grade1
⊢ AlgHom.id R (TensorAlgebra R M) = AlgHom.comp (Subalgebra.val s) ((lift R) of)

Next tactic:
ext
/-- If `C` holds for the `algebraMap` of `r : R` into `TensorAlgebra R M`, the `ι` of `x : M`,
and is preserved under addition and muliplication, then it holds for all of `TensorAlgebra R M`.
-/
@[elab_as_elim]
theorem induction {C : TensorAlgebra R M → Prop}
    (h_grade0 : ∀ r, C (algebraMap R (TensorAlgebra R M) r)) (h_grade1 : ∀ x, C (ι R x))
    (h_mul : ∀ a b, C a → C b → C (a * b)) (h_add : ∀ a b, C a → C b → C (a + b))
    (a : TensorAlgebra R M) : C a := by
  -- the arguments are enough to construct a subalgebra, and a mapping into it from M
  let s : Subalgebra R (TensorAlgebra R M) :=
    { carrier := C
      mul_mem' := @h_mul
      add_mem' := @h_add
      algebraMap_mem' := h_grade0 }
  -- porting note: Added `h`. `h` is needed for `of`.
  let h : AddCommMonoid s := inferInstanceAs (AddCommMonoid (Subalgebra.toSubmodule s))
  let of : M →ₗ[R] s := (ι R).codRestrict (Subalgebra.toSubmodule s) h_grade1
  -- the mapping through the subalgebra is the identity
  have of_id : AlgHom.id R (TensorAlgebra R M) = s.val.comp (lift R of) := by
    ext
    

Proof state:
case w.h
R : Type u_1
inst✝² : CommSemiring R
M : Type u_2
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
C : TensorAlgebra R M → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (TensorAlgebra R M)) r)
h_grade1 : ∀ (x : M), C ((ι R) x)
h_mul : ∀ (a b : TensorAlgebra R M), C a → C b → C (a * b)
h_add : ∀ (a b : TensorAlgebra R M), C a → C b → C (a + b)
a : TensorAlgebra R M
s : Subalgebra R (TensorAlgebra R M) :=
  {
    toSubsemiring :=
      { toSubmonoid := { toSubsemigroup := { carrier := C, mul_mem' := h_mul }, one_mem' := (_ : 1 ∈ C) },
        add_mem' := h_add, zero_mem' := (_ : 0 ∈ C) },
    algebraMap_mem' := h_grade0 }
h : AddCommMonoid ↥s := inferInstanceAs (AddCommMonoid ↥(Subalgebra.toSubmodule s))
of : M →ₗ[R] ↥s := LinearMap.codRestrict (Subalgebra.toSubmodule s) (ι R) h_grade1
x✝ : M
⊢ (AlgHom.toLinearMap (AlgHom.id R (TensorAlgebra R M)) ∘ₗ ι R) x✝ =
    (AlgHom.toLinearMap (AlgHom.comp (Subalgebra.val s) ((lift R) of)) ∘ₗ ι R) x✝

Next tactic:
simp only [AlgHom.toLinearMap_id, LinearMap.id_comp, AlgHom.comp_toLinearMap,
      LinearMap.coe_comp, Function.comp_apply, AlgHom.toLinearMap_apply, lift_ι_apply,
      Subalgebra.coe_val]
/-- If `C` holds for the `algebraMap` of `r : R` into `TensorAlgebra R M`, the `ι` of `x : M`,
and is preserved under addition and muliplication, then it holds for all of `TensorAlgebra R M`.
-/
@[elab_as_elim]
theorem induction {C : TensorAlgebra R M → Prop}
    (h_grade0 : ∀ r, C (algebraMap R (TensorAlgebra R M) r)) (h_grade1 : ∀ x, C (ι R x))
    (h_mul : ∀ a b, C a → C b → C (a * b)) (h_add : ∀ a b, C a → C b → C (a + b))
    (a : TensorAlgebra R M) : C a := by
  -- the arguments are enough to construct a subalgebra, and a mapping into it from M
  let s : Subalgebra R (TensorAlgebra R M) :=
    { carrier := C
      mul_mem' := @h_mul
      add_mem' := @h_add
      algebraMap_mem' := h_grade0 }
  -- porting note: Added `h`. `h` is needed for `of`.
  let h : AddCommMonoid s := inferInstanceAs (AddCommMonoid (Subalgebra.toSubmodule s))
  let of : M →ₗ[R] s := (ι R).codRestrict (Subalgebra.toSubmodule s) h_grade1
  -- the mapping through the subalgebra is the identity
  have of_id : AlgHom.id R (TensorAlgebra R M) = s.val.comp (lift R of) := by
    ext
    simp only [AlgHom.toLinearMap_id, LinearMap.id_comp, AlgHom.comp_toLinearMap,
      LinearMap.coe_comp, Function.comp_apply, AlgHom.toLinearMap_apply, lift_ι_apply,
      Subalgebra.coe_val]
    

Proof state:
case w.h
R : Type u_1
inst✝² : CommSemiring R
M : Type u_2
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
C : TensorAlgebra R M → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (TensorAlgebra R M)) r)
h_grade1 : ∀ (x : M), C ((ι R) x)
h_mul : ∀ (a b : TensorAlgebra R M), C a → C b → C (a * b)
h_add : ∀ (a b : TensorAlgebra R M), C a → C b → C (a + b)
a : TensorAlgebra R M
s : Subalgebra R (TensorAlgebra R M) :=
  {
    toSubsemiring :=
      { toSubmonoid := { toSubsemigroup := { carrier := C, mul_mem' := h_mul }, one_mem' := (_ : 1 ∈ C) },
        add_mem' := h_add, zero_mem' := (_ : 0 ∈ C) },
    algebraMap_mem' := h_grade0 }
h : AddCommMonoid ↥s := inferInstanceAs (AddCommMonoid ↥(Subalgebra.toSubmodule s))
of : M →ₗ[R] ↥s := LinearMap.codRestrict (Subalgebra.toSubmodule s) (ι R) h_grade1
x✝ : M
⊢ (ι R) x✝ = ↑((LinearMap.codRestrict (Subalgebra.toSubmodule s) (ι R) h_grade1) x✝)

Next tactic:
erw [LinearMap.codRestrict_apply]
/-- If `C` holds for the `algebraMap` of `r : R` into `TensorAlgebra R M`, the `ι` of `x : M`,
and is preserved under addition and muliplication, then it holds for all of `TensorAlgebra R M`.
-/
@[elab_as_elim]
theorem induction {C : TensorAlgebra R M → Prop}
    (h_grade0 : ∀ r, C (algebraMap R (TensorAlgebra R M) r)) (h_grade1 : ∀ x, C (ι R x))
    (h_mul : ∀ a b, C a → C b → C (a * b)) (h_add : ∀ a b, C a → C b → C (a + b))
    (a : TensorAlgebra R M) : C a := by
  -- the arguments are enough to construct a subalgebra, and a mapping into it from M
  let s : Subalgebra R (TensorAlgebra R M) :=
    { carrier := C
      mul_mem' := @h_mul
      add_mem' := @h_add
      algebraMap_mem' := h_grade0 }
  -- porting note: Added `h`. `h` is needed for `of`.
  let h : AddCommMonoid s := inferInstanceAs (AddCommMonoid (Subalgebra.toSubmodule s))
  let of : M →ₗ[R] s := (ι R).codRestrict (Subalgebra.toSubmodule s) h_grade1
  -- the mapping through the subalgebra is the identity
  have of_id : AlgHom.id R (TensorAlgebra R M) = s.val.comp (lift R of) := by
    ext
    simp only [AlgHom.toLinearMap_id, LinearMap.id_comp, AlgHom.comp_toLinearMap,
      LinearMap.coe_comp, Function.comp_apply, AlgHom.toLinearMap_apply, lift_ι_apply,
      Subalgebra.coe_val]
    erw [LinearMap.codRestrict_apply]
  -- finding a proof is finding an element of the subalgebra
  

Proof state:
R : Type u_1
inst✝² : CommSemiring R
M : Type u_2
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
C : TensorAlgebra R M → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (TensorAlgebra R M)) r)
h_grade1 : ∀ (x : M), C ((ι R) x)
h_mul : ∀ (a b : TensorAlgebra R M), C a → C b → C (a * b)
h_add : ∀ (a b : TensorAlgebra R M), C a → C b → C (a + b)
a : TensorAlgebra R M
s : Subalgebra R (TensorAlgebra R M) :=
  {
    toSubsemiring :=
      { toSubmonoid := { toSubsemigroup := { carrier := C, mul_mem' := h_mul }, one_mem' := (_ : 1 ∈ C) },
        add_mem' := h_add, zero_mem' := (_ : 0 ∈ C) },
    algebraMap_mem' := h_grade0 }
h : AddCommMonoid ↥s := inferInstanceAs (AddCommMonoid ↥(Subalgebra.toSubmodule s))
of : M →ₗ[R] ↥s := LinearMap.codRestrict (Subalgebra.toSubmodule s) (ι R) h_grade1
of_id : AlgHom.id R (TensorAlgebra R M) = AlgHom.comp (Subalgebra.val s) ((lift R) of)
⊢ C a

Next tactic:
rw [← AlgHom.id_apply (R := R) a, of_id]