l3lab/ntp-mathlib huggingface dataset:
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 : _)
      rwa [hx, map_zero, ← Ideal.Quotient.mk_eq_mk, Submodule.Quotient.mk_eq_zero] at this
    

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
this : RingHom.ker f ≤ Ideal.comap (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) I
⊢ ∀ a ∈ RingHom.ker ↑f ^ 2, (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) a = 0

Next tactic:
intro x hx
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 : _)
      rwa [hx, map_zero, ← Ideal.Quotient.mk_eq_mk, Submodule.Quotient.mk_eq_zero] at this
    intro x hx
    

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
this : RingHom.ker f ≤ Ideal.comap (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) I
x : P
hx : x ∈ RingHom.ker ↑f ^ 2
⊢ (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) x = 0

Next tactic:
have := (Ideal.pow_right_mono this 2).trans (Ideal.le_comap_pow _ 2) hx
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 : _)
      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
    

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
this✝ : RingHom.ker f ≤ Ideal.comap (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) I
x : P
hx : x ∈ RingHom.ker ↑f ^ 2
this : x ∈ Ideal.comap (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) (I ^ 2)
⊢ (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) x = 0

Next tactic:
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
    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
  

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
l : P ⧸ RingHom.ker ↑f ^ 2 →ₐ[R] C :=
  Ideal.Quotient.liftₐ (RingHom.ker ↑f ^ 2) (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f))
    (_ : ∀ x ∈ RingHom.ker ↑f ^ 2, x ∈ Ideal.comap (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) ⊥)
⊢ ∃ a, AlgHom.comp (Ideal.Quotient.mkₐ R I) a = i

Next tactic:
have : i.comp f.kerSquareLift = (Ideal.Quotient.mkₐ R _).comp l := by
    apply AlgHom.coe_ringHom_injective
    apply Ideal.Quotient.ringHom_ext
    ext x
    exact (FormallySmooth.mk_lift I ⟨2, hI⟩ (i.comp f) x).symm
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 : _)
      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
  have : i.comp f.kerSquareLift = (Ideal.Quotient.mkₐ R _).comp l := 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
l : P ⧸ RingHom.ker ↑f ^ 2 →ₐ[R] C :=
  Ideal.Quotient.liftₐ (RingHom.ker ↑f ^ 2) (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f))
    (_ : ∀ x ∈ RingHom.ker ↑f ^ 2, x ∈ Ideal.comap (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) ⊥)
⊢ AlgHom.comp i (AlgHom.kerSquareLift f) = AlgHom.comp (Ideal.Quotient.mkₐ R I) l

Next tactic:
apply AlgHom.coe_ringHom_injective
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 : _)
      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
  have : i.comp f.kerSquareLift = (Ideal.Quotient.mkₐ R _).comp l := by
    apply AlgHom.coe_ringHom_injective
    

Proof state:
case a
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
l : P ⧸ RingHom.ker ↑f ^ 2 →ₐ[R] C :=
  Ideal.Quotient.liftₐ (RingHom.ker ↑f ^ 2) (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f))
    (_ : ∀ x ∈ RingHom.ker ↑f ^ 2, x ∈ Ideal.comap (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) ⊥)
⊢ ↑(AlgHom.comp i (AlgHom.kerSquareLift f)) = ↑(AlgHom.comp (Ideal.Quotient.mkₐ R I) l)

Next tactic:
apply Ideal.Quotient.ringHom_ext
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 : _)
      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
  have : i.comp f.kerSquareLift = (Ideal.Quotient.mkₐ R _).comp l := by
    apply AlgHom.coe_ringHom_injective
    apply Ideal.Quotient.ringHom_ext
    

Proof state:
case a.h
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
l : P ⧸ RingHom.ker ↑f ^ 2 →ₐ[R] C :=
  Ideal.Quotient.liftₐ (RingHom.ker ↑f ^ 2) (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f))
    (_ : ∀ x ∈ RingHom.ker ↑f ^ 2, x ∈ Ideal.comap (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) ⊥)
⊢ RingHom.comp (↑(AlgHom.comp i (AlgHom.kerSquareLift f))) (Ideal.Quotient.mk (RingHom.ker ↑f ^ 2)) =
    RingHom.comp (↑(AlgHom.comp (Ideal.Quotient.mkₐ R I) l)) (Ideal.Quotient.mk (RingHom.ker ↑f ^ 2))

Next tactic:
ext 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 : _)
      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
  have : i.comp f.kerSquareLift = (Ideal.Quotient.mkₐ R _).comp l := by
    apply AlgHom.coe_ringHom_injective
    apply Ideal.Quotient.ringHom_ext
    ext x
    

Proof state:
case a.h.a
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
l : P ⧸ RingHom.ker ↑f ^ 2 →ₐ[R] C :=
  Ideal.Quotient.liftₐ (RingHom.ker ↑f ^ 2) (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f))
    (_ : ∀ x ∈ RingHom.ker ↑f ^ 2, x ∈ Ideal.comap (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) ⊥)
x : P
⊢ (RingHom.comp (↑(AlgHom.comp i (AlgHom.kerSquareLift f))) (Ideal.Quotient.mk (RingHom.ker ↑f ^ 2))) x =
    (RingHom.comp (↑(AlgHom.comp (Ideal.Quotient.mkₐ R I) l)) (Ideal.Quotient.mk (RingHom.ker ↑f ^ 2))) x

Next tactic:
exact (FormallySmooth.mk_lift I ⟨2, hI⟩ (i.comp f) x).symm
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 : _)
      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
  have : i.comp f.kerSquareLift = (Ideal.Quotient.mkₐ R _).comp l := by
    apply AlgHom.coe_ringHom_injective
    apply Ideal.Quotient.ringHom_ext
    ext x
    exact (FormallySmooth.mk_lift I ⟨2, hI⟩ (i.comp f) x).symm
  

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
l : P ⧸ RingHom.ker ↑f ^ 2 →ₐ[R] C :=
  Ideal.Quotient.liftₐ (RingHom.ker ↑f ^ 2) (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f))
    (_ : ∀ x ∈ RingHom.ker ↑f ^ 2, x ∈ Ideal.comap (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) ⊥)
this : AlgHom.comp i (AlgHom.kerSquareLift f) = AlgHom.comp (Ideal.Quotient.mkₐ R I) l
⊢ ∃ a, AlgHom.comp (Ideal.Quotient.mkₐ R I) a = i

Next tactic:
exact ⟨l.comp g, by rw [← AlgHom.comp_assoc, ← this, AlgHom.comp_assoc, hg, AlgHom.comp_id]⟩
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 : _)
      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
  have : i.comp f.kerSquareLift = (Ideal.Quotient.mkₐ R _).comp l := by
    apply AlgHom.coe_ringHom_injective
    apply Ideal.Quotient.ringHom_ext
    ext x
    exact (FormallySmooth.mk_lift I ⟨2, hI⟩ (i.comp f) x).symm
  exact ⟨l.comp g, 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
l : P ⧸ RingHom.ker ↑f ^ 2 →ₐ[R] C :=
  Ideal.Quotient.liftₐ (RingHom.ker ↑f ^ 2) (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f))
    (_ : ∀ x ∈ RingHom.ker ↑f ^ 2, x ∈ Ideal.comap (lift I (_ : ∃ n, I ^ n = 0) (AlgHom.comp i f)) ⊥)
this : AlgHom.comp i (AlgHom.kerSquareLift f) = AlgHom.comp (Ideal.Quotient.mkₐ R I) l
⊢ AlgHom.comp (Ideal.Quotient.mkₐ R I) (AlgHom.comp l g) = i

Next tactic:
rw [← AlgHom.comp_assoc, ← this, AlgHom.comp_assoc, hg, AlgHom.comp_id]
/-- Let `P →ₐ[R] A` be a surjection with kernel `J`, and `P` a formally smooth `R`-algebra,
then `A` is formally smooth over `R` iff the surjection `P ⧸ J ^ 2 →ₐ[R] A` has a section.

Geometric intuition: we require that a first-order thickening of `Spec A` inside `Spec P` admits
a retraction. -/
theorem FormallySmooth.iff_split_surjection [FormallySmooth R P] :
    FormallySmooth R A ↔ ∃ g, f.kerSquareLift.comp g = AlgHom.id 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
⊢ FormallySmooth R A ↔ ∃ g, AlgHom.comp (AlgHom.kerSquareLift f) g = AlgHom.id R A

Next tactic:
constructor
/-- Let `P →ₐ[R] A` be a surjection with kernel `J`, and `P` a formally smooth `R`-algebra,
then `A` is formally smooth over `R` iff the surjection `P ⧸ J ^ 2 →ₐ[R] A` has a section.

Geometric intuition: we require that a first-order thickening of `Spec A` inside `Spec P` admits
a retraction. -/
theorem FormallySmooth.iff_split_surjection [FormallySmooth R P] :
    FormallySmooth R A ↔ ∃ g, f.kerSquareLift.comp g = AlgHom.id R A := by
  constructor
  · 

Proof state:
case mp
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
⊢ FormallySmooth R A → ∃ g, AlgHom.comp (AlgHom.kerSquareLift f) g = AlgHom.id R A

Next tactic:
intro
/-- Let `P →ₐ[R] A` be a surjection with kernel `J`, and `P` a formally smooth `R`-algebra,
then `A` is formally smooth over `R` iff the surjection `P ⧸ J ^ 2 →ₐ[R] A` has a section.

Geometric intuition: we require that a first-order thickening of `Spec A` inside `Spec P` admits
a retraction. -/
theorem FormallySmooth.iff_split_surjection [FormallySmooth R P] :
    FormallySmooth R A ↔ ∃ g, f.kerSquareLift.comp g = AlgHom.id R A := by
  constructor
  · intro
    

Proof state:
case mp
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
a✝ : FormallySmooth R A
⊢ ∃ g, AlgHom.comp (AlgHom.kerSquareLift f) g = AlgHom.id R A

Next tactic:
have surj : Function.Surjective f.kerSquareLift := fun x =>
      ⟨Submodule.Quotient.mk (hf x).choose, (hf x).choose_spec⟩
/-- Let `P →ₐ[R] A` be a surjection with kernel `J`, and `P` a formally smooth `R`-algebra,
then `A` is formally smooth over `R` iff the surjection `P ⧸ J ^ 2 →ₐ[R] A` has a section.

Geometric intuition: we require that a first-order thickening of `Spec A` inside `Spec P` admits
a retraction. -/
theorem FormallySmooth.iff_split_surjection [FormallySmooth R P] :
    FormallySmooth R A ↔ ∃ g, f.kerSquareLift.comp g = AlgHom.id R A := by
  constructor
  · intro
    have surj : Function.Surjective f.kerSquareLift := fun x =>
      ⟨Submodule.Quotient.mk (hf x).choose, (hf x).choose_spec⟩
    

Proof state:
case mp
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
a✝ : FormallySmooth R A
surj : Function.Surjective ⇑(AlgHom.kerSquareLift f)
⊢ ∃ g, AlgHom.comp (AlgHom.kerSquareLift f) g = AlgHom.id R A

Next tactic:
have sqz : RingHom.ker f.kerSquareLift.toRingHom ^ 2 = 0 := by
      rw [AlgHom.ker_kerSquareLift, Ideal.cotangentIdeal_square, Ideal.zero_eq_bot]
/-- Let `P →ₐ[R] A` be a surjection with kernel `J`, and `P` a formally smooth `R`-algebra,
then `A` is formally smooth over `R` iff the surjection `P ⧸ J ^ 2 →ₐ[R] A` has a section.

Geometric intuition: we require that a first-order thickening of `Spec A` inside `Spec P` admits
a retraction. -/
theorem FormallySmooth.iff_split_surjection [FormallySmooth R P] :
    FormallySmooth R A ↔ ∃ g, f.kerSquareLift.comp g = AlgHom.id R A := by
  constructor
  · intro
    have surj : Function.Surjective f.kerSquareLift := fun x =>
      ⟨Submodule.Quotient.mk (hf x).choose, (hf x).choose_spec⟩
    have sqz : RingHom.ker f.kerSquareLift.toRingHom ^ 2 = 0 := 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
a✝ : FormallySmooth R A
surj : Function.Surjective ⇑(AlgHom.kerSquareLift f)
⊢ RingHom.ker ↑(AlgHom.kerSquareLift f) ^ 2 = 0

Next tactic:
rw [AlgHom.ker_kerSquareLift, Ideal.cotangentIdeal_square, Ideal.zero_eq_bot]
/-- Let `P →ₐ[R] A` be a surjection with kernel `J`, and `P` a formally smooth `R`-algebra,
then `A` is formally smooth over `R` iff the surjection `P ⧸ J ^ 2 →ₐ[R] A` has a section.

Geometric intuition: we require that a first-order thickening of `Spec A` inside `Spec P` admits
a retraction. -/
theorem FormallySmooth.iff_split_surjection [FormallySmooth R P] :
    FormallySmooth R A ↔ ∃ g, f.kerSquareLift.comp g = AlgHom.id R A := by
  constructor
  · intro
    have surj : Function.Surjective f.kerSquareLift := fun x =>
      ⟨Submodule.Quotient.mk (hf x).choose, (hf x).choose_spec⟩
    have sqz : RingHom.ker f.kerSquareLift.toRingHom ^ 2 = 0 := by
      rw [AlgHom.ker_kerSquareLift, Ideal.cotangentIdeal_square, Ideal.zero_eq_bot]
    

Proof state:
case mp
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
a✝ : FormallySmooth R A
surj : Function.Surjective ⇑(AlgHom.kerSquareLift f)
sqz : RingHom.ker ↑(AlgHom.kerSquareLift f) ^ 2 = 0
⊢ ∃ g, AlgHom.comp (AlgHom.kerSquareLift f) g = AlgHom.id R A

Next tactic:
refine'
      ⟨FormallySmooth.lift _ ⟨2, sqz⟩ (Ideal.quotientKerAlgEquivOfSurjective surj).symm.toAlgHom,
        _⟩
/-- Let `P →ₐ[R] A` be a surjection with kernel `J`, and `P` a formally smooth `R`-algebra,
then `A` is formally smooth over `R` iff the surjection `P ⧸ J ^ 2 →ₐ[R] A` has a section.

Geometric intuition: we require that a first-order thickening of `Spec A` inside `Spec P` admits
a retraction. -/
theorem FormallySmooth.iff_split_surjection [FormallySmooth R P] :
    FormallySmooth R A ↔ ∃ g, f.kerSquareLift.comp g = AlgHom.id R A := by
  constructor
  · intro
    have surj : Function.Surjective f.kerSquareLift := fun x =>
      ⟨Submodule.Quotient.mk (hf x).choose, (hf x).choose_spec⟩
    have sqz : RingHom.ker f.kerSquareLift.toRingHom ^ 2 = 0 := by
      rw [AlgHom.ker_kerSquareLift, Ideal.cotangentIdeal_square, Ideal.zero_eq_bot]
    refine'
      ⟨FormallySmooth.lift _ ⟨2, sqz⟩ (Ideal.quotientKerAlgEquivOfSurjective surj).symm.toAlgHom,
        _⟩
    

Proof state:
case mp
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
a✝ : FormallySmooth R A
surj : Function.Surjective ⇑(AlgHom.kerSquareLift f)
sqz : RingHom.ker ↑(AlgHom.kerSquareLift f) ^ 2 = 0
⊢ AlgHom.comp (AlgHom.kerSquareLift f)
      (lift (RingHom.ker ↑(AlgHom.kerSquareLift f)) (_ : ∃ n, RingHom.ker ↑(AlgHom.kerSquareLift f) ^ n = 0)
        ↑(AlgEquiv.symm (Ideal.quotientKerAlgEquivOfSurjective surj))) =
    AlgHom.id R A

Next tactic:
ext x