l3lab/ntp-mathlib huggingface dataset:
lemma map_symm_eq_iff_eq_map {M : Sublattice β} {e : β ≃o α} :
    L.map ↑e.symm = M ↔ L = M.map ↑e := by
  simp_rw [← coe_inj]; 

Proof state:
ι : Sort u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Lattice α
inst✝¹ : Lattice β
inst✝ : Lattice γ
L M✝ : Sublattice α
f : LatticeHom α β
s t : Set α
a : α
M : Sublattice β
e : β ≃o α
⊢ ↑(map
          {
            toSupHom :=
              { toFun := ⇑(OrderIso.symm e),
                map_sup' := (_ : ∀ (a b : α), (OrderIso.symm e) (a ⊔ b) = (OrderIso.symm e) a ⊔ (OrderIso.symm e) b) },
            map_inf' := (_ : ∀ (a b : α), (OrderIso.symm e) (a ⊓ b) = (OrderIso.symm e) a ⊓ (OrderIso.symm e) b) }
          L) =
      ↑M ↔
    ↑L =
      ↑(map
          { toSupHom := { toFun := ⇑e, map_sup' := (_ : ∀ (a b : β), e (a ⊔ b) = e a ⊔ e b) },
            map_inf' := (_ : ∀ (a b : β), e (a ⊓ b) = e a ⊓ e b) }
          M)

Next tactic:
exact (Equiv.eq_image_iff_symm_image_eq _ _ _).symm
lemma map_inf (L M : Sublattice α) (f : LatticeHom α β) (hf : Injective f) :
    map f (L ⊓ M) = map f L ⊓ map f M := by
  

Proof state:
ι : Sort u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Lattice α
inst✝¹ : Lattice β
inst✝ : Lattice γ
L✝ M✝ : Sublattice α
f✝ : LatticeHom α β
s t : Set α
a : α
L M : Sublattice α
f : LatticeHom α β
hf : Injective ⇑f
⊢ map f (L ⊓ M) = map f L ⊓ map f M

Next tactic:
rw [← SetLike.coe_set_eq]
lemma map_inf (L M : Sublattice α) (f : LatticeHom α β) (hf : Injective f) :
    map f (L ⊓ M) = map f L ⊓ map f M := by
  rw [← SetLike.coe_set_eq]
  

Proof state:
ι : Sort u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Lattice α
inst✝¹ : Lattice β
inst✝ : Lattice γ
L✝ M✝ : Sublattice α
f✝ : LatticeHom α β
s t : Set α
a : α
L M : Sublattice α
f : LatticeHom α β
hf : Injective ⇑f
⊢ ↑(map f (L ⊓ M)) = ↑(map f L ⊓ map f M)

Next tactic:
simp [Set.image_inter hf]
lemma map_top (f : LatticeHom α β) (h : Surjective f) : Sublattice.map f ⊤ = ⊤ :=
  SetLike.coe_injective $ by 

Proof state:
ι : Sort u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝² : Lattice α
inst✝¹ : Lattice β
inst✝ : Lattice γ
L M : Sublattice α
f✝ : LatticeHom α β
s t : Set α
a : α
f : LatticeHom α β
h : Surjective ⇑f
⊢ ↑(map f ⊤) = ↑⊤

Next tactic:
simp [h.range_eq]
/-- As well as being linear, `ι Q` squares to the quadratic form -/
@[simp]
theorem ι_sq_scalar (m : M) : ι Q m * ι Q m = algebraMap R _ (Q m) := by
  

Proof state:
R : Type u_1
inst✝² : CommRing R
M : Type u_2
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
n : ℕ
m : M
⊢ (ι Q) m * (ι Q) m = (algebraMap R (CliffordAlgebra Q)) (Q m)

Next tactic:
erw [← AlgHom.map_mul, RingQuot.mkAlgHom_rel R (Rel.of m), AlgHom.commutes]
/-- As well as being linear, `ι Q` squares to the quadratic form -/
@[simp]
theorem ι_sq_scalar (m : M) : ι Q m * ι Q m = algebraMap R _ (Q m) := by
  erw [← AlgHom.map_mul, RingQuot.mkAlgHom_rel R (Rel.of m), AlgHom.commutes]
  

Proof state:
R : Type u_1
inst✝² : CommRing R
M : Type u_2
inst✝¹ : AddCommGroup M
inst✝ : Module R M
Q : QuadraticForm R M
n : ℕ
m : M
⊢ (algebraMap R (RingQuot (Rel Q))) (Q m) = (algebraMap R (CliffordAlgebra Q)) (Q m)

Next tactic:
rfl
@[simp]
theorem comp_ι_sq_scalar (g : CliffordAlgebra Q →ₐ[R] A) (m : M) :
    g (ι Q m) * g (ι Q m) = algebraMap _ _ (Q m) := by
  

Proof state:
R : Type u_1
inst✝⁴ : CommRing R
M : Type u_2
inst✝³ : AddCommGroup M
inst✝² : Module R M
Q : QuadraticForm R M
n : ℕ
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
g : CliffordAlgebra Q →ₐ[R] A
m : M
⊢ g ((ι Q) m) * g ((ι Q) m) = (algebraMap R A) (Q m)

Next tactic:
rw [← AlgHom.map_mul, ι_sq_scalar, AlgHom.commutes]
/-- Given a linear map `f : M →ₗ[R] A` into an `R`-algebra `A`, which satisfies the condition:
`cond : ∀ m : M, f m * f m = Q(m)`, this is the canonical lift of `f` to a morphism of `R`-algebras
from `CliffordAlgebra Q` to `A`.
-/
@[simps symm_apply]
def lift : { f : M →ₗ[R] A // ∀ m, f m * f m = algebraMap _ _ (Q m) } ≃ (CliffordAlgebra Q →ₐ[R] A)
    where
  toFun f :=
    RingQuot.liftAlgHom R
      ⟨TensorAlgebra.lift R (f : M →ₗ[R] A), fun x y (h : Rel Q x y) => by
        

Proof state:
R : Type u_1
inst✝⁴ : CommRing R
M : Type u_2
inst✝³ : AddCommGroup M
inst✝² : Module R M
Q : QuadraticForm R M
n : ℕ
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
f : { f // ∀ (m : M), f m * f m = (algebraMap R A) (Q m) }
x y : TensorAlgebra R M
h : Rel Q x y
⊢ ((TensorAlgebra.lift R) ↑f) x = ((TensorAlgebra.lift R) ↑f) y

Next tactic:
induction h
/-- Given a linear map `f : M →ₗ[R] A` into an `R`-algebra `A`, which satisfies the condition:
`cond : ∀ m : M, f m * f m = Q(m)`, this is the canonical lift of `f` to a morphism of `R`-algebras
from `CliffordAlgebra Q` to `A`.
-/
@[simps symm_apply]
def lift : { f : M →ₗ[R] A // ∀ m, f m * f m = algebraMap _ _ (Q m) } ≃ (CliffordAlgebra Q →ₐ[R] A)
    where
  toFun f :=
    RingQuot.liftAlgHom R
      ⟨TensorAlgebra.lift R (f : M →ₗ[R] A), fun x y (h : Rel Q x y) => by
        induction h
        

Proof state:
case of
R : Type u_1
inst✝⁴ : CommRing R
M : Type u_2
inst✝³ : AddCommGroup M
inst✝² : Module R M
Q : QuadraticForm R M
n : ℕ
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
f : { f // ∀ (m : M), f m * f m = (algebraMap R A) (Q m) }
x y : TensorAlgebra R M
m✝ : M
⊢ ((TensorAlgebra.lift R) ↑f) ((TensorAlgebra.ι R) m✝ * (TensorAlgebra.ι R) m✝) =
    ((TensorAlgebra.lift R) ↑f) ((algebraMap R (TensorAlgebra R M)) (Q m✝))

Next tactic:
rw [AlgHom.commutes, AlgHom.map_mul, TensorAlgebra.lift_ι_apply, f.prop]
/-- Given a linear map `f : M →ₗ[R] A` into an `R`-algebra `A`, which satisfies the condition:
`cond : ∀ m : M, f m * f m = Q(m)`, this is the canonical lift of `f` to a morphism of `R`-algebras
from `CliffordAlgebra Q` to `A`.
-/
@[simps symm_apply]
def lift : { f : M →ₗ[R] A // ∀ m, f m * f m = algebraMap _ _ (Q m) } ≃ (CliffordAlgebra Q →ₐ[R] A)
    where
  toFun f :=
    RingQuot.liftAlgHom R
      ⟨TensorAlgebra.lift R (f : M →ₗ[R] A), fun x y (h : Rel Q x y) => by
        induction h
        rw [AlgHom.commutes, AlgHom.map_mul, TensorAlgebra.lift_ι_apply, f.prop]⟩
  invFun F :=
    ⟨F.toLinearMap.comp (ι Q), fun m => by
      

Proof state:
R : Type u_1
inst✝⁴ : CommRing R
M : Type u_2
inst✝³ : AddCommGroup M
inst✝² : Module R M
Q : QuadraticForm R M
n : ℕ
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
F : CliffordAlgebra Q →ₐ[R] A
m : M
⊢ (AlgHom.toLinearMap F ∘ₗ ι Q) m * (AlgHom.toLinearMap F ∘ₗ ι Q) m = (algebraMap R A) (Q m)

Next tactic:
rw [LinearMap.comp_apply, AlgHom.toLinearMap_apply, comp_ι_sq_scalar]
/-- Given a linear map `f : M →ₗ[R] A` into an `R`-algebra `A`, which satisfies the condition:
`cond : ∀ m : M, f m * f m = Q(m)`, this is the canonical lift of `f` to a morphism of `R`-algebras
from `CliffordAlgebra Q` to `A`.
-/
@[simps symm_apply]
def lift : { f : M →ₗ[R] A // ∀ m, f m * f m = algebraMap _ _ (Q m) } ≃ (CliffordAlgebra Q →ₐ[R] A)
    where
  toFun f :=
    RingQuot.liftAlgHom R
      ⟨TensorAlgebra.lift R (f : M →ₗ[R] A), fun x y (h : Rel Q x y) => by
        induction h
        rw [AlgHom.commutes, AlgHom.map_mul, TensorAlgebra.lift_ι_apply, f.prop]⟩
  invFun F :=
    ⟨F.toLinearMap.comp (ι Q), fun m => by
      rw [LinearMap.comp_apply, AlgHom.toLinearMap_apply, comp_ι_sq_scalar]⟩
  left_inv f := by
    

Proof state:
R : Type u_1
inst✝⁴ : CommRing R
M : Type u_2
inst✝³ : AddCommGroup M
inst✝² : Module R M
Q : QuadraticForm R M
n : ℕ
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
f : { f // ∀ (m : M), f m * f m = (algebraMap R A) (Q m) }
⊢ (fun F =>
        { val := AlgHom.toLinearMap F ∘ₗ ι Q,
          property :=
            (_ :
              ∀ (m : M), (AlgHom.toLinearMap F ∘ₗ ι Q) m * (AlgHom.toLinearMap F ∘ₗ ι Q) m = (algebraMap R A) (Q m)) })
      ((fun f =>
          (RingQuot.liftAlgHom R)
            { val := (TensorAlgebra.lift R) ↑f,
              property :=
                (_ :
                  ∀ (x y : TensorAlgebra R M),
                    Rel Q x y → ((TensorAlgebra.lift R) ↑f) x = ((TensorAlgebra.lift R) ↑f) y) })
        f) =
    f

Next tactic:
ext x
/-- Given a linear map `f : M →ₗ[R] A` into an `R`-algebra `A`, which satisfies the condition:
`cond : ∀ m : M, f m * f m = Q(m)`, this is the canonical lift of `f` to a morphism of `R`-algebras
from `CliffordAlgebra Q` to `A`.
-/
@[simps symm_apply]
def lift : { f : M →ₗ[R] A // ∀ m, f m * f m = algebraMap _ _ (Q m) } ≃ (CliffordAlgebra Q →ₐ[R] A)
    where
  toFun f :=
    RingQuot.liftAlgHom R
      ⟨TensorAlgebra.lift R (f : M →ₗ[R] A), fun x y (h : Rel Q x y) => by
        induction h
        rw [AlgHom.commutes, AlgHom.map_mul, TensorAlgebra.lift_ι_apply, f.prop]⟩
  invFun F :=
    ⟨F.toLinearMap.comp (ι Q), fun m => by
      rw [LinearMap.comp_apply, AlgHom.toLinearMap_apply, comp_ι_sq_scalar]⟩
  left_inv f := by
    ext x
    -- porting note: removed `simp only` proof which gets stuck simplifying `LinearMap.comp_apply`
    

Proof state:
case a.h
R : Type u_1
inst✝⁴ : CommRing R
M : Type u_2
inst✝³ : AddCommGroup M
inst✝² : Module R M
Q : QuadraticForm R M
n : ℕ
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
f : { f // ∀ (m : M), f m * f m = (algebraMap R A) (Q m) }
x : M
⊢ ↑((fun F =>
            { val := AlgHom.toLinearMap F ∘ₗ ι Q,
              property :=
                (_ :
                  ∀ (m : M),
                    (AlgHom.toLinearMap F ∘ₗ ι Q) m * (AlgHom.toLinearMap F ∘ₗ ι Q) m = (algebraMap R A) (Q m)) })
          ((fun f =>
              (RingQuot.liftAlgHom R)
                { val := (TensorAlgebra.lift R) ↑f,
                  property :=
                    (_ :
                      ∀ (x y : TensorAlgebra R M),
                        Rel Q x y → ((TensorAlgebra.lift R) ↑f) x = ((TensorAlgebra.lift R) ↑f) y) })
            f))
      x =
    ↑f x

Next tactic:
exact (RingQuot.liftAlgHom_mkAlgHom_apply _ _ _ _).trans (TensorAlgebra.lift_ι_apply _ x)
/-- Given a linear map `f : M →ₗ[R] A` into an `R`-algebra `A`, which satisfies the condition:
`cond : ∀ m : M, f m * f m = Q(m)`, this is the canonical lift of `f` to a morphism of `R`-algebras
from `CliffordAlgebra Q` to `A`.
-/
@[simps symm_apply]
def lift : { f : M →ₗ[R] A // ∀ m, f m * f m = algebraMap _ _ (Q m) } ≃ (CliffordAlgebra Q →ₐ[R] A)
    where
  toFun f :=
    RingQuot.liftAlgHom R
      ⟨TensorAlgebra.lift R (f : M →ₗ[R] A), fun x y (h : Rel Q x y) => by
        induction h
        rw [AlgHom.commutes, AlgHom.map_mul, TensorAlgebra.lift_ι_apply, f.prop]⟩
  invFun F :=
    ⟨F.toLinearMap.comp (ι Q), fun m => by
      rw [LinearMap.comp_apply, AlgHom.toLinearMap_apply, comp_ι_sq_scalar]⟩
  left_inv f := by
    ext x
    -- porting note: removed `simp only` proof which gets stuck simplifying `LinearMap.comp_apply`
    exact (RingQuot.liftAlgHom_mkAlgHom_apply _ _ _ _).trans (TensorAlgebra.lift_ι_apply _ x)
  right_inv F :=
    -- porting note: replaced with proof derived from the one for `TensorAlgebra`
    RingQuot.ringQuot_ext' _ _ _ <|
      TensorAlgebra.hom_ext <|
        LinearMap.ext fun x => by
          

Proof state:
R : Type u_1
inst✝⁴ : CommRing R
M : Type u_2
inst✝³ : AddCommGroup M
inst✝² : Module R M
Q : QuadraticForm R M
n : ℕ
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
F : CliffordAlgebra Q →ₐ[R] A
x : M
⊢ (AlgHom.toLinearMap
          (AlgHom.comp
            ((fun f =>
                (RingQuot.liftAlgHom R)
                  { val := (TensorAlgebra.lift R) ↑f,
                    property :=
                      (_ :
                        ∀ (x y : TensorAlgebra R M),
                          Rel Q x y → ((TensorAlgebra.lift R) ↑f) x = ((TensorAlgebra.lift R) ↑f) y) })
              ((fun F =>
                  { val := AlgHom.toLinearMap F ∘ₗ ι Q,
                    property :=
                      (_ :
                        ∀ (m : M),
                          (AlgHom.toLinearMap F ∘ₗ ι Q) m * (AlgHom.toLinearMap F ∘ₗ ι Q) m = (algebraMap R A) (Q m)) })
                F))
            (RingQuot.mkAlgHom R (Rel Q))) ∘ₗ
        TensorAlgebra.ι R)
      x =
    (AlgHom.toLinearMap (AlgHom.comp F (RingQuot.mkAlgHom R (Rel Q))) ∘ₗ TensorAlgebra.ι R) x

Next tactic:
exact
            (RingQuot.liftAlgHom_mkAlgHom_apply _ _ _ _).trans (TensorAlgebra.lift_ι_apply _ _)
@[simp]
theorem lift_unique (f : M →ₗ[R] A) (cond : ∀ m : M, f m * f m = algebraMap _ _ (Q m))
    (g : CliffordAlgebra Q →ₐ[R] A) : g.toLinearMap.comp (ι Q) = f ↔ g = lift Q ⟨f, cond⟩ := by
  

Proof state:
R : Type u_1
inst✝⁴ : CommRing R
M : Type u_2
inst✝³ : AddCommGroup M
inst✝² : Module R M
Q : QuadraticForm R M
n : ℕ
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
f : M →ₗ[R] A
cond : ∀ (m : M), f m * f m = (algebraMap R A) (Q m)
g : CliffordAlgebra Q →ₐ[R] A
⊢ AlgHom.toLinearMap g ∘ₗ ι Q = f ↔ g = (lift Q) { val := f, property := cond }

Next tactic:
convert (lift Q : _ ≃ (CliffordAlgebra Q →ₐ[R] A)).symm_apply_eq
@[simp]
theorem lift_unique (f : M →ₗ[R] A) (cond : ∀ m : M, f m * f m = algebraMap _ _ (Q m))
    (g : CliffordAlgebra Q →ₐ[R] A) : g.toLinearMap.comp (ι Q) = f ↔ g = lift Q ⟨f, cond⟩ := by
  convert (lift Q : _ ≃ (CliffordAlgebra Q →ₐ[R] A)).symm_apply_eq
  -- porting note: added `Subtype.mk_eq_mk`
  

Proof state:
case h.e'_1.a
R : Type u_1
inst✝⁴ : CommRing R
M : Type u_2
inst✝³ : AddCommGroup M
inst✝² : Module R M
Q : QuadraticForm R M
n : ℕ
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
f : M →ₗ[R] A
cond : ∀ (m : M), f m * f m = (algebraMap R A) (Q m)
g : CliffordAlgebra Q →ₐ[R] A
⊢ AlgHom.toLinearMap g ∘ₗ ι Q = f ↔ (lift Q).symm g = { val := f, property := cond }

Next tactic:
rw [lift_symm_apply, Subtype.mk_eq_mk]
@[simp]
theorem lift_comp_ι (g : CliffordAlgebra Q →ₐ[R] A) :
    lift Q ⟨g.toLinearMap.comp (ι Q), comp_ι_sq_scalar _⟩ = g := by
  -- porting note: removed `rw [lift_symm_apply]; rfl`, changed `convert` to `exact`
  

Proof state:
R : Type u_1
inst✝⁴ : CommRing R
M : Type u_2
inst✝³ : AddCommGroup M
inst✝² : Module R M
Q : QuadraticForm R M
n : ℕ
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
g : CliffordAlgebra Q →ₐ[R] A
⊢ (lift Q)
      { val := AlgHom.toLinearMap g ∘ₗ ι Q,
        property := (_ : ∀ (m : M), g ((ι Q) m) * g ((ι Q) m) = (algebraMap R A) (Q m)) } =
    g

Next tactic:
exact (lift Q : _ ≃ (CliffordAlgebra Q →ₐ[R] A)).apply_symm_apply g
/-- See note [partially-applied ext lemmas]. -/
@[ext high]
theorem hom_ext {A : Type*} [Semiring A] [Algebra R A] {f g : CliffordAlgebra Q →ₐ[R] A} :
    f.toLinearMap.comp (ι Q) = g.toLinearMap.comp (ι Q) → f = g := by
  

Proof state:
R : Type u_1
inst✝⁶ : CommRing R
M : Type u_2
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
Q : QuadraticForm R M
n : ℕ
A✝ : Type u_3
inst✝³ : Semiring A✝
inst✝² : Algebra R A✝
A : Type u_4
inst✝¹ : Semiring A
inst✝ : Algebra R A
f g : CliffordAlgebra Q →ₐ[R] A
⊢ AlgHom.toLinearMap f ∘ₗ ι Q = AlgHom.toLinearMap g ∘ₗ ι Q → f = g

Next tactic:
intro h
/-- See note [partially-applied ext lemmas]. -/
@[ext high]
theorem hom_ext {A : Type*} [Semiring A] [Algebra R A] {f g : CliffordAlgebra Q →ₐ[R] A} :
    f.toLinearMap.comp (ι Q) = g.toLinearMap.comp (ι Q) → f = g := by
  intro h
  

Proof state:
R : Type u_1
inst✝⁶ : CommRing R
M : Type u_2
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
Q : QuadraticForm R M
n : ℕ
A✝ : Type u_3
inst✝³ : Semiring A✝
inst✝² : Algebra R A✝
A : Type u_4
inst✝¹ : Semiring A
inst✝ : Algebra R A
f g : CliffordAlgebra Q →ₐ[R] A
h : AlgHom.toLinearMap f ∘ₗ ι Q = AlgHom.toLinearMap g ∘ₗ ι Q
⊢ f = g

Next tactic:
apply (lift Q).symm.injective
/-- See note [partially-applied ext lemmas]. -/
@[ext high]
theorem hom_ext {A : Type*} [Semiring A] [Algebra R A] {f g : CliffordAlgebra Q →ₐ[R] A} :
    f.toLinearMap.comp (ι Q) = g.toLinearMap.comp (ι Q) → f = g := by
  intro h
  apply (lift Q).symm.injective
  

Proof state:
case a
R : Type u_1
inst✝⁶ : CommRing R
M : Type u_2
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
Q : QuadraticForm R M
n : ℕ
A✝ : Type u_3
inst✝³ : Semiring A✝
inst✝² : Algebra R A✝
A : Type u_4
inst✝¹ : Semiring A
inst✝ : Algebra R A
f g : CliffordAlgebra Q →ₐ[R] A
h : AlgHom.toLinearMap f ∘ₗ ι Q = AlgHom.toLinearMap g ∘ₗ ι Q
⊢ (lift Q).symm f = (lift Q).symm g

Next tactic:
rw [lift_symm_apply, lift_symm_apply]
/-- See note [partially-applied ext lemmas]. -/
@[ext high]
theorem hom_ext {A : Type*} [Semiring A] [Algebra R A] {f g : CliffordAlgebra Q →ₐ[R] A} :
    f.toLinearMap.comp (ι Q) = g.toLinearMap.comp (ι Q) → f = g := by
  intro h
  apply (lift Q).symm.injective
  rw [lift_symm_apply, lift_symm_apply]
  

Proof state:
case a
R : Type u_1
inst✝⁶ : CommRing R
M : Type u_2
inst✝⁵ : AddCommGroup M
inst✝⁴ : Module R M
Q : QuadraticForm R M
n : ℕ
A✝ : Type u_3
inst✝³ : Semiring A✝
inst✝² : Algebra R A✝
A : Type u_4
inst✝¹ : Semiring A
inst✝ : Algebra R A
f g : CliffordAlgebra Q →ₐ[R] A
h : AlgHom.toLinearMap f ∘ₗ ι Q = AlgHom.toLinearMap g ∘ₗ ι Q
⊢ { val := LinearMap.comp (AlgHom.toLinearMap f) (ι Q),
      property :=
        (_ : ∀ (m : M), (AlgHom.toLinearMap f ∘ₗ ι Q) m * (AlgHom.toLinearMap f ∘ₗ ι Q) m = (algebraMap R A) (Q m)) } =
    { val := LinearMap.comp (AlgHom.toLinearMap g) (ι Q),
      property :=
        (_ : ∀ (m : M), (AlgHom.toLinearMap g ∘ₗ ι Q) m * (AlgHom.toLinearMap g ∘ₗ ι Q) m = (algebraMap R A) (Q m)) }

Next tactic:
simp only [h]
/-- If `C` holds for the `algebraMap` of `r : R` into `CliffordAlgebra Q`, the `ι` of `x : M`,
and is preserved under addition and muliplication, then it holds for all of `CliffordAlgebra Q`.

See also the stronger `CliffordAlgebra.left_induction` and `CliffordAlgebra.right_induction`.
-/
@[elab_as_elim]
theorem induction {C : CliffordAlgebra Q → Prop}
    (h_grade0 : ∀ r, C (algebraMap R (CliffordAlgebra Q) r)) (h_grade1 : ∀ x, C (ι Q x))
    (h_mul : ∀ a b, C a → C b → C (a * b)) (h_add : ∀ a b, C a → C b → C (a + b))
    (a : CliffordAlgebra Q) : 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✝⁴ : CommRing R
M : Type u_2
inst✝³ : AddCommGroup M
inst✝² : Module R M
Q : QuadraticForm R M
n : ℕ
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
C : CliffordAlgebra Q → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (CliffordAlgebra Q)) r)
h_grade1 : ∀ (x : M), C ((ι Q) x)
h_mul : ∀ (a b : CliffordAlgebra Q), C a → C b → C (a * b)
h_add : ∀ (a b : CliffordAlgebra Q), C a → C b → C (a + b)
a : CliffordAlgebra Q
⊢ C a

Next tactic:
let s : Subalgebra R (CliffordAlgebra Q) :=
    { carrier := C
      mul_mem' := @h_mul
      add_mem' := @h_add
      algebraMap_mem' := h_grade0 }
/-- If `C` holds for the `algebraMap` of `r : R` into `CliffordAlgebra Q`, the `ι` of `x : M`,
and is preserved under addition and muliplication, then it holds for all of `CliffordAlgebra Q`.

See also the stronger `CliffordAlgebra.left_induction` and `CliffordAlgebra.right_induction`.
-/
@[elab_as_elim]
theorem induction {C : CliffordAlgebra Q → Prop}
    (h_grade0 : ∀ r, C (algebraMap R (CliffordAlgebra Q) r)) (h_grade1 : ∀ x, C (ι Q x))
    (h_mul : ∀ a b, C a → C b → C (a * b)) (h_add : ∀ a b, C a → C b → C (a + b))
    (a : CliffordAlgebra Q) : C a := by
  -- the arguments are enough to construct a subalgebra, and a mapping into it from M
  let s : Subalgebra R (CliffordAlgebra Q) :=
    { 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✝⁴ : CommRing R
M : Type u_2
inst✝³ : AddCommGroup M
inst✝² : Module R M
Q : QuadraticForm R M
n : ℕ
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
C : CliffordAlgebra Q → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (CliffordAlgebra Q)) r)
h_grade1 : ∀ (x : M), C ((ι Q) x)
h_mul : ∀ (a b : CliffordAlgebra Q), C a → C b → C (a * b)
h_add : ∀ (a b : CliffordAlgebra Q), C a → C b → C (a + b)
a : CliffordAlgebra Q
s : Subalgebra R (CliffordAlgebra Q) :=
  {
    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:
letI h : AddCommMonoid s := inferInstanceAs (AddCommMonoid (Subalgebra.toSubmodule s))
/-- If `C` holds for the `algebraMap` of `r : R` into `CliffordAlgebra Q`, the `ι` of `x : M`,
and is preserved under addition and muliplication, then it holds for all of `CliffordAlgebra Q`.

See also the stronger `CliffordAlgebra.left_induction` and `CliffordAlgebra.right_induction`.
-/
@[elab_as_elim]
theorem induction {C : CliffordAlgebra Q → Prop}
    (h_grade0 : ∀ r, C (algebraMap R (CliffordAlgebra Q) r)) (h_grade1 : ∀ x, C (ι Q x))
    (h_mul : ∀ a b, C a → C b → C (a * b)) (h_add : ∀ a b, C a → C b → C (a + b))
    (a : CliffordAlgebra Q) : C a := by
  -- the arguments are enough to construct a subalgebra, and a mapping into it from M
  let s : Subalgebra R (CliffordAlgebra Q) :=
    { carrier := C
      mul_mem' := @h_mul
      add_mem' := @h_add
      algebraMap_mem' := h_grade0 }
  -- porting note: Added `h`. `h` is needed for `of`.
  letI h : AddCommMonoid s := inferInstanceAs (AddCommMonoid (Subalgebra.toSubmodule s))
  

Proof state:
R : Type u_1
inst✝⁴ : CommRing R
M : Type u_2
inst✝³ : AddCommGroup M
inst✝² : Module R M
Q : QuadraticForm R M
n : ℕ
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
C : CliffordAlgebra Q → Prop
h_grade0 : ∀ (r : R), C ((algebraMap R (CliffordAlgebra Q)) r)
h_grade1 : ∀ (x : M), C ((ι Q) x)
h_mul : ∀ (a b : CliffordAlgebra Q), C a → C b → C (a * b)
h_add : ∀ (a b : CliffordAlgebra Q), C a → C b → C (a + b)
a : CliffordAlgebra Q
s : Subalgebra R (CliffordAlgebra Q) :=
  {
    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 : { f : M →ₗ[R] s // ∀ m, f m * f m = algebraMap _ _ (Q m) } :=
    ⟨(ι Q).codRestrict (Subalgebra.toSubmodule s) h_grade1, fun m => Subtype.eq <| ι_sq_scalar Q m⟩