l3lab/ntp-mathlib huggingface dataset:
protected theorem mul' {p a b : α} (hp : Prime p) (h : (multiplicity p (a * b)).Dom) :
    get (multiplicity p (a * b)) h =
      get (multiplicity p a) ((finite_mul_iff hp).1 h).1 +
        get (multiplicity p b) ((finite_mul_iff hp).1 h).2 := by
  have hdiva : p ^ get (multiplicity p a) ((finite_mul_iff hp).1 h).1 ∣ a := pow_multiplicity_dvd _
  have hdivb : p ^ get (multiplicity p b) ((finite_mul_iff hp).1 h).2 ∣ b := pow_multiplicity_dvd _
  have hpoweq :
    p ^ (get (multiplicity p a) ((finite_mul_iff hp).1 h).1 +
          get (multiplicity p b) ((finite_mul_iff hp).1 h).2) =
      p ^ get (multiplicity p a) ((finite_mul_iff hp).1 h).1 *
        p ^ get (multiplicity p b) ((finite_mul_iff hp).1 h).2 :=
    by simp [pow_add]
  have hdiv :
    p ^ (get (multiplicity p a) ((finite_mul_iff hp).1 h).1 +
          get (multiplicity p b) ((finite_mul_iff hp).1 h).2) ∣
      a * b :=
    by rw [hpoweq]; apply mul_dvd_mul <;> assumption
  have hsucc :
    ¬p ^ (get (multiplicity p a) ((finite_mul_iff hp).1 h).1 +
              get (multiplicity p b) ((finite_mul_iff hp).1 h).2 +
            1) ∣
        a * b :=
    fun h =>
    not_or_of_not (is_greatest' _ (lt_succ_self _)) (is_greatest' _ (lt_succ_self _))
      (_root_.succ_dvd_or_succ_dvd_of_succ_sum_dvd_mul hp hdiva hdivb h)
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
hp : Prime p
h : (multiplicity p (a * b)).Dom
hdiva : p ^ Part.get (multiplicity p a) (_ : Finite p a) ∣ a
hdivb : p ^ Part.get (multiplicity p b) (_ : Finite p b) ∣ b
hpoweq :
  p ^ (Part.get (multiplicity p a) (_ : Finite p a) + Part.get (multiplicity p b) (_ : Finite p b)) =
    p ^ Part.get (multiplicity p a) (_ : Finite p a) * p ^ Part.get (multiplicity p b) (_ : Finite p b)
hdiv : p ^ (Part.get (multiplicity p a) (_ : Finite p a) + Part.get (multiplicity p b) (_ : Finite p b)) ∣ a * b
hsucc : ¬p ^ (Part.get (multiplicity p a) (_ : Finite p a) + Part.get (multiplicity p b) (_ : Finite p b) + 1) ∣ a * b
⊢ Part.get (multiplicity p (a * b)) h =
    Part.get (multiplicity p a) (_ : Finite p a) + Part.get (multiplicity p b) (_ : Finite p b)

Next tactic:
rw [← PartENat.natCast_inj, PartENat.natCast_get, eq_coe_iff]
protected theorem mul' {p a b : α} (hp : Prime p) (h : (multiplicity p (a * b)).Dom) :
    get (multiplicity p (a * b)) h =
      get (multiplicity p a) ((finite_mul_iff hp).1 h).1 +
        get (multiplicity p b) ((finite_mul_iff hp).1 h).2 := by
  have hdiva : p ^ get (multiplicity p a) ((finite_mul_iff hp).1 h).1 ∣ a := pow_multiplicity_dvd _
  have hdivb : p ^ get (multiplicity p b) ((finite_mul_iff hp).1 h).2 ∣ b := pow_multiplicity_dvd _
  have hpoweq :
    p ^ (get (multiplicity p a) ((finite_mul_iff hp).1 h).1 +
          get (multiplicity p b) ((finite_mul_iff hp).1 h).2) =
      p ^ get (multiplicity p a) ((finite_mul_iff hp).1 h).1 *
        p ^ get (multiplicity p b) ((finite_mul_iff hp).1 h).2 :=
    by simp [pow_add]
  have hdiv :
    p ^ (get (multiplicity p a) ((finite_mul_iff hp).1 h).1 +
          get (multiplicity p b) ((finite_mul_iff hp).1 h).2) ∣
      a * b :=
    by rw [hpoweq]; apply mul_dvd_mul <;> assumption
  have hsucc :
    ¬p ^ (get (multiplicity p a) ((finite_mul_iff hp).1 h).1 +
              get (multiplicity p b) ((finite_mul_iff hp).1 h).2 +
            1) ∣
        a * b :=
    fun h =>
    not_or_of_not (is_greatest' _ (lt_succ_self _)) (is_greatest' _ (lt_succ_self _))
      (_root_.succ_dvd_or_succ_dvd_of_succ_sum_dvd_mul hp hdiva hdivb h)
  rw [← PartENat.natCast_inj, PartENat.natCast_get, eq_coe_iff]; 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
hp : Prime p
h : (multiplicity p (a * b)).Dom
hdiva : p ^ Part.get (multiplicity p a) (_ : Finite p a) ∣ a
hdivb : p ^ Part.get (multiplicity p b) (_ : Finite p b) ∣ b
hpoweq :
  p ^ (Part.get (multiplicity p a) (_ : Finite p a) + Part.get (multiplicity p b) (_ : Finite p b)) =
    p ^ Part.get (multiplicity p a) (_ : Finite p a) * p ^ Part.get (multiplicity p b) (_ : Finite p b)
hdiv : p ^ (Part.get (multiplicity p a) (_ : Finite p a) + Part.get (multiplicity p b) (_ : Finite p b)) ∣ a * b
hsucc : ¬p ^ (Part.get (multiplicity p a) (_ : Finite p a) + Part.get (multiplicity p b) (_ : Finite p b) + 1) ∣ a * b
⊢ p ^ (Part.get (multiplicity p a) (_ : Finite p a) + Part.get (multiplicity p b) (_ : Finite p b)) ∣ a * b ∧
    ¬p ^ (Part.get (multiplicity p a) (_ : Finite p a) + Part.get (multiplicity p b) (_ : Finite p b) + 1) ∣ a * b

Next tactic:
exact ⟨hdiv, hsucc⟩
protected theorem mul {p a b : α} (hp : Prime p) :
    multiplicity p (a * b) = multiplicity p a + multiplicity p b :=
  if h : Finite p a ∧ Finite p b then by
    

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
hp : Prime p
h : Finite p a ∧ Finite p b
⊢ multiplicity p (a * b) = multiplicity p a + multiplicity p b

Next tactic:
rw [← PartENat.natCast_get (finite_iff_dom.1 h.1), ←
        PartENat.natCast_get (finite_iff_dom.1 h.2), ←
        PartENat.natCast_get (finite_iff_dom.1 (finite_mul hp h.1 h.2)), ← Nat.cast_add,
        PartENat.natCast_inj, multiplicity.mul' hp]
protected theorem mul {p a b : α} (hp : Prime p) :
    multiplicity p (a * b) = multiplicity p a + multiplicity p b :=
  if h : Finite p a ∧ Finite p b then by
    rw [← PartENat.natCast_get (finite_iff_dom.1 h.1), ←
        PartENat.natCast_get (finite_iff_dom.1 h.2), ←
        PartENat.natCast_get (finite_iff_dom.1 (finite_mul hp h.1 h.2)), ← Nat.cast_add,
        PartENat.natCast_inj, multiplicity.mul' hp]
  else by
    

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
hp : Prime p
h : ¬(Finite p a ∧ Finite p b)
⊢ multiplicity p (a * b) = multiplicity p a + multiplicity p b

Next tactic:
rw [eq_top_iff_not_finite.2 (mt (finite_mul_iff hp).1 h)]
protected theorem mul {p a b : α} (hp : Prime p) :
    multiplicity p (a * b) = multiplicity p a + multiplicity p b :=
  if h : Finite p a ∧ Finite p b then by
    rw [← PartENat.natCast_get (finite_iff_dom.1 h.1), ←
        PartENat.natCast_get (finite_iff_dom.1 h.2), ←
        PartENat.natCast_get (finite_iff_dom.1 (finite_mul hp h.1 h.2)), ← Nat.cast_add,
        PartENat.natCast_inj, multiplicity.mul' hp]
  else by
    rw [eq_top_iff_not_finite.2 (mt (finite_mul_iff hp).1 h)]
    

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
hp : Prime p
h : ¬(Finite p a ∧ Finite p b)
⊢ ⊤ = multiplicity p a + multiplicity p b

Next tactic:
cases' not_and_or.1 h with h h
protected theorem mul {p a b : α} (hp : Prime p) :
    multiplicity p (a * b) = multiplicity p a + multiplicity p b :=
  if h : Finite p a ∧ Finite p b then by
    rw [← PartENat.natCast_get (finite_iff_dom.1 h.1), ←
        PartENat.natCast_get (finite_iff_dom.1 h.2), ←
        PartENat.natCast_get (finite_iff_dom.1 (finite_mul hp h.1 h.2)), ← Nat.cast_add,
        PartENat.natCast_inj, multiplicity.mul' hp]
  else by
    rw [eq_top_iff_not_finite.2 (mt (finite_mul_iff hp).1 h)]
    cases' not_and_or.1 h with h h <;> 

Proof state:
case inl
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
hp : Prime p
h✝ : ¬(Finite p a ∧ Finite p b)
h : ¬Finite p a
⊢ ⊤ = multiplicity p a + multiplicity p b

Next tactic:
simp [eq_top_iff_not_finite.2 h]
protected theorem mul {p a b : α} (hp : Prime p) :
    multiplicity p (a * b) = multiplicity p a + multiplicity p b :=
  if h : Finite p a ∧ Finite p b then by
    rw [← PartENat.natCast_get (finite_iff_dom.1 h.1), ←
        PartENat.natCast_get (finite_iff_dom.1 h.2), ←
        PartENat.natCast_get (finite_iff_dom.1 (finite_mul hp h.1 h.2)), ← Nat.cast_add,
        PartENat.natCast_inj, multiplicity.mul' hp]
  else by
    rw [eq_top_iff_not_finite.2 (mt (finite_mul_iff hp).1 h)]
    cases' not_and_or.1 h with h h <;> 

Proof state:
case inr
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a b : α
hp : Prime p
h✝ : ¬(Finite p a ∧ Finite p b)
h : ¬Finite p b
⊢ ⊤ = multiplicity p a + multiplicity p b

Next tactic:
simp [eq_top_iff_not_finite.2 h]
theorem Finset.prod {β : Type*} {p : α} (hp : Prime p) (s : Finset β) (f : β → α) :
    multiplicity p (∏ x in s, f x) = ∑ x in s, multiplicity p (f x) := by
  

Proof state:
α : Type u_1
β✝ : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
β : Type u_3
p : α
hp : Prime p
s : Finset β
f : β → α
⊢ multiplicity p (∏ x in s, f x) = ∑ x in s, multiplicity p (f x)

Next tactic:
classical
    induction' s using Finset.induction with a s has ih h
    · simp only [Finset.sum_empty, Finset.prod_empty]
      convert one_right hp.not_unit
    · simp [has, ← ih]
      convert multiplicity.mul hp
theorem Finset.prod {β : Type*} {p : α} (hp : Prime p) (s : Finset β) (f : β → α) :
    multiplicity p (∏ x in s, f x) = ∑ x in s, multiplicity p (f x) := by
  classical
    

Proof state:
α : Type u_1
β✝ : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
β : Type u_3
p : α
hp : Prime p
s : Finset β
f : β → α
⊢ multiplicity p (∏ x in s, f x) = ∑ x in s, multiplicity p (f x)

Next tactic:
induction' s using Finset.induction with a s has ih h
theorem Finset.prod {β : Type*} {p : α} (hp : Prime p) (s : Finset β) (f : β → α) :
    multiplicity p (∏ x in s, f x) = ∑ x in s, multiplicity p (f x) := by
  classical
    induction' s using Finset.induction with a s has ih h
    · 

Proof state:
case empty
α : Type u_1
β✝ : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
β : Type u_3
p : α
hp : Prime p
f : β → α
⊢ multiplicity p (∏ x in ∅, f x) = ∑ x in ∅, multiplicity p (f x)

Next tactic:
simp only [Finset.sum_empty, Finset.prod_empty]
theorem Finset.prod {β : Type*} {p : α} (hp : Prime p) (s : Finset β) (f : β → α) :
    multiplicity p (∏ x in s, f x) = ∑ x in s, multiplicity p (f x) := by
  classical
    induction' s using Finset.induction with a s has ih h
    · simp only [Finset.sum_empty, Finset.prod_empty]
      

Proof state:
case empty
α : Type u_1
β✝ : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
β : Type u_3
p : α
hp : Prime p
f : β → α
⊢ multiplicity p 1 = 0

Next tactic:
convert one_right hp.not_unit
theorem Finset.prod {β : Type*} {p : α} (hp : Prime p) (s : Finset β) (f : β → α) :
    multiplicity p (∏ x in s, f x) = ∑ x in s, multiplicity p (f x) := by
  classical
    induction' s using Finset.induction with a s has ih h
    · simp only [Finset.sum_empty, Finset.prod_empty]
      convert one_right hp.not_unit
    · 

Proof state:
case insert
α : Type u_1
β✝ : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
β : Type u_3
p : α
hp : Prime p
f : β → α
a : β
s : Finset β
has : a ∉ s
ih : multiplicity p (∏ x in s, f x) = ∑ x in s, multiplicity p (f x)
⊢ multiplicity p (∏ x in insert a s, f x) = ∑ x in insert a s, multiplicity p (f x)

Next tactic:
simp [has, ← ih]
theorem Finset.prod {β : Type*} {p : α} (hp : Prime p) (s : Finset β) (f : β → α) :
    multiplicity p (∏ x in s, f x) = ∑ x in s, multiplicity p (f x) := by
  classical
    induction' s using Finset.induction with a s has ih h
    · simp only [Finset.sum_empty, Finset.prod_empty]
      convert one_right hp.not_unit
    · simp [has, ← ih]
      

Proof state:
case insert
α : Type u_1
β✝ : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
β : Type u_3
p : α
hp : Prime p
f : β → α
a : β
s : Finset β
has : a ∉ s
ih : multiplicity p (∏ x in s, f x) = ∑ x in s, multiplicity p (f x)
⊢ multiplicity p (f a * ∏ x in s, f x) = multiplicity p (f a) + multiplicity p (∏ x in s, f x)

Next tactic:
convert multiplicity.mul hp
protected theorem pow' {p a : α} (hp : Prime p) (ha : Finite p a) :
    ∀ {k : ℕ}, get (multiplicity p (a ^ k)) (finite_pow hp ha) = k * get (multiplicity p a) ha := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a : α
hp : Prime p
ha : Finite p a
⊢ ∀ {k : ℕ}, Part.get (multiplicity p (a ^ k)) (_ : Finite p (a ^ k)) = k * Part.get (multiplicity p a) ha

Next tactic:
intro k
protected theorem pow' {p a : α} (hp : Prime p) (ha : Finite p a) :
    ∀ {k : ℕ}, get (multiplicity p (a ^ k)) (finite_pow hp ha) = k * get (multiplicity p a) ha := by
  intro k
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a : α
hp : Prime p
ha : Finite p a
k : ℕ
⊢ Part.get (multiplicity p (a ^ k)) (_ : Finite p (a ^ k)) = k * Part.get (multiplicity p a) ha

Next tactic:
induction' k with k hk
protected theorem pow' {p a : α} (hp : Prime p) (ha : Finite p a) :
    ∀ {k : ℕ}, get (multiplicity p (a ^ k)) (finite_pow hp ha) = k * get (multiplicity p a) ha := by
  intro k
  induction' k with k hk
  · 

Proof state:
case zero
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a : α
hp : Prime p
ha : Finite p a
⊢ Part.get (multiplicity p (a ^ zero)) (_ : Finite p (a ^ zero)) = zero * Part.get (multiplicity p a) ha

Next tactic:
simp [one_right hp.not_unit]
protected theorem pow' {p a : α} (hp : Prime p) (ha : Finite p a) :
    ∀ {k : ℕ}, get (multiplicity p (a ^ k)) (finite_pow hp ha) = k * get (multiplicity p a) ha := by
  intro k
  induction' k with k hk
  · simp [one_right hp.not_unit]
  · 

Proof state:
case succ
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a : α
hp : Prime p
ha : Finite p a
k : ℕ
hk : Part.get (multiplicity p (a ^ k)) (_ : Finite p (a ^ k)) = k * Part.get (multiplicity p a) ha
⊢ Part.get (multiplicity p (a ^ succ k)) (_ : Finite p (a ^ succ k)) = succ k * Part.get (multiplicity p a) ha

Next tactic:
have : multiplicity p (a ^ (k + 1)) = multiplicity p (a * a ^ k) := by rw [_root_.pow_succ]
protected theorem pow' {p a : α} (hp : Prime p) (ha : Finite p a) :
    ∀ {k : ℕ}, get (multiplicity p (a ^ k)) (finite_pow hp ha) = k * get (multiplicity p a) ha := by
  intro k
  induction' k with k hk
  · simp [one_right hp.not_unit]
  · have : multiplicity p (a ^ (k + 1)) = multiplicity p (a * a ^ k) := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a : α
hp : Prime p
ha : Finite p a
k : ℕ
hk : Part.get (multiplicity p (a ^ k)) (_ : Finite p (a ^ k)) = k * Part.get (multiplicity p a) ha
⊢ multiplicity p (a ^ (k + 1)) = multiplicity p (a * a ^ k)

Next tactic:
rw [_root_.pow_succ]
protected theorem pow' {p a : α} (hp : Prime p) (ha : Finite p a) :
    ∀ {k : ℕ}, get (multiplicity p (a ^ k)) (finite_pow hp ha) = k * get (multiplicity p a) ha := by
  intro k
  induction' k with k hk
  · simp [one_right hp.not_unit]
  · have : multiplicity p (a ^ (k + 1)) = multiplicity p (a * a ^ k) := by rw [_root_.pow_succ]
    

Proof state:
case succ
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a : α
hp : Prime p
ha : Finite p a
k : ℕ
hk : Part.get (multiplicity p (a ^ k)) (_ : Finite p (a ^ k)) = k * Part.get (multiplicity p a) ha
this : multiplicity p (a ^ (k + 1)) = multiplicity p (a * a ^ k)
⊢ Part.get (multiplicity p (a ^ succ k)) (_ : Finite p (a ^ succ k)) = succ k * Part.get (multiplicity p a) ha

Next tactic:
rw [succ_eq_add_one, get_eq_get_of_eq _ _ this,
      multiplicity.mul' hp, hk, add_mul, one_mul, add_comm]
theorem pow {p a : α} (hp : Prime p) : ∀ {k : ℕ}, multiplicity p (a ^ k) = k • multiplicity p a
  | 0 => by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a : α
hp : Prime p
⊢ multiplicity p (a ^ 0) = 0 • multiplicity p a

Next tactic:
simp [one_right hp.not_unit]
theorem pow {p a : α} (hp : Prime p) : ∀ {k : ℕ}, multiplicity p (a ^ k) = k • multiplicity p a
  | 0 => by simp [one_right hp.not_unit]
  | succ k => by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p a : α
hp : Prime p
k : ℕ
⊢ multiplicity p (a ^ succ k) = succ k • multiplicity p a

Next tactic:
simp [_root_.pow_succ, succ_nsmul, pow hp, multiplicity.mul hp]
theorem multiplicity_pow_self {p : α} (h0 : p ≠ 0) (hu : ¬IsUnit p) (n : ℕ) :
    multiplicity p (p ^ n) = n := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p : α
h0 : p ≠ 0
hu : ¬IsUnit p
n : ℕ
⊢ multiplicity p (p ^ n) = ↑n

Next tactic:
rw [eq_coe_iff]
theorem multiplicity_pow_self {p : α} (h0 : p ≠ 0) (hu : ¬IsUnit p) (n : ℕ) :
    multiplicity p (p ^ n) = n := by
  rw [eq_coe_iff]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p : α
h0 : p ≠ 0
hu : ¬IsUnit p
n : ℕ
⊢ p ^ n ∣ p ^ n ∧ ¬p ^ (n + 1) ∣ p ^ n

Next tactic:
use dvd_rfl
theorem multiplicity_pow_self {p : α} (h0 : p ≠ 0) (hu : ¬IsUnit p) (n : ℕ) :
    multiplicity p (p ^ n) = n := by
  rw [eq_coe_iff]
  use dvd_rfl
  

Proof state:
case right
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p : α
h0 : p ≠ 0
hu : ¬IsUnit p
n : ℕ
⊢ ¬p ^ (n + 1) ∣ p ^ n

Next tactic:
rw [pow_dvd_pow_iff h0 hu]
theorem multiplicity_pow_self {p : α} (h0 : p ≠ 0) (hu : ¬IsUnit p) (n : ℕ) :
    multiplicity p (p ^ n) = n := by
  rw [eq_coe_iff]
  use dvd_rfl
  rw [pow_dvd_pow_iff h0 hu]
  

Proof state:
case right
α : Type u_1
β : Type u_2
inst✝¹ : CancelCommMonoidWithZero α
inst✝ : DecidableRel fun x x_1 => x ∣ x_1
p : α
h0 : p ≠ 0
hu : ¬IsUnit p
n : ℕ
⊢ ¬n + 1 ≤ n

Next tactic:
apply Nat.not_succ_le_self
theorem multiplicity_eq_zero_of_coprime {p a b : ℕ} (hp : p ≠ 1)
    (hle : multiplicity p a ≤ multiplicity p b) (hab : Nat.Coprime a b) : multiplicity p a = 0 := by
  

Proof state:
α : Type u_1
β : Type u_2
p a b : ℕ
hp : p ≠ 1
hle : multiplicity p a ≤ multiplicity p b
hab : Coprime a b
⊢ multiplicity p a = 0

Next tactic:
rw [multiplicity_le_multiplicity_iff] at hle
theorem multiplicity_eq_zero_of_coprime {p a b : ℕ} (hp : p ≠ 1)
    (hle : multiplicity p a ≤ multiplicity p b) (hab : Nat.Coprime a b) : multiplicity p a = 0 := by
  rw [multiplicity_le_multiplicity_iff] at hle
  

Proof state:
α : Type u_1
β : Type u_2
p a b : ℕ
hp : p ≠ 1
hle : ∀ (n : ℕ), p ^ n ∣ a → p ^ n ∣ b
hab : Coprime a b
⊢ multiplicity p a = 0

Next tactic:
rw [← nonpos_iff_eq_zero, ← not_lt, PartENat.pos_iff_one_le, ← Nat.cast_one, ←
    pow_dvd_iff_le_multiplicity]
theorem multiplicity_eq_zero_of_coprime {p a b : ℕ} (hp : p ≠ 1)
    (hle : multiplicity p a ≤ multiplicity p b) (hab : Nat.Coprime a b) : multiplicity p a = 0 := by
  rw [multiplicity_le_multiplicity_iff] at hle
  rw [← nonpos_iff_eq_zero, ← not_lt, PartENat.pos_iff_one_le, ← Nat.cast_one, ←
    pow_dvd_iff_le_multiplicity]
  

Proof state:
α : Type u_1
β : Type u_2
p a b : ℕ
hp : p ≠ 1
hle : ∀ (n : ℕ), p ^ n ∣ a → p ^ n ∣ b
hab : Coprime a b
⊢ ¬p ^ 1 ∣ a

Next tactic:
intro h
theorem multiplicity_eq_zero_of_coprime {p a b : ℕ} (hp : p ≠ 1)
    (hle : multiplicity p a ≤ multiplicity p b) (hab : Nat.Coprime a b) : multiplicity p a = 0 := by
  rw [multiplicity_le_multiplicity_iff] at hle
  rw [← nonpos_iff_eq_zero, ← not_lt, PartENat.pos_iff_one_le, ← Nat.cast_one, ←
    pow_dvd_iff_le_multiplicity]
  intro h
  

Proof state:
α : Type u_1
β : Type u_2
p a b : ℕ
hp : p ≠ 1
hle : ∀ (n : ℕ), p ^ n ∣ a → p ^ n ∣ b
hab : Coprime a b
h : p ^ 1 ∣ a
⊢ False

Next tactic:
have := Nat.dvd_gcd h (hle _ h)
theorem multiplicity_eq_zero_of_coprime {p a b : ℕ} (hp : p ≠ 1)
    (hle : multiplicity p a ≤ multiplicity p b) (hab : Nat.Coprime a b) : multiplicity p a = 0 := by
  rw [multiplicity_le_multiplicity_iff] at hle
  rw [← nonpos_iff_eq_zero, ← not_lt, PartENat.pos_iff_one_le, ← Nat.cast_one, ←
    pow_dvd_iff_le_multiplicity]
  intro h
  have := Nat.dvd_gcd h (hle _ h)
  

Proof state:
α : Type u_1
β : Type u_2
p a b : ℕ
hp : p ≠ 1
hle : ∀ (n : ℕ), p ^ n ∣ a → p ^ n ∣ b
hab : Coprime a b
h : p ^ 1 ∣ a
this : p ^ 1 ∣ gcd a b
⊢ False

Next tactic:
rw [Coprime.gcd_eq_one hab, Nat.dvd_one, pow_one] at this
theorem multiplicity_eq_zero_of_coprime {p a b : ℕ} (hp : p ≠ 1)
    (hle : multiplicity p a ≤ multiplicity p b) (hab : Nat.Coprime a b) : multiplicity p a = 0 := by
  rw [multiplicity_le_multiplicity_iff] at hle
  rw [← nonpos_iff_eq_zero, ← not_lt, PartENat.pos_iff_one_le, ← Nat.cast_one, ←
    pow_dvd_iff_le_multiplicity]
  intro h
  have := Nat.dvd_gcd h (hle _ h)
  rw [Coprime.gcd_eq_one hab, Nat.dvd_one, pow_one] at this
  

Proof state:
α : Type u_1
β : Type u_2
p a b : ℕ
hp : p ≠ 1
hle : ∀ (n : ℕ), p ^ n ∣ a → p ^ n ∣ b
hab : Coprime a b
h : p ^ 1 ∣ a
this : p = 1
⊢ False

Next tactic:
exact hp this
@[to_additive (attr := simp)]
theorem one_le_mul_self_iff : 1 ≤ a * a ↔ 1 ≤ a :=
  ⟨(fun h ↦ by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrderedCommMonoid α
a : α
h : ¬1 ≤ a
⊢ ¬1 ≤ a * a

Next tactic:
push_neg at h ⊢
@[to_additive (attr := simp)]
theorem one_le_mul_self_iff : 1 ≤ a * a ↔ 1 ≤ a :=
  ⟨(fun h ↦ by push_neg at h ⊢; 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrderedCommMonoid α
a : α
h : a < 1
⊢ a * a < 1

Next tactic:
exact mul_lt_one' h h
@[to_additive (attr := simp)]
theorem one_lt_mul_self_iff : 1 < a * a ↔ 1 < a :=
  ⟨(fun h ↦ by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrderedCommMonoid α
a : α
h : ¬1 < a
⊢ ¬1 < a * a

Next tactic:
push_neg at h ⊢
@[to_additive (attr := simp)]
theorem one_lt_mul_self_iff : 1 < a * a ↔ 1 < a :=
  ⟨(fun h ↦ by push_neg at h ⊢; 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrderedCommMonoid α
a : α
h : a ≤ 1
⊢ a * a ≤ 1

Next tactic:
exact mul_le_one' h h
@[to_additive (attr := simp)]
theorem mul_self_le_one_iff : a * a ≤ 1 ↔ a ≤ 1 := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrderedCommMonoid α
a : α
⊢ a * a ≤ 1 ↔ a ≤ 1

Next tactic:
simp [← not_iff_not]
@[to_additive (attr := simp)]
theorem mul_self_lt_one_iff : a * a < 1 ↔ a < 1 := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrderedCommMonoid α
a : α
⊢ a * a < 1 ↔ a < 1

Next tactic:
simp [← not_iff_not]
/-- On `Ideal`s, `Submodule.quotientRel` is a ring congruence. -/
protected def ringCon (I : Ideal R) : RingCon R :=
  { QuotientAddGroup.con I.toAddSubgroup with
    mul' := fun {a₁ b₁ a₂ b₂} h₁ h₂ => by
      

Proof state:
R : Type u
inst✝ : CommRing R
I✝ : Ideal R
a b : R
S : Type v
x y : R
I : Ideal R
src✝ : AddCon R := QuotientAddGroup.con (Submodule.toAddSubgroup I)
a₁ b₁ a₂ b₂ : R
h₁ : Setoid.r a₁ b₁
h₂ : Setoid.r a₂ b₂
⊢ Setoid.r (a₁ * a₂) (b₁ * b₂)

Next tactic:
rw [Submodule.quotientRel_r_def] at h₁ h₂ ⊢
/-- On `Ideal`s, `Submodule.quotientRel` is a ring congruence. -/
protected def ringCon (I : Ideal R) : RingCon R :=
  { QuotientAddGroup.con I.toAddSubgroup with
    mul' := fun {a₁ b₁ a₂ b₂} h₁ h₂ => by
      rw [Submodule.quotientRel_r_def] at h₁ h₂ ⊢
      

Proof state:
R : Type u
inst✝ : CommRing R
I✝ : Ideal R
a b : R
S : Type v
x y : R
I : Ideal R
src✝ : AddCon R := QuotientAddGroup.con (Submodule.toAddSubgroup I)
a₁ b₁ a₂ b₂ : R
h₁ : a₁ - b₁ ∈ I
h₂ : a₂ - b₂ ∈ I
⊢ a₁ * a₂ - b₁ * b₂ ∈ I

Next tactic:
have F := I.add_mem (I.mul_mem_left a₂ h₁) (I.mul_mem_right b₁ h₂)
/-- On `Ideal`s, `Submodule.quotientRel` is a ring congruence. -/
protected def ringCon (I : Ideal R) : RingCon R :=
  { QuotientAddGroup.con I.toAddSubgroup with
    mul' := fun {a₁ b₁ a₂ b₂} h₁ h₂ => by
      rw [Submodule.quotientRel_r_def] at h₁ h₂ ⊢
      have F := I.add_mem (I.mul_mem_left a₂ h₁) (I.mul_mem_right b₁ h₂)
      

Proof state:
R : Type u
inst✝ : CommRing R
I✝ : Ideal R
a b : R
S : Type v
x y : R
I : Ideal R
src✝ : AddCon R := QuotientAddGroup.con (Submodule.toAddSubgroup I)
a₁ b₁ a₂ b₂ : R
h₁ : a₁ - b₁ ∈ I
h₂ : a₂ - b₂ ∈ I
F : a₂ * (a₁ - b₁) + (a₂ - b₂) * b₁ ∈ I
⊢ a₁ * a₂ - b₁ * b₂ ∈ I

Next tactic:
have : a₁ * a₂ - b₁ * b₂ = a₂ * (a₁ - b₁) + (a₂ - b₂) * b₁ := by
        rw [mul_sub, sub_mul, sub_add_sub_cancel, mul_comm, mul_comm b₁]