l3lab/ntp-mathlib huggingface dataset:
theorem finite_nat_iff {a b : ℕ} : Finite a b ↔ a ≠ 1 ∧ 0 < b := by
  rw [← not_iff_not, not_finite_iff_forall, not_and_or, Ne.def, Classical.not_not, not_lt,
    le_zero_iff]
  exact
    ⟨fun h =>
      or_iff_not_imp_right.2 fun hb =>
        have ha : a ≠ 0 := fun ha => hb <| zero_dvd_iff.mp <| by rw [ha] at h; exact h 1
        Classical.by_contradiction fun ha1 : a ≠ 1 =>
          have ha_gt_one : 1 < a :=
            lt_of_not_ge fun _ =>
              match a with
              | 0 => ha rfl
              | 1 => ha1 rfl
              | b+2 => by linarith
          not_lt_of_ge (le_of_dvd (Nat.pos_of_ne_zero hb) (h b)) (lt_pow_self ha_gt_one b),
      fun h => by cases h <;> 

Proof state:
case inl
α : Type u_1
β : Type u_2
inst✝³ : Monoid α
inst✝² : Monoid β
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : ℕ
h✝ : a = 1
⊢ ∀ (n : ℕ), a ^ n ∣ b

Next tactic:
simp [*]
theorem finite_nat_iff {a b : ℕ} : Finite a b ↔ a ≠ 1 ∧ 0 < b := by
  rw [← not_iff_not, not_finite_iff_forall, not_and_or, Ne.def, Classical.not_not, not_lt,
    le_zero_iff]
  exact
    ⟨fun h =>
      or_iff_not_imp_right.2 fun hb =>
        have ha : a ≠ 0 := fun ha => hb <| zero_dvd_iff.mp <| by rw [ha] at h; exact h 1
        Classical.by_contradiction fun ha1 : a ≠ 1 =>
          have ha_gt_one : 1 < a :=
            lt_of_not_ge fun _ =>
              match a with
              | 0 => ha rfl
              | 1 => ha1 rfl
              | b+2 => by linarith
          not_lt_of_ge (le_of_dvd (Nat.pos_of_ne_zero hb) (h b)) (lt_pow_self ha_gt_one b),
      fun h => by cases h <;> 

Proof state:
case inr
α : Type u_1
β : Type u_2
inst✝³ : Monoid α
inst✝² : Monoid β
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : ℕ
h✝ : b = 0
⊢ ∀ (n : ℕ), a ^ n ∣ b

Next tactic:
simp [*]
theorem finite_of_finite_mul_left {a b c : α} : Finite a (b * c) → Finite a c := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : CommMonoid α
a b c : α
⊢ Finite a (b * c) → Finite a c

Next tactic:
rw [mul_comm]
theorem finite_of_finite_mul_left {a b c : α} : Finite a (b * c) → Finite a c := by
  rw [mul_comm]; 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : CommMonoid α
a b c : α
⊢ Finite a (c * b) → Finite a c

Next tactic:
exact finite_of_finite_mul_right
theorem isUnit_right {a b : α} (ha : ¬IsUnit a) (hb : IsUnit b) : multiplicity a b = 0 :=
  eq_coe_iff.2
    ⟨show a ^ 0 ∣ b by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CommMonoid α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
ha : ¬IsUnit a
hb : IsUnit b
⊢ a ^ 0 ∣ b

Next tactic:
simp only [_root_.pow_zero, one_dvd]
theorem isUnit_right {a b : α} (ha : ¬IsUnit a) (hb : IsUnit b) : multiplicity a b = 0 :=
  eq_coe_iff.2
    ⟨show a ^ 0 ∣ b by simp only [_root_.pow_zero, one_dvd], by
      

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CommMonoid α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
ha : ¬IsUnit a
hb : IsUnit b
⊢ ¬a ^ (0 + 1) ∣ b

Next tactic:
rw [pow_one]
theorem isUnit_right {a b : α} (ha : ¬IsUnit a) (hb : IsUnit b) : multiplicity a b = 0 :=
  eq_coe_iff.2
    ⟨show a ^ 0 ∣ b by simp only [_root_.pow_zero, one_dvd], by
      rw [pow_one]
      

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CommMonoid α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
ha : ¬IsUnit a
hb : IsUnit b
⊢ ¬a ∣ b

Next tactic:
exact fun h => mt (isUnit_of_dvd_unit h) ha hb
theorem ne_zero_of_finite {a b : α} (h : Finite a b) : b ≠ 0 :=
  let ⟨n, hn⟩ := h
  fun hb => by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : MonoidWithZero α
a b : α
h : Finite a b
n : ℕ
hn : ¬a ^ (n + 1) ∣ b
hb : b = 0
⊢ False

Next tactic:
simp [hb] at hn
theorem multiplicity_mk_eq_multiplicity
    [DecidableRel ((· ∣ ·) : Associates α → Associates α → Prop)] {a b : α} :
    multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝² : CommMonoidWithZero α
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
⊢ multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b

Next tactic:
by_cases h : Finite a b
theorem multiplicity_mk_eq_multiplicity
    [DecidableRel ((· ∣ ·) : Associates α → Associates α → Prop)] {a b : α} :
    multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b := by
  by_cases h : Finite a b
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝² : CommMonoidWithZero α
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
h : Finite a b
⊢ multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b

Next tactic:
rw [← PartENat.natCast_get (finite_iff_dom.mp h)]
theorem multiplicity_mk_eq_multiplicity
    [DecidableRel ((· ∣ ·) : Associates α → Associates α → Prop)] {a b : α} :
    multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b := by
  by_cases h : Finite a b
  · rw [← PartENat.natCast_get (finite_iff_dom.mp h)]
    

Proof state:
case pos
α : Type u_1
β : Type u_2
inst✝² : CommMonoidWithZero α
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
h : Finite a b
⊢ multiplicity (Associates.mk a) (Associates.mk b) = ↑(Part.get (multiplicity a b) (_ : (multiplicity a b).Dom))

Next tactic:
refine'
        (multiplicity.unique
            (show Associates.mk a ^ (multiplicity a b).get h ∣ Associates.mk b from _) _).symm
theorem multiplicity_mk_eq_multiplicity
    [DecidableRel ((· ∣ ·) : Associates α → Associates α → Prop)] {a b : α} :
    multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b := by
  by_cases h : Finite a b
  · rw [← PartENat.natCast_get (finite_iff_dom.mp h)]
    refine'
        (multiplicity.unique
            (show Associates.mk a ^ (multiplicity a b).get h ∣ Associates.mk b from _) _).symm <;>
      

Proof state:
case pos.refine'_1
α : Type u_1
β : Type u_2
inst✝² : CommMonoidWithZero α
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
h : Finite a b
⊢ Associates.mk a ^ Part.get (multiplicity a b) h ∣ Associates.mk b

Next tactic:
rw [← Associates.mk_pow, Associates.mk_dvd_mk]
theorem multiplicity_mk_eq_multiplicity
    [DecidableRel ((· ∣ ·) : Associates α → Associates α → Prop)] {a b : α} :
    multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b := by
  by_cases h : Finite a b
  · rw [← PartENat.natCast_get (finite_iff_dom.mp h)]
    refine'
        (multiplicity.unique
            (show Associates.mk a ^ (multiplicity a b).get h ∣ Associates.mk b from _) _).symm <;>
      

Proof state:
case pos.refine'_2
α : Type u_1
β : Type u_2
inst✝² : CommMonoidWithZero α
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
h : Finite a b
⊢ ¬Associates.mk a ^ (Part.get (multiplicity a b) h + 1) ∣ Associates.mk b

Next tactic:
rw [← Associates.mk_pow, Associates.mk_dvd_mk]
theorem multiplicity_mk_eq_multiplicity
    [DecidableRel ((· ∣ ·) : Associates α → Associates α → Prop)] {a b : α} :
    multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b := by
  by_cases h : Finite a b
  · rw [← PartENat.natCast_get (finite_iff_dom.mp h)]
    refine'
        (multiplicity.unique
            (show Associates.mk a ^ (multiplicity a b).get h ∣ Associates.mk b from _) _).symm <;>
      rw [← Associates.mk_pow, Associates.mk_dvd_mk]
    · 

Proof state:
case pos.refine'_1
α : Type u_1
β : Type u_2
inst✝² : CommMonoidWithZero α
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
h : Finite a b
⊢ a ^ Part.get (multiplicity a b) h ∣ b

Next tactic:
exact pow_multiplicity_dvd h
theorem multiplicity_mk_eq_multiplicity
    [DecidableRel ((· ∣ ·) : Associates α → Associates α → Prop)] {a b : α} :
    multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b := by
  by_cases h : Finite a b
  · rw [← PartENat.natCast_get (finite_iff_dom.mp h)]
    refine'
        (multiplicity.unique
            (show Associates.mk a ^ (multiplicity a b).get h ∣ Associates.mk b from _) _).symm <;>
      rw [← Associates.mk_pow, Associates.mk_dvd_mk]
    · exact pow_multiplicity_dvd h
    · 

Proof state:
case pos.refine'_2
α : Type u_1
β : Type u_2
inst✝² : CommMonoidWithZero α
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
h : Finite a b
⊢ ¬a ^ (Part.get (multiplicity a b) h + 1) ∣ b

Next tactic:
exact is_greatest
          ((PartENat.lt_coe_iff _ _).mpr (Exists.intro (finite_iff_dom.mp h) (Nat.lt_succ_self _)))
theorem multiplicity_mk_eq_multiplicity
    [DecidableRel ((· ∣ ·) : Associates α → Associates α → Prop)] {a b : α} :
    multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b := by
  by_cases h : Finite a b
  · rw [← PartENat.natCast_get (finite_iff_dom.mp h)]
    refine'
        (multiplicity.unique
            (show Associates.mk a ^ (multiplicity a b).get h ∣ Associates.mk b from _) _).symm <;>
      rw [← Associates.mk_pow, Associates.mk_dvd_mk]
    · exact pow_multiplicity_dvd h
    · exact is_greatest
          ((PartENat.lt_coe_iff _ _).mpr (Exists.intro (finite_iff_dom.mp h) (Nat.lt_succ_self _)))
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝² : CommMonoidWithZero α
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
h : ¬Finite a b
⊢ multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b

Next tactic:
suffices ¬Finite (Associates.mk a) (Associates.mk b) by
      rw [finite_iff_dom, PartENat.not_dom_iff_eq_top] at h this
      rw [h, this]
theorem multiplicity_mk_eq_multiplicity
    [DecidableRel ((· ∣ ·) : Associates α → Associates α → Prop)] {a b : α} :
    multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b := by
  by_cases h : Finite a b
  · rw [← PartENat.natCast_get (finite_iff_dom.mp h)]
    refine'
        (multiplicity.unique
            (show Associates.mk a ^ (multiplicity a b).get h ∣ Associates.mk b from _) _).symm <;>
      rw [← Associates.mk_pow, Associates.mk_dvd_mk]
    · exact pow_multiplicity_dvd h
    · exact is_greatest
          ((PartENat.lt_coe_iff _ _).mpr (Exists.intro (finite_iff_dom.mp h) (Nat.lt_succ_self _)))
  · suffices ¬Finite (Associates.mk a) (Associates.mk b) by
      

Proof state:
α : Type u_1
β : Type u_2
inst✝² : CommMonoidWithZero α
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
h : ¬Finite a b
this : ¬Finite (Associates.mk a) (Associates.mk b)
⊢ multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b

Next tactic:
rw [finite_iff_dom, PartENat.not_dom_iff_eq_top] at h this
theorem multiplicity_mk_eq_multiplicity
    [DecidableRel ((· ∣ ·) : Associates α → Associates α → Prop)] {a b : α} :
    multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b := by
  by_cases h : Finite a b
  · rw [← PartENat.natCast_get (finite_iff_dom.mp h)]
    refine'
        (multiplicity.unique
            (show Associates.mk a ^ (multiplicity a b).get h ∣ Associates.mk b from _) _).symm <;>
      rw [← Associates.mk_pow, Associates.mk_dvd_mk]
    · exact pow_multiplicity_dvd h
    · exact is_greatest
          ((PartENat.lt_coe_iff _ _).mpr (Exists.intro (finite_iff_dom.mp h) (Nat.lt_succ_self _)))
  · suffices ¬Finite (Associates.mk a) (Associates.mk b) by
      rw [finite_iff_dom, PartENat.not_dom_iff_eq_top] at h this
      

Proof state:
α : Type u_1
β : Type u_2
inst✝² : CommMonoidWithZero α
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
h : multiplicity a b = ⊤
this : multiplicity (Associates.mk a) (Associates.mk b) = ⊤
⊢ multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b

Next tactic:
rw [h, this]
theorem multiplicity_mk_eq_multiplicity
    [DecidableRel ((· ∣ ·) : Associates α → Associates α → Prop)] {a b : α} :
    multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b := by
  by_cases h : Finite a b
  · rw [← PartENat.natCast_get (finite_iff_dom.mp h)]
    refine'
        (multiplicity.unique
            (show Associates.mk a ^ (multiplicity a b).get h ∣ Associates.mk b from _) _).symm <;>
      rw [← Associates.mk_pow, Associates.mk_dvd_mk]
    · exact pow_multiplicity_dvd h
    · exact is_greatest
          ((PartENat.lt_coe_iff _ _).mpr (Exists.intro (finite_iff_dom.mp h) (Nat.lt_succ_self _)))
  · suffices ¬Finite (Associates.mk a) (Associates.mk b) by
      rw [finite_iff_dom, PartENat.not_dom_iff_eq_top] at h this
      rw [h, this]
    

Proof state:
case neg
α : Type u_1
β : Type u_2
inst✝² : CommMonoidWithZero α
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
h : ¬Finite a b
⊢ ¬Finite (Associates.mk a) (Associates.mk b)

Next tactic:
refine'
      not_finite_iff_forall.mpr fun n => by
        rw [← Associates.mk_pow, Associates.mk_dvd_mk]
        exact not_finite_iff_forall.mp h n
theorem multiplicity_mk_eq_multiplicity
    [DecidableRel ((· ∣ ·) : Associates α → Associates α → Prop)] {a b : α} :
    multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b := by
  by_cases h : Finite a b
  · rw [← PartENat.natCast_get (finite_iff_dom.mp h)]
    refine'
        (multiplicity.unique
            (show Associates.mk a ^ (multiplicity a b).get h ∣ Associates.mk b from _) _).symm <;>
      rw [← Associates.mk_pow, Associates.mk_dvd_mk]
    · exact pow_multiplicity_dvd h
    · exact is_greatest
          ((PartENat.lt_coe_iff _ _).mpr (Exists.intro (finite_iff_dom.mp h) (Nat.lt_succ_self _)))
  · suffices ¬Finite (Associates.mk a) (Associates.mk b) by
      rw [finite_iff_dom, PartENat.not_dom_iff_eq_top] at h this
      rw [h, this]
    refine'
      not_finite_iff_forall.mpr fun n => by
        

Proof state:
α : Type u_1
β : Type u_2
inst✝² : CommMonoidWithZero α
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
h : ¬Finite a b
n : ℕ
⊢ Associates.mk a ^ n ∣ Associates.mk b

Next tactic:
rw [← Associates.mk_pow, Associates.mk_dvd_mk]
theorem multiplicity_mk_eq_multiplicity
    [DecidableRel ((· ∣ ·) : Associates α → Associates α → Prop)] {a b : α} :
    multiplicity (Associates.mk a) (Associates.mk b) = multiplicity a b := by
  by_cases h : Finite a b
  · rw [← PartENat.natCast_get (finite_iff_dom.mp h)]
    refine'
        (multiplicity.unique
            (show Associates.mk a ^ (multiplicity a b).get h ∣ Associates.mk b from _) _).symm <;>
      rw [← Associates.mk_pow, Associates.mk_dvd_mk]
    · exact pow_multiplicity_dvd h
    · exact is_greatest
          ((PartENat.lt_coe_iff _ _).mpr (Exists.intro (finite_iff_dom.mp h) (Nat.lt_succ_self _)))
  · suffices ¬Finite (Associates.mk a) (Associates.mk b) by
      rw [finite_iff_dom, PartENat.not_dom_iff_eq_top] at h this
      rw [h, this]
    refine'
      not_finite_iff_forall.mpr fun n => by
        rw [← Associates.mk_pow, Associates.mk_dvd_mk]
        

Proof state:
α : Type u_1
β : Type u_2
inst✝² : CommMonoidWithZero α
inst✝¹ : DecidableRel fun x x_1 => x ∣ x_1
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
h : ¬Finite a b
n : ℕ
⊢ a ^ n ∣ b

Next tactic:
exact not_finite_iff_forall.mp h n
theorem min_le_multiplicity_add {p a b : α} :
    min (multiplicity p a) (multiplicity p b) ≤ multiplicity p (a + b) :=
  (le_total (multiplicity p a) (multiplicity p b)).elim
    (fun h => by
      

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Semiring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
h : multiplicity p a ≤ multiplicity p b
⊢ min (multiplicity p a) (multiplicity p b) ≤ multiplicity p (a + b)

Next tactic:
rw [min_eq_left h, multiplicity_le_multiplicity_iff]
theorem min_le_multiplicity_add {p a b : α} :
    min (multiplicity p a) (multiplicity p b) ≤ multiplicity p (a + b) :=
  (le_total (multiplicity p a) (multiplicity p b)).elim
    (fun h => by
      rw [min_eq_left h, multiplicity_le_multiplicity_iff];
        

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Semiring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
h : multiplicity p a ≤ multiplicity p b
⊢ ∀ (n : ℕ), p ^ n ∣ a → p ^ n ∣ a + b

Next tactic:
exact fun n hn => dvd_add hn (multiplicity_le_multiplicity_iff.1 h n hn)
theorem min_le_multiplicity_add {p a b : α} :
    min (multiplicity p a) (multiplicity p b) ≤ multiplicity p (a + b) :=
  (le_total (multiplicity p a) (multiplicity p b)).elim
    (fun h => by
      rw [min_eq_left h, multiplicity_le_multiplicity_iff];
        exact fun n hn => dvd_add hn (multiplicity_le_multiplicity_iff.1 h n hn))
    fun h => by
    

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Semiring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
h : multiplicity p b ≤ multiplicity p a
⊢ min (multiplicity p a) (multiplicity p b) ≤ multiplicity p (a + b)

Next tactic:
rw [min_eq_right h, multiplicity_le_multiplicity_iff]
theorem min_le_multiplicity_add {p a b : α} :
    min (multiplicity p a) (multiplicity p b) ≤ multiplicity p (a + b) :=
  (le_total (multiplicity p a) (multiplicity p b)).elim
    (fun h => by
      rw [min_eq_left h, multiplicity_le_multiplicity_iff];
        exact fun n hn => dvd_add hn (multiplicity_le_multiplicity_iff.1 h n hn))
    fun h => by
    rw [min_eq_right h, multiplicity_le_multiplicity_iff];
      

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Semiring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
h : multiplicity p b ≤ multiplicity p a
⊢ ∀ (n : ℕ), p ^ n ∣ b → p ^ n ∣ a + b

Next tactic:
exact fun n hn => dvd_add (multiplicity_le_multiplicity_iff.1 h n hn) hn
@[simp]
protected theorem neg (a b : α) : multiplicity a (-b) = multiplicity a b :=
  Part.ext' (by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
⊢ (multiplicity a (-b)).Dom ↔ (multiplicity a b).Dom

Next tactic:
simp only [multiplicity, PartENat.find, dvd_neg]
@[simp]
protected theorem neg (a b : α) : multiplicity a (-b) = multiplicity a b :=
  Part.ext' (by simp only [multiplicity, PartENat.find, dvd_neg]) fun h₁ h₂ =>
    PartENat.natCast_inj.1 (by
      

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
h₁ : (multiplicity a (-b)).Dom
h₂ : (multiplicity a b).Dom
⊢ ↑(Part.get (multiplicity a (-b)) h₁) = ↑(Part.get (multiplicity a b) h₂)

Next tactic:
rw [PartENat.natCast_get]
@[simp]
protected theorem neg (a b : α) : multiplicity a (-b) = multiplicity a b :=
  Part.ext' (by simp only [multiplicity, PartENat.find, dvd_neg]) fun h₁ h₂ =>
    PartENat.natCast_inj.1 (by
      rw [PartENat.natCast_get]
      

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a b : α
h₁ : (multiplicity a (-b)).Dom
h₂ : (multiplicity a b).Dom
⊢ multiplicity a (-b) = ↑(Part.get (multiplicity a b) h₂)

Next tactic:
exact Eq.symm
              (unique (pow_multiplicity_dvd _).neg_right
                (mt dvd_neg.1 (is_greatest' _ (lt_succ_self _))))
theorem Int.natAbs (a : ℕ) (b : ℤ) : multiplicity a b.natAbs = multiplicity (a : ℤ) b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a : ℕ
b : ℤ
⊢ multiplicity a (_root_.Int.natAbs b) = multiplicity (↑a) b

Next tactic:
cases' Int.natAbs_eq b with h h
theorem Int.natAbs (a : ℕ) (b : ℤ) : multiplicity a b.natAbs = multiplicity (a : ℤ) b := by
  cases' Int.natAbs_eq b with h h <;> 

Proof state:
case inl
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a : ℕ
b : ℤ
h : b = ↑(_root_.Int.natAbs b)
⊢ multiplicity a (_root_.Int.natAbs b) = multiplicity (↑a) b

Next tactic:
conv_rhs => rw [h]
theorem Int.natAbs (a : ℕ) (b : ℤ) : multiplicity a b.natAbs = multiplicity (a : ℤ) b := by
  cases' Int.natAbs_eq b with h h <;> conv_rhs => 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a : ℕ
b : ℤ
h : b = ↑(_root_.Int.natAbs b)
| multiplicity (↑a) b

Next tactic:
rw [h]
theorem Int.natAbs (a : ℕ) (b : ℤ) : multiplicity a b.natAbs = multiplicity (a : ℤ) b := by
  cases' Int.natAbs_eq b with h h <;> 

Proof state:
case inr
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a : ℕ
b : ℤ
h : b = -↑(_root_.Int.natAbs b)
⊢ multiplicity a (_root_.Int.natAbs b) = multiplicity (↑a) b

Next tactic:
conv_rhs => rw [h]
theorem Int.natAbs (a : ℕ) (b : ℤ) : multiplicity a b.natAbs = multiplicity (a : ℤ) b := by
  cases' Int.natAbs_eq b with h h <;> conv_rhs => 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a : ℕ
b : ℤ
h : b = -↑(_root_.Int.natAbs b)
| multiplicity (↑a) b

Next tactic:
rw [h]
theorem Int.natAbs (a : ℕ) (b : ℤ) : multiplicity a b.natAbs = multiplicity (a : ℤ) b := by
  cases' Int.natAbs_eq b with h h <;> conv_rhs => rw [h]
  · 

Proof state:
case inl
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a : ℕ
b : ℤ
h : b = ↑(_root_.Int.natAbs b)
⊢ multiplicity a (_root_.Int.natAbs b) = multiplicity ↑a ↑(_root_.Int.natAbs b)

Next tactic:
rw [Int.coe_nat_multiplicity]
theorem Int.natAbs (a : ℕ) (b : ℤ) : multiplicity a b.natAbs = multiplicity (a : ℤ) b := by
  cases' Int.natAbs_eq b with h h <;> conv_rhs => rw [h]
  · rw [Int.coe_nat_multiplicity]
  · 

Proof state:
case inr
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
a : ℕ
b : ℤ
h : b = -↑(_root_.Int.natAbs b)
⊢ multiplicity a (_root_.Int.natAbs b) = multiplicity (↑a) (-↑(_root_.Int.natAbs b))

Next tactic:
rw [multiplicity.neg, Int.coe_nat_multiplicity]
theorem multiplicity_add_of_gt {p a b : α} (h : multiplicity p b < multiplicity p a) :
    multiplicity p (a + b) = multiplicity p b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
h : multiplicity p b < multiplicity p a
⊢ multiplicity p (a + b) = multiplicity p b

Next tactic:
apply le_antisymm
theorem multiplicity_add_of_gt {p a b : α} (h : multiplicity p b < multiplicity p a) :
    multiplicity p (a + b) = multiplicity p b := by
  apply le_antisymm
  · 

Proof state:
case a
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
h : multiplicity p b < multiplicity p a
⊢ multiplicity p (a + b) ≤ multiplicity p b

Next tactic:
apply PartENat.le_of_lt_add_one
theorem multiplicity_add_of_gt {p a b : α} (h : multiplicity p b < multiplicity p a) :
    multiplicity p (a + b) = multiplicity p b := by
  apply le_antisymm
  · apply PartENat.le_of_lt_add_one
    

Proof state:
case a.h
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
h : multiplicity p b < multiplicity p a
⊢ multiplicity p (a + b) < multiplicity p b + 1

Next tactic:
cases' PartENat.ne_top_iff.mp (PartENat.ne_top_of_lt h) with k hk
theorem multiplicity_add_of_gt {p a b : α} (h : multiplicity p b < multiplicity p a) :
    multiplicity p (a + b) = multiplicity p b := by
  apply le_antisymm
  · apply PartENat.le_of_lt_add_one
    cases' PartENat.ne_top_iff.mp (PartENat.ne_top_of_lt h) with k hk
    

Proof state:
case a.h.intro
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
h : multiplicity p b < multiplicity p a
k : ℕ
hk : multiplicity p b = ↑k
⊢ multiplicity p (a + b) < multiplicity p b + 1

Next tactic:
rw [hk]
theorem multiplicity_add_of_gt {p a b : α} (h : multiplicity p b < multiplicity p a) :
    multiplicity p (a + b) = multiplicity p b := by
  apply le_antisymm
  · apply PartENat.le_of_lt_add_one
    cases' PartENat.ne_top_iff.mp (PartENat.ne_top_of_lt h) with k hk
    rw [hk]
    

Proof state:
case a.h.intro
α : Type u_1
β : Type u_2
inst✝¹ : Ring α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
h : multiplicity p b < multiplicity p a
k : ℕ
hk : multiplicity p b = ↑k
⊢ multiplicity p (a + b) < ↑k + 1

Next tactic:
rw_mod_cast [multiplicity_lt_iff_not_dvd, dvd_add_right]