/-- If `S' = S ⊗[R] R'`, then any pair of `R`-algebra homomorphisms `f : S → A` and `g : R' → A`
such that `f x` and `g y` commutes for all `x, y` descends to a (unique) homomoprhism `S' → A`.
-/
--@[simps (config := .lemmasOnly) apply] --Porting note: removed and added by hand
noncomputable def Algebra.pushoutDesc [H : Algebra.IsPushout R S R' S'] {A : Type*} [Semiring A]
    [Algebra R A] (f : S →ₐ[R] A) (g : R' →ₐ[R] A) (hf : ∀ x y, f x * g y = g y * f x) :
    S' →ₐ[R] A := by
  letI := Module.compHom A f.toRingHom
  haveI : IsScalarTower R S A :=
    { smul_assoc := fun r s a =>
        show f (r • s) * a = r • (f s * a) by rw [f.map_smul, smul_mul_assoc] }
  haveI : IsScalarTower S A A := { smul_assoc := fun r a b => mul_assoc _ _ _ }
  have : ∀ x, H.out.lift g.toLinearMap (algebraMap R' S' x) = g x := H.out.lift_eq _
  refine' AlgHom.ofLinearMap ((H.out.lift g.toLinearMap).restrictScalars R) _ _
  · dsimp only [LinearMap.restrictScalars_apply]
    rw [← (algebraMap R' S').map_one, this, g.map_one]
  · intro x y
    refine H.out.inductionOn x ?_ ?_ ?_ ?_
    · rw [zero_mul, map_zero, zero_mul]
    

Proof state:
case refine'_2.refine_2
R : Type u_1
M : Type v₁
N : Type v₂
S : Type v₃
inst✝³³ : AddCommMonoid M
inst✝³² : AddCommMonoid N
inst✝³¹ : CommRing R
inst✝³⁰ : CommRing S
inst✝²⁹ : Algebra R S
inst✝²⁸ : Module R M
inst✝²⁷ : Module R N
inst✝²⁶ : Module S N
inst✝²⁵ : IsScalarTower R S N
f✝ : M →ₗ[R] N
h : IsBaseChange S f✝
P : Type u_2
Q : Type u_3
inst✝²⁴ : AddCommMonoid P
inst✝²³ : Module R P
inst✝²² : AddCommMonoid Q
inst✝²¹ : Module S Q
T : Type u_4
O : Type u_5
inst✝²⁰ : CommRing T
inst✝¹⁹ : Algebra R T
inst✝¹⁸ : Algebra S T
inst✝¹⁷ : IsScalarTower R S T
inst✝¹⁶ : AddCommMonoid O
inst✝¹⁵ : Module R O
inst✝¹⁴ : Module S O
inst✝¹³ : Module T O
inst✝¹² : IsScalarTower S T O
inst✝¹¹ : IsScalarTower R S O
inst✝¹⁰ : IsScalarTower R T O
R' : Type u_6
S' : Type u_7
inst✝⁹ : CommRing R'
inst✝⁸ : CommRing S'
inst✝⁷ : Algebra R R'
inst✝⁶ : Algebra S S'
inst✝⁵ : Algebra R' S'
inst✝⁴ : Algebra R S'
inst✝³ : IsScalarTower R R' S'
inst✝² : IsScalarTower R S S'
H : IsPushout R S R' S'
A : Type u_8
inst✝¹ : Semiring A
inst✝ : Algebra R A
f : S →ₐ[R] A
g : R' →ₐ[R] A
hf : ∀ (x : S) (y : R'), f x * g y = g y * f x
this✝² : Module S A := Module.compHom A ↑f
this✝¹ : IsScalarTower R S A
this✝ : IsScalarTower S A A
this :
  ∀ (x : R'),
    (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g))
        ((algebraMap R' S') x) =
      g x
x y : S'
⊢ ∀ (m : R'),
    (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
        ((AlgHom.toLinearMap (toAlgHom R R' S')) m * y) =
      (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
          ((AlgHom.toLinearMap (toAlgHom R R' S')) m) *
        (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g))) y
case refine'_2.refine_3
R : Type u_1
M : Type v₁
N : Type v₂
S : Type v₃
inst✝³³ : AddCommMonoid M
inst✝³² : AddCommMonoid N
inst✝³¹ : CommRing R
inst✝³⁰ : CommRing S
inst✝²⁹ : Algebra R S
inst✝²⁸ : Module R M
inst✝²⁷ : Module R N
inst✝²⁶ : Module S N
inst✝²⁵ : IsScalarTower R S N
f✝ : M →ₗ[R] N
h : IsBaseChange S f✝
P : Type u_2
Q : Type u_3
inst✝²⁴ : AddCommMonoid P
inst✝²³ : Module R P
inst✝²² : AddCommMonoid Q
inst✝²¹ : Module S Q
T : Type u_4
O : Type u_5
inst✝²⁰ : CommRing T
inst✝¹⁹ : Algebra R T
inst✝¹⁸ : Algebra S T
inst✝¹⁷ : IsScalarTower R S T
inst✝¹⁶ : AddCommMonoid O
inst✝¹⁵ : Module R O
inst✝¹⁴ : Module S O
inst✝¹³ : Module T O
inst✝¹² : IsScalarTower S T O
inst✝¹¹ : IsScalarTower R S O
inst✝¹⁰ : IsScalarTower R T O
R' : Type u_6
S' : Type u_7
inst✝⁹ : CommRing R'
inst✝⁸ : CommRing S'
inst✝⁷ : Algebra R R'
inst✝⁶ : Algebra S S'
inst✝⁵ : Algebra R' S'
inst✝⁴ : Algebra R S'
inst✝³ : IsScalarTower R R' S'
inst✝² : IsScalarTower R S S'
H : IsPushout R S R' S'
A : Type u_8
inst✝¹ : Semiring A
inst✝ : Algebra R A
f : S →ₐ[R] A
g : R' →ₐ[R] A
hf : ∀ (x : S) (y : R'), f x * g y = g y * f x
this✝² : Module S A := Module.compHom A ↑f
this✝¹ : IsScalarTower R S A
this✝ : IsScalarTower S A A
this :
  ∀ (x : R'),
    (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g))
        ((algebraMap R' S') x) =
      g x
x y : S'
⊢ ∀ (s : S) (n : S'),
    (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
          (n * y) =
        (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g))) n *
          (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
            y →
      (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
          (s • n * y) =
        (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
            (s • n) *
          (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g))) y
case refine'_2.refine_4
R : Type u_1
M : Type v₁
N : Type v₂
S : Type v₃
inst✝³³ : AddCommMonoid M
inst✝³² : AddCommMonoid N
inst✝³¹ : CommRing R
inst✝³⁰ : CommRing S
inst✝²⁹ : Algebra R S
inst✝²⁸ : Module R M
inst✝²⁷ : Module R N
inst✝²⁶ : Module S N
inst✝²⁵ : IsScalarTower R S N
f✝ : M →ₗ[R] N
h : IsBaseChange S f✝
P : Type u_2
Q : Type u_3
inst✝²⁴ : AddCommMonoid P
inst✝²³ : Module R P
inst✝²² : AddCommMonoid Q
inst✝²¹ : Module S Q
T : Type u_4
O : Type u_5
inst✝²⁰ : CommRing T
inst✝¹⁹ : Algebra R T
inst✝¹⁸ : Algebra S T
inst✝¹⁷ : IsScalarTower R S T
inst✝¹⁶ : AddCommMonoid O
inst✝¹⁵ : Module R O
inst✝¹⁴ : Module S O
inst✝¹³ : Module T O
inst✝¹² : IsScalarTower S T O
inst✝¹¹ : IsScalarTower R S O
inst✝¹⁰ : IsScalarTower R T O
R' : Type u_6
S' : Type u_7
inst✝⁹ : CommRing R'
inst✝⁸ : CommRing S'
inst✝⁷ : Algebra R R'
inst✝⁶ : Algebra S S'
inst✝⁵ : Algebra R' S'
inst✝⁴ : Algebra R S'
inst✝³ : IsScalarTower R R' S'
inst✝² : IsScalarTower R S S'
H : IsPushout R S R' S'
A : Type u_8
inst✝¹ : Semiring A
inst✝ : Algebra R A
f : S →ₐ[R] A
g : R' →ₐ[R] A
hf : ∀ (x : S) (y : R'), f x * g y = g y * f x
this✝² : Module S A := Module.compHom A ↑f
this✝¹ : IsScalarTower R S A
this✝ : IsScalarTower S A A
this :
  ∀ (x : R'),
    (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g))
        ((algebraMap R' S') x) =
      g x
x y : S'
⊢ ∀ (n₁ n₂ : S'),
    (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
          (n₁ * y) =
        (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
            n₁ *
          (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
            y →
      (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
            (n₂ * y) =
          (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
              n₂ *
            (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
              y →
        (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
            ((n₁ + n₂) * y) =
          (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
              (n₁ + n₂) *
            (↑R (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)))
              y

Next tactic:
rotate_left