/-- Lift a monoid homomorphism that maps polynomials `φ : R[X] →* S[X]`
to a `RatFunc R →* RatFunc S`,
on the condition that `φ` maps non zero divisors to non zero divisors,
by mapping both the numerator and denominator and quotienting them. -/
def map [MonoidHomClass F R[X] S[X]] (φ : F) (hφ : R[X]⁰ ≤ S[X]⁰.comap φ) : RatFunc R →* RatFunc S
    where
  toFun f :=
    RatFunc.liftOn f
      (fun n d => if h : φ d ∈ S[X]⁰ then ofFractionRing (Localization.mk (φ n) ⟨φ d, h⟩) else 0)
      fun {p q p' q'} hq hq' h => by
      dsimp only -- porting note: force the function to be applied
      rw [dif_pos, dif_pos]
      congr 1 -- porting note: this was a `rw [ofFractionRing.inj_eq]` which was overkill anyway
      rw [Localization.mk_eq_mk_iff]
      rotate_left
      · exact hφ hq
      · exact hφ hq'
      refine' Localization.r_of_eq _
      simpa only [map_mul] using congr_arg φ h
  map_one' := by
    dsimp only -- porting note: force the function to be applied
    rw [← ofFractionRing_one, ← Localization.mk_one, liftOn_ofFractionRing_mk, dif_pos]
    · simpa using ofFractionRing_one
    · simpa using Submonoid.one_mem _
  map_mul' x y := by
    dsimp only -- porting note: force the function to be applied
    cases' x with x; cases' y with y
    -- porting note: added `using Localization.rec` (`Localization.induction_on` didn't work)
    induction' x using Localization.rec with p q
    

Proof state:
case ofFractionRing.ofFractionRing.f
K : Type u
inst✝⁵ : CommRing K
G₀ : Type u_1
L : Type u_2
R : Type u_3
S : Type u_4
F : Type u_5
inst✝⁴ : CommGroupWithZero G₀
inst✝³ : Field L
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : MonoidHomClass F R[X] S[X]
φ : F
hφ : R[X]⁰ ≤ Submonoid.comap φ S[X]⁰
y : FractionRing R[X]
p : R[X]
q : ↥R[X]⁰
⊢ RatFunc.liftOn ({ toFractionRing := Localization.mk p q } * { toFractionRing := y })
      (fun n d =>
        if h : φ d ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ n) { val := φ d, property := h } } else 0)
      (_ :
        ∀ {p q p' q' : R[X]},
          q ∈ R[X]⁰ →
            q' ∈ R[X]⁰ →
              q' * p = q * p' →
                (if h : φ q ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ p) { val := φ q, property := h } }
                  else 0) =
                  if h : φ q' ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ p') { val := φ q', property := h } }
                  else 0) =
    RatFunc.liftOn { toFractionRing := Localization.mk p q }
        (fun n d =>
          if h : φ d ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ n) { val := φ d, property := h } } else 0)
        (_ :
          ∀ {p q p' q' : R[X]},
            q ∈ R[X]⁰ →
              q' ∈ R[X]⁰ →
                q' * p = q * p' →
                  (if h : φ q ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ p) { val := φ q, property := h } }
                    else 0) =
                    if h : φ q' ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ p') { val := φ q', property := h } }
                    else 0) *
      RatFunc.liftOn { toFractionRing := y }
        (fun n d =>
          if h : φ d ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ n) { val := φ d, property := h } } else 0)
        (_ :
          ∀ {p q p' q' : R[X]},
            q ∈ R[X]⁰ →
              q' ∈ R[X]⁰ →
                q' * p = q * p' →
                  (if h : φ q ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ p) { val := φ q, property := h } }
                    else 0) =
                    if h : φ q' ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ p') { val := φ q', property := h } }
                    else 0)
case ofFractionRing.ofFractionRing.H
K : Type u
inst✝⁵ : CommRing K
G₀ : Type u_1
L : Type u_2
R : Type u_3
S : Type u_4
F : Type u_5
inst✝⁴ : CommGroupWithZero G₀
inst✝³ : Field L
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : MonoidHomClass F R[X] S[X]
φ : F
hφ : R[X]⁰ ≤ Submonoid.comap φ S[X]⁰
x y : FractionRing R[X]
a✝ c✝ : R[X]
b✝ d✝ : ↥R[X]⁰
h✝ : (Localization.r R[X]⁰) (a✝, b✝) (c✝, d✝)
⊢ (_ :
      RatFunc.liftOn ({ toFractionRing := Localization.mk c✝ d✝ } * { toFractionRing := y })
          (fun n d =>
            if h : φ d ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ n) { val := φ d, property := h } } else 0)
          (_ :
            ∀ {p q p' q' : R[X]},
              q ∈ R[X]⁰ →
                q' ∈ R[X]⁰ →
                  q' * p = q * p' →
                    (if h : φ q ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ p) { val := φ q, property := h } }
                      else 0) =
                      if h : φ q' ∈ S[X]⁰ then
                        { toFractionRing := Localization.mk (φ p') { val := φ q', property := h } }
                      else 0) =
        RatFunc.liftOn { toFractionRing := Localization.mk c✝ d✝ }
            (fun n d =>
              if h : φ d ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ n) { val := φ d, property := h } } else 0)
            (_ :
              ∀ {p q p' q' : R[X]},
                q ∈ R[X]⁰ →
                  q' ∈ R[X]⁰ →
                    q' * p = q * p' →
                      (if h : φ q ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ p) { val := φ q, property := h } }
                        else 0) =
                        if h : φ q' ∈ S[X]⁰ then
                          { toFractionRing := Localization.mk (φ p') { val := φ q', property := h } }
                        else 0) *
          RatFunc.liftOn { toFractionRing := y }
            (fun n d =>
              if h : φ d ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ n) { val := φ d, property := h } } else 0)
            (_ :
              ∀ {p q p' q' : R[X]},
                q ∈ R[X]⁰ →
                  q' ∈ R[X]⁰ →
                    q' * p = q * p' →
                      (if h : φ q ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ p) { val := φ q, property := h } }
                        else 0) =
                        if h : φ q' ∈ S[X]⁰ then
                          { toFractionRing := Localization.mk (φ p') { val := φ q', property := h } }
                        else 0)) =
    (_ :
      RatFunc.liftOn ({ toFractionRing := Localization.mk c✝ d✝ } * { toFractionRing := y })
          (fun n d =>
            if h : φ d ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ n) { val := φ d, property := h } } else 0)
          (_ :
            ∀ {p q p' q' : R[X]},
              q ∈ R[X]⁰ →
                q' ∈ R[X]⁰ →
                  q' * p = q * p' →
                    (if h : φ q ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ p) { val := φ q, property := h } }
                      else 0) =
                      if h : φ q' ∈ S[X]⁰ then
                        { toFractionRing := Localization.mk (φ p') { val := φ q', property := h } }
                      else 0) =
        RatFunc.liftOn { toFractionRing := Localization.mk c✝ d✝ }
            (fun n d =>
              if h : φ d ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ n) { val := φ d, property := h } } else 0)
            (_ :
              ∀ {p q p' q' : R[X]},
                q ∈ R[X]⁰ →
                  q' ∈ R[X]⁰ →
                    q' * p = q * p' →
                      (if h : φ q ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ p) { val := φ q, property := h } }
                        else 0) =
                        if h : φ q' ∈ S[X]⁰ then
                          { toFractionRing := Localization.mk (φ p') { val := φ q', property := h } }
                        else 0) *
          RatFunc.liftOn { toFractionRing := y }
            (fun n d =>
              if h : φ d ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ n) { val := φ d, property := h } } else 0)
            (_ :
              ∀ {p q p' q' : R[X]},
                q ∈ R[X]⁰ →
                  q' ∈ R[X]⁰ →
                    q' * p = q * p' →
                      (if h : φ q ∈ S[X]⁰ then { toFractionRing := Localization.mk (φ p) { val := φ q, property := h } }
                        else 0) =
                        if h : φ q' ∈ S[X]⁰ then
                          { toFractionRing := Localization.mk (φ p') { val := φ q', property := h } }
                        else 0))

Next tactic:
induction' y using Localization.rec with p' q'