l3lab/ntp-mathlib huggingface dataset:
/-- Given a tower of algebras `R → A → B`, and a square-zero `I : Ideal B`, each lift `A →ₐ[R] B`
of the canonical map `A →ₐ[R] B ⧸ I` corresponds to an `R`-derivation from `A` to `I`. -/
def derivationToSquareZeroOfLift (f : A →ₐ[R] B)
    (e : (Ideal.Quotient.mkₐ R I).comp f = IsScalarTower.toAlgHom R A (B ⧸ I)) :
    Derivation R A I := by
  refine'
    { diffToIdealOfQuotientCompEq I f (IsScalarTower.toAlgHom R A B) _ with
      map_one_eq_zero' := _
      leibniz' := _ }
  · rw [e]; ext; rfl
  · ext; change f 1 - algebraMap A B 1 = 0; rw [map_one, map_one, sub_self]
  · intro x y
    let F := diffToIdealOfQuotientCompEq I f (IsScalarTower.toAlgHom R A B) (by rw [e]; ext; rfl)
    have : (f x - algebraMap A B x) * (f y - algebraMap A B y) = 0 := by
      rw [← Ideal.mem_bot, ← hI, pow_two]
      convert Ideal.mul_mem_mul (F x).2 (F y).2 using 1
    ext
    dsimp only [Submodule.coe_add, Submodule.coe_mk, LinearMap.coe_mk,
      diffToIdealOfQuotientCompEq_apply, Submodule.coe_smul_of_tower, IsScalarTower.coe_toAlgHom',
      LinearMap.toFun_eq_coe]
    simp only [map_mul, sub_mul, mul_sub, Algebra.smul_def] at this ⊢
    rw [sub_eq_iff_eq_add, sub_eq_iff_eq_add] at this
    

Proof state:
case refine'_3.a
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
f : A →ₐ[R] B
e : AlgHom.comp (Ideal.Quotient.mkₐ R I) f = IsScalarTower.toAlgHom R A (B ⧸ I)
src✝ : A →ₗ[R] ↥I :=
  diffToIdealOfQuotientCompEq I f (IsScalarTower.toAlgHom R A B)
    (_ : AlgHom.comp (Ideal.Quotient.mkₐ R I) f = AlgHom.comp (Ideal.Quotient.mkₐ R I) (IsScalarTower.toAlgHom R A B))
x y : A
F : A →ₗ[R] ↥I :=
  diffToIdealOfQuotientCompEq I f (IsScalarTower.toAlgHom R A B)
    (_ : AlgHom.comp (Ideal.Quotient.mkₐ R I) f = AlgHom.comp (Ideal.Quotient.mkₐ R I) (IsScalarTower.toAlgHom R A B))
this : f x * f y = 0 + (f x * (algebraMap A B) y - (algebraMap A B) x * (algebraMap A B) y) + (algebraMap A B) x * f y
⊢ ↑((diffToIdealOfQuotientCompEq I f (IsScalarTower.toAlgHom R A B)
            (_ :
              AlgHom.comp (Ideal.Quotient.mkₐ R I) f =
                AlgHom.comp (Ideal.Quotient.mkₐ R I) (IsScalarTower.toAlgHom R A B))).toAddHom
        (x * y)) =
    (algebraMap A B) x *
        ↑((diffToIdealOfQuotientCompEq I f (IsScalarTower.toAlgHom R A B)
                (_ :
                  AlgHom.comp (Ideal.Quotient.mkₐ R I) f =
                    AlgHom.comp (Ideal.Quotient.mkₐ R I) (IsScalarTower.toAlgHom R A B))).toAddHom
            y) +
      (algebraMap A B) y *
        ↑((diffToIdealOfQuotientCompEq I f (IsScalarTower.toAlgHom R A B)
                (_ :
                  AlgHom.comp (Ideal.Quotient.mkₐ R I) f =
                    AlgHom.comp (Ideal.Quotient.mkₐ R I) (IsScalarTower.toAlgHom R A B))).toAddHom
            x)

Next tactic:
simp only [LinearMap.coe_toAddHom, diffToIdealOfQuotientCompEq_apply, map_mul, this,
      IsScalarTower.coe_toAlgHom']
/-- Given a tower of algebras `R → A → B`, and a square-zero `I : Ideal B`, each lift `A →ₐ[R] B`
of the canonical map `A →ₐ[R] B ⧸ I` corresponds to an `R`-derivation from `A` to `I`. -/
def derivationToSquareZeroOfLift (f : A →ₐ[R] B)
    (e : (Ideal.Quotient.mkₐ R I).comp f = IsScalarTower.toAlgHom R A (B ⧸ I)) :
    Derivation R A I := by
  refine'
    { diffToIdealOfQuotientCompEq I f (IsScalarTower.toAlgHom R A B) _ with
      map_one_eq_zero' := _
      leibniz' := _ }
  · rw [e]; ext; rfl
  · ext; change f 1 - algebraMap A B 1 = 0; rw [map_one, map_one, sub_self]
  · intro x y
    let F := diffToIdealOfQuotientCompEq I f (IsScalarTower.toAlgHom R A B) (by rw [e]; ext; rfl)
    have : (f x - algebraMap A B x) * (f y - algebraMap A B y) = 0 := by
      rw [← Ideal.mem_bot, ← hI, pow_two]
      convert Ideal.mul_mem_mul (F x).2 (F y).2 using 1
    ext
    dsimp only [Submodule.coe_add, Submodule.coe_mk, LinearMap.coe_mk,
      diffToIdealOfQuotientCompEq_apply, Submodule.coe_smul_of_tower, IsScalarTower.coe_toAlgHom',
      LinearMap.toFun_eq_coe]
    simp only [map_mul, sub_mul, mul_sub, Algebra.smul_def] at this ⊢
    rw [sub_eq_iff_eq_add, sub_eq_iff_eq_add] at this
    simp only [LinearMap.coe_toAddHom, diffToIdealOfQuotientCompEq_apply, map_mul, this,
      IsScalarTower.coe_toAlgHom']
    

Proof state:
case refine'_3.a
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
f : A →ₐ[R] B
e : AlgHom.comp (Ideal.Quotient.mkₐ R I) f = IsScalarTower.toAlgHom R A (B ⧸ I)
src✝ : A →ₗ[R] ↥I :=
  diffToIdealOfQuotientCompEq I f (IsScalarTower.toAlgHom R A B)
    (_ : AlgHom.comp (Ideal.Quotient.mkₐ R I) f = AlgHom.comp (Ideal.Quotient.mkₐ R I) (IsScalarTower.toAlgHom R A B))
x y : A
F : A →ₗ[R] ↥I :=
  diffToIdealOfQuotientCompEq I f (IsScalarTower.toAlgHom R A B)
    (_ : AlgHom.comp (Ideal.Quotient.mkₐ R I) f = AlgHom.comp (Ideal.Quotient.mkₐ R I) (IsScalarTower.toAlgHom R A B))
this : f x * f y = 0 + (f x * (algebraMap A B) y - (algebraMap A B) x * (algebraMap A B) y) + (algebraMap A B) x * f y
⊢ 0 + (f x * (algebraMap A B) y - (algebraMap A B) x * (algebraMap A B) y) + (algebraMap A B) x * f y -
      (algebraMap A B) x * (algebraMap A B) y =
    (algebraMap A B) x * (f y - (algebraMap A B) y) + (algebraMap A B) y * (f x - (algebraMap A B) x)

Next tactic:
ring
/-- Given a tower of algebras `R → A → B`, and a square-zero `I : Ideal B`, each `R`-derivation
from `A` to `I` corresponds to a lift `A →ₐ[R] B` of the canonical map `A →ₐ[R] B ⧸ I`. -/
@[simps (config := .lemmasOnly)]
def liftOfDerivationToSquareZero (f : Derivation R A I) : A →ₐ[R] B :=
  { ((I.restrictScalars R).subtype.comp f.toLinearMap + (IsScalarTower.toAlgHom R A B).toLinearMap :
      A →ₗ[R] B) with
    toFun := fun x => f x + algebraMap A B x
    map_one' := by 

Proof state:
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
f : Derivation R A ↥I
src✝ : A →ₗ[R] B :=
  Submodule.subtype (Submodule.restrictScalars R I) ∘ₗ ↑f + AlgHom.toLinearMap (IsScalarTower.toAlgHom R A B)
⊢ (fun x => ↑(f x) + (algebraMap A B) x) 1 = 1

Next tactic:
dsimp
/-- Given a tower of algebras `R → A → B`, and a square-zero `I : Ideal B`, each `R`-derivation
from `A` to `I` corresponds to a lift `A →ₐ[R] B` of the canonical map `A →ₐ[R] B ⧸ I`. -/
@[simps (config := .lemmasOnly)]
def liftOfDerivationToSquareZero (f : Derivation R A I) : A →ₐ[R] B :=
  { ((I.restrictScalars R).subtype.comp f.toLinearMap + (IsScalarTower.toAlgHom R A B).toLinearMap :
      A →ₗ[R] B) with
    toFun := fun x => f x + algebraMap A B x
    map_one' := by dsimp; 

Proof state:
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
f : Derivation R A ↥I
src✝ : A →ₗ[R] B :=
  Submodule.subtype (Submodule.restrictScalars R I) ∘ₗ ↑f + AlgHom.toLinearMap (IsScalarTower.toAlgHom R A B)
⊢ ↑(f 1) + (algebraMap A B) 1 = 1

Next tactic:
rw [map_one, f.map_one_eq_zero, Submodule.coe_zero, zero_add]
/-- Given a tower of algebras `R → A → B`, and a square-zero `I : Ideal B`, each `R`-derivation
from `A` to `I` corresponds to a lift `A →ₐ[R] B` of the canonical map `A →ₐ[R] B ⧸ I`. -/
@[simps (config := .lemmasOnly)]
def liftOfDerivationToSquareZero (f : Derivation R A I) : A →ₐ[R] B :=
  { ((I.restrictScalars R).subtype.comp f.toLinearMap + (IsScalarTower.toAlgHom R A B).toLinearMap :
      A →ₗ[R] B) with
    toFun := fun x => f x + algebraMap A B x
    map_one' := by dsimp; rw [map_one, f.map_one_eq_zero, Submodule.coe_zero, zero_add]
    map_mul' := fun x y => by
      

Proof state:
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
f : Derivation R A ↥I
src✝ : A →ₗ[R] B :=
  Submodule.subtype (Submodule.restrictScalars R I) ∘ₗ ↑f + AlgHom.toLinearMap (IsScalarTower.toAlgHom R A B)
x y : A
⊢ OneHom.toFun
      { toFun := fun x => ↑(f x) + (algebraMap A B) x, map_one' := (_ : (fun x => ↑(f x) + (algebraMap A B) x) 1 = 1) }
      (x * y) =
    OneHom.toFun
        { toFun := fun x => ↑(f x) + (algebraMap A B) x,
          map_one' := (_ : (fun x => ↑(f x) + (algebraMap A B) x) 1 = 1) }
        x *
      OneHom.toFun
        { toFun := fun x => ↑(f x) + (algebraMap A B) x,
          map_one' := (_ : (fun x => ↑(f x) + (algebraMap A B) x) 1 = 1) }
        y

Next tactic:
have : (f x : B) * f y = 0 := by
        rw [← Ideal.mem_bot, ← hI, pow_two]
        convert Ideal.mul_mem_mul (f x).2 (f y).2 using 1
/-- Given a tower of algebras `R → A → B`, and a square-zero `I : Ideal B`, each `R`-derivation
from `A` to `I` corresponds to a lift `A →ₐ[R] B` of the canonical map `A →ₐ[R] B ⧸ I`. -/
@[simps (config := .lemmasOnly)]
def liftOfDerivationToSquareZero (f : Derivation R A I) : A →ₐ[R] B :=
  { ((I.restrictScalars R).subtype.comp f.toLinearMap + (IsScalarTower.toAlgHom R A B).toLinearMap :
      A →ₗ[R] B) with
    toFun := fun x => f x + algebraMap A B x
    map_one' := by dsimp; rw [map_one, f.map_one_eq_zero, Submodule.coe_zero, zero_add]
    map_mul' := fun x y => by
      have : (f x : B) * f y = 0 := by
        

Proof state:
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
f : Derivation R A ↥I
src✝ : A →ₗ[R] B :=
  Submodule.subtype (Submodule.restrictScalars R I) ∘ₗ ↑f + AlgHom.toLinearMap (IsScalarTower.toAlgHom R A B)
x y : A
⊢ ↑(f x) * ↑(f y) = 0

Next tactic:
rw [← Ideal.mem_bot, ← hI, pow_two]
/-- Given a tower of algebras `R → A → B`, and a square-zero `I : Ideal B`, each `R`-derivation
from `A` to `I` corresponds to a lift `A →ₐ[R] B` of the canonical map `A →ₐ[R] B ⧸ I`. -/
@[simps (config := .lemmasOnly)]
def liftOfDerivationToSquareZero (f : Derivation R A I) : A →ₐ[R] B :=
  { ((I.restrictScalars R).subtype.comp f.toLinearMap + (IsScalarTower.toAlgHom R A B).toLinearMap :
      A →ₗ[R] B) with
    toFun := fun x => f x + algebraMap A B x
    map_one' := by dsimp; rw [map_one, f.map_one_eq_zero, Submodule.coe_zero, zero_add]
    map_mul' := fun x y => by
      have : (f x : B) * f y = 0 := by
        rw [← Ideal.mem_bot, ← hI, pow_two]
        

Proof state:
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
f : Derivation R A ↥I
src✝ : A →ₗ[R] B :=
  Submodule.subtype (Submodule.restrictScalars R I) ∘ₗ ↑f + AlgHom.toLinearMap (IsScalarTower.toAlgHom R A B)
x y : A
⊢ ↑(f x) * ↑(f y) ∈ I * I

Next tactic:
convert Ideal.mul_mem_mul (f x).2 (f y).2 using 1
/-- Given a tower of algebras `R → A → B`, and a square-zero `I : Ideal B`, each `R`-derivation
from `A` to `I` corresponds to a lift `A →ₐ[R] B` of the canonical map `A →ₐ[R] B ⧸ I`. -/
@[simps (config := .lemmasOnly)]
def liftOfDerivationToSquareZero (f : Derivation R A I) : A →ₐ[R] B :=
  { ((I.restrictScalars R).subtype.comp f.toLinearMap + (IsScalarTower.toAlgHom R A B).toLinearMap :
      A →ₗ[R] B) with
    toFun := fun x => f x + algebraMap A B x
    map_one' := by dsimp; rw [map_one, f.map_one_eq_zero, Submodule.coe_zero, zero_add]
    map_mul' := fun x y => by
      have : (f x : B) * f y = 0 := by
        rw [← Ideal.mem_bot, ← hI, pow_two]
        convert Ideal.mul_mem_mul (f x).2 (f y).2 using 1
      

Proof state:
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
f : Derivation R A ↥I
src✝ : A →ₗ[R] B :=
  Submodule.subtype (Submodule.restrictScalars R I) ∘ₗ ↑f + AlgHom.toLinearMap (IsScalarTower.toAlgHom R A B)
x y : A
this : ↑(f x) * ↑(f y) = 0
⊢ OneHom.toFun
      { toFun := fun x => ↑(f x) + (algebraMap A B) x, map_one' := (_ : (fun x => ↑(f x) + (algebraMap A B) x) 1 = 1) }
      (x * y) =
    OneHom.toFun
        { toFun := fun x => ↑(f x) + (algebraMap A B) x,
          map_one' := (_ : (fun x => ↑(f x) + (algebraMap A B) x) 1 = 1) }
        x *
      OneHom.toFun
        { toFun := fun x => ↑(f x) + (algebraMap A B) x,
          map_one' := (_ : (fun x => ↑(f x) + (algebraMap A B) x) 1 = 1) }
        y

Next tactic:
simp only [map_mul, f.leibniz, add_mul, mul_add, Submodule.coe_add,
        Submodule.coe_smul_of_tower, Algebra.smul_def, this]
/-- Given a tower of algebras `R → A → B`, and a square-zero `I : Ideal B`, each `R`-derivation
from `A` to `I` corresponds to a lift `A →ₐ[R] B` of the canonical map `A →ₐ[R] B ⧸ I`. -/
@[simps (config := .lemmasOnly)]
def liftOfDerivationToSquareZero (f : Derivation R A I) : A →ₐ[R] B :=
  { ((I.restrictScalars R).subtype.comp f.toLinearMap + (IsScalarTower.toAlgHom R A B).toLinearMap :
      A →ₗ[R] B) with
    toFun := fun x => f x + algebraMap A B x
    map_one' := by dsimp; rw [map_one, f.map_one_eq_zero, Submodule.coe_zero, zero_add]
    map_mul' := fun x y => by
      have : (f x : B) * f y = 0 := by
        rw [← Ideal.mem_bot, ← hI, pow_two]
        convert Ideal.mul_mem_mul (f x).2 (f y).2 using 1
      simp only [map_mul, f.leibniz, add_mul, mul_add, Submodule.coe_add,
        Submodule.coe_smul_of_tower, Algebra.smul_def, this]
      

Proof state:
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
f : Derivation R A ↥I
src✝ : A →ₗ[R] B :=
  Submodule.subtype (Submodule.restrictScalars R I) ∘ₗ ↑f + AlgHom.toLinearMap (IsScalarTower.toAlgHom R A B)
x y : A
this : ↑(f x) * ↑(f y) = 0
⊢ (algebraMap A B) x * ↑(f y) + (algebraMap A B) y * ↑(f x) + (algebraMap A B) x * (algebraMap A B) y =
    0 + (algebraMap A B) x * ↑(f y) + (↑(f x) * (algebraMap A B) y + (algebraMap A B) x * (algebraMap A B) y)

Next tactic:
ring
/-- Given a tower of algebras `R → A → B`, and a square-zero `I : Ideal B`, each `R`-derivation
from `A` to `I` corresponds to a lift `A →ₐ[R] B` of the canonical map `A →ₐ[R] B ⧸ I`. -/
@[simps (config := .lemmasOnly)]
def liftOfDerivationToSquareZero (f : Derivation R A I) : A →ₐ[R] B :=
  { ((I.restrictScalars R).subtype.comp f.toLinearMap + (IsScalarTower.toAlgHom R A B).toLinearMap :
      A →ₗ[R] B) with
    toFun := fun x => f x + algebraMap A B x
    map_one' := by dsimp; rw [map_one, f.map_one_eq_zero, Submodule.coe_zero, zero_add]
    map_mul' := fun x y => by
      have : (f x : B) * f y = 0 := by
        rw [← Ideal.mem_bot, ← hI, pow_two]
        convert Ideal.mul_mem_mul (f x).2 (f y).2 using 1
      simp only [map_mul, f.leibniz, add_mul, mul_add, Submodule.coe_add,
        Submodule.coe_smul_of_tower, Algebra.smul_def, this]
      ring
    commutes' := fun r => by
      

Proof state:
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
f : Derivation R A ↥I
src✝ : A →ₗ[R] B :=
  Submodule.subtype (Submodule.restrictScalars R I) ∘ₗ ↑f + AlgHom.toLinearMap (IsScalarTower.toAlgHom R A B)
r : R
⊢ OneHom.toFun
      (↑↑{
            toMonoidHom :=
              {
                toOneHom :=
                  { toFun := fun x => ↑(f x) + (algebraMap A B) x,
                    map_one' := (_ : (fun x => ↑(f x) + (algebraMap A B) x) 1 = 1) },
                map_mul' :=
                  (_ :
                    ∀ (x y : A),
                      OneHom.toFun
                          { toFun := fun x => ↑(f x) + (algebraMap A B) x,
                            map_one' := (_ : (fun x => ↑(f x) + (algebraMap A B) x) 1 = 1) }
                          (x * y) =
                        OneHom.toFun
                            { toFun := fun x => ↑(f x) + (algebraMap A B) x,
                              map_one' := (_ : (fun x => ↑(f x) + (algebraMap A B) x) 1 = 1) }
                            x *
                          OneHom.toFun
                            { toFun := fun x => ↑(f x) + (algebraMap A B) x,
                              map_one' := (_ : (fun x => ↑(f x) + (algebraMap A B) x) 1 = 1) }
                            y) },
            map_zero' :=
              (_ :
                (Submodule.subtype (Submodule.restrictScalars R I) ∘ₗ ↑f +
                      AlgHom.toLinearMap (IsScalarTower.toAlgHom R A B))
                    0 =
                  0),
            map_add' :=
              (_ :
                ∀ (x y : A),
                  AddHom.toFun src✝.toAddHom (x + y) = AddHom.toFun src✝.toAddHom x + AddHom.toFun src✝.toAddHom y) })
      ((algebraMap R A) r) =
    (algebraMap R B) r

Next tactic:
simp only [Derivation.map_algebraMap, eq_self_iff_true, zero_add, Submodule.coe_zero, ←
        IsScalarTower.algebraMap_apply R A B r]
theorem liftOfDerivationToSquareZero_mk_apply (d : Derivation R A I) (x : A) :
    Ideal.Quotient.mk I (liftOfDerivationToSquareZero I hI d x) = algebraMap A (B ⧸ I) x := by
  

Proof state:
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
d : Derivation R A ↥I
x : A
⊢ (Ideal.Quotient.mk I) ((liftOfDerivationToSquareZero I hI d) x) = (algebraMap A (B ⧸ I)) x

Next tactic:
rw [liftOfDerivationToSquareZero_apply, map_add, Ideal.Quotient.eq_zero_iff_mem.mpr (d x).prop,
    zero_add]
theorem liftOfDerivationToSquareZero_mk_apply (d : Derivation R A I) (x : A) :
    Ideal.Quotient.mk I (liftOfDerivationToSquareZero I hI d x) = algebraMap A (B ⧸ I) x := by
  rw [liftOfDerivationToSquareZero_apply, map_add, Ideal.Quotient.eq_zero_iff_mem.mpr (d x).prop,
    zero_add]
  

Proof state:
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
d : Derivation R A ↥I
x : A
⊢ (Ideal.Quotient.mk I) ((algebraMap A B) x) = (algebraMap A (B ⧸ I)) x

Next tactic:
rfl
@[simp]
theorem liftOfDerivationToSquareZero_mk_apply' (d : Derivation R A I) (x : A) :
    (Ideal.Quotient.mk I) (d x) + (algebraMap A (B ⧸ I)) x = algebraMap A (B ⧸ I) x := by
  

Proof state:
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
d : Derivation R A ↥I
x : A
⊢ (Ideal.Quotient.mk I) ↑(d x) + (algebraMap A (B ⧸ I)) x = (algebraMap A (B ⧸ I)) x

Next tactic:
simp only [Ideal.Quotient.eq_zero_iff_mem.mpr (d x).prop, zero_add]
/-- Given a tower of algebras `R → A → B`, and a square-zero `I : ideal B`,
there is a 1-1 correspondence between `R`-derivations from `A` to `I` and
lifts `A →ₐ[R] B` of the canonical map `A →ₐ[R] B ⧸ I`. -/
@[simps!]
def derivationToSquareZeroEquivLift : Derivation R A I ≃
    { f : A →ₐ[R] B // (Ideal.Quotient.mkₐ R I).comp f = IsScalarTower.toAlgHom R A (B ⧸ I) } := by
  

Proof state:
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
⊢ Derivation R A ↥I ≃ { f // AlgHom.comp (Ideal.Quotient.mkₐ R I) f = IsScalarTower.toAlgHom R A (B ⧸ I) }

Next tactic:
refine' ⟨fun d => ⟨liftOfDerivationToSquareZero I hI d, _⟩, fun f =>
    (derivationToSquareZeroOfLift I hI f.1 f.2 : _), _, _⟩
/-- Given a tower of algebras `R → A → B`, and a square-zero `I : ideal B`,
there is a 1-1 correspondence between `R`-derivations from `A` to `I` and
lifts `A →ₐ[R] B` of the canonical map `A →ₐ[R] B ⧸ I`. -/
@[simps!]
def derivationToSquareZeroEquivLift : Derivation R A I ≃
    { f : A →ₐ[R] B // (Ideal.Quotient.mkₐ R I).comp f = IsScalarTower.toAlgHom R A (B ⧸ I) } := by
  refine' ⟨fun d => ⟨liftOfDerivationToSquareZero I hI d, _⟩, fun f =>
    (derivationToSquareZeroOfLift I hI f.1 f.2 : _), _, _⟩
  · 

Proof state:
case refine'_1
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
d : Derivation R A ↥I
⊢ AlgHom.comp (Ideal.Quotient.mkₐ R I) (liftOfDerivationToSquareZero I hI d) = IsScalarTower.toAlgHom R A (B ⧸ I)

Next tactic:
ext x
/-- Given a tower of algebras `R → A → B`, and a square-zero `I : ideal B`,
there is a 1-1 correspondence between `R`-derivations from `A` to `I` and
lifts `A →ₐ[R] B` of the canonical map `A →ₐ[R] B ⧸ I`. -/
@[simps!]
def derivationToSquareZeroEquivLift : Derivation R A I ≃
    { f : A →ₐ[R] B // (Ideal.Quotient.mkₐ R I).comp f = IsScalarTower.toAlgHom R A (B ⧸ I) } := by
  refine' ⟨fun d => ⟨liftOfDerivationToSquareZero I hI d, _⟩, fun f =>
    (derivationToSquareZeroOfLift I hI f.1 f.2 : _), _, _⟩
  · ext x; 

Proof state:
case refine'_1.H
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
d : Derivation R A ↥I
x : A
⊢ (AlgHom.comp (Ideal.Quotient.mkₐ R I) (liftOfDerivationToSquareZero I hI d)) x =
    (IsScalarTower.toAlgHom R A (B ⧸ I)) x

Next tactic:
exact liftOfDerivationToSquareZero_mk_apply I hI d x
/-- Given a tower of algebras `R → A → B`, and a square-zero `I : ideal B`,
there is a 1-1 correspondence between `R`-derivations from `A` to `I` and
lifts `A →ₐ[R] B` of the canonical map `A →ₐ[R] B ⧸ I`. -/
@[simps!]
def derivationToSquareZeroEquivLift : Derivation R A I ≃
    { f : A →ₐ[R] B // (Ideal.Quotient.mkₐ R I).comp f = IsScalarTower.toAlgHom R A (B ⧸ I) } := by
  refine' ⟨fun d => ⟨liftOfDerivationToSquareZero I hI d, _⟩, fun f =>
    (derivationToSquareZeroOfLift I hI f.1 f.2 : _), _, _⟩
  · ext x; exact liftOfDerivationToSquareZero_mk_apply I hI d x
  · 

Proof state:
case refine'_2
R : Type u
A : Type v
B : Type w
inst✝⁶ : CommSemiring R
inst✝⁵ : CommSemiring A
inst✝⁴ : CommRing B
inst✝³ : Algebra R A
inst✝² : Algebra R B
I : Ideal B
hI : I ^ 2 = ⊥
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
⊢ Function.LeftInverse
    (fun f =>
      derivationToSquareZeroOfLift I hI ↑f
        (_ : AlgHom.comp (Ideal.Quotient.mkₐ R I) ↑f = IsScalarTower.toAlgHom R A (B ⧸ I)))
    fun d =>
    { val := liftOfDerivationToSquareZero I hI d,
      property :=
        (_ :
          AlgHom.comp (Ideal.Quotient.mkₐ R I) (liftOfDerivationToSquareZero I hI d) =
            IsScalarTower.toAlgHom R A (B ⧸ I)) }

Next tactic:
intro d