l3lab/ntp-mathlib huggingface dataset:
theorem map_injective [MonoidHomClass F R[X] S[X]] (φ : F) (hφ : R[X]⁰ ≤ S[X]⁰.comap φ)
    (hf : Function.Injective φ) : Function.Injective (map φ hφ) := by
  rintro ⟨x⟩ ⟨y⟩ h
  -- porting note: had to hint `induction` which induction principle to use
  induction x using Localization.induction_on
  induction y using Localization.induction_on
  

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✝ : MonoidHomClass F R[X] S[X]
φ : F
hφ : R[X]⁰ ≤ Submonoid.comap φ S[X]⁰
hf : Function.Injective ⇑φ
y✝¹ y✝ : R[X] × ↥R[X]⁰
h :
  (map φ hφ) { toFractionRing := Localization.mk y✝¹.1 y✝¹.2 } =
    (map φ hφ) { toFractionRing := Localization.mk y✝.1 y✝.2 }
⊢ { toFractionRing := Localization.mk y✝¹.1 y✝¹.2 } = { toFractionRing := Localization.mk y✝.1 y✝.2 }

Next tactic:
simpa only [map_apply_ofFractionRing_mk, ofFractionRing_injective.eq_iff,
    Localization.mk_eq_mk_iff, Localization.r_iff_exists, mul_cancel_left_coe_nonZeroDivisors,
    exists_const, ← map_mul, hf.eq_iff] using h
/-- Lift a ring 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 mapRingHom [RingHomClass F R[X] S[X]] (φ : F) (hφ : R[X]⁰ ≤ S[X]⁰.comap φ) :
    RatFunc R →+* RatFunc S :=
  { map φ hφ with
    map_zero' := 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✝ : RingHomClass F R[X] S[X]
φ : F
hφ : R[X]⁰ ≤ Submonoid.comap φ S[X]⁰
src✝ : RatFunc R →* RatFunc S := map φ hφ
⊢ OneHom.toFun
      (↑{ toOneHom := ↑src✝,
          map_mul' :=
            (_ : ∀ (x y : RatFunc R), OneHom.toFun (↑src✝) (x * y) = OneHom.toFun (↑src✝) x * OneHom.toFun (↑src✝) y) })
      0 =
    0

Next tactic:
simp_rw [MonoidHom.toFun_eq_coe, ← ofFractionRing_zero, ← Localization.mk_zero (1 : R[X]⁰),
        ← Localization.mk_zero (1 : S[X]⁰), map_apply_ofFractionRing_mk, map_zero,
        Localization.mk_eq_mk', IsLocalization.mk'_zero]
/-- Lift a ring 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 mapRingHom [RingHomClass F R[X] S[X]] (φ : F) (hφ : R[X]⁰ ≤ S[X]⁰.comap φ) :
    RatFunc R →+* RatFunc S :=
  { map φ hφ with
    map_zero' := by
      simp_rw [MonoidHom.toFun_eq_coe, ← ofFractionRing_zero, ← Localization.mk_zero (1 : R[X]⁰),
        ← Localization.mk_zero (1 : S[X]⁰), map_apply_ofFractionRing_mk, map_zero,
        Localization.mk_eq_mk', IsLocalization.mk'_zero]
    map_add' := 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✝ : RingHomClass F R[X] S[X]
φ : F
hφ : R[X]⁰ ≤ Submonoid.comap φ S[X]⁰
src✝ : RatFunc R →* RatFunc S := map φ hφ
⊢ ∀ (x y : RatFunc R),
    OneHom.toFun
        (↑{ toOneHom := ↑src✝,
            map_mul' :=
              (_ :
                ∀ (x y : RatFunc R), OneHom.toFun (↑src✝) (x * y) = OneHom.toFun (↑src✝) x * OneHom.toFun (↑src✝) y) })
        (x + y) =
      OneHom.toFun
          (↑{ toOneHom := ↑src✝,
              map_mul' :=
                (_ :
                  ∀ (x y : RatFunc R),
                    OneHom.toFun (↑src✝) (x * y) = OneHom.toFun (↑src✝) x * OneHom.toFun (↑src✝) y) })
          x +
        OneHom.toFun
          (↑{ toOneHom := ↑src✝,
              map_mul' :=
                (_ :
                  ∀ (x y : RatFunc R),
                    OneHom.toFun (↑src✝) (x * y) = OneHom.toFun (↑src✝) x * OneHom.toFun (↑src✝) y) })
          y

Next tactic:
rintro ⟨x⟩ ⟨y⟩
/-- Lift a ring 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 mapRingHom [RingHomClass F R[X] S[X]] (φ : F) (hφ : R[X]⁰ ≤ S[X]⁰.comap φ) :
    RatFunc R →+* RatFunc S :=
  { map φ hφ with
    map_zero' := by
      simp_rw [MonoidHom.toFun_eq_coe, ← ofFractionRing_zero, ← Localization.mk_zero (1 : R[X]⁰),
        ← Localization.mk_zero (1 : S[X]⁰), map_apply_ofFractionRing_mk, map_zero,
        Localization.mk_eq_mk', IsLocalization.mk'_zero]
    map_add' := by
      rintro ⟨x⟩ ⟨y⟩
      -- porting note: had to hint `induction` which induction principle to use
      

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✝ : RingHomClass F R[X] S[X]
φ : F
hφ : R[X]⁰ ≤ Submonoid.comap φ S[X]⁰
src✝ : RatFunc R →* RatFunc S := map φ hφ
x y : FractionRing R[X]
⊢ OneHom.toFun
      (↑{ toOneHom := ↑src✝,
          map_mul' :=
            (_ : ∀ (x y : RatFunc R), OneHom.toFun (↑src✝) (x * y) = OneHom.toFun (↑src✝) x * OneHom.toFun (↑src✝) y) })
      ({ toFractionRing := x } + { toFractionRing := y }) =
    OneHom.toFun
        ↑{ toOneHom := ↑src✝,
            map_mul' :=
              (_ :
                ∀ (x y : RatFunc R), OneHom.toFun (↑src✝) (x * y) = OneHom.toFun (↑src✝) x * OneHom.toFun (↑src✝) y) }
        { toFractionRing := x } +
      OneHom.toFun
        ↑{ toOneHom := ↑src✝,
            map_mul' :=
              (_ :
                ∀ (x y : RatFunc R), OneHom.toFun (↑src✝) (x * y) = OneHom.toFun (↑src✝) x * OneHom.toFun (↑src✝) y) }
        { toFractionRing := y }

Next tactic:
induction x using Localization.rec
/-- Lift a ring 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 mapRingHom [RingHomClass F R[X] S[X]] (φ : F) (hφ : R[X]⁰ ≤ S[X]⁰.comap φ) :
    RatFunc R →+* RatFunc S :=
  { map φ hφ with
    map_zero' := by
      simp_rw [MonoidHom.toFun_eq_coe, ← ofFractionRing_zero, ← Localization.mk_zero (1 : R[X]⁰),
        ← Localization.mk_zero (1 : S[X]⁰), map_apply_ofFractionRing_mk, map_zero,
        Localization.mk_eq_mk', IsLocalization.mk'_zero]
    map_add' := by
      rintro ⟨x⟩ ⟨y⟩
      -- porting note: had to hint `induction` which induction principle to use
      induction x using Localization.rec
      induction y using Localization.rec
      · 

Proof state:
case ofFractionRing.ofFractionRing.f.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✝ : RingHomClass F R[X] S[X]
φ : F
hφ : R[X]⁰ ≤ Submonoid.comap φ S[X]⁰
src✝ : RatFunc R →* RatFunc S := map φ hφ
a✝¹ : R[X]
b✝¹ : ↥R[X]⁰
a✝ : R[X]
b✝ : ↥R[X]⁰
⊢ OneHom.toFun
      (↑{ toOneHom := ↑src✝,
          map_mul' :=
            (_ : ∀ (x y : RatFunc R), OneHom.toFun (↑src✝) (x * y) = OneHom.toFun (↑src✝) x * OneHom.toFun (↑src✝) y) })
      ({ toFractionRing := Localization.mk a✝¹ b✝¹ } + { toFractionRing := Localization.mk a✝ b✝ }) =
    OneHom.toFun
        ↑{ toOneHom := ↑src✝,
            map_mul' :=
              (_ :
                ∀ (x y : RatFunc R), OneHom.toFun (↑src✝) (x * y) = OneHom.toFun (↑src✝) x * OneHom.toFun (↑src✝) y) }
        { toFractionRing := Localization.mk a✝¹ b✝¹ } +
      OneHom.toFun
        ↑{ toOneHom := ↑src✝,
            map_mul' :=
              (_ :
                ∀ (x y : RatFunc R), OneHom.toFun (↑src✝) (x * y) = OneHom.toFun (↑src✝) x * OneHom.toFun (↑src✝) y) }
        { toFractionRing := Localization.mk a✝ b✝ }

Next tactic:
simp only [← ofFractionRing_add, Localization.add_mk, map_add, map_mul,
          MonoidHom.toFun_eq_coe, map_apply_ofFractionRing_mk, Submonoid.coe_mul]
/-- Lift a ring 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 mapRingHom [RingHomClass F R[X] S[X]] (φ : F) (hφ : R[X]⁰ ≤ S[X]⁰.comap φ) :
    RatFunc R →+* RatFunc S :=
  { map φ hφ with
    map_zero' := by
      simp_rw [MonoidHom.toFun_eq_coe, ← ofFractionRing_zero, ← Localization.mk_zero (1 : R[X]⁰),
        ← Localization.mk_zero (1 : S[X]⁰), map_apply_ofFractionRing_mk, map_zero,
        Localization.mk_eq_mk', IsLocalization.mk'_zero]
    map_add' := by
      rintro ⟨x⟩ ⟨y⟩
      -- porting note: had to hint `induction` which induction principle to use
      induction x using Localization.rec
      induction y using Localization.rec
      · simp only [← ofFractionRing_add, Localization.add_mk, map_add, map_mul,
          MonoidHom.toFun_eq_coe, map_apply_ofFractionRing_mk, Submonoid.coe_mul]
        -- Porting note: `Submonoid.mk_mul_mk` couldn't be applied: motive incorrect,
        -- even though it is a rfl lemma.
        

Proof state:
case ofFractionRing.ofFractionRing.f.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✝ : RingHomClass F R[X] S[X]
φ : F
hφ : R[X]⁰ ≤ Submonoid.comap φ S[X]⁰
src✝ : RatFunc R →* RatFunc S := map φ hφ
a✝¹ : R[X]
b✝¹ : ↥R[X]⁰
a✝ : R[X]
b✝ : ↥R[X]⁰
⊢ {
      toFractionRing :=
        Localization.mk (φ ↑b✝¹ * φ a✝ + φ ↑b✝ * φ a✝¹)
          { val := φ ↑b✝¹ * φ ↑b✝, property := (_ : (fun x => x ∈ S[X]⁰) (φ ↑b✝¹ * φ ↑b✝)) } } =
    {
      toFractionRing :=
        Localization.mk (φ ↑b✝¹ * φ a✝ + φ ↑b✝ * φ a✝¹)
          ({ val := φ ↑b✝¹, property := (_ : ↑b✝¹ ∈ Submonoid.comap φ S[X]⁰) } *
            { val := φ ↑b✝, property := (_ : ↑b✝ ∈ Submonoid.comap φ S[X]⁰) }) }

Next tactic:
rfl
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
      

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₀⁰
f : RatFunc R
p q p' q' : R[X]
hq : q ∈ R[X]⁰
hq' : q' ∈ R[X]⁰
h : q' * p = q * p'
⊢ (fun p q => φ p / φ q) p q = (fun p q => φ p / φ q) p' q'

Next tactic:
cases subsingleton_or_nontrivial R
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
      · 

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] →*₀ G₀
hφ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰
f : RatFunc R
p q p' q' : R[X]
hq : q ∈ R[X]⁰
hq' : q' ∈ R[X]⁰
h : q' * p = q * p'
h✝ : Subsingleton R
⊢ (fun p q => φ p / φ q) p q = (fun p q => φ p / φ q) p' q'

Next tactic:
rw [Subsingleton.elim p q, Subsingleton.elim p' q, Subsingleton.elim q' q]
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]
      

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] →*₀ G₀
hφ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰
f : RatFunc R
p q p' q' : R[X]
hq : q ∈ R[X]⁰
hq' : q' ∈ R[X]⁰
h : q' * p = q * p'
h✝ : Nontrivial R
⊢ (fun p q => φ p / φ q) p q = (fun p q => φ p / φ q) p' q'

Next tactic:
rw [div_eq_div_iff, ← map_mul, mul_comm p, h, map_mul, mul_comm]
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] <;>
        

Proof state:
case inr.hb
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₀⁰
f : RatFunc R
p q p' q' : R[X]
hq : q ∈ R[X]⁰
hq' : q' ∈ R[X]⁰
h : q' * p = q * p'
h✝ : Nontrivial R
⊢ φ q ≠ 0

Next tactic:
exact nonZeroDivisors.ne_zero (hφ ‹_›)
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] <;>
        

Proof state:
case inr.hd
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₀⁰
f : RatFunc R
p q p' q' : R[X]
hq : q ∈ R[X]⁰
hq' : q' ∈ R[X]⁰
h : q' * p = q * p'
h✝ : Nontrivial R
⊢ φ q' ≠ 0

Next tactic:
exact nonZeroDivisors.ne_zero (hφ ‹_›)
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]
    simp only [map_one, OneMemClass.coe_one, div_one]
  map_mul' x y := by
    cases' x with x
    cases' y with y
    induction' x using Localization.rec with p q
    induction' y using Localization.rec with p' q'
    · rw [← ofFractionRing_mul, Localization.mk_mul]
      simp only [liftOn_ofFractionRing_mk, div_mul_div_comm, map_mul, Submonoid.coe_mul]
    · rfl
    · rfl
  map_zero' := 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
φ : R[X] →*₀ G₀
hφ : R[X]⁰ ≤ Submonoid.comap φ G₀⁰
⊢ (fun f =>
        RatFunc.liftOn f (fun p q => φ p / φ q)
          (_ :
            ∀ {p q p' q' : R[X]},
              q ∈ R[X]⁰ → q' ∈ R[X]⁰ → q' * p = q * p' → (fun p q => φ p / φ q) p q = (fun p q => φ p / φ q) p' q'))
      0 =
    0

Next tactic:
dsimp only
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]
    simp only [map_one, OneMemClass.coe_one, div_one]
  map_mul' x y := by
    cases' x with x
    cases' y with y
    induction' x using Localization.rec with p q
    induction' y using Localization.rec with p' q'
    · rw [← ofFractionRing_mul, Localization.mk_mul]
      simp only [liftOn_ofFractionRing_mk, div_mul_div_comm, map_mul, Submonoid.coe_mul]
    · rfl
    · rfl
  map_zero' := by
    dsimp only -- porting note: force the function to be applied
    

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₀⁰
⊢ RatFunc.liftOn 0 (fun p q => φ p / φ q)
      (_ : ∀ {p q p' q' : R[X]}, q ∈ R[X]⁰ → q' ∈ R[X]⁰ → q' * p = q * p' → φ p / φ q = φ p' / φ q') =
    0

Next tactic:
rw [← ofFractionRing_zero, ← Localization.mk_zero (1 : R[X]⁰), liftOn_ofFractionRing_mk]
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]
    simp only [map_one, OneMemClass.coe_one, div_one]
  map_mul' x y := by
    cases' x with x
    cases' y with y
    induction' x using Localization.rec with p q
    induction' y using Localization.rec with p' q'
    · rw [← ofFractionRing_mul, Localization.mk_mul]
      simp only [liftOn_ofFractionRing_mk, div_mul_div_comm, map_mul, Submonoid.coe_mul]
    · rfl
    · rfl
  map_zero' := by
    dsimp only -- porting note: force the function to be applied
    rw [← ofFractionRing_zero, ← Localization.mk_zero (1 : R[X]⁰), 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₀⁰
⊢ φ 0 / φ ↑1 = 0

Next tactic:
simp only [map_zero, zero_div]
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
    

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₀⁰
⊢ ZeroHom.toFun
      {
        toFun := fun f =>
          RatFunc.liftOn f (fun p q => φ p / φ q)
            (_ :
              ∀ {p q p' q' : R[X]},
                q ∈ R[X]⁰ → q' ∈ R[X]⁰ → q' * p = q * p' → (fun p q => φ p / φ q) p q = (fun p q => φ p / φ q) p' q'),
        map_zero' :=
          (_ :
            (fun f =>
                  RatFunc.liftOn f (fun p q => φ p / φ q)
                    (_ :
                      ∀ {p q p' q' : R[X]},
                        q ∈ R[X]⁰ →
                          q' ∈ R[X]⁰ → q' * p = q * p' → (fun p q => φ p / φ q) p q = (fun p q => φ p / φ q) p' q'))
                0 =
              0) }
      1 =
    1

Next tactic:
dsimp only
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
    

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₀⁰
⊢ RatFunc.liftOn 1 (fun p q => φ p / φ q)
      (_ : ∀ {p q p' q' : R[X]}, q ∈ R[X]⁰ → q' ∈ R[X]⁰ → q' * p = q * p' → φ p / φ q = φ p' / φ q') =
    1

Next tactic:
rw [← ofFractionRing_one, ← Localization.mk_one, liftOn_ofFractionRing_mk]