-- Mathlib/Algebra/FreeAlgebra.lean
theorem induction {C : FreeAlgebra R X → Prop}
    (h_grade0 : ∀ r, C (algebraMap R (FreeAlgebra R X) 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 : FreeAlgebra R X) : C a

Proof state:
R : Type u_1
inst✝ : CommSemiring R
X : Type u_2
C : FreeAlgebra R X → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (FreeAlgebra R X)) r)
h_grade1 : ∀ (x : X), C (ι R x)
h_mul : ∀ (a b : FreeAlgebra R X), C a → C b → C (a * b)
h_add : ∀ (a b : FreeAlgebra R X), C a → C b → C (a + b)
a : FreeAlgebra R X
s : Subalgebra R (FreeAlgebra R X) :=
  { carrier := C, mul_mem' := ⋯, one_mem' := ⋯, add_mem' := ⋯, zero_mem' := ⋯, algebraMap_mem' := h_grade0 }
of : X → ↥s := Subtype.coind (ι R) h_grade1
⊢ C a

Tactic:
have of_id : AlgHom.id R (FreeAlgebra R X) = s.val.comp (lift R of) := by
  ext
  simp [of, Subtype.coind]

Result:
R : Type u_1
inst✝ : CommSemiring R
X : Type u_2
C : FreeAlgebra R X → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (FreeAlgebra R X)) r)
h_grade1 : ∀ (x : X), C (ι R x)
h_mul : ∀ (a b : FreeAlgebra R X), C a → C b → C (a * b)
h_add : ∀ (a b : FreeAlgebra R X), C a → C b → C (a + b)
a : FreeAlgebra R X
s : Subalgebra R (FreeAlgebra R X) :=
  { carrier := C, mul_mem' := ⋯, one_mem' := ⋯, add_mem' := ⋯, zero_mem' := ⋯, algebraMap_mem' := h_grade0 }
of : X → ↥s := Subtype.coind (ι R) h_grade1
of_id : AlgHom.id R (FreeAlgebra R X) = s.val.comp ((lift R) of)
⊢ C a

Proof state:
R : Type u_1
inst✝ : CommSemiring R
X : Type u_2
C : FreeAlgebra R X → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (FreeAlgebra R X)) r)
h_grade1 : ∀ (x : X), C (ι R x)
h_mul : ∀ (a b : FreeAlgebra R X), C a → C b → C (a * b)
h_add : ∀ (a b : FreeAlgebra R X), C a → C b → C (a + b)
a : FreeAlgebra R X
s : Subalgebra R (FreeAlgebra R X) :=
  { carrier := C, mul_mem' := ⋯, one_mem' := ⋯, add_mem' := ⋯, zero_mem' := ⋯, algebraMap_mem' := h_grade0 }
of : X → ↥s := Subtype.coind (ι R) h_grade1
of_id : ∀ (x : FreeAlgebra R X), x = ↑(((lift R) of) x)
⊢ a = ↑(((lift R) of) a)

Tactic:
exact of_id a

Result:
no goals

Proof state:
R : Type u_1
inst✝ : CommSemiring R
X : Type u_2
C : FreeAlgebra R X → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (FreeAlgebra R X)) r)
h_grade1 : ∀ (x : X), C (ι R x)
h_mul : ∀ (a b : FreeAlgebra R X), C a → C b → C (a * b)
h_add : ∀ (a b : FreeAlgebra R X), C a → C b → C (a + b)
a : FreeAlgebra R X
s : Subalgebra R (FreeAlgebra R X) :=
  { carrier := C, mul_mem' := ⋯, one_mem' := ⋯, add_mem' := ⋯, zero_mem' := ⋯, algebraMap_mem' := h_grade0 }
⊢ C a

Tactic:
let of : X → s := Subtype.coind (ι R) h_grade1

Result:
R : Type u_1
inst✝ : CommSemiring R
X : Type u_2
C : FreeAlgebra R X → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (FreeAlgebra R X)) r)
h_grade1 : ∀ (x : X), C (ι R x)
h_mul : ∀ (a b : FreeAlgebra R X), C a → C b → C (a * b)
h_add : ∀ (a b : FreeAlgebra R X), C a → C b → C (a + b)
a : FreeAlgebra R X
s : Subalgebra R (FreeAlgebra R X) :=
  { carrier := C, mul_mem' := ⋯, one_mem' := ⋯, add_mem' := ⋯, zero_mem' := ⋯, algebraMap_mem' := h_grade0 }
of : X → ↥s := Subtype.coind (ι R) h_grade1
⊢ C a

Proof state:
case w.h
R : Type u_1
inst✝ : CommSemiring R
X : Type u_2
C : FreeAlgebra R X → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (FreeAlgebra R X)) r)
h_grade1 : ∀ (x : X), C (ι R x)
h_mul : ∀ (a b : FreeAlgebra R X), C a → C b → C (a * b)
h_add : ∀ (a b : FreeAlgebra R X), C a → C b → C (a + b)
a : FreeAlgebra R X
s : Subalgebra R (FreeAlgebra R X) :=
  { carrier := C, mul_mem' := ⋯, one_mem' := ⋯, add_mem' := ⋯, zero_mem' := ⋯, algebraMap_mem' := h_grade0 }
of : X → ↥s := Subtype.coind (ι R) h_grade1
x✝ : X
⊢ (⇑(AlgHom.id R (FreeAlgebra R X)) ∘ ι R) x✝ = (⇑(s.val.comp ((lift R) of)) ∘ ι R) x✝

Tactic:
simp [of, Subtype.coind]

Result:
no goals

Proof state:
R : Type u_1
inst✝ : CommSemiring R
X : Type u_2
C : FreeAlgebra R X → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (FreeAlgebra R X)) r)
h_grade1 : ∀ (x : X), C (ι R x)
h_mul : ∀ (a b : FreeAlgebra R X), C a → C b → C (a * b)
h_add : ∀ (a b : FreeAlgebra R X), C a → C b → C (a + b)
a : FreeAlgebra R X
⊢ C a

Tactic:
let s : Subalgebra R (FreeAlgebra R X) :=
  { carrier := C
    mul_mem' := h_mul _ _
    add_mem' := h_add _ _
    algebraMap_mem' := h_grade0 }

Result:
R : Type u_1
inst✝ : CommSemiring R
X : Type u_2
C : FreeAlgebra R X → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (FreeAlgebra R X)) r)
h_grade1 : ∀ (x : X), C (ι R x)
h_mul : ∀ (a b : FreeAlgebra R X), C a → C b → C (a * b)
h_add : ∀ (a b : FreeAlgebra R X), C a → C b → C (a + b)
a : FreeAlgebra R X
s : Subalgebra R (FreeAlgebra R X) :=
  { carrier := C, mul_mem' := ⋯, one_mem' := ⋯, add_mem' := ⋯, zero_mem' := ⋯, algebraMap_mem' := h_grade0 }
⊢ C a

Proof state:
R : Type u_1
inst✝ : CommSemiring R
X : Type u_2
C : FreeAlgebra R X → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (FreeAlgebra R X)) r)
h_grade1 : ∀ (x : X), C (ι R x)
h_mul : ∀ (a b : FreeAlgebra R X), C a → C b → C (a * b)
h_add : ∀ (a b : FreeAlgebra R X), C a → C b → C (a + b)
a : FreeAlgebra R X
s : Subalgebra R (FreeAlgebra R X) :=
  { carrier := C, mul_mem' := ⋯, one_mem' := ⋯, add_mem' := ⋯, zero_mem' := ⋯, algebraMap_mem' := h_grade0 }
of : X → ↥s := Subtype.coind (ι R) h_grade1
of_id : AlgHom.id R (FreeAlgebra R X) = s.val.comp ((lift R) of)
⊢ a = ↑(((lift R) of) a)

Tactic:
simp [AlgHom.ext_iff] at of_id

Result:
R : Type u_1
inst✝ : CommSemiring R
X : Type u_2
C : FreeAlgebra R X → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (FreeAlgebra R X)) r)
h_grade1 : ∀ (x : X), C (ι R x)
h_mul : ∀ (a b : FreeAlgebra R X), C a → C b → C (a * b)
h_add : ∀ (a b : FreeAlgebra R X), C a → C b → C (a + b)
a : FreeAlgebra R X
s : Subalgebra R (FreeAlgebra R X) :=
  { carrier := C, mul_mem' := ⋯, one_mem' := ⋯, add_mem' := ⋯, zero_mem' := ⋯, algebraMap_mem' := h_grade0 }
of : X → ↥s := Subtype.coind (ι R) h_grade1
of_id : ∀ (x : FreeAlgebra R X), x = ↑(((lift R) of) x)
⊢ a = ↑(((lift R) of) a)

Proof state:
R : Type u_1
inst✝ : CommSemiring R
X : Type u_2
C : FreeAlgebra R X → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (FreeAlgebra R X)) r)
h_grade1 : ∀ (x : X), C (ι R x)
h_mul : ∀ (a b : FreeAlgebra R X), C a → C b → C (a * b)
h_add : ∀ (a b : FreeAlgebra R X), C a → C b → C (a + b)
a : FreeAlgebra R X
s : Subalgebra R (FreeAlgebra R X) :=
  { carrier := C, mul_mem' := ⋯, one_mem' := ⋯, add_mem' := ⋯, zero_mem' := ⋯, algebraMap_mem' := h_grade0 }
of : X → ↥s := Subtype.coind (ι R) h_grade1
of_id : AlgHom.id R (FreeAlgebra R X) = s.val.comp ((lift R) of)
this : a = ↑(((lift R) of) a)
⊢ C ↑(((lift R) of) a)

Tactic:
exact Subtype.prop (lift R of a)

Result:
no goals

Proof state:
R : Type u_1
inst✝ : CommSemiring R
X : Type u_2
C : FreeAlgebra R X → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (FreeAlgebra R X)) r)
h_grade1 : ∀ (x : X), C (ι R x)
h_mul : ∀ (a b : FreeAlgebra R X), C a → C b → C (a * b)
h_add : ∀ (a b : FreeAlgebra R X), C a → C b → C (a + b)
a : FreeAlgebra R X
s : Subalgebra R (FreeAlgebra R X) :=
  { carrier := C, mul_mem' := ⋯, one_mem' := ⋯, add_mem' := ⋯, zero_mem' := ⋯, algebraMap_mem' := h_grade0 }
of : X → ↥s := Subtype.coind (ι R) h_grade1
⊢ AlgHom.id R (FreeAlgebra R X) = s.val.comp ((lift R) of)

Tactic:
ext

Result:
case w.h
R : Type u_1
inst✝ : CommSemiring R
X : Type u_2
C : FreeAlgebra R X → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (FreeAlgebra R X)) r)
h_grade1 : ∀ (x : X), C (ι R x)
h_mul : ∀ (a b : FreeAlgebra R X), C a → C b → C (a * b)
h_add : ∀ (a b : FreeAlgebra R X), C a → C b → C (a + b)
a : FreeAlgebra R X
s : Subalgebra R (FreeAlgebra R X) :=
  { carrier := C, mul_mem' := ⋯, one_mem' := ⋯, add_mem' := ⋯, zero_mem' := ⋯, algebraMap_mem' := h_grade0 }
of : X → ↥s := Subtype.coind (ι R) h_grade1
x✝ : X
⊢ (⇑(AlgHom.id R (FreeAlgebra R X)) ∘ ι R) x✝ = (⇑(s.val.comp ((lift R) of)) ∘ ι R) x✝