l3lab/ntp-mathlib huggingface dataset:
set_option maxHeartbeats 300000 in
-- TODO: Generalize to `FunLike` classes,
/-- Lift a monoid with zero homomorphism `R[X] →*₀ G₀` to a `RatFunc R →*₀ G₀`
on the condition that `φ` maps non zero divisors to non zero divisors,
by mapping both the numerator and denominator and quotienting them. -/
def liftMonoidWithZeroHom (φ : R[X] →*₀ G₀) (hφ : R[X]⁰ ≤ G₀⁰.comap φ) : RatFunc R →*₀ G₀ where
  toFun f :=
    RatFunc.liftOn f (fun p q => φ p / φ q) fun {p q p' q'} hq hq' h => by
      cases subsingleton_or_nontrivial R
      · rw [Subsingleton.elim p q, Subsingleton.elim p' q, Subsingleton.elim q' q]
      rw [div_eq_div_iff, ← map_mul, mul_comm p, h, map_mul, mul_comm] <;>
        exact nonZeroDivisors.ne_zero (hφ ‹_›)
  map_one' := by
    dsimp only -- porting note: force the function to be applied
    rw [← ofFractionRing_one, ← Localization.mk_one, liftOn_ofFractionRing_mk]
    

Proof state:
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
φ : R[X] →*₀ G₀
hφ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰
⊢ φ 1 / φ ↑1 = 1

Next tactic:
simp only [map_one, OneMemClass.coe_one, div_one]
theorem liftMonoidWithZeroHom_injective [Nontrivial R] (φ : R[X] →*₀ G₀) (hφ : Function.Injective φ)
    (hφ' : R[X]⁰ ≤ G₀⁰.comap φ := nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ hφ) :
    Function.Injective (liftMonoidWithZeroHom φ hφ') := by
  

Proof state:
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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
⊢ Function.Injective ⇑(liftMonoidWithZeroHom φ hφ')

Next tactic:
rintro ⟨x⟩ ⟨y⟩
theorem liftMonoidWithZeroHom_injective [Nontrivial R] (φ : R[X] →*₀ G₀) (hφ : Function.Injective φ)
    (hφ' : R[X]⁰ ≤ G₀⁰.comap φ := nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ hφ) :
    Function.Injective (liftMonoidWithZeroHom φ hφ') := by
  rintro ⟨x⟩ ⟨y⟩
  

Proof state:
case ofFractionRing.ofFractionRing
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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
x y : FractionRing R[X]
⊢ (liftMonoidWithZeroHom φ hφ') { toFractionRing := x } = (liftMonoidWithZeroHom φ hφ') { toFractionRing := y } →
    { toFractionRing := x } = { toFractionRing := y }

Next tactic:
induction' x using Localization.induction_on with a
theorem liftMonoidWithZeroHom_injective [Nontrivial R] (φ : R[X] →*₀ G₀) (hφ : Function.Injective φ)
    (hφ' : R[X]⁰ ≤ G₀⁰.comap φ := nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ hφ) :
    Function.Injective (liftMonoidWithZeroHom φ hφ') := by
  rintro ⟨x⟩ ⟨y⟩
  induction' x using Localization.induction_on with a
  

Proof state:
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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
y : FractionRing R[X]
a : R[X] × ↥R[X]⁰
⊢ (liftMonoidWithZeroHom φ hφ') { toFractionRing := Localization.mk a.1 a.2 } =
      (liftMonoidWithZeroHom φ hφ') { toFractionRing := y } →
    { toFractionRing := Localization.mk a.1 a.2 } = { toFractionRing := y }

Next tactic:
induction' y using Localization.induction_on with a'
theorem liftMonoidWithZeroHom_injective [Nontrivial R] (φ : R[X] →*₀ G₀) (hφ : Function.Injective φ)
    (hφ' : R[X]⁰ ≤ G₀⁰.comap φ := nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ hφ) :
    Function.Injective (liftMonoidWithZeroHom φ hφ') := by
  rintro ⟨x⟩ ⟨y⟩
  induction' x using Localization.induction_on with a
  induction' y using Localization.induction_on with a'
  · 

Proof state:
case ofFractionRing.ofFractionRing.H.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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
a a' : R[X] × ↥R[X]⁰
⊢ (liftMonoidWithZeroHom φ hφ') { toFractionRing := Localization.mk a.1 a.2 } =
      (liftMonoidWithZeroHom φ hφ') { toFractionRing := Localization.mk a'.1 a'.2 } →
    { toFractionRing := Localization.mk a.1 a.2 } = { toFractionRing := Localization.mk a'.1 a'.2 }

Next tactic:
simp_rw [liftMonoidWithZeroHom_apply_ofFractionRing_mk]
theorem liftMonoidWithZeroHom_injective [Nontrivial R] (φ : R[X] →*₀ G₀) (hφ : Function.Injective φ)
    (hφ' : R[X]⁰ ≤ G₀⁰.comap φ := nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ hφ) :
    Function.Injective (liftMonoidWithZeroHom φ hφ') := by
  rintro ⟨x⟩ ⟨y⟩
  induction' x using Localization.induction_on with a
  induction' y using Localization.induction_on with a'
  · simp_rw [liftMonoidWithZeroHom_apply_ofFractionRing_mk]
    

Proof state:
case ofFractionRing.ofFractionRing.H.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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
a a' : R[X] × ↥R[X]⁰
⊢ φ a.1 / φ ↑a.2 = φ a'.1 / φ ↑a'.2 →
    { toFractionRing := Localization.mk a.1 a.2 } = { toFractionRing := Localization.mk a'.1 a'.2 }

Next tactic:
intro h
theorem liftMonoidWithZeroHom_injective [Nontrivial R] (φ : R[X] →*₀ G₀) (hφ : Function.Injective φ)
    (hφ' : R[X]⁰ ≤ G₀⁰.comap φ := nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ hφ) :
    Function.Injective (liftMonoidWithZeroHom φ hφ') := by
  rintro ⟨x⟩ ⟨y⟩
  induction' x using Localization.induction_on with a
  induction' y using Localization.induction_on with a'
  · simp_rw [liftMonoidWithZeroHom_apply_ofFractionRing_mk]
    intro h
    

Proof state:
case ofFractionRing.ofFractionRing.H.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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
a a' : R[X] × ↥R[X]⁰
h : φ a.1 / φ ↑a.2 = φ a'.1 / φ ↑a'.2
⊢ { toFractionRing := Localization.mk a.1 a.2 } = { toFractionRing := Localization.mk a'.1 a'.2 }

Next tactic:
congr 1
theorem liftMonoidWithZeroHom_injective [Nontrivial R] (φ : R[X] →*₀ G₀) (hφ : Function.Injective φ)
    (hφ' : R[X]⁰ ≤ G₀⁰.comap φ := nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ hφ) :
    Function.Injective (liftMonoidWithZeroHom φ hφ') := by
  rintro ⟨x⟩ ⟨y⟩
  induction' x using Localization.induction_on with a
  induction' y using Localization.induction_on with a'
  · simp_rw [liftMonoidWithZeroHom_apply_ofFractionRing_mk]
    intro h
    congr 1
    

Proof state:
case ofFractionRing.ofFractionRing.H.H.e_toFractionRing
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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
a a' : R[X] × ↥R[X]⁰
h : φ a.1 / φ ↑a.2 = φ a'.1 / φ ↑a'.2
⊢ Localization.mk a.1 a.2 = Localization.mk a'.1 a'.2

Next tactic:
refine Localization.mk_eq_mk_iff.mpr (Localization.r_of_eq (M := R[X]) ?_)
theorem liftMonoidWithZeroHom_injective [Nontrivial R] (φ : R[X] →*₀ G₀) (hφ : Function.Injective φ)
    (hφ' : R[X]⁰ ≤ G₀⁰.comap φ := nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ hφ) :
    Function.Injective (liftMonoidWithZeroHom φ hφ') := by
  rintro ⟨x⟩ ⟨y⟩
  induction' x using Localization.induction_on with a
  induction' y using Localization.induction_on with a'
  · simp_rw [liftMonoidWithZeroHom_apply_ofFractionRing_mk]
    intro h
    congr 1
    refine Localization.mk_eq_mk_iff.mpr (Localization.r_of_eq (M := R[X]) ?_)
    

Proof state:
case ofFractionRing.ofFractionRing.H.H.e_toFractionRing
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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
a a' : R[X] × ↥R[X]⁰
h : φ a.1 / φ ↑a.2 = φ a'.1 / φ ↑a'.2
⊢ ↑(a'.1, a'.2).2 * (a.1, a.2).1 = ↑(a.1, a.2).2 * (a'.1, a'.2).1

Next tactic:
have := mul_eq_mul_of_div_eq_div _ _ ?_ ?_ h
theorem liftMonoidWithZeroHom_injective [Nontrivial R] (φ : R[X] →*₀ G₀) (hφ : Function.Injective φ)
    (hφ' : R[X]⁰ ≤ G₀⁰.comap φ := nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ hφ) :
    Function.Injective (liftMonoidWithZeroHom φ hφ') := by
  rintro ⟨x⟩ ⟨y⟩
  induction' x using Localization.induction_on with a
  induction' y using Localization.induction_on with a'
  · simp_rw [liftMonoidWithZeroHom_apply_ofFractionRing_mk]
    intro h
    congr 1
    refine Localization.mk_eq_mk_iff.mpr (Localization.r_of_eq (M := R[X]) ?_)
    have := mul_eq_mul_of_div_eq_div _ _ ?_ ?_ h
    

Proof state:
case ofFractionRing.ofFractionRing.H.H.e_toFractionRing.refine_3
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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
a a' : R[X] × ↥R[X]⁰
h : φ a.1 / φ ↑a.2 = φ a'.1 / φ ↑a'.2
this : φ a.1 * φ ↑a'.2 = φ a'.1 * φ ↑a.2
⊢ ↑(a'.1, a'.2).2 * (a.1, a.2).1 = ↑(a.1, a.2).2 * (a'.1, a'.2).1
case ofFractionRing.ofFractionRing.H.H.e_toFractionRing.refine_1
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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
a a' : R[X] × ↥R[X]⁰
h : φ a.1 / φ ↑a.2 = φ a'.1 / φ ↑a'.2
⊢ φ ↑a.2 ≠ 0
case ofFractionRing.ofFractionRing.H.H.e_toFractionRing.refine_2
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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
a a' : R[X] × ↥R[X]⁰
h : φ a.1 / φ ↑a.2 = φ a'.1 / φ ↑a'.2
⊢ φ ↑a'.2 ≠ 0

Next tactic:
rwa [← map_mul, ← map_mul, hφ.eq_iff, mul_comm, mul_comm a'.fst] at this
theorem liftMonoidWithZeroHom_injective [Nontrivial R] (φ : R[X] →*₀ G₀) (hφ : Function.Injective φ)
    (hφ' : R[X]⁰ ≤ G₀⁰.comap φ := nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ hφ) :
    Function.Injective (liftMonoidWithZeroHom φ hφ') := by
  rintro ⟨x⟩ ⟨y⟩
  induction' x using Localization.induction_on with a
  induction' y using Localization.induction_on with a'
  · simp_rw [liftMonoidWithZeroHom_apply_ofFractionRing_mk]
    intro h
    congr 1
    refine Localization.mk_eq_mk_iff.mpr (Localization.r_of_eq (M := R[X]) ?_)
    have := mul_eq_mul_of_div_eq_div _ _ ?_ ?_ h
    rwa [← map_mul, ← map_mul, hφ.eq_iff, mul_comm, mul_comm a'.fst] at this
    

Proof state:
case ofFractionRing.ofFractionRing.H.H.e_toFractionRing.refine_1
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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
a a' : R[X] × ↥R[X]⁰
h : φ a.1 / φ ↑a.2 = φ a'.1 / φ ↑a'.2
⊢ φ ↑a.2 ≠ 0
case ofFractionRing.ofFractionRing.H.H.e_toFractionRing.refine_2
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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
a a' : R[X] × ↥R[X]⁰
h : φ a.1 / φ ↑a.2 = φ a'.1 / φ ↑a'.2
⊢ φ ↑a'.2 ≠ 0

Next tactic:
all_goals exact map_ne_zero_of_mem_nonZeroDivisors _ hφ (SetLike.coe_mem _)
theorem liftMonoidWithZeroHom_injective [Nontrivial R] (φ : R[X] →*₀ G₀) (hφ : Function.Injective φ)
    (hφ' : R[X]⁰ ≤ G₀⁰.comap φ := nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ hφ) :
    Function.Injective (liftMonoidWithZeroHom φ hφ') := by
  rintro ⟨x⟩ ⟨y⟩
  induction' x using Localization.induction_on with a
  induction' y using Localization.induction_on with a'
  · simp_rw [liftMonoidWithZeroHom_apply_ofFractionRing_mk]
    intro h
    congr 1
    refine Localization.mk_eq_mk_iff.mpr (Localization.r_of_eq (M := R[X]) ?_)
    have := mul_eq_mul_of_div_eq_div _ _ ?_ ?_ h
    rwa [← map_mul, ← map_mul, hφ.eq_iff, mul_comm, mul_comm a'.fst] at this
    all_goals 

Proof state:
case ofFractionRing.ofFractionRing.H.H.e_toFractionRing.refine_1
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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
a a' : R[X] × ↥R[X]⁰
h : φ a.1 / φ ↑a.2 = φ a'.1 / φ ↑a'.2
⊢ φ ↑a.2 ≠ 0

Next tactic:
exact map_ne_zero_of_mem_nonZeroDivisors _ hφ (SetLike.coe_mem _)
theorem liftMonoidWithZeroHom_injective [Nontrivial R] (φ : R[X] →*₀ G₀) (hφ : Function.Injective φ)
    (hφ' : R[X]⁰ ≤ G₀⁰.comap φ := nonZeroDivisors_le_comap_nonZeroDivisors_of_injective _ hφ) :
    Function.Injective (liftMonoidWithZeroHom φ hφ') := by
  rintro ⟨x⟩ ⟨y⟩
  induction' x using Localization.induction_on with a
  induction' y using Localization.induction_on with a'
  · simp_rw [liftMonoidWithZeroHom_apply_ofFractionRing_mk]
    intro h
    congr 1
    refine Localization.mk_eq_mk_iff.mpr (Localization.r_of_eq (M := R[X]) ?_)
    have := mul_eq_mul_of_div_eq_div _ _ ?_ ?_ h
    rwa [← map_mul, ← map_mul, hφ.eq_iff, mul_comm, mul_comm a'.fst] at this
    all_goals 

Proof state:
case ofFractionRing.ofFractionRing.H.H.e_toFractionRing.refine_2
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✝ : Nontrivial R
φ : R[X] →*₀ G₀
hφ : Function.Injective ⇑φ
hφ' : optParam (R[X]⁰ ≤ Submonoid.comap φ G₀⁰) (_ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰)
a a' : R[X] × ↥R[X]⁰
h : φ a.1 / φ ↑a.2 = φ a'.1 / φ ↑a'.2
⊢ φ ↑a'.2 ≠ 0

Next tactic:
exact map_ne_zero_of_mem_nonZeroDivisors _ hφ (SetLike.coe_mem _)
/-- Lift an injective ring homomorphism `R[X] →+* L` to a `RatFunc R →+* L`
by mapping both the numerator and denominator and quotienting them. -/
def liftRingHom (φ : R[X] →+* L) (hφ : R[X]⁰ ≤ L⁰.comap φ) : RatFunc R →+* L :=
  { liftMonoidWithZeroHom φ.toMonoidWithZeroHom hφ with
    map_add' := fun x y => by
      -- porting note: used to invoke `MonoidWithZeroHom.toFun_eq_coe`
      

Proof state:
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
φ : R[X] →+* L
hφ : R[X]⁰ ≤ Submonoid.comap φ L⁰
src✝ : RatFunc R →*₀ L := liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ
x y : RatFunc R
⊢ OneHom.toFun
      (↑{ toOneHom := { toFun := src✝.toFun, map_one' := (_ : ZeroHom.toFun (↑src✝) 1 = 1) },
          map_mul' :=
            (_ :
              ∀ (x y : RatFunc R), ZeroHom.toFun (↑src✝) (x * y) = ZeroHom.toFun (↑src✝) x * ZeroHom.toFun (↑src✝) y) })
      (x + y) =
    OneHom.toFun
        (↑{ toOneHom := { toFun := src✝.toFun, map_one' := (_ : ZeroHom.toFun (↑src✝) 1 = 1) },
            map_mul' :=
              (_ :
                ∀ (x y : RatFunc R),
                  ZeroHom.toFun (↑src✝) (x * y) = ZeroHom.toFun (↑src✝) x * ZeroHom.toFun (↑src✝) y) })
        x +
      OneHom.toFun
        (↑{ toOneHom := { toFun := src✝.toFun, map_one' := (_ : ZeroHom.toFun (↑src✝) 1 = 1) },
            map_mul' :=
              (_ :
                ∀ (x y : RatFunc R),
                  ZeroHom.toFun (↑src✝) (x * y) = ZeroHom.toFun (↑src✝) x * ZeroHom.toFun (↑src✝) y) })
        y

Next tactic:
simp only [ZeroHom.toFun_eq_coe, MonoidWithZeroHom.toZeroHom_coe]
/-- Lift an injective ring homomorphism `R[X] →+* L` to a `RatFunc R →+* L`
by mapping both the numerator and denominator and quotienting them. -/
def liftRingHom (φ : R[X] →+* L) (hφ : R[X]⁰ ≤ L⁰.comap φ) : RatFunc R →+* L :=
  { liftMonoidWithZeroHom φ.toMonoidWithZeroHom hφ with
    map_add' := fun x y => by
      -- porting note: used to invoke `MonoidWithZeroHom.toFun_eq_coe`
      simp only [ZeroHom.toFun_eq_coe, MonoidWithZeroHom.toZeroHom_coe]
      

Proof state:
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
φ : R[X] →+* L
hφ : R[X]⁰ ≤ Submonoid.comap φ L⁰
src✝ : RatFunc R →*₀ L := liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ
x y : RatFunc R
⊢ (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) (x + y) =
    (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) x +
      (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) y

Next tactic:
cases subsingleton_or_nontrivial R
/-- Lift an injective ring homomorphism `R[X] →+* L` to a `RatFunc R →+* L`
by mapping both the numerator and denominator and quotienting them. -/
def liftRingHom (φ : R[X] →+* L) (hφ : R[X]⁰ ≤ L⁰.comap φ) : RatFunc R →+* L :=
  { liftMonoidWithZeroHom φ.toMonoidWithZeroHom hφ with
    map_add' := fun x y => by
      -- porting note: used to invoke `MonoidWithZeroHom.toFun_eq_coe`
      simp only [ZeroHom.toFun_eq_coe, MonoidWithZeroHom.toZeroHom_coe]
      cases subsingleton_or_nontrivial R
      · 

Proof state:
case inl
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
φ : R[X] →+* L
hφ : R[X]⁰ ≤ Submonoid.comap φ L⁰
src✝ : RatFunc R →*₀ L := liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ
x y : RatFunc R
h✝ : Subsingleton R
⊢ (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) (x + y) =
    (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) x +
      (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) y

Next tactic:
rw [Subsingleton.elim (x + y) y, Subsingleton.elim x 0, map_zero, zero_add]
/-- Lift an injective ring homomorphism `R[X] →+* L` to a `RatFunc R →+* L`
by mapping both the numerator and denominator and quotienting them. -/
def liftRingHom (φ : R[X] →+* L) (hφ : R[X]⁰ ≤ L⁰.comap φ) : RatFunc R →+* L :=
  { liftMonoidWithZeroHom φ.toMonoidWithZeroHom hφ with
    map_add' := fun x y => by
      -- porting note: used to invoke `MonoidWithZeroHom.toFun_eq_coe`
      simp only [ZeroHom.toFun_eq_coe, MonoidWithZeroHom.toZeroHom_coe]
      cases subsingleton_or_nontrivial R
      · rw [Subsingleton.elim (x + y) y, Subsingleton.elim x 0, map_zero, zero_add]
      

Proof state:
case inr
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
φ : R[X] →+* L
hφ : R[X]⁰ ≤ Submonoid.comap φ L⁰
src✝ : RatFunc R →*₀ L := liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ
x y : RatFunc R
h✝ : Nontrivial R
⊢ (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) (x + y) =
    (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) x +
      (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) y

Next tactic:
cases' x with x
/-- Lift an injective ring homomorphism `R[X] →+* L` to a `RatFunc R →+* L`
by mapping both the numerator and denominator and quotienting them. -/
def liftRingHom (φ : R[X] →+* L) (hφ : R[X]⁰ ≤ L⁰.comap φ) : RatFunc R →+* L :=
  { liftMonoidWithZeroHom φ.toMonoidWithZeroHom hφ with
    map_add' := fun x y => by
      -- porting note: used to invoke `MonoidWithZeroHom.toFun_eq_coe`
      simp only [ZeroHom.toFun_eq_coe, MonoidWithZeroHom.toZeroHom_coe]
      cases subsingleton_or_nontrivial R
      · rw [Subsingleton.elim (x + y) y, Subsingleton.elim x 0, map_zero, zero_add]
      cases' x with x
      

Proof state:
case inr.ofFractionRing
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
φ : R[X] →+* L
hφ : R[X]⁰ ≤ Submonoid.comap φ L⁰
src✝ : RatFunc R →*₀ L := liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ
y : RatFunc R
h✝ : Nontrivial R
x : FractionRing R[X]
⊢ (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) ({ toFractionRing := x } + y) =
    (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) { toFractionRing := x } +
      (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) y

Next tactic:
cases' y with y
/-- Lift an injective ring homomorphism `R[X] →+* L` to a `RatFunc R →+* L`
by mapping both the numerator and denominator and quotienting them. -/
def liftRingHom (φ : R[X] →+* L) (hφ : R[X]⁰ ≤ L⁰.comap φ) : RatFunc R →+* L :=
  { liftMonoidWithZeroHom φ.toMonoidWithZeroHom hφ with
    map_add' := fun x y => by
      -- porting note: used to invoke `MonoidWithZeroHom.toFun_eq_coe`
      simp only [ZeroHom.toFun_eq_coe, MonoidWithZeroHom.toZeroHom_coe]
      cases subsingleton_or_nontrivial R
      · rw [Subsingleton.elim (x + y) y, Subsingleton.elim x 0, map_zero, zero_add]
      cases' x with x
      cases' y with y
      -- Porting note: had to add the recursor explicitly below
      

Proof state:
case inr.ofFractionRing.ofFractionRing
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
φ : R[X] →+* L
hφ : R[X]⁰ ≤ Submonoid.comap φ L⁰
src✝ : RatFunc R →*₀ L := liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ
h✝ : Nontrivial R
x y : FractionRing R[X]
⊢ (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) ({ toFractionRing := x } + { toFractionRing := y }) =
    (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) { toFractionRing := x } +
      (liftMonoidWithZeroHom (RingHom.toMonoidWithZeroHom φ) hφ) { toFractionRing := y }

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