l3lab/ntp-mathlib huggingface dataset:
theorem ord_compl_dvd_ord_compl_of_dvd {a b : ℕ} (hab : a ∣ b) (p : ℕ) :
    ord_compl[p] a ∣ ord_compl[p] b := by
  rcases em' p.Prime with (pp | pp)
  · simp [pp, hab]
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  rcases eq_or_ne a 0 with (rfl | ha0)
  · cases hb0 (zero_dvd_iff.1 hab)
  have ha := (Nat.div_pos (ord_proj_le p ha0) (ord_proj_pos a p)).ne'
  have hb := (Nat.div_pos (ord_proj_le p hb0) (ord_proj_pos b p)).ne'
  

Proof state:
case inr.inr.inr
a✝ b✝ m n p✝ a b : ℕ
hab : a ∣ b
p : ℕ
pp : Prime p
hb0 : b ≠ 0
ha0 : a ≠ 0
ha : a / p ^ (factorization a) p ≠ 0
hb : b / p ^ (factorization b) p ≠ 0
⊢ a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p

Next tactic:
rw [← factorization_le_iff_dvd ha hb, factorization_ord_compl a p, factorization_ord_compl b p]
theorem ord_compl_dvd_ord_compl_of_dvd {a b : ℕ} (hab : a ∣ b) (p : ℕ) :
    ord_compl[p] a ∣ ord_compl[p] b := by
  rcases em' p.Prime with (pp | pp)
  · simp [pp, hab]
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  rcases eq_or_ne a 0 with (rfl | ha0)
  · cases hb0 (zero_dvd_iff.1 hab)
  have ha := (Nat.div_pos (ord_proj_le p ha0) (ord_proj_pos a p)).ne'
  have hb := (Nat.div_pos (ord_proj_le p hb0) (ord_proj_pos b p)).ne'
  rw [← factorization_le_iff_dvd ha hb, factorization_ord_compl a p, factorization_ord_compl b p]
  

Proof state:
case inr.inr.inr
a✝ b✝ m n p✝ a b : ℕ
hab : a ∣ b
p : ℕ
pp : Prime p
hb0 : b ≠ 0
ha0 : a ≠ 0
ha : a / p ^ (factorization a) p ≠ 0
hb : b / p ^ (factorization b) p ≠ 0
⊢ Finsupp.erase p (factorization a) ≤ Finsupp.erase p (factorization b)

Next tactic:
intro q
theorem ord_compl_dvd_ord_compl_of_dvd {a b : ℕ} (hab : a ∣ b) (p : ℕ) :
    ord_compl[p] a ∣ ord_compl[p] b := by
  rcases em' p.Prime with (pp | pp)
  · simp [pp, hab]
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  rcases eq_or_ne a 0 with (rfl | ha0)
  · cases hb0 (zero_dvd_iff.1 hab)
  have ha := (Nat.div_pos (ord_proj_le p ha0) (ord_proj_pos a p)).ne'
  have hb := (Nat.div_pos (ord_proj_le p hb0) (ord_proj_pos b p)).ne'
  rw [← factorization_le_iff_dvd ha hb, factorization_ord_compl a p, factorization_ord_compl b p]
  intro q
  

Proof state:
case inr.inr.inr
a✝ b✝ m n p✝ a b : ℕ
hab : a ∣ b
p : ℕ
pp : Prime p
hb0 : b ≠ 0
ha0 : a ≠ 0
ha : a / p ^ (factorization a) p ≠ 0
hb : b / p ^ (factorization b) p ≠ 0
q : ℕ
⊢ (Finsupp.erase p (factorization a)) q ≤ (Finsupp.erase p (factorization b)) q

Next tactic:
rcases eq_or_ne q p with (rfl | hqp)
theorem ord_compl_dvd_ord_compl_of_dvd {a b : ℕ} (hab : a ∣ b) (p : ℕ) :
    ord_compl[p] a ∣ ord_compl[p] b := by
  rcases em' p.Prime with (pp | pp)
  · simp [pp, hab]
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  rcases eq_or_ne a 0 with (rfl | ha0)
  · cases hb0 (zero_dvd_iff.1 hab)
  have ha := (Nat.div_pos (ord_proj_le p ha0) (ord_proj_pos a p)).ne'
  have hb := (Nat.div_pos (ord_proj_le p hb0) (ord_proj_pos b p)).ne'
  rw [← factorization_le_iff_dvd ha hb, factorization_ord_compl a p, factorization_ord_compl b p]
  intro q
  rcases eq_or_ne q p with (rfl | hqp)
  · 

Proof state:
case inr.inr.inr.inl
a✝ b✝ m n p a b : ℕ
hab : a ∣ b
hb0 : b ≠ 0
ha0 : a ≠ 0
q : ℕ
pp : Prime q
ha : a / q ^ (factorization a) q ≠ 0
hb : b / q ^ (factorization b) q ≠ 0
⊢ (Finsupp.erase q (factorization a)) q ≤ (Finsupp.erase q (factorization b)) q

Next tactic:
simp
theorem ord_compl_dvd_ord_compl_of_dvd {a b : ℕ} (hab : a ∣ b) (p : ℕ) :
    ord_compl[p] a ∣ ord_compl[p] b := by
  rcases em' p.Prime with (pp | pp)
  · simp [pp, hab]
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  rcases eq_or_ne a 0 with (rfl | ha0)
  · cases hb0 (zero_dvd_iff.1 hab)
  have ha := (Nat.div_pos (ord_proj_le p ha0) (ord_proj_pos a p)).ne'
  have hb := (Nat.div_pos (ord_proj_le p hb0) (ord_proj_pos b p)).ne'
  rw [← factorization_le_iff_dvd ha hb, factorization_ord_compl a p, factorization_ord_compl b p]
  intro q
  rcases eq_or_ne q p with (rfl | hqp)
  · simp
  

Proof state:
case inr.inr.inr.inr
a✝ b✝ m n p✝ a b : ℕ
hab : a ∣ b
p : ℕ
pp : Prime p
hb0 : b ≠ 0
ha0 : a ≠ 0
ha : a / p ^ (factorization a) p ≠ 0
hb : b / p ^ (factorization b) p ≠ 0
q : ℕ
hqp : q ≠ p
⊢ (Finsupp.erase p (factorization a)) q ≤ (Finsupp.erase p (factorization b)) q

Next tactic:
simp_rw [erase_ne hqp]
theorem ord_compl_dvd_ord_compl_of_dvd {a b : ℕ} (hab : a ∣ b) (p : ℕ) :
    ord_compl[p] a ∣ ord_compl[p] b := by
  rcases em' p.Prime with (pp | pp)
  · simp [pp, hab]
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  rcases eq_or_ne a 0 with (rfl | ha0)
  · cases hb0 (zero_dvd_iff.1 hab)
  have ha := (Nat.div_pos (ord_proj_le p ha0) (ord_proj_pos a p)).ne'
  have hb := (Nat.div_pos (ord_proj_le p hb0) (ord_proj_pos b p)).ne'
  rw [← factorization_le_iff_dvd ha hb, factorization_ord_compl a p, factorization_ord_compl b p]
  intro q
  rcases eq_or_ne q p with (rfl | hqp)
  · simp
  simp_rw [erase_ne hqp]
  

Proof state:
case inr.inr.inr.inr
a✝ b✝ m n p✝ a b : ℕ
hab : a ∣ b
p : ℕ
pp : Prime p
hb0 : b ≠ 0
ha0 : a ≠ 0
ha : a / p ^ (factorization a) p ≠ 0
hb : b / p ^ (factorization b) p ≠ 0
q : ℕ
hqp : q ≠ p
⊢ (factorization a) q ≤ (factorization b) q

Next tactic:
exact (factorization_le_iff_dvd ha0 hb0).2 hab q
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  

Proof state:
a✝ b✝ m n p a b : ℕ
⊢ (∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p) ↔ a ∣ b

Next tactic:
refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  

Proof state:
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
⊢ a ∣ b

Next tactic:
rcases eq_or_ne b 0 with (rfl | hb0)
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  rcases eq_or_ne b 0 with (rfl | hb0)
  · 

Proof state:
case inl
a✝ b m n p a : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ 0 / p ^ (factorization 0) p
⊢ a ∣ 0

Next tactic:
simp
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  

Proof state:
case inr
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
⊢ a ∣ b

Next tactic:
by_cases pa : a.Prime
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  by_cases pa : a.Prime
  

Proof state:
case pos
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
pa : Prime a
⊢ a ∣ b
case neg
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
pa : ¬Prime a
⊢ a ∣ b

Next tactic:
case neg => simpa [pa] using h a
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  by_cases pa : a.Prime
  

Proof state:
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
pa : ¬Prime a
⊢ a ∣ b

Next tactic:
case neg => simpa [pa] using h a
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  by_cases pa : a.Prime
  case neg => 

Proof state:
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
pa : ¬Prime a
⊢ a ∣ b

Next tactic:
simpa [pa] using h a
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  by_cases pa : a.Prime
  case neg => simpa [pa] using h a
  

Proof state:
case pos
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
pa : Prime a
⊢ a ∣ b

Next tactic:
by_cases pb : b.Prime
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  by_cases pa : a.Prime
  case neg => simpa [pa] using h a
  by_cases pb : b.Prime
  

Proof state:
case pos
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
pa : Prime a
pb : Prime b
⊢ a ∣ b
case neg
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
pa : Prime a
pb : ¬Prime b
⊢ a ∣ b

Next tactic:
case neg => simpa [pb] using h b
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  by_cases pa : a.Prime
  case neg => simpa [pa] using h a
  by_cases pb : b.Prime
  

Proof state:
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
pa : Prime a
pb : ¬Prime b
⊢ a ∣ b

Next tactic:
case neg => simpa [pb] using h b
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  by_cases pa : a.Prime
  case neg => simpa [pa] using h a
  by_cases pb : b.Prime
  case neg => 

Proof state:
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
pa : Prime a
pb : ¬Prime b
⊢ a ∣ b

Next tactic:
simpa [pb] using h b
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  by_cases pa : a.Prime
  case neg => simpa [pa] using h a
  by_cases pb : b.Prime
  case neg => simpa [pb] using h b
  

Proof state:
case pos
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
pa : Prime a
pb : Prime b
⊢ a ∣ b

Next tactic:
rw [prime_dvd_prime_iff_eq pa pb]
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  by_cases pa : a.Prime
  case neg => simpa [pa] using h a
  by_cases pb : b.Prime
  case neg => simpa [pb] using h b
  rw [prime_dvd_prime_iff_eq pa pb]
  

Proof state:
case pos
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
pa : Prime a
pb : Prime b
⊢ a = b

Next tactic:
by_contra hab
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  by_cases pa : a.Prime
  case neg => simpa [pa] using h a
  by_cases pb : b.Prime
  case neg => simpa [pb] using h b
  rw [prime_dvd_prime_iff_eq pa pb]
  by_contra hab
  

Proof state:
case pos
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
pa : Prime a
pb : Prime b
hab : ¬a = b
⊢ False

Next tactic:
apply pa.ne_one
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  by_cases pa : a.Prime
  case neg => simpa [pa] using h a
  by_cases pb : b.Prime
  case neg => simpa [pb] using h b
  rw [prime_dvd_prime_iff_eq pa pb]
  by_contra hab
  apply pa.ne_one
  

Proof state:
case pos
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
pa : Prime a
pb : Prime b
hab : ¬a = b
⊢ a = 1

Next tactic:
rw [← Nat.dvd_one, ← Nat.mul_dvd_mul_iff_left hb0.bot_lt, mul_one]
theorem ord_compl_dvd_ord_compl_iff_dvd (a b : ℕ) :
    (∀ p : ℕ, ord_compl[p] a ∣ ord_compl[p] b) ↔ a ∣ b := by
  refine' ⟨fun h => _, fun hab p => ord_compl_dvd_ord_compl_of_dvd hab p⟩
  rcases eq_or_ne b 0 with (rfl | hb0)
  · simp
  by_cases pa : a.Prime
  case neg => simpa [pa] using h a
  by_cases pb : b.Prime
  case neg => simpa [pb] using h b
  rw [prime_dvd_prime_iff_eq pa pb]
  by_contra hab
  apply pa.ne_one
  rw [← Nat.dvd_one, ← Nat.mul_dvd_mul_iff_left hb0.bot_lt, mul_one]
  

Proof state:
case pos
a✝ b✝ m n p a b : ℕ
h : ∀ (p : ℕ), a / p ^ (factorization a) p ∣ b / p ^ (factorization b) p
hb0 : b ≠ 0
pa : Prime a
pb : Prime b
hab : ¬a = b
⊢ b * a ∣ b

Next tactic:
simpa [Prime.factorization_self pb, Prime.factorization pa, hab] using h b
theorem dvd_iff_prime_pow_dvd_dvd (n d : ℕ) :
    d ∣ n ↔ ∀ p k : ℕ, Prime p → p ^ k ∣ d → p ^ k ∣ n := by
  

Proof state:
a b m n✝ p n d : ℕ
⊢ d ∣ n ↔ ∀ (p k : ℕ), Prime p → p ^ k ∣ d → p ^ k ∣ n

Next tactic:
rcases eq_or_ne n 0 with (rfl | hn)
theorem dvd_iff_prime_pow_dvd_dvd (n d : ℕ) :
    d ∣ n ↔ ∀ p k : ℕ, Prime p → p ^ k ∣ d → p ^ k ∣ n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · 

Proof state:
case inl
a b m n p d : ℕ
⊢ d ∣ 0 ↔ ∀ (p k : ℕ), Prime p → p ^ k ∣ d → p ^ k ∣ 0

Next tactic:
simp
theorem dvd_iff_prime_pow_dvd_dvd (n d : ℕ) :
    d ∣ n ↔ ∀ p k : ℕ, Prime p → p ^ k ∣ d → p ^ k ∣ n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  

Proof state:
case inr
a b m n✝ p n d : ℕ
hn : n ≠ 0
⊢ d ∣ n ↔ ∀ (p k : ℕ), Prime p → p ^ k ∣ d → p ^ k ∣ n

Next tactic:
rcases eq_or_ne d 0 with (rfl | hd)
theorem dvd_iff_prime_pow_dvd_dvd (n d : ℕ) :
    d ∣ n ↔ ∀ p k : ℕ, Prime p → p ^ k ∣ d → p ^ k ∣ n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  rcases eq_or_ne d 0 with (rfl | hd)
  · 

Proof state:
case inr.inl
a b m n✝ p n : ℕ
hn : n ≠ 0
⊢ 0 ∣ n ↔ ∀ (p k : ℕ), Prime p → p ^ k ∣ 0 → p ^ k ∣ n

Next tactic:
simp only [zero_dvd_iff, hn, false_iff_iff, not_forall]
theorem dvd_iff_prime_pow_dvd_dvd (n d : ℕ) :
    d ∣ n ↔ ∀ p k : ℕ, Prime p → p ^ k ∣ d → p ^ k ∣ n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  rcases eq_or_ne d 0 with (rfl | hd)
  · simp only [zero_dvd_iff, hn, false_iff_iff, not_forall]
    

Proof state:
case inr.inl
a b m n✝ p n : ℕ
hn : n ≠ 0
⊢ ∃ x x_1, ∃ (_ : Prime x) (_ : x ^ x_1 ∣ 0), ¬x ^ x_1 ∣ n

Next tactic:
exact ⟨2, n, prime_two, dvd_zero _, mt (le_of_dvd hn.bot_lt) (lt_two_pow n).not_le⟩
theorem dvd_iff_prime_pow_dvd_dvd (n d : ℕ) :
    d ∣ n ↔ ∀ p k : ℕ, Prime p → p ^ k ∣ d → p ^ k ∣ n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  rcases eq_or_ne d 0 with (rfl | hd)
  · simp only [zero_dvd_iff, hn, false_iff_iff, not_forall]
    exact ⟨2, n, prime_two, dvd_zero _, mt (le_of_dvd hn.bot_lt) (lt_two_pow n).not_le⟩
  

Proof state:
case inr.inr
a b m n✝ p n d : ℕ
hn : n ≠ 0
hd : d ≠ 0
⊢ d ∣ n ↔ ∀ (p k : ℕ), Prime p → p ^ k ∣ d → p ^ k ∣ n

Next tactic:
refine' ⟨fun h p k _ hpkd => dvd_trans hpkd h, _⟩
theorem dvd_iff_prime_pow_dvd_dvd (n d : ℕ) :
    d ∣ n ↔ ∀ p k : ℕ, Prime p → p ^ k ∣ d → p ^ k ∣ n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  rcases eq_or_ne d 0 with (rfl | hd)
  · simp only [zero_dvd_iff, hn, false_iff_iff, not_forall]
    exact ⟨2, n, prime_two, dvd_zero _, mt (le_of_dvd hn.bot_lt) (lt_two_pow n).not_le⟩
  refine' ⟨fun h p k _ hpkd => dvd_trans hpkd h, _⟩
  

Proof state:
case inr.inr
a b m n✝ p n d : ℕ
hn : n ≠ 0
hd : d ≠ 0
⊢ (∀ (p k : ℕ), Prime p → p ^ k ∣ d → p ^ k ∣ n) → d ∣ n

Next tactic:
rw [← factorization_prime_le_iff_dvd hd hn]
theorem dvd_iff_prime_pow_dvd_dvd (n d : ℕ) :
    d ∣ n ↔ ∀ p k : ℕ, Prime p → p ^ k ∣ d → p ^ k ∣ n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  rcases eq_or_ne d 0 with (rfl | hd)
  · simp only [zero_dvd_iff, hn, false_iff_iff, not_forall]
    exact ⟨2, n, prime_two, dvd_zero _, mt (le_of_dvd hn.bot_lt) (lt_two_pow n).not_le⟩
  refine' ⟨fun h p k _ hpkd => dvd_trans hpkd h, _⟩
  rw [← factorization_prime_le_iff_dvd hd hn]
  

Proof state:
case inr.inr
a b m n✝ p n d : ℕ
hn : n ≠ 0
hd : d ≠ 0
⊢ (∀ (p k : ℕ), Prime p → p ^ k ∣ d → p ^ k ∣ n) → ∀ (p : ℕ), Prime p → (factorization d) p ≤ (factorization n) p

Next tactic:
intro h p pp
theorem dvd_iff_prime_pow_dvd_dvd (n d : ℕ) :
    d ∣ n ↔ ∀ p k : ℕ, Prime p → p ^ k ∣ d → p ^ k ∣ n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  rcases eq_or_ne d 0 with (rfl | hd)
  · simp only [zero_dvd_iff, hn, false_iff_iff, not_forall]
    exact ⟨2, n, prime_two, dvd_zero _, mt (le_of_dvd hn.bot_lt) (lt_two_pow n).not_le⟩
  refine' ⟨fun h p k _ hpkd => dvd_trans hpkd h, _⟩
  rw [← factorization_prime_le_iff_dvd hd hn]
  intro h p pp
  

Proof state:
case inr.inr
a b m n✝ p✝ n d : ℕ
hn : n ≠ 0
hd : d ≠ 0
h : ∀ (p k : ℕ), Prime p → p ^ k ∣ d → p ^ k ∣ n
p : ℕ
pp : Prime p
⊢ (factorization d) p ≤ (factorization n) p

Next tactic:
simp_rw [← pp.pow_dvd_iff_le_factorization hn]
theorem dvd_iff_prime_pow_dvd_dvd (n d : ℕ) :
    d ∣ n ↔ ∀ p k : ℕ, Prime p → p ^ k ∣ d → p ^ k ∣ n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  rcases eq_or_ne d 0 with (rfl | hd)
  · simp only [zero_dvd_iff, hn, false_iff_iff, not_forall]
    exact ⟨2, n, prime_two, dvd_zero _, mt (le_of_dvd hn.bot_lt) (lt_two_pow n).not_le⟩
  refine' ⟨fun h p k _ hpkd => dvd_trans hpkd h, _⟩
  rw [← factorization_prime_le_iff_dvd hd hn]
  intro h p pp
  simp_rw [← pp.pow_dvd_iff_le_factorization hn]
  

Proof state:
case inr.inr
a b m n✝ p✝ n d : ℕ
hn : n ≠ 0
hd : d ≠ 0
h : ∀ (p k : ℕ), Prime p → p ^ k ∣ d → p ^ k ∣ n
p : ℕ
pp : Prime p
⊢ p ^ (factorization d) p ∣ n

Next tactic:
exact h p _ pp (ord_proj_dvd _ _)
theorem prod_primeFactors_dvd (n : ℕ) : ∏ p in n.primeFactors, p ∣ n := by
  

Proof state:
a b m n✝ p n : ℕ
⊢ ∏ p in n.primeFactors, p ∣ n

Next tactic:
by_cases hn : n = 0
theorem prod_primeFactors_dvd (n : ℕ) : ∏ p in n.primeFactors, p ∣ n := by
  by_cases hn : n = 0
  · 

Proof state:
case pos
a b m n✝ p n : ℕ
hn : n = 0
⊢ ∏ p in n.primeFactors, p ∣ n

Next tactic:
subst hn
theorem prod_primeFactors_dvd (n : ℕ) : ∏ p in n.primeFactors, p ∣ n := by
  by_cases hn : n = 0
  · subst hn
    

Proof state:
case pos
a b m n p : ℕ
⊢ ∏ p in 0.primeFactors, p ∣ 0

Next tactic:
simp
theorem prod_primeFactors_dvd (n : ℕ) : ∏ p in n.primeFactors, p ∣ n := by
  by_cases hn : n = 0
  · subst hn
    simp
  

Proof state:
case neg
a b m n✝ p n : ℕ
hn : ¬n = 0
⊢ ∏ p in n.primeFactors, p ∣ n

Next tactic:
simpa [prod_factors hn] using Multiset.toFinset_prod_dvd_prod (n.factors : Multiset ℕ)
theorem factorization_gcd {a b : ℕ} (ha_pos : a ≠ 0) (hb_pos : b ≠ 0) :
    (gcd a b).factorization = a.factorization ⊓ b.factorization := by
  

Proof state:
a✝ b✝ m n p a b : ℕ
ha_pos : a ≠ 0
hb_pos : b ≠ 0
⊢ factorization (gcd a b) = factorization a ⊓ factorization b

Next tactic:
let dfac := a.factorization ⊓ b.factorization
theorem factorization_gcd {a b : ℕ} (ha_pos : a ≠ 0) (hb_pos : b ≠ 0) :
    (gcd a b).factorization = a.factorization ⊓ b.factorization := by
  let dfac := a.factorization ⊓ b.factorization
  

Proof state:
a✝ b✝ m n p a b : ℕ
ha_pos : a ≠ 0
hb_pos : b ≠ 0
dfac : ℕ →₀ ℕ := factorization a ⊓ factorization b
⊢ factorization (gcd a b) = factorization a ⊓ factorization b

Next tactic:
let d := dfac.prod (· ^ ·)
theorem factorization_gcd {a b : ℕ} (ha_pos : a ≠ 0) (hb_pos : b ≠ 0) :
    (gcd a b).factorization = a.factorization ⊓ b.factorization := by
  let dfac := a.factorization ⊓ b.factorization
  let d := dfac.prod (· ^ ·)
  

Proof state:
a✝ b✝ m n p a b : ℕ
ha_pos : a ≠ 0
hb_pos : b ≠ 0
dfac : ℕ →₀ ℕ := factorization a ⊓ factorization b
d : ℕ := Finsupp.prod dfac fun x x_1 => x ^ x_1
⊢ factorization (gcd a b) = factorization a ⊓ factorization b

Next tactic:
have dfac_prime : ∀ p : ℕ, p ∈ dfac.support → Prime p := by
    intro p hp
    have : p ∈ a.factors ∧ p ∈ b.factors := by simpa using hp
    exact prime_of_mem_factors this.1
theorem factorization_gcd {a b : ℕ} (ha_pos : a ≠ 0) (hb_pos : b ≠ 0) :
    (gcd a b).factorization = a.factorization ⊓ b.factorization := by
  let dfac := a.factorization ⊓ b.factorization
  let d := dfac.prod (· ^ ·)
  have dfac_prime : ∀ p : ℕ, p ∈ dfac.support → Prime p := by
    

Proof state:
a✝ b✝ m n p a b : ℕ
ha_pos : a ≠ 0
hb_pos : b ≠ 0
dfac : ℕ →₀ ℕ := factorization a ⊓ factorization b
d : ℕ := Finsupp.prod dfac fun x x_1 => x ^ x_1
⊢ ∀ p ∈ dfac.support, Prime p

Next tactic:
intro p hp
theorem factorization_gcd {a b : ℕ} (ha_pos : a ≠ 0) (hb_pos : b ≠ 0) :
    (gcd a b).factorization = a.factorization ⊓ b.factorization := by
  let dfac := a.factorization ⊓ b.factorization
  let d := dfac.prod (· ^ ·)
  have dfac_prime : ∀ p : ℕ, p ∈ dfac.support → Prime p := by
    intro p hp
    

Proof state:
a✝ b✝ m n p✝ a b : ℕ
ha_pos : a ≠ 0
hb_pos : b ≠ 0
dfac : ℕ →₀ ℕ := factorization a ⊓ factorization b
d : ℕ := Finsupp.prod dfac fun x x_1 => x ^ x_1
p : ℕ
hp : p ∈ dfac.support
⊢ Prime p

Next tactic:
have : p ∈ a.factors ∧ p ∈ b.factors := by simpa using hp
theorem factorization_gcd {a b : ℕ} (ha_pos : a ≠ 0) (hb_pos : b ≠ 0) :
    (gcd a b).factorization = a.factorization ⊓ b.factorization := by
  let dfac := a.factorization ⊓ b.factorization
  let d := dfac.prod (· ^ ·)
  have dfac_prime : ∀ p : ℕ, p ∈ dfac.support → Prime p := by
    intro p hp
    have : p ∈ a.factors ∧ p ∈ b.factors := by 

Proof state:
a✝ b✝ m n p✝ a b : ℕ
ha_pos : a ≠ 0
hb_pos : b ≠ 0
dfac : ℕ →₀ ℕ := factorization a ⊓ factorization b
d : ℕ := Finsupp.prod dfac fun x x_1 => x ^ x_1
p : ℕ
hp : p ∈ dfac.support
⊢ p ∈ factors a ∧ p ∈ factors b

Next tactic:
simpa using hp
theorem factorization_gcd {a b : ℕ} (ha_pos : a ≠ 0) (hb_pos : b ≠ 0) :
    (gcd a b).factorization = a.factorization ⊓ b.factorization := by
  let dfac := a.factorization ⊓ b.factorization
  let d := dfac.prod (· ^ ·)
  have dfac_prime : ∀ p : ℕ, p ∈ dfac.support → Prime p := by
    intro p hp
    have : p ∈ a.factors ∧ p ∈ b.factors := by simpa using hp
    

Proof state:
a✝ b✝ m n p✝ a b : ℕ
ha_pos : a ≠ 0
hb_pos : b ≠ 0
dfac : ℕ →₀ ℕ := factorization a ⊓ factorization b
d : ℕ := Finsupp.prod dfac fun x x_1 => x ^ x_1
p : ℕ
hp : p ∈ dfac.support
this : p ∈ factors a ∧ p ∈ factors b
⊢ Prime p

Next tactic:
exact prime_of_mem_factors this.1
theorem factorization_gcd {a b : ℕ} (ha_pos : a ≠ 0) (hb_pos : b ≠ 0) :
    (gcd a b).factorization = a.factorization ⊓ b.factorization := by
  let dfac := a.factorization ⊓ b.factorization
  let d := dfac.prod (· ^ ·)
  have dfac_prime : ∀ p : ℕ, p ∈ dfac.support → Prime p := by
    intro p hp
    have : p ∈ a.factors ∧ p ∈ b.factors := by simpa using hp
    exact prime_of_mem_factors this.1
  

Proof state:
a✝ b✝ m n p a b : ℕ
ha_pos : a ≠ 0
hb_pos : b ≠ 0
dfac : ℕ →₀ ℕ := factorization a ⊓ factorization b
d : ℕ := Finsupp.prod dfac fun x x_1 => x ^ x_1
dfac_prime : ∀ p ∈ dfac.support, Prime p
⊢ factorization (gcd a b) = factorization a ⊓ factorization b

Next tactic:
have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime