/-- 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]
    rotate_left
    · intro s s' e
      dsimp only [LinearMap.restrictScalars_apply] at e ⊢
      rw [LinearMap.map_smul, smul_mul_assoc, LinearMap.map_smul, e, smul_mul_assoc]
    · intro s s' e₁ e₂
      dsimp only [LinearMap.restrictScalars_apply] at e₁ e₂ ⊢
      rw [add_mul, map_add, map_add, add_mul, e₁, e₂]
    intro x
    dsimp
    rw [this]
    refine H.out.inductionOn y ?_ ?_ ?_ ?_
    · rw [mul_zero, map_zero, mul_zero]
    · intro y
      dsimp
      rw [← _root_.map_mul, this, this, _root_.map_mul]
    · intro s s' e
      rw [mul_comm, smul_mul_assoc, LinearMap.map_smul, LinearMap.map_smul, mul_comm, e]
      

Proof state:
case refine'_2.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'
x : R'
s : S
s' : S'
e :
  (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g))
      ((algebraMap R' S') x * s') =
    g x * (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)) s'
⊢ s •
      (g x *
        (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)) s') =
    g x * s • (IsBaseChange.lift (_ : IsBaseChange S (AlgHom.toLinearMap (toAlgHom R R' S'))) (AlgHom.toLinearMap g)) s'

Next tactic:
change f s * (g x * _) = g x * (f s * _)