l3lab/ntp-mathlib huggingface dataset:
theorem FormallyUnramified.comp [FormallyUnramified R A] [FormallyUnramified A B] :
    FormallyUnramified R B := by
  constructor
  intro C _ _ I hI f₁ f₂ e
  have e' :=
    FormallyUnramified.lift_unique I ⟨2, hI⟩ (f₁.comp <| IsScalarTower.toAlgHom R A B)
      (f₂.comp <| IsScalarTower.toAlgHom R A B) (by rw [← AlgHom.comp_assoc, e, AlgHom.comp_assoc])
  letI := (f₁.comp (IsScalarTower.toAlgHom R A B)).toRingHom.toAlgebra
  

Proof state:
case comp_injective
R : Type u
inst✝¹⁰ : CommSemiring R
A : Type u
inst✝⁹ : CommSemiring A
inst✝⁸ : Algebra R A
B : Type u
inst✝⁷ : Semiring B
inst✝⁶ : Algebra R B
inst✝⁵ : Algebra A B
inst✝⁴ : IsScalarTower R A B
inst✝³ : FormallyUnramified R A
inst✝² : FormallyUnramified A B
C : Type u
inst✝¹ : CommRing C
inst✝ : Algebra R C
I : Ideal C
hI : I ^ 2 = ⊥
f₁ f₂ : B →ₐ[R] C
e : AlgHom.comp (Ideal.Quotient.mkₐ R I) f₁ = AlgHom.comp (Ideal.Quotient.mkₐ R I) f₂
e' : AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B) = AlgHom.comp f₂ (IsScalarTower.toAlgHom R A B)
this : Algebra A C := RingHom.toAlgebra ↑(AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B))
⊢ f₁ = f₂

Next tactic:
let F₁ : B →ₐ[A] C := { f₁ with commutes' := fun r => rfl }
theorem FormallyUnramified.comp [FormallyUnramified R A] [FormallyUnramified A B] :
    FormallyUnramified R B := by
  constructor
  intro C _ _ I hI f₁ f₂ e
  have e' :=
    FormallyUnramified.lift_unique I ⟨2, hI⟩ (f₁.comp <| IsScalarTower.toAlgHom R A B)
      (f₂.comp <| IsScalarTower.toAlgHom R A B) (by rw [← AlgHom.comp_assoc, e, AlgHom.comp_assoc])
  letI := (f₁.comp (IsScalarTower.toAlgHom R A B)).toRingHom.toAlgebra
  let F₁ : B →ₐ[A] C := { f₁ with commutes' := fun r => rfl }
  

Proof state:
case comp_injective
R : Type u
inst✝¹⁰ : CommSemiring R
A : Type u
inst✝⁹ : CommSemiring A
inst✝⁸ : Algebra R A
B : Type u
inst✝⁷ : Semiring B
inst✝⁶ : Algebra R B
inst✝⁵ : Algebra A B
inst✝⁴ : IsScalarTower R A B
inst✝³ : FormallyUnramified R A
inst✝² : FormallyUnramified A B
C : Type u
inst✝¹ : CommRing C
inst✝ : Algebra R C
I : Ideal C
hI : I ^ 2 = ⊥
f₁ f₂ : B →ₐ[R] C
e : AlgHom.comp (Ideal.Quotient.mkₐ R I) f₁ = AlgHom.comp (Ideal.Quotient.mkₐ R I) f₂
e' : AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B) = AlgHom.comp f₂ (IsScalarTower.toAlgHom R A B)
this : Algebra A C := RingHom.toAlgebra ↑(AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B))
F₁ : B →ₐ[A] C :=
  { toRingHom := ↑f₁,
    commutes' :=
      (_ : ∀ (r : A), OneHom.toFun (↑↑↑f₁) ((algebraMap A B) r) = OneHom.toFun (↑↑↑f₁) ((algebraMap A B) r)) }
⊢ f₁ = f₂

Next tactic:
let F₂ : B →ₐ[A] C := { f₂ with commutes' := AlgHom.congr_fun e'.symm }
theorem FormallyUnramified.comp [FormallyUnramified R A] [FormallyUnramified A B] :
    FormallyUnramified R B := by
  constructor
  intro C _ _ I hI f₁ f₂ e
  have e' :=
    FormallyUnramified.lift_unique I ⟨2, hI⟩ (f₁.comp <| IsScalarTower.toAlgHom R A B)
      (f₂.comp <| IsScalarTower.toAlgHom R A B) (by rw [← AlgHom.comp_assoc, e, AlgHom.comp_assoc])
  letI := (f₁.comp (IsScalarTower.toAlgHom R A B)).toRingHom.toAlgebra
  let F₁ : B →ₐ[A] C := { f₁ with commutes' := fun r => rfl }
  let F₂ : B →ₐ[A] C := { f₂ with commutes' := AlgHom.congr_fun e'.symm }
  

Proof state:
case comp_injective
R : Type u
inst✝¹⁰ : CommSemiring R
A : Type u
inst✝⁹ : CommSemiring A
inst✝⁸ : Algebra R A
B : Type u
inst✝⁷ : Semiring B
inst✝⁶ : Algebra R B
inst✝⁵ : Algebra A B
inst✝⁴ : IsScalarTower R A B
inst✝³ : FormallyUnramified R A
inst✝² : FormallyUnramified A B
C : Type u
inst✝¹ : CommRing C
inst✝ : Algebra R C
I : Ideal C
hI : I ^ 2 = ⊥
f₁ f₂ : B →ₐ[R] C
e : AlgHom.comp (Ideal.Quotient.mkₐ R I) f₁ = AlgHom.comp (Ideal.Quotient.mkₐ R I) f₂
e' : AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B) = AlgHom.comp f₂ (IsScalarTower.toAlgHom R A B)
this : Algebra A C := RingHom.toAlgebra ↑(AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B))
F₁ : B →ₐ[A] C :=
  { toRingHom := ↑f₁,
    commutes' :=
      (_ : ∀ (r : A), OneHom.toFun (↑↑↑f₁) ((algebraMap A B) r) = OneHom.toFun (↑↑↑f₁) ((algebraMap A B) r)) }
F₂ : B →ₐ[A] C :=
  { toRingHom := ↑f₂,
    commutes' :=
      (_ :
        ∀ (x : A),
          (AlgHom.comp f₂ (IsScalarTower.toAlgHom R A B)) x = (AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B)) x) }
⊢ f₁ = f₂

Next tactic:
ext1 x
theorem FormallyUnramified.comp [FormallyUnramified R A] [FormallyUnramified A B] :
    FormallyUnramified R B := by
  constructor
  intro C _ _ I hI f₁ f₂ e
  have e' :=
    FormallyUnramified.lift_unique I ⟨2, hI⟩ (f₁.comp <| IsScalarTower.toAlgHom R A B)
      (f₂.comp <| IsScalarTower.toAlgHom R A B) (by rw [← AlgHom.comp_assoc, e, AlgHom.comp_assoc])
  letI := (f₁.comp (IsScalarTower.toAlgHom R A B)).toRingHom.toAlgebra
  let F₁ : B →ₐ[A] C := { f₁ with commutes' := fun r => rfl }
  let F₂ : B →ₐ[A] C := { f₂ with commutes' := AlgHom.congr_fun e'.symm }
  ext1 x
  

Proof state:
case comp_injective.H
R : Type u
inst✝¹⁰ : CommSemiring R
A : Type u
inst✝⁹ : CommSemiring A
inst✝⁸ : Algebra R A
B : Type u
inst✝⁷ : Semiring B
inst✝⁶ : Algebra R B
inst✝⁵ : Algebra A B
inst✝⁴ : IsScalarTower R A B
inst✝³ : FormallyUnramified R A
inst✝² : FormallyUnramified A B
C : Type u
inst✝¹ : CommRing C
inst✝ : Algebra R C
I : Ideal C
hI : I ^ 2 = ⊥
f₁ f₂ : B →ₐ[R] C
e : AlgHom.comp (Ideal.Quotient.mkₐ R I) f₁ = AlgHom.comp (Ideal.Quotient.mkₐ R I) f₂
e' : AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B) = AlgHom.comp f₂ (IsScalarTower.toAlgHom R A B)
this : Algebra A C := RingHom.toAlgebra ↑(AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B))
F₁ : B →ₐ[A] C :=
  { toRingHom := ↑f₁,
    commutes' :=
      (_ : ∀ (r : A), OneHom.toFun (↑↑↑f₁) ((algebraMap A B) r) = OneHom.toFun (↑↑↑f₁) ((algebraMap A B) r)) }
F₂ : B →ₐ[A] C :=
  { toRingHom := ↑f₂,
    commutes' :=
      (_ :
        ∀ (x : A),
          (AlgHom.comp f₂ (IsScalarTower.toAlgHom R A B)) x = (AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B)) x) }
x : B
⊢ f₁ x = f₂ x

Next tactic:
change F₁ x = F₂ x
theorem FormallyUnramified.comp [FormallyUnramified R A] [FormallyUnramified A B] :
    FormallyUnramified R B := by
  constructor
  intro C _ _ I hI f₁ f₂ e
  have e' :=
    FormallyUnramified.lift_unique I ⟨2, hI⟩ (f₁.comp <| IsScalarTower.toAlgHom R A B)
      (f₂.comp <| IsScalarTower.toAlgHom R A B) (by rw [← AlgHom.comp_assoc, e, AlgHom.comp_assoc])
  letI := (f₁.comp (IsScalarTower.toAlgHom R A B)).toRingHom.toAlgebra
  let F₁ : B →ₐ[A] C := { f₁ with commutes' := fun r => rfl }
  let F₂ : B →ₐ[A] C := { f₂ with commutes' := AlgHom.congr_fun e'.symm }
  ext1 x
  change F₁ x = F₂ x
  

Proof state:
case comp_injective.H
R : Type u
inst✝¹⁰ : CommSemiring R
A : Type u
inst✝⁹ : CommSemiring A
inst✝⁸ : Algebra R A
B : Type u
inst✝⁷ : Semiring B
inst✝⁶ : Algebra R B
inst✝⁵ : Algebra A B
inst✝⁴ : IsScalarTower R A B
inst✝³ : FormallyUnramified R A
inst✝² : FormallyUnramified A B
C : Type u
inst✝¹ : CommRing C
inst✝ : Algebra R C
I : Ideal C
hI : I ^ 2 = ⊥
f₁ f₂ : B →ₐ[R] C
e : AlgHom.comp (Ideal.Quotient.mkₐ R I) f₁ = AlgHom.comp (Ideal.Quotient.mkₐ R I) f₂
e' : AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B) = AlgHom.comp f₂ (IsScalarTower.toAlgHom R A B)
this : Algebra A C := RingHom.toAlgebra ↑(AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B))
F₁ : B →ₐ[A] C :=
  { toRingHom := ↑f₁,
    commutes' :=
      (_ : ∀ (r : A), OneHom.toFun (↑↑↑f₁) ((algebraMap A B) r) = OneHom.toFun (↑↑↑f₁) ((algebraMap A B) r)) }
F₂ : B →ₐ[A] C :=
  { toRingHom := ↑f₂,
    commutes' :=
      (_ :
        ∀ (x : A),
          (AlgHom.comp f₂ (IsScalarTower.toAlgHom R A B)) x = (AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B)) x) }
x : B
⊢ F₁ x = F₂ x

Next tactic:
congr
theorem FormallyUnramified.comp [FormallyUnramified R A] [FormallyUnramified A B] :
    FormallyUnramified R B := by
  constructor
  intro C _ _ I hI f₁ f₂ e
  have e' :=
    FormallyUnramified.lift_unique I ⟨2, hI⟩ (f₁.comp <| IsScalarTower.toAlgHom R A B)
      (f₂.comp <| IsScalarTower.toAlgHom R A B) (by rw [← AlgHom.comp_assoc, e, AlgHom.comp_assoc])
  letI := (f₁.comp (IsScalarTower.toAlgHom R A B)).toRingHom.toAlgebra
  let F₁ : B →ₐ[A] C := { f₁ with commutes' := fun r => rfl }
  let F₂ : B →ₐ[A] C := { f₂ with commutes' := AlgHom.congr_fun e'.symm }
  ext1 x
  change F₁ x = F₂ x
  congr
  

Proof state:
case comp_injective.H.e_a
R : Type u
inst✝¹⁰ : CommSemiring R
A : Type u
inst✝⁹ : CommSemiring A
inst✝⁸ : Algebra R A
B : Type u
inst✝⁷ : Semiring B
inst✝⁶ : Algebra R B
inst✝⁵ : Algebra A B
inst✝⁴ : IsScalarTower R A B
inst✝³ : FormallyUnramified R A
inst✝² : FormallyUnramified A B
C : Type u
inst✝¹ : CommRing C
inst✝ : Algebra R C
I : Ideal C
hI : I ^ 2 = ⊥
f₁ f₂ : B →ₐ[R] C
e : AlgHom.comp (Ideal.Quotient.mkₐ R I) f₁ = AlgHom.comp (Ideal.Quotient.mkₐ R I) f₂
e' : AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B) = AlgHom.comp f₂ (IsScalarTower.toAlgHom R A B)
this : Algebra A C := RingHom.toAlgebra ↑(AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B))
F₁ : B →ₐ[A] C :=
  { toRingHom := ↑f₁,
    commutes' :=
      (_ : ∀ (r : A), OneHom.toFun (↑↑↑f₁) ((algebraMap A B) r) = OneHom.toFun (↑↑↑f₁) ((algebraMap A B) r)) }
F₂ : B →ₐ[A] C :=
  { toRingHom := ↑f₂,
    commutes' :=
      (_ :
        ∀ (x : A),
          (AlgHom.comp f₂ (IsScalarTower.toAlgHom R A B)) x = (AlgHom.comp f₁ (IsScalarTower.toAlgHom R A B)) x) }
x : B
⊢ F₁ = F₂

Next tactic:
exact FormallyUnramified.ext I ⟨2, hI⟩ (AlgHom.congr_fun e)
theorem FormallyUnramified.of_comp [FormallyUnramified R B] : FormallyUnramified A B := by
  

Proof state:
R : Type u
inst✝⁷ : CommSemiring R
A : Type u
inst✝⁶ : CommSemiring A
inst✝⁵ : Algebra R A
B : Type u
inst✝⁴ : Semiring B
inst✝³ : Algebra R B
inst✝² : Algebra A B
inst✝¹ : IsScalarTower R A B
inst✝ : FormallyUnramified R B
⊢ FormallyUnramified A B

Next tactic:
constructor
theorem FormallyUnramified.of_comp [FormallyUnramified R B] : FormallyUnramified A B := by
  constructor
  

Proof state:
case comp_injective
R : Type u
inst✝⁷ : CommSemiring R
A : Type u
inst✝⁶ : CommSemiring A
inst✝⁵ : Algebra R A
B : Type u
inst✝⁴ : Semiring B
inst✝³ : Algebra R B
inst✝² : Algebra A B
inst✝¹ : IsScalarTower R A B
inst✝ : FormallyUnramified R B
⊢ ∀ ⦃B_1 : Type u⦄ [inst : CommRing B_1] [inst_1 : Algebra A B_1] (I : Ideal B_1),
    I ^ 2 = ⊥ → Function.Injective (AlgHom.comp (Ideal.Quotient.mkₐ A I))

Next tactic:
intro Q _ _ I e f₁ f₂ e'
theorem FormallyUnramified.of_comp [FormallyUnramified R B] : FormallyUnramified A B := by
  constructor
  intro Q _ _ I e f₁ f₂ e'
  

Proof state:
case comp_injective
R : Type u
inst✝⁹ : CommSemiring R
A : Type u
inst✝⁸ : CommSemiring A
inst✝⁷ : Algebra R A
B : Type u
inst✝⁶ : Semiring B
inst✝⁵ : Algebra R B
inst✝⁴ : Algebra A B
inst✝³ : IsScalarTower R A B
inst✝² : FormallyUnramified R B
Q : Type u
inst✝¹ : CommRing Q
inst✝ : Algebra A Q
I : Ideal Q
e : I ^ 2 = ⊥
f₁ f₂ : B →ₐ[A] Q
e' : AlgHom.comp (Ideal.Quotient.mkₐ A I) f₁ = AlgHom.comp (Ideal.Quotient.mkₐ A I) f₂
⊢ f₁ = f₂

Next tactic:
letI := ((algebraMap A Q).comp (algebraMap R A)).toAlgebra
theorem FormallyUnramified.of_comp [FormallyUnramified R B] : FormallyUnramified A B := by
  constructor
  intro Q _ _ I e f₁ f₂ e'
  letI := ((algebraMap A Q).comp (algebraMap R A)).toAlgebra
  

Proof state:
case comp_injective
R : Type u
inst✝⁹ : CommSemiring R
A : Type u
inst✝⁸ : CommSemiring A
inst✝⁷ : Algebra R A
B : Type u
inst✝⁶ : Semiring B
inst✝⁵ : Algebra R B
inst✝⁴ : Algebra A B
inst✝³ : IsScalarTower R A B
inst✝² : FormallyUnramified R B
Q : Type u
inst✝¹ : CommRing Q
inst✝ : Algebra A Q
I : Ideal Q
e : I ^ 2 = ⊥
f₁ f₂ : B →ₐ[A] Q
e' : AlgHom.comp (Ideal.Quotient.mkₐ A I) f₁ = AlgHom.comp (Ideal.Quotient.mkₐ A I) f₂
this : Algebra R Q := RingHom.toAlgebra (RingHom.comp (algebraMap A Q) (algebraMap R A))
⊢ f₁ = f₂

Next tactic:
letI : IsScalarTower R A Q := IsScalarTower.of_algebraMap_eq' rfl
theorem FormallyUnramified.of_comp [FormallyUnramified R B] : FormallyUnramified A B := by
  constructor
  intro Q _ _ I e f₁ f₂ e'
  letI := ((algebraMap A Q).comp (algebraMap R A)).toAlgebra
  letI : IsScalarTower R A Q := IsScalarTower.of_algebraMap_eq' rfl
  

Proof state:
case comp_injective
R : Type u
inst✝⁹ : CommSemiring R
A : Type u
inst✝⁸ : CommSemiring A
inst✝⁷ : Algebra R A
B : Type u
inst✝⁶ : Semiring B
inst✝⁵ : Algebra R B
inst✝⁴ : Algebra A B
inst✝³ : IsScalarTower R A B
inst✝² : FormallyUnramified R B
Q : Type u
inst✝¹ : CommRing Q
inst✝ : Algebra A Q
I : Ideal Q
e : I ^ 2 = ⊥
f₁ f₂ : B →ₐ[A] Q
e' : AlgHom.comp (Ideal.Quotient.mkₐ A I) f₁ = AlgHom.comp (Ideal.Quotient.mkₐ A I) f₂
this✝ : Algebra R Q := RingHom.toAlgebra (RingHom.comp (algebraMap A Q) (algebraMap R A))
this : IsScalarTower R A Q := IsScalarTower.of_algebraMap_eq' rfl
⊢ f₁ = f₂

Next tactic:
refine' AlgHom.restrictScalars_injective R _
theorem FormallyUnramified.of_comp [FormallyUnramified R B] : FormallyUnramified A B := by
  constructor
  intro Q _ _ I e f₁ f₂ e'
  letI := ((algebraMap A Q).comp (algebraMap R A)).toAlgebra
  letI : IsScalarTower R A Q := IsScalarTower.of_algebraMap_eq' rfl
  refine' AlgHom.restrictScalars_injective R _
  

Proof state:
case comp_injective
R : Type u
inst✝⁹ : CommSemiring R
A : Type u
inst✝⁸ : CommSemiring A
inst✝⁷ : Algebra R A
B : Type u
inst✝⁶ : Semiring B
inst✝⁵ : Algebra R B
inst✝⁴ : Algebra A B
inst✝³ : IsScalarTower R A B
inst✝² : FormallyUnramified R B
Q : Type u
inst✝¹ : CommRing Q
inst✝ : Algebra A Q
I : Ideal Q
e : I ^ 2 = ⊥
f₁ f₂ : B →ₐ[A] Q
e' : AlgHom.comp (Ideal.Quotient.mkₐ A I) f₁ = AlgHom.comp (Ideal.Quotient.mkₐ A I) f₂
this✝ : Algebra R Q := RingHom.toAlgebra (RingHom.comp (algebraMap A Q) (algebraMap R A))
this : IsScalarTower R A Q := IsScalarTower.of_algebraMap_eq' rfl
⊢ AlgHom.restrictScalars R f₁ = AlgHom.restrictScalars R f₂

Next tactic:
refine' FormallyUnramified.ext I ⟨2, e⟩ _
theorem FormallyUnramified.of_comp [FormallyUnramified R B] : FormallyUnramified A B := by
  constructor
  intro Q _ _ I e f₁ f₂ e'
  letI := ((algebraMap A Q).comp (algebraMap R A)).toAlgebra
  letI : IsScalarTower R A Q := IsScalarTower.of_algebraMap_eq' rfl
  refine' AlgHom.restrictScalars_injective R _
  refine' FormallyUnramified.ext I ⟨2, e⟩ _
  

Proof state:
case comp_injective
R : Type u
inst✝⁹ : CommSemiring R
A : Type u
inst✝⁸ : CommSemiring A
inst✝⁷ : Algebra R A
B : Type u
inst✝⁶ : Semiring B
inst✝⁵ : Algebra R B
inst✝⁴ : Algebra A B
inst✝³ : IsScalarTower R A B
inst✝² : FormallyUnramified R B
Q : Type u
inst✝¹ : CommRing Q
inst✝ : Algebra A Q
I : Ideal Q
e : I ^ 2 = ⊥
f₁ f₂ : B →ₐ[A] Q
e' : AlgHom.comp (Ideal.Quotient.mkₐ A I) f₁ = AlgHom.comp (Ideal.Quotient.mkₐ A I) f₂
this✝ : Algebra R Q := RingHom.toAlgebra (RingHom.comp (algebraMap A Q) (algebraMap R A))
this : IsScalarTower R A Q := IsScalarTower.of_algebraMap_eq' rfl
⊢ ∀ (x : B),
    (Ideal.Quotient.mk I) ((AlgHom.restrictScalars R f₁) x) = (Ideal.Quotient.mk I) ((AlgHom.restrictScalars R f₂) x)

Next tactic:
intro x
theorem FormallyUnramified.of_comp [FormallyUnramified R B] : FormallyUnramified A B := by
  constructor
  intro Q _ _ I e f₁ f₂ e'
  letI := ((algebraMap A Q).comp (algebraMap R A)).toAlgebra
  letI : IsScalarTower R A Q := IsScalarTower.of_algebraMap_eq' rfl
  refine' AlgHom.restrictScalars_injective R _
  refine' FormallyUnramified.ext I ⟨2, e⟩ _
  intro x
  

Proof state:
case comp_injective
R : Type u
inst✝⁹ : CommSemiring R
A : Type u
inst✝⁸ : CommSemiring A
inst✝⁷ : Algebra R A
B : Type u
inst✝⁶ : Semiring B
inst✝⁵ : Algebra R B
inst✝⁴ : Algebra A B
inst✝³ : IsScalarTower R A B
inst✝² : FormallyUnramified R B
Q : Type u
inst✝¹ : CommRing Q
inst✝ : Algebra A Q
I : Ideal Q
e : I ^ 2 = ⊥
f₁ f₂ : B →ₐ[A] Q
e' : AlgHom.comp (Ideal.Quotient.mkₐ A I) f₁ = AlgHom.comp (Ideal.Quotient.mkₐ A I) f₂
this✝ : Algebra R Q := RingHom.toAlgebra (RingHom.comp (algebraMap A Q) (algebraMap R A))
this : IsScalarTower R A Q := IsScalarTower.of_algebraMap_eq' rfl
x : B
⊢ (Ideal.Quotient.mk I) ((AlgHom.restrictScalars R f₁) x) = (Ideal.Quotient.mk I) ((AlgHom.restrictScalars R f₂) x)

Next tactic:
exact AlgHom.congr_fun e' x
theorem FormallySmooth.of_split [FormallySmooth R P] (g : A →ₐ[R] P ⧸ (RingHom.ker f.toRingHom) ^ 2)
    (hg : f.kerSquareLift.comp g = AlgHom.id R A) : FormallySmooth R A := by
  

Proof state:
R S : Type u
inst✝⁶ : CommRing R
inst✝⁵ : CommSemiring S
P A : Type u
inst✝⁴ : CommRing A
inst✝³ : Algebra R A
inst✝² : CommRing P
inst✝¹ : Algebra R P
I : Ideal P
f : P →ₐ[R] A
hf : Function.Surjective ⇑f
inst✝ : FormallySmooth R P
g : A →ₐ[R] P ⧸ RingHom.ker ↑f ^ 2
hg : AlgHom.comp (AlgHom.kerSquareLift f) g = AlgHom.id R A
⊢ FormallySmooth R A

Next tactic:
constructor
theorem FormallySmooth.of_split [FormallySmooth R P] (g : A →ₐ[R] P ⧸ (RingHom.ker f.toRingHom) ^ 2)
    (hg : f.kerSquareLift.comp g = AlgHom.id R A) : FormallySmooth R A := by
  constructor
  

Proof state:
case comp_surjective
R S : Type u
inst✝⁶ : CommRing R
inst✝⁵ : CommSemiring S
P A : Type u
inst✝⁴ : CommRing A
inst✝³ : Algebra R A
inst✝² : CommRing P
inst✝¹ : Algebra R P
I : Ideal P
f : P →ₐ[R] A
hf : Function.Surjective ⇑f
inst✝ : FormallySmooth R P
g : A →ₐ[R] P ⧸ RingHom.ker ↑f ^ 2
hg : AlgHom.comp (AlgHom.kerSquareLift f) g = AlgHom.id R A
⊢ ∀ ⦃B : Type u⦄ [inst : CommRing B] [inst_1 : Algebra R B] (I : Ideal B),
    I ^ 2 = ⊥ → Function.Surjective (AlgHom.comp (Ideal.Quotient.mkₐ R I))

Next tactic:
intro C _ _ I hI i
theorem FormallySmooth.of_split [FormallySmooth R P] (g : A →ₐ[R] P ⧸ (RingHom.ker f.toRingHom) ^ 2)
    (hg : f.kerSquareLift.comp g = AlgHom.id R A) : FormallySmooth R A := by
  constructor
  intro C _ _ I hI i
  

Proof state:
case comp_surjective
R S : Type u
inst✝⁸ : CommRing R
inst✝⁷ : CommSemiring S
P A : Type u
inst✝⁶ : CommRing A
inst✝⁵ : Algebra R A
inst✝⁴ : CommRing P
inst✝³ : Algebra R P
I✝ : Ideal P
f : P →ₐ[R] A
hf : Function.Surjective ⇑f
inst✝² : FormallySmooth R P
g : A →ₐ[R] P ⧸ RingHom.ker ↑f ^ 2
hg : AlgHom.comp (AlgHom.kerSquareLift f) g = AlgHom.id R A
C : Type u
inst✝¹ : CommRing C
inst✝ : Algebra R C
I : Ideal C
hI : I ^ 2 = ⊥
i : A →ₐ[R] C ⧸ I
⊢ ∃ a, AlgHom.comp (Ideal.Quotient.mkₐ R I) a = i

Next tactic:
let l : P ⧸ (RingHom.ker f.toRingHom) ^ 2 →ₐ[R] C := by
    refine' Ideal.Quotient.liftₐ _ (FormallySmooth.lift I ⟨2, hI⟩ (i.comp f)) _
    have : RingHom.ker f ≤ I.comap (FormallySmooth.lift I ⟨2, hI⟩ (i.comp f)) := by
      rintro x (hx : f x = 0)
      have : _ = i (f x) := (FormallySmooth.mk_lift I ⟨2, hI⟩ (i.comp f) x : _)
      rwa [hx, map_zero, ← Ideal.Quotient.mk_eq_mk, Submodule.Quotient.mk_eq_zero] at this
    intro x hx
    have := (Ideal.pow_right_mono this 2).trans (Ideal.le_comap_pow _ 2) hx
    rwa [hI] at this
theorem FormallySmooth.of_split [FormallySmooth R P] (g : A →ₐ[R] P ⧸ (RingHom.ker f.toRingHom) ^ 2)
    (hg : f.kerSquareLift.comp g = AlgHom.id R A) : FormallySmooth R A := by
  constructor
  intro C _ _ I hI i
  let l : P ⧸ (RingHom.ker f.toRingHom) ^ 2 →ₐ[R] C := by
    

Proof state:
R S : Type u
inst✝⁸ : CommRing R
inst✝⁷ : CommSemiring S
P A : Type u
inst✝⁶ : CommRing A
inst✝⁵ : Algebra R A
inst✝⁴ : CommRing P
inst✝³ : Algebra R P
I✝ : Ideal P
f : P →ₐ[R] A
hf : Function.Surjective ⇑f
inst✝² : FormallySmooth R P
g : A →ₐ[R] P ⧸ RingHom.ker ↑f ^ 2
hg : AlgHom.comp (AlgHom.kerSquareLift f) g = AlgHom.id R A
C : Type u
inst✝¹ : CommRing C
inst✝ : Algebra R C
I : Ideal C
hI : I ^ 2 = ⊥
i : A →ₐ[R] C ⧸ I
⊢ P ⧸ RingHom.ker ↑f ^ 2 →ₐ[R] C

Next tactic:
refine' Ideal.Quotient.liftₐ _ (FormallySmooth.lift I ⟨2, hI⟩ (i.comp f)) _
theorem FormallySmooth.of_split [FormallySmooth R P] (g : A →ₐ[R] P ⧸ (RingHom.ker f.toRingHom) ^ 2)
    (hg : f.kerSquareLift.comp g = AlgHom.id R A) : FormallySmooth R A := by
  constructor
  intro C _ _ I hI i
  let l : P ⧸ (RingHom.ker f.toRingHom) ^ 2 →ₐ[R] C := by
    refine' Ideal.Quotient.liftₐ _ (FormallySmooth.lift I ⟨2, hI⟩ (i.comp f)) _
    

Proof state:
R S : Type u
inst✝⁸ : CommRing R
inst✝⁷ : CommSemiring S
P A : Type u
inst✝⁶ : CommRing A
inst✝⁵ : Algebra R A
inst✝⁴ : CommRing P
inst✝³ : Algebra R P
I✝ : Ideal P
f : P →ₐ[R] A
hf : Function.Surjective ⇑f
inst✝² : FormallySmooth R P
g : A →ₐ[R] P ⧸ RingHom.ker ↑f ^ 2
hg : AlgHom.comp (AlgHom.kerSquareLift f) g = AlgHom.id R A
C : Type u
inst✝¹ : CommRing C
inst✝ : Algebra R C
I : Ideal C
hI : I ^ 2 = ⊥
i : A →ₐ[R] C ⧸ I
⊢ ∀ a ∈ RingHom.ker ↑f ^ 2, (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) a = 0

Next tactic:
have : RingHom.ker f ≤ I.comap (FormallySmooth.lift I ⟨2, hI⟩ (i.comp f)) := by
      rintro x (hx : f x = 0)
      have : _ = i (f x) := (FormallySmooth.mk_lift I ⟨2, hI⟩ (i.comp f) x : _)
      rwa [hx, map_zero, ← Ideal.Quotient.mk_eq_mk, Submodule.Quotient.mk_eq_zero] at this
theorem FormallySmooth.of_split [FormallySmooth R P] (g : A →ₐ[R] P ⧸ (RingHom.ker f.toRingHom) ^ 2)
    (hg : f.kerSquareLift.comp g = AlgHom.id R A) : FormallySmooth R A := by
  constructor
  intro C _ _ I hI i
  let l : P ⧸ (RingHom.ker f.toRingHom) ^ 2 →ₐ[R] C := by
    refine' Ideal.Quotient.liftₐ _ (FormallySmooth.lift I ⟨2, hI⟩ (i.comp f)) _
    have : RingHom.ker f ≤ I.comap (FormallySmooth.lift I ⟨2, hI⟩ (i.comp f)) := by
      

Proof state:
R S : Type u
inst✝⁸ : CommRing R
inst✝⁷ : CommSemiring S
P A : Type u
inst✝⁶ : CommRing A
inst✝⁵ : Algebra R A
inst✝⁴ : CommRing P
inst✝³ : Algebra R P
I✝ : Ideal P
f : P →ₐ[R] A
hf : Function.Surjective ⇑f
inst✝² : FormallySmooth R P
g : A →ₐ[R] P ⧸ RingHom.ker ↑f ^ 2
hg : AlgHom.comp (AlgHom.kerSquareLift f) g = AlgHom.id R A
C : Type u
inst✝¹ : CommRing C
inst✝ : Algebra R C
I : Ideal C
hI : I ^ 2 = ⊥
i : A →ₐ[R] C ⧸ I
⊢ RingHom.ker f ≤ Ideal.comap (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) I

Next tactic:
rintro x (hx : f x = 0)
theorem FormallySmooth.of_split [FormallySmooth R P] (g : A →ₐ[R] P ⧸ (RingHom.ker f.toRingHom) ^ 2)
    (hg : f.kerSquareLift.comp g = AlgHom.id R A) : FormallySmooth R A := by
  constructor
  intro C _ _ I hI i
  let l : P ⧸ (RingHom.ker f.toRingHom) ^ 2 →ₐ[R] C := by
    refine' Ideal.Quotient.liftₐ _ (FormallySmooth.lift I ⟨2, hI⟩ (i.comp f)) _
    have : RingHom.ker f ≤ I.comap (FormallySmooth.lift I ⟨2, hI⟩ (i.comp f)) := by
      rintro x (hx : f x = 0)
      

Proof state:
R S : Type u
inst✝⁸ : CommRing R
inst✝⁷ : CommSemiring S
P A : Type u
inst✝⁶ : CommRing A
inst✝⁵ : Algebra R A
inst✝⁴ : CommRing P
inst✝³ : Algebra R P
I✝ : Ideal P
f : P →ₐ[R] A
hf : Function.Surjective ⇑f
inst✝² : FormallySmooth R P
g : A →ₐ[R] P ⧸ RingHom.ker ↑f ^ 2
hg : AlgHom.comp (AlgHom.kerSquareLift f) g = AlgHom.id R A
C : Type u
inst✝¹ : CommRing C
inst✝ : Algebra R C
I : Ideal C
hI : I ^ 2 = ⊥
i : A →ₐ[R] C ⧸ I
x : P
hx : f x = 0
⊢ x ∈ Ideal.comap (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) I

Next tactic:
have : _ = i (f x) := (FormallySmooth.mk_lift I ⟨2, hI⟩ (i.comp f) x : _)
theorem FormallySmooth.of_split [FormallySmooth R P] (g : A →ₐ[R] P ⧸ (RingHom.ker f.toRingHom) ^ 2)
    (hg : f.kerSquareLift.comp g = AlgHom.id R A) : FormallySmooth R A := by
  constructor
  intro C _ _ I hI i
  let l : P ⧸ (RingHom.ker f.toRingHom) ^ 2 →ₐ[R] C := by
    refine' Ideal.Quotient.liftₐ _ (FormallySmooth.lift I ⟨2, hI⟩ (i.comp f)) _
    have : RingHom.ker f ≤ I.comap (FormallySmooth.lift I ⟨2, hI⟩ (i.comp f)) := by
      rintro x (hx : f x = 0)
      have : _ = i (f x) := (FormallySmooth.mk_lift I ⟨2, hI⟩ (i.comp f) x : _)
      

Proof state:
R S : Type u
inst✝⁸ : CommRing R
inst✝⁷ : CommSemiring S
P A : Type u
inst✝⁶ : CommRing A
inst✝⁵ : Algebra R A
inst✝⁴ : CommRing P
inst✝³ : Algebra R P
I✝ : Ideal P
f : P →ₐ[R] A
hf : Function.Surjective ⇑f
inst✝² : FormallySmooth R P
g : A →ₐ[R] P ⧸ RingHom.ker ↑f ^ 2
hg : AlgHom.comp (AlgHom.kerSquareLift f) g = AlgHom.id R A
C : Type u
inst✝¹ : CommRing C
inst✝ : Algebra R C
I : Ideal C
hI : I ^ 2 = ⊥
i : A →ₐ[R] C ⧸ I
x : P
hx : f x = 0
this : (Ideal.Quotient.mk I) ((lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) x) = i (f x)
⊢ x ∈ Ideal.comap (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) I

Next tactic:
rwa [hx, map_zero, ← Ideal.Quotient.mk_eq_mk, Submodule.Quotient.mk_eq_zero] at this