l3lab/ntp-mathlib huggingface dataset:
/-- Induction principle for `RatFunc K`: if `f p q : P (p / q)` for all `p q : K[X]`,
then `P` holds on all elements of `RatFunc K`.

See also `induction_on'`, which is a recursion principle defined in terms of `RatFunc.mk`.
-/
protected theorem induction_on {P : RatFunc K → Prop} (x : RatFunc K)
    (f : ∀ (p q : K[X]) (hq : q ≠ 0), P (algebraMap _ (RatFunc K) p / algebraMap _ _ q)) : P x :=
  x.induction_on' fun p q hq => by 

Proof state:
K : Type u
inst✝¹ : CommRing K
inst✝ : IsDomain K
P : RatFunc K → Prop
x : RatFunc K
f : ∀ (p q : K[X]), q ≠ 0 → P ((algebraMap K[X] (RatFunc K)) p / (algebraMap K[X] (RatFunc K)) q)
p q : K[X]
hq : q ≠ 0
⊢ P (RatFunc.mk p q)

Next tactic:
simpa using f p q hq
theorem ofFractionRing_mk' (x : K[X]) (y : K[X]⁰) :
    -- porting note: I gave explicitly the argument `(FractionRing K[X])`
    ofFractionRing (IsLocalization.mk' (FractionRing K[X]) x y) =
      IsLocalization.mk' (RatFunc K) x y := by
  

Proof state:
K : Type u
inst✝¹ : CommRing K
inst✝ : IsDomain K
x : K[X]
y : ↥K[X]⁰
⊢ { toFractionRing := IsLocalization.mk' (FractionRing K[X]) x y } = IsLocalization.mk' (RatFunc K) x y

Next tactic:
rw [IsFractionRing.mk'_eq_div, IsFractionRing.mk'_eq_div, ← mk_eq_div', ← mk_eq_div]
@[simp]
theorem ofFractionRing_eq :
    (ofFractionRing : FractionRing K[X] → RatFunc K) = IsLocalization.algEquiv K[X]⁰ _ _ :=
  funext fun x =>
    Localization.induction_on x fun x => by
      

Proof state:
K : Type u
inst✝¹ : CommRing K
inst✝ : IsDomain K
x✝ : FractionRing K[X]
x : K[X] × ↥K[X]⁰
⊢ { toFractionRing := Localization.mk x.1 x.2 } =
    (IsLocalization.algEquiv K[X]⁰ (FractionRing K[X]) (RatFunc K)) (Localization.mk x.1 x.2)

Next tactic:
simp only [IsLocalization.algEquiv_apply, IsLocalization.ringEquivOfRingEquiv_apply,
        Localization.mk_eq_mk'_apply, IsLocalization.map_mk', ofFractionRing_mk',
        RingEquiv.coe_toRingHom, RingEquiv.refl_apply, SetLike.eta]
@[simp]
theorem ofFractionRing_eq :
    (ofFractionRing : FractionRing K[X] → RatFunc K) = IsLocalization.algEquiv K[X]⁰ _ _ :=
  funext fun x =>
    Localization.induction_on x fun x => by
      simp only [IsLocalization.algEquiv_apply, IsLocalization.ringEquivOfRingEquiv_apply,
        Localization.mk_eq_mk'_apply, IsLocalization.map_mk', ofFractionRing_mk',
        RingEquiv.coe_toRingHom, RingEquiv.refl_apply, SetLike.eta]
      -- porting note: added following `simp`.  The previous one can be squeezed.
      

Proof state:
K : Type u
inst✝¹ : CommRing K
inst✝ : IsDomain K
x✝ : FractionRing K[X]
x : K[X] × ↥K[X]⁰
⊢ IsLocalization.mk' (RatFunc K) x.1 x.2 =
    IsLocalization.mk' (RatFunc K) ((RingHom.id K[X]) x.1)
      { val := (RingHom.id K[X]) ↑x.2, property := (_ : ↑x.2 ∈ Submonoid.comap (RingHom.id K[X]) K[X]⁰) }

Next tactic:
simp only [IsFractionRing.mk'_eq_div, RingHom.id_apply, Subtype.coe_eta]
@[simp]
theorem toFractionRing_eq :
    (toFractionRing : RatFunc K → FractionRing K[X]) = IsLocalization.algEquiv K[X]⁰ _ _ :=
  funext fun ⟨x⟩ =>
    Localization.induction_on x fun x => by
      

Proof state:
K : Type u
inst✝¹ : CommRing K
inst✝ : IsDomain K
x✝¹ : RatFunc K
x✝ : FractionRing K[X]
x : K[X] × ↥K[X]⁰
⊢ { toFractionRing := Localization.mk x.1 x.2 }.toFractionRing =
    (IsLocalization.algEquiv K[X]⁰ (RatFunc K) (FractionRing K[X])) { toFractionRing := Localization.mk x.1 x.2 }

Next tactic:
simp only [Localization.mk_eq_mk'_apply, ofFractionRing_mk', IsLocalization.algEquiv_apply,
        IsLocalization.ringEquivOfRingEquiv_apply, IsLocalization.map_mk',
        RingEquiv.coe_toRingHom, RingEquiv.refl_apply, SetLike.eta]
@[simp]
theorem toFractionRing_eq :
    (toFractionRing : RatFunc K → FractionRing K[X]) = IsLocalization.algEquiv K[X]⁰ _ _ :=
  funext fun ⟨x⟩ =>
    Localization.induction_on x fun x => by
      simp only [Localization.mk_eq_mk'_apply, ofFractionRing_mk', IsLocalization.algEquiv_apply,
        IsLocalization.ringEquivOfRingEquiv_apply, IsLocalization.map_mk',
        RingEquiv.coe_toRingHom, RingEquiv.refl_apply, SetLike.eta]
      -- porting note: added following `simp`.  The previous one can be squeezed.
      

Proof state:
K : Type u
inst✝¹ : CommRing K
inst✝ : IsDomain K
x✝¹ : RatFunc K
x✝ : FractionRing K[X]
x : K[X] × ↥K[X]⁰
⊢ IsLocalization.mk' (Localization K[X]⁰) x.1 x.2 =
    IsLocalization.mk' (FractionRing K[X]) ((RingHom.id K[X]) x.1)
      { val := (RingHom.id K[X]) ↑x.2, property := (_ : ↑x.2 ∈ Submonoid.comap (RingHom.id K[X]) K[X]⁰) }

Next tactic:
simp only [IsFractionRing.mk'_eq_div, RingHom.id_apply, Subtype.coe_eta]
@[simp]
theorem toFractionRingRingEquiv_symm_eq :
    (toFractionRingRingEquiv K).symm = (IsLocalization.algEquiv K[X]⁰ _ _).toRingEquiv := by
  

Proof state:
K : Type u
inst✝¹ : CommRing K
inst✝ : IsDomain K
⊢ RingEquiv.symm (toFractionRingRingEquiv K) =
    AlgEquiv.toRingEquiv (IsLocalization.algEquiv K[X]⁰ (FractionRing K[X]) (RatFunc K))

Next tactic:
ext x
@[simp]
theorem toFractionRingRingEquiv_symm_eq :
    (toFractionRingRingEquiv K).symm = (IsLocalization.algEquiv K[X]⁰ _ _).toRingEquiv := by
  ext x
  

Proof state:
case h
K : Type u
inst✝¹ : CommRing K
inst✝ : IsDomain K
x : FractionRing K[X]
⊢ (RingEquiv.symm (toFractionRingRingEquiv K)) x =
    (AlgEquiv.toRingEquiv (IsLocalization.algEquiv K[X]⁰ (FractionRing K[X]) (RatFunc K))) x

Next tactic:
simp [toFractionRingRingEquiv, ofFractionRing_eq, AlgEquiv.coe_ringEquiv']
/-- `RatFunc.numDenom` are numerator and denominator of a rational function over a field,
normalized such that the denominator is monic. -/
def numDenom (x : RatFunc K) : K[X] × K[X] :=
  x.liftOn'
    (fun p q =>
      if q = 0 then ⟨0, 1⟩
      else
        let r := gcd p q
        ⟨Polynomial.C (q / r).leadingCoeff⁻¹ * (p / r),
          Polynomial.C (q / r).leadingCoeff⁻¹ * (q / r)⟩)
  (by
      

Proof state:
K : Type u
inst✝ : Field K
x : RatFunc K
⊢ ∀ {p q a : K[X]},
    q ≠ 0 →
      a ≠ 0 →
        (fun p q =>
              if q = 0 then (0, 1)
              else
                let r := gcd p q;
                (C (leadingCoeff (q / r))⁻¹ * (p / r), C (leadingCoeff (q / r))⁻¹ * (q / r)))
            (a * p) (a * q) =
          (fun p q =>
              if q = 0 then (0, 1)
              else
                let r := gcd p q;
                (C (leadingCoeff (q / r))⁻¹ * (p / r), C (leadingCoeff (q / r))⁻¹ * (q / r)))
            p q

Next tactic:
intros p q a hq ha
/-- `RatFunc.numDenom` are numerator and denominator of a rational function over a field,
normalized such that the denominator is monic. -/
def numDenom (x : RatFunc K) : K[X] × K[X] :=
  x.liftOn'
    (fun p q =>
      if q = 0 then ⟨0, 1⟩
      else
        let r := gcd p q
        ⟨Polynomial.C (q / r).leadingCoeff⁻¹ * (p / r),
          Polynomial.C (q / r).leadingCoeff⁻¹ * (q / r)⟩)
  (by
      intros p q a hq ha
      

Proof state:
K : Type u
inst✝ : Field K
x : RatFunc K
p q a : K[X]
hq : q ≠ 0
ha : a ≠ 0
⊢ (fun p q =>
        if q = 0 then (0, 1)
        else
          let r := gcd p q;
          (C (leadingCoeff (q / r))⁻¹ * (p / r), C (leadingCoeff (q / r))⁻¹ * (q / r)))
      (a * p) (a * q) =
    (fun p q =>
        if q = 0 then (0, 1)
        else
          let r := gcd p q;
          (C (leadingCoeff (q / r))⁻¹ * (p / r), C (leadingCoeff (q / r))⁻¹ * (q / r)))
      p q

Next tactic:
dsimp
/-- `RatFunc.numDenom` are numerator and denominator of a rational function over a field,
normalized such that the denominator is monic. -/
def numDenom (x : RatFunc K) : K[X] × K[X] :=
  x.liftOn'
    (fun p q =>
      if q = 0 then ⟨0, 1⟩
      else
        let r := gcd p q
        ⟨Polynomial.C (q / r).leadingCoeff⁻¹ * (p / r),
          Polynomial.C (q / r).leadingCoeff⁻¹ * (q / r)⟩)
  (by
      intros p q a hq ha
      dsimp
      

Proof state:
K : Type u
inst✝ : Field K
x : RatFunc K
p q a : K[X]
hq : q ≠ 0
ha : a ≠ 0
⊢ (if a * q = 0 then (0, 1)
    else
      (C (leadingCoeff (a * q / gcd (a * p) (a * q)))⁻¹ * (a * p / gcd (a * p) (a * q)),
        C (leadingCoeff (a * q / gcd (a * p) (a * q)))⁻¹ * (a * q / gcd (a * p) (a * q)))) =
    if q = 0 then (0, 1)
    else (C (leadingCoeff (q / gcd p q))⁻¹ * (p / gcd p q), C (leadingCoeff (q / gcd p q))⁻¹ * (q / gcd p q))

Next tactic:
rw [if_neg hq, if_neg (mul_ne_zero ha hq)]
/-- `RatFunc.numDenom` are numerator and denominator of a rational function over a field,
normalized such that the denominator is monic. -/
def numDenom (x : RatFunc K) : K[X] × K[X] :=
  x.liftOn'
    (fun p q =>
      if q = 0 then ⟨0, 1⟩
      else
        let r := gcd p q
        ⟨Polynomial.C (q / r).leadingCoeff⁻¹ * (p / r),
          Polynomial.C (q / r).leadingCoeff⁻¹ * (q / r)⟩)
  (by
      intros p q a hq ha
      dsimp
      rw [if_neg hq, if_neg (mul_ne_zero ha hq)]
      

Proof state:
K : Type u
inst✝ : Field K
x : RatFunc K
p q a : K[X]
hq : q ≠ 0
ha : a ≠ 0
⊢ (C (leadingCoeff (a * q / gcd (a * p) (a * q)))⁻¹ * (a * p / gcd (a * p) (a * q)),
      C (leadingCoeff (a * q / gcd (a * p) (a * q)))⁻¹ * (a * q / gcd (a * p) (a * q))) =
    (C (leadingCoeff (q / gcd p q))⁻¹ * (p / gcd p q), C (leadingCoeff (q / gcd p q))⁻¹ * (q / gcd p q))

Next tactic:
have ha' : a.leadingCoeff ≠ 0 := Polynomial.leadingCoeff_ne_zero.mpr ha
/-- `RatFunc.numDenom` are numerator and denominator of a rational function over a field,
normalized such that the denominator is monic. -/
def numDenom (x : RatFunc K) : K[X] × K[X] :=
  x.liftOn'
    (fun p q =>
      if q = 0 then ⟨0, 1⟩
      else
        let r := gcd p q
        ⟨Polynomial.C (q / r).leadingCoeff⁻¹ * (p / r),
          Polynomial.C (q / r).leadingCoeff⁻¹ * (q / r)⟩)
  (by
      intros p q a hq ha
      dsimp
      rw [if_neg hq, if_neg (mul_ne_zero ha hq)]
      have ha' : a.leadingCoeff ≠ 0 := Polynomial.leadingCoeff_ne_zero.mpr ha
      

Proof state:
K : Type u
inst✝ : Field K
x : RatFunc K
p q a : K[X]
hq : q ≠ 0
ha : a ≠ 0
ha' : leadingCoeff a ≠ 0
⊢ (C (leadingCoeff (a * q / gcd (a * p) (a * q)))⁻¹ * (a * p / gcd (a * p) (a * q)),
      C (leadingCoeff (a * q / gcd (a * p) (a * q)))⁻¹ * (a * q / gcd (a * p) (a * q))) =
    (C (leadingCoeff (q / gcd p q))⁻¹ * (p / gcd p q), C (leadingCoeff (q / gcd p q))⁻¹ * (q / gcd p q))

Next tactic:
have hainv : a.leadingCoeff⁻¹ ≠ 0 := inv_ne_zero ha'
/-- `RatFunc.numDenom` are numerator and denominator of a rational function over a field,
normalized such that the denominator is monic. -/
def numDenom (x : RatFunc K) : K[X] × K[X] :=
  x.liftOn'
    (fun p q =>
      if q = 0 then ⟨0, 1⟩
      else
        let r := gcd p q
        ⟨Polynomial.C (q / r).leadingCoeff⁻¹ * (p / r),
          Polynomial.C (q / r).leadingCoeff⁻¹ * (q / r)⟩)
  (by
      intros p q a hq ha
      dsimp
      rw [if_neg hq, if_neg (mul_ne_zero ha hq)]
      have ha' : a.leadingCoeff ≠ 0 := Polynomial.leadingCoeff_ne_zero.mpr ha
      have hainv : a.leadingCoeff⁻¹ ≠ 0 := inv_ne_zero ha'
      

Proof state:
K : Type u
inst✝ : Field K
x : RatFunc K
p q a : K[X]
hq : q ≠ 0
ha : a ≠ 0
ha' : leadingCoeff a ≠ 0
hainv : (leadingCoeff a)⁻¹ ≠ 0
⊢ (C (leadingCoeff (a * q / gcd (a * p) (a * q)))⁻¹ * (a * p / gcd (a * p) (a * q)),
      C (leadingCoeff (a * q / gcd (a * p) (a * q)))⁻¹ * (a * q / gcd (a * p) (a * q))) =
    (C (leadingCoeff (q / gcd p q))⁻¹ * (p / gcd p q), C (leadingCoeff (q / gcd p q))⁻¹ * (q / gcd p q))

Next tactic:
simp only [Prod.ext_iff, gcd_mul_left, normalize_apply, Polynomial.coe_normUnit, mul_assoc,
        CommGroupWithZero.coe_normUnit _ ha']
/-- `RatFunc.numDenom` are numerator and denominator of a rational function over a field,
normalized such that the denominator is monic. -/
def numDenom (x : RatFunc K) : K[X] × K[X] :=
  x.liftOn'
    (fun p q =>
      if q = 0 then ⟨0, 1⟩
      else
        let r := gcd p q
        ⟨Polynomial.C (q / r).leadingCoeff⁻¹ * (p / r),
          Polynomial.C (q / r).leadingCoeff⁻¹ * (q / r)⟩)
  (by
      intros p q a hq ha
      dsimp
      rw [if_neg hq, if_neg (mul_ne_zero ha hq)]
      have ha' : a.leadingCoeff ≠ 0 := Polynomial.leadingCoeff_ne_zero.mpr ha
      have hainv : a.leadingCoeff⁻¹ ≠ 0 := inv_ne_zero ha'
      simp only [Prod.ext_iff, gcd_mul_left, normalize_apply, Polynomial.coe_normUnit, mul_assoc,
        CommGroupWithZero.coe_normUnit _ ha']
      

Proof state:
K : Type u
inst✝ : Field K
x : RatFunc K
p q a : K[X]
hq : q ≠ 0
ha : a ≠ 0
ha' : leadingCoeff a ≠ 0
hainv : (leadingCoeff a)⁻¹ ≠ 0
⊢ C (leadingCoeff (a * q / (normalize a * gcd p q)))⁻¹ * (a * p / (normalize a * gcd p q)) =
      C (leadingCoeff (q / gcd p q))⁻¹ * (p / gcd p q) ∧
    C (leadingCoeff (a * q / (normalize a * gcd p q)))⁻¹ * (a * q / (normalize a * gcd p q)) =
      C (leadingCoeff (q / gcd p q))⁻¹ * (q / gcd p q)

Next tactic:
have hdeg : (gcd p q).degree ≤ q.degree := degree_gcd_le_right _ hq
/-- `RatFunc.numDenom` are numerator and denominator of a rational function over a field,
normalized such that the denominator is monic. -/
def numDenom (x : RatFunc K) : K[X] × K[X] :=
  x.liftOn'
    (fun p q =>
      if q = 0 then ⟨0, 1⟩
      else
        let r := gcd p q
        ⟨Polynomial.C (q / r).leadingCoeff⁻¹ * (p / r),
          Polynomial.C (q / r).leadingCoeff⁻¹ * (q / r)⟩)
  (by
      intros p q a hq ha
      dsimp
      rw [if_neg hq, if_neg (mul_ne_zero ha hq)]
      have ha' : a.leadingCoeff ≠ 0 := Polynomial.leadingCoeff_ne_zero.mpr ha
      have hainv : a.leadingCoeff⁻¹ ≠ 0 := inv_ne_zero ha'
      simp only [Prod.ext_iff, gcd_mul_left, normalize_apply, Polynomial.coe_normUnit, mul_assoc,
        CommGroupWithZero.coe_normUnit _ ha']
      have hdeg : (gcd p q).degree ≤ q.degree := degree_gcd_le_right _ hq
      

Proof state:
K : Type u
inst✝ : Field K
x : RatFunc K
p q a : K[X]
hq : q ≠ 0
ha : a ≠ 0
ha' : leadingCoeff a ≠ 0
hainv : (leadingCoeff a)⁻¹ ≠ 0
hdeg : degree (gcd p q) ≤ degree q
⊢ C (leadingCoeff (a * q / (normalize a * gcd p q)))⁻¹ * (a * p / (normalize a * gcd p q)) =
      C (leadingCoeff (q / gcd p q))⁻¹ * (p / gcd p q) ∧
    C (leadingCoeff (a * q / (normalize a * gcd p q)))⁻¹ * (a * q / (normalize a * gcd p q)) =
      C (leadingCoeff (q / gcd p q))⁻¹ * (q / gcd p q)

Next tactic:
have hdeg' : (Polynomial.C a.leadingCoeff⁻¹ * gcd p q).degree ≤ q.degree := by
        rw [Polynomial.degree_mul, Polynomial.degree_C hainv, zero_add]
        exact hdeg
/-- `RatFunc.numDenom` are numerator and denominator of a rational function over a field,
normalized such that the denominator is monic. -/
def numDenom (x : RatFunc K) : K[X] × K[X] :=
  x.liftOn'
    (fun p q =>
      if q = 0 then ⟨0, 1⟩
      else
        let r := gcd p q
        ⟨Polynomial.C (q / r).leadingCoeff⁻¹ * (p / r),
          Polynomial.C (q / r).leadingCoeff⁻¹ * (q / r)⟩)
  (by
      intros p q a hq ha
      dsimp
      rw [if_neg hq, if_neg (mul_ne_zero ha hq)]
      have ha' : a.leadingCoeff ≠ 0 := Polynomial.leadingCoeff_ne_zero.mpr ha
      have hainv : a.leadingCoeff⁻¹ ≠ 0 := inv_ne_zero ha'
      simp only [Prod.ext_iff, gcd_mul_left, normalize_apply, Polynomial.coe_normUnit, mul_assoc,
        CommGroupWithZero.coe_normUnit _ ha']
      have hdeg : (gcd p q).degree ≤ q.degree := degree_gcd_le_right _ hq
      have hdeg' : (Polynomial.C a.leadingCoeff⁻¹ * gcd p q).degree ≤ q.degree := by
        

Proof state:
K : Type u
inst✝ : Field K
x : RatFunc K
p q a : K[X]
hq : q ≠ 0
ha : a ≠ 0
ha' : leadingCoeff a ≠ 0
hainv : (leadingCoeff a)⁻¹ ≠ 0
hdeg : degree (gcd p q) ≤ degree q
⊢ degree (C (leadingCoeff a)⁻¹ * gcd p q) ≤ degree q

Next tactic:
rw [Polynomial.degree_mul, Polynomial.degree_C hainv, zero_add]
/-- `RatFunc.numDenom` are numerator and denominator of a rational function over a field,
normalized such that the denominator is monic. -/
def numDenom (x : RatFunc K) : K[X] × K[X] :=
  x.liftOn'
    (fun p q =>
      if q = 0 then ⟨0, 1⟩
      else
        let r := gcd p q
        ⟨Polynomial.C (q / r).leadingCoeff⁻¹ * (p / r),
          Polynomial.C (q / r).leadingCoeff⁻¹ * (q / r)⟩)
  (by
      intros p q a hq ha
      dsimp
      rw [if_neg hq, if_neg (mul_ne_zero ha hq)]
      have ha' : a.leadingCoeff ≠ 0 := Polynomial.leadingCoeff_ne_zero.mpr ha
      have hainv : a.leadingCoeff⁻¹ ≠ 0 := inv_ne_zero ha'
      simp only [Prod.ext_iff, gcd_mul_left, normalize_apply, Polynomial.coe_normUnit, mul_assoc,
        CommGroupWithZero.coe_normUnit _ ha']
      have hdeg : (gcd p q).degree ≤ q.degree := degree_gcd_le_right _ hq
      have hdeg' : (Polynomial.C a.leadingCoeff⁻¹ * gcd p q).degree ≤ q.degree := by
        rw [Polynomial.degree_mul, Polynomial.degree_C hainv, zero_add]
        

Proof state:
K : Type u
inst✝ : Field K
x : RatFunc K
p q a : K[X]
hq : q ≠ 0
ha : a ≠ 0
ha' : leadingCoeff a ≠ 0
hainv : (leadingCoeff a)⁻¹ ≠ 0
hdeg : degree (gcd p q) ≤ degree q
⊢ degree (gcd p q) ≤ degree q

Next tactic:
exact hdeg
/-- `RatFunc.numDenom` are numerator and denominator of a rational function over a field,
normalized such that the denominator is monic. -/
def numDenom (x : RatFunc K) : K[X] × K[X] :=
  x.liftOn'
    (fun p q =>
      if q = 0 then ⟨0, 1⟩
      else
        let r := gcd p q
        ⟨Polynomial.C (q / r).leadingCoeff⁻¹ * (p / r),
          Polynomial.C (q / r).leadingCoeff⁻¹ * (q / r)⟩)
  (by
      intros p q a hq ha
      dsimp
      rw [if_neg hq, if_neg (mul_ne_zero ha hq)]
      have ha' : a.leadingCoeff ≠ 0 := Polynomial.leadingCoeff_ne_zero.mpr ha
      have hainv : a.leadingCoeff⁻¹ ≠ 0 := inv_ne_zero ha'
      simp only [Prod.ext_iff, gcd_mul_left, normalize_apply, Polynomial.coe_normUnit, mul_assoc,
        CommGroupWithZero.coe_normUnit _ ha']
      have hdeg : (gcd p q).degree ≤ q.degree := degree_gcd_le_right _ hq
      have hdeg' : (Polynomial.C a.leadingCoeff⁻¹ * gcd p q).degree ≤ q.degree := by
        rw [Polynomial.degree_mul, Polynomial.degree_C hainv, zero_add]
        exact hdeg
      

Proof state:
K : Type u
inst✝ : Field K
x : RatFunc K
p q a : K[X]
hq : q ≠ 0
ha : a ≠ 0
ha' : leadingCoeff a ≠ 0
hainv : (leadingCoeff a)⁻¹ ≠ 0
hdeg : degree (gcd p q) ≤ degree q
hdeg' : degree (C (leadingCoeff a)⁻¹ * gcd p q) ≤ degree q
⊢ C (leadingCoeff (a * q / (normalize a * gcd p q)))⁻¹ * (a * p / (normalize a * gcd p q)) =
      C (leadingCoeff (q / gcd p q))⁻¹ * (p / gcd p q) ∧
    C (leadingCoeff (a * q / (normalize a * gcd p q)))⁻¹ * (a * q / (normalize a * gcd p q)) =
      C (leadingCoeff (q / gcd p q))⁻¹ * (q / gcd p q)

Next tactic:
have hdivp : Polynomial.C a.leadingCoeff⁻¹ * gcd p q ∣ p :=
        (C_mul_dvd hainv).mpr (gcd_dvd_left p q)
/-- `RatFunc.numDenom` are numerator and denominator of a rational function over a field,
normalized such that the denominator is monic. -/
def numDenom (x : RatFunc K) : K[X] × K[X] :=
  x.liftOn'
    (fun p q =>
      if q = 0 then ⟨0, 1⟩
      else
        let r := gcd p q
        ⟨Polynomial.C (q / r).leadingCoeff⁻¹ * (p / r),
          Polynomial.C (q / r).leadingCoeff⁻¹ * (q / r)⟩)
  (by
      intros p q a hq ha
      dsimp
      rw [if_neg hq, if_neg (mul_ne_zero ha hq)]
      have ha' : a.leadingCoeff ≠ 0 := Polynomial.leadingCoeff_ne_zero.mpr ha
      have hainv : a.leadingCoeff⁻¹ ≠ 0 := inv_ne_zero ha'
      simp only [Prod.ext_iff, gcd_mul_left, normalize_apply, Polynomial.coe_normUnit, mul_assoc,
        CommGroupWithZero.coe_normUnit _ ha']
      have hdeg : (gcd p q).degree ≤ q.degree := degree_gcd_le_right _ hq
      have hdeg' : (Polynomial.C a.leadingCoeff⁻¹ * gcd p q).degree ≤ q.degree := by
        rw [Polynomial.degree_mul, Polynomial.degree_C hainv, zero_add]
        exact hdeg
      have hdivp : Polynomial.C a.leadingCoeff⁻¹ * gcd p q ∣ p :=
        (C_mul_dvd hainv).mpr (gcd_dvd_left p q)
      

Proof state:
K : Type u
inst✝ : Field K
x : RatFunc K
p q a : K[X]
hq : q ≠ 0
ha : a ≠ 0
ha' : leadingCoeff a ≠ 0
hainv : (leadingCoeff a)⁻¹ ≠ 0
hdeg : degree (gcd p q) ≤ degree q
hdeg' : degree (C (leadingCoeff a)⁻¹ * gcd p q) ≤ degree q
hdivp : C (leadingCoeff a)⁻¹ * gcd p q ∣ p
⊢ C (leadingCoeff (a * q / (normalize a * gcd p q)))⁻¹ * (a * p / (normalize a * gcd p q)) =
      C (leadingCoeff (q / gcd p q))⁻¹ * (p / gcd p q) ∧
    C (leadingCoeff (a * q / (normalize a * gcd p q)))⁻¹ * (a * q / (normalize a * gcd p q)) =
      C (leadingCoeff (q / gcd p q))⁻¹ * (q / gcd p q)

Next tactic:
have hdivq : Polynomial.C a.leadingCoeff⁻¹ * gcd p q ∣ q :=
        (C_mul_dvd hainv).mpr (gcd_dvd_right p q)
/-- `RatFunc.numDenom` are numerator and denominator of a rational function over a field,
normalized such that the denominator is monic. -/
def numDenom (x : RatFunc K) : K[X] × K[X] :=
  x.liftOn'
    (fun p q =>
      if q = 0 then ⟨0, 1⟩
      else
        let r := gcd p q
        ⟨Polynomial.C (q / r).leadingCoeff⁻¹ * (p / r),
          Polynomial.C (q / r).leadingCoeff⁻¹ * (q / r)⟩)
  (by
      intros p q a hq ha
      dsimp
      rw [if_neg hq, if_neg (mul_ne_zero ha hq)]
      have ha' : a.leadingCoeff ≠ 0 := Polynomial.leadingCoeff_ne_zero.mpr ha
      have hainv : a.leadingCoeff⁻¹ ≠ 0 := inv_ne_zero ha'
      simp only [Prod.ext_iff, gcd_mul_left, normalize_apply, Polynomial.coe_normUnit, mul_assoc,
        CommGroupWithZero.coe_normUnit _ ha']
      have hdeg : (gcd p q).degree ≤ q.degree := degree_gcd_le_right _ hq
      have hdeg' : (Polynomial.C a.leadingCoeff⁻¹ * gcd p q).degree ≤ q.degree := by
        rw [Polynomial.degree_mul, Polynomial.degree_C hainv, zero_add]
        exact hdeg
      have hdivp : Polynomial.C a.leadingCoeff⁻¹ * gcd p q ∣ p :=
        (C_mul_dvd hainv).mpr (gcd_dvd_left p q)
      have hdivq : Polynomial.C a.leadingCoeff⁻¹ * gcd p q ∣ q :=
        (C_mul_dvd hainv).mpr (gcd_dvd_right p q)
      -- porting note: added `simp only [...]` and `rw [mul_assoc]`
      -- porting note: note the unfolding of `normalize` and `normUnit`!
      

Proof state:
K : Type u
inst✝ : Field K
x : RatFunc K
p q a : K[X]
hq : q ≠ 0
ha : a ≠ 0
ha' : leadingCoeff a ≠ 0
hainv : (leadingCoeff a)⁻¹ ≠ 0
hdeg : degree (gcd p q) ≤ degree q
hdeg' : degree (C (leadingCoeff a)⁻¹ * gcd p q) ≤ degree q
hdivp : C (leadingCoeff a)⁻¹ * gcd p q ∣ p
hdivq : C (leadingCoeff a)⁻¹ * gcd p q ∣ q
⊢ C (leadingCoeff (a * q / (normalize a * gcd p q)))⁻¹ * (a * p / (normalize a * gcd p q)) =
      C (leadingCoeff (q / gcd p q))⁻¹ * (p / gcd p q) ∧
    C (leadingCoeff (a * q / (normalize a * gcd p q)))⁻¹ * (a * q / (normalize a * gcd p q)) =
      C (leadingCoeff (q / gcd p q))⁻¹ * (q / gcd p q)

Next tactic:
simp only [normalize, normUnit, coe_normUnit, leadingCoeff_eq_zero, MonoidWithZeroHom.coe_mk,
        ZeroHom.coe_mk, ha, dite_false, Units.val_inv_eq_inv_val, Units.val_mk0]