l3lab/ntp-mathlib huggingface dataset:
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  

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
h1 : factorization d = dfac
⊢ factorization (gcd a b) = factorization a ⊓ factorization b

Next tactic:
have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
  

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
h1 : factorization d = dfac
hd_pos : d ≠ 0
⊢ factorization (gcd a b) = factorization a ⊓ factorization b

Next tactic:
suffices d = gcd a b by rwa [← this]
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
  suffices d = gcd a b 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
dfac_prime : ∀ p ∈ dfac.support, Prime p
h1 : factorization d = dfac
hd_pos : d ≠ 0
this : d = gcd a b
⊢ factorization (gcd a b) = factorization a ⊓ factorization b

Next tactic:
rwa [← this]
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
  suffices d = gcd a b by rwa [← this]
  

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
h1 : factorization d = dfac
hd_pos : d ≠ 0
⊢ d = gcd a b

Next tactic:
apply gcd_greatest
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
  suffices d = gcd a b by rwa [← this]
  apply gcd_greatest
  · 

Proof state:
case hda
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
h1 : factorization d = dfac
hd_pos : d ≠ 0
⊢ d ∣ a

Next tactic:
rw [← factorization_le_iff_dvd hd_pos ha_pos, h1]
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
  suffices d = gcd a b by rwa [← this]
  apply gcd_greatest
  · rw [← factorization_le_iff_dvd hd_pos ha_pos, h1]
    

Proof state:
case hda
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
h1 : factorization d = dfac
hd_pos : d ≠ 0
⊢ dfac ≤ factorization a

Next tactic:
exact inf_le_left
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
  suffices d = gcd a b by rwa [← this]
  apply gcd_greatest
  · rw [← factorization_le_iff_dvd hd_pos ha_pos, h1]
    exact inf_le_left
  · 

Proof state:
case hdb
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
h1 : factorization d = dfac
hd_pos : d ≠ 0
⊢ d ∣ b

Next tactic:
rw [← factorization_le_iff_dvd hd_pos hb_pos, h1]
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
  suffices d = gcd a b by rwa [← this]
  apply gcd_greatest
  · rw [← factorization_le_iff_dvd hd_pos ha_pos, h1]
    exact inf_le_left
  · rw [← factorization_le_iff_dvd hd_pos hb_pos, h1]
    

Proof state:
case hdb
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
h1 : factorization d = dfac
hd_pos : d ≠ 0
⊢ dfac ≤ factorization b

Next tactic:
exact inf_le_right
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
  suffices d = gcd a b by rwa [← this]
  apply gcd_greatest
  · rw [← factorization_le_iff_dvd hd_pos ha_pos, h1]
    exact inf_le_left
  · rw [← factorization_le_iff_dvd hd_pos hb_pos, h1]
    exact inf_le_right
  · 

Proof state:
case hd
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
h1 : factorization d = dfac
hd_pos : d ≠ 0
⊢ ∀ (e : ℕ), e ∣ a → e ∣ b → e ∣ d

Next tactic:
intro e hea heb
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
  suffices d = gcd a b by rwa [← this]
  apply gcd_greatest
  · rw [← factorization_le_iff_dvd hd_pos ha_pos, h1]
    exact inf_le_left
  · rw [← factorization_le_iff_dvd hd_pos hb_pos, h1]
    exact inf_le_right
  · intro e hea heb
    

Proof state:
case hd
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
h1 : factorization d = dfac
hd_pos : d ≠ 0
e : ℕ
hea : e ∣ a
heb : e ∣ b
⊢ e ∣ d

Next tactic:
rcases Decidable.eq_or_ne e 0 with (rfl | he_pos)
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
  suffices d = gcd a b by rwa [← this]
  apply gcd_greatest
  · rw [← factorization_le_iff_dvd hd_pos ha_pos, h1]
    exact inf_le_left
  · rw [← factorization_le_iff_dvd hd_pos hb_pos, h1]
    exact inf_le_right
  · intro e hea heb
    rcases Decidable.eq_or_ne e 0 with (rfl | he_pos)
    · 

Proof state:
case hd.inl
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
h1 : factorization d = dfac
hd_pos : d ≠ 0
hea : 0 ∣ a
heb : 0 ∣ b
⊢ 0 ∣ d

Next tactic:
simp only [zero_dvd_iff] at hea
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
  suffices d = gcd a b by rwa [← this]
  apply gcd_greatest
  · rw [← factorization_le_iff_dvd hd_pos ha_pos, h1]
    exact inf_le_left
  · rw [← factorization_le_iff_dvd hd_pos hb_pos, h1]
    exact inf_le_right
  · intro e hea heb
    rcases Decidable.eq_or_ne e 0 with (rfl | he_pos)
    · simp only [zero_dvd_iff] at hea
      

Proof state:
case hd.inl
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
h1 : factorization d = dfac
hd_pos : d ≠ 0
heb : 0 ∣ b
hea : a = 0
⊢ 0 ∣ d

Next tactic:
contradiction
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
  suffices d = gcd a b by rwa [← this]
  apply gcd_greatest
  · rw [← factorization_le_iff_dvd hd_pos ha_pos, h1]
    exact inf_le_left
  · rw [← factorization_le_iff_dvd hd_pos hb_pos, h1]
    exact inf_le_right
  · intro e hea heb
    rcases Decidable.eq_or_ne e 0 with (rfl | he_pos)
    · simp only [zero_dvd_iff] at hea
      contradiction
    

Proof state:
case hd.inr
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
h1 : factorization d = dfac
hd_pos : d ≠ 0
e : ℕ
hea : e ∣ a
heb : e ∣ b
he_pos : e ≠ 0
⊢ e ∣ d

Next tactic:
have hea' := (factorization_le_iff_dvd he_pos ha_pos).mpr hea
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
  suffices d = gcd a b by rwa [← this]
  apply gcd_greatest
  · rw [← factorization_le_iff_dvd hd_pos ha_pos, h1]
    exact inf_le_left
  · rw [← factorization_le_iff_dvd hd_pos hb_pos, h1]
    exact inf_le_right
  · intro e hea heb
    rcases Decidable.eq_or_ne e 0 with (rfl | he_pos)
    · simp only [zero_dvd_iff] at hea
      contradiction
    have hea' := (factorization_le_iff_dvd he_pos ha_pos).mpr hea
    

Proof state:
case hd.inr
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
h1 : factorization d = dfac
hd_pos : d ≠ 0
e : ℕ
hea : e ∣ a
heb : e ∣ b
he_pos : e ≠ 0
hea' : factorization e ≤ factorization a
⊢ e ∣ d

Next tactic:
have heb' := (factorization_le_iff_dvd he_pos hb_pos).mpr heb
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
  have h1 : d.factorization = dfac := prod_pow_factorization_eq_self dfac_prime
  have hd_pos : d ≠ 0 := (factorizationEquiv.invFun ⟨dfac, dfac_prime⟩).2.ne'
  suffices d = gcd a b by rwa [← this]
  apply gcd_greatest
  · rw [← factorization_le_iff_dvd hd_pos ha_pos, h1]
    exact inf_le_left
  · rw [← factorization_le_iff_dvd hd_pos hb_pos, h1]
    exact inf_le_right
  · intro e hea heb
    rcases Decidable.eq_or_ne e 0 with (rfl | he_pos)
    · simp only [zero_dvd_iff] at hea
      contradiction
    have hea' := (factorization_le_iff_dvd he_pos ha_pos).mpr hea
    have heb' := (factorization_le_iff_dvd he_pos hb_pos).mpr heb
    

Proof state:
case hd.inr
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
h1 : factorization d = dfac
hd_pos : d ≠ 0
e : ℕ
hea : e ∣ a
heb : e ∣ b
he_pos : e ≠ 0
hea' : factorization e ≤ factorization a
heb' : factorization e ≤ factorization b
⊢ e ∣ d

Next tactic:
simp [← factorization_le_iff_dvd he_pos hd_pos, h1, hea', heb']
theorem factorization_lcm {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) :
    (a.lcm b).factorization = a.factorization ⊔ b.factorization := by
  

Proof state:
a✝ b✝ m n p a b : ℕ
ha : a ≠ 0
hb : b ≠ 0
⊢ factorization (lcm a b) = factorization a ⊔ factorization b

Next tactic:
rw [← add_right_inj (a.gcd b).factorization, ←
    factorization_mul (mt gcd_eq_zero_iff.1 fun h => ha h.1) (lcm_ne_zero ha hb), gcd_mul_lcm,
    factorization_gcd ha hb, factorization_mul ha hb]
theorem factorization_lcm {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) :
    (a.lcm b).factorization = a.factorization ⊔ b.factorization := by
  rw [← add_right_inj (a.gcd b).factorization, ←
    factorization_mul (mt gcd_eq_zero_iff.1 fun h => ha h.1) (lcm_ne_zero ha hb), gcd_mul_lcm,
    factorization_gcd ha hb, factorization_mul ha hb]
  

Proof state:
a✝ b✝ m n p a b : ℕ
ha : a ≠ 0
hb : b ≠ 0
⊢ factorization a + factorization b = factorization a ⊓ factorization b + factorization a ⊔ factorization b

Next tactic:
ext1
theorem factorization_lcm {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) :
    (a.lcm b).factorization = a.factorization ⊔ b.factorization := by
  rw [← add_right_inj (a.gcd b).factorization, ←
    factorization_mul (mt gcd_eq_zero_iff.1 fun h => ha h.1) (lcm_ne_zero ha hb), gcd_mul_lcm,
    factorization_gcd ha hb, factorization_mul ha hb]
  ext1
  

Proof state:
case h
a✝¹ b✝ m n p a b : ℕ
ha : a ≠ 0
hb : b ≠ 0
a✝ : ℕ
⊢ (factorization a + factorization b) a✝ = (factorization a ⊓ factorization b + factorization a ⊔ factorization b) a✝

Next tactic:
exact (min_add_max _ _).symm
@[to_additive sum_primeFactors_gcd_add_sum_primeFactors_mul]
theorem prod_primeFactors_gcd_mul_prod_primeFactors_mul {β : Type*} [CommMonoid β] (m n : ℕ)
    (f : ℕ → β) :
    (m.gcd n).primeFactors.prod f * (m * n).primeFactors.prod f =
      m.primeFactors.prod f * n.primeFactors.prod f := by
  

Proof state:
a b m✝ n✝ p : ℕ
β : Type u_1
inst✝ : CommMonoid β
m n : ℕ
f : ℕ → β
⊢ Finset.prod (gcd m n).primeFactors f * Finset.prod (m * n).primeFactors f =
    Finset.prod m.primeFactors f * Finset.prod n.primeFactors f

Next tactic:
obtain rfl | hm₀ := eq_or_ne m 0
@[to_additive sum_primeFactors_gcd_add_sum_primeFactors_mul]
theorem prod_primeFactors_gcd_mul_prod_primeFactors_mul {β : Type*} [CommMonoid β] (m n : ℕ)
    (f : ℕ → β) :
    (m.gcd n).primeFactors.prod f * (m * n).primeFactors.prod f =
      m.primeFactors.prod f * n.primeFactors.prod f := by
  obtain rfl | hm₀ := eq_or_ne m 0
  · 

Proof state:
case inl
a b m n✝ p : ℕ
β : Type u_1
inst✝ : CommMonoid β
n : ℕ
f : ℕ → β
⊢ Finset.prod (gcd 0 n).primeFactors f * Finset.prod (0 * n).primeFactors f =
    Finset.prod 0.primeFactors f * Finset.prod n.primeFactors f

Next tactic:
simp
@[to_additive sum_primeFactors_gcd_add_sum_primeFactors_mul]
theorem prod_primeFactors_gcd_mul_prod_primeFactors_mul {β : Type*} [CommMonoid β] (m n : ℕ)
    (f : ℕ → β) :
    (m.gcd n).primeFactors.prod f * (m * n).primeFactors.prod f =
      m.primeFactors.prod f * n.primeFactors.prod f := by
  obtain rfl | hm₀ := eq_or_ne m 0
  · simp
  

Proof state:
case inr
a b m✝ n✝ p : ℕ
β : Type u_1
inst✝ : CommMonoid β
m n : ℕ
f : ℕ → β
hm₀ : m ≠ 0
⊢ Finset.prod (gcd m n).primeFactors f * Finset.prod (m * n).primeFactors f =
    Finset.prod m.primeFactors f * Finset.prod n.primeFactors f

Next tactic:
obtain rfl | hn₀ := eq_or_ne n 0
@[to_additive sum_primeFactors_gcd_add_sum_primeFactors_mul]
theorem prod_primeFactors_gcd_mul_prod_primeFactors_mul {β : Type*} [CommMonoid β] (m n : ℕ)
    (f : ℕ → β) :
    (m.gcd n).primeFactors.prod f * (m * n).primeFactors.prod f =
      m.primeFactors.prod f * n.primeFactors.prod f := by
  obtain rfl | hm₀ := eq_or_ne m 0
  · simp
  obtain rfl | hn₀ := eq_or_ne n 0
  · 

Proof state:
case inr.inl
a b m✝ n p : ℕ
β : Type u_1
inst✝ : CommMonoid β
m : ℕ
f : ℕ → β
hm₀ : m ≠ 0
⊢ Finset.prod (gcd m 0).primeFactors f * Finset.prod (m * 0).primeFactors f =
    Finset.prod m.primeFactors f * Finset.prod 0.primeFactors f

Next tactic:
simp
@[to_additive sum_primeFactors_gcd_add_sum_primeFactors_mul]
theorem prod_primeFactors_gcd_mul_prod_primeFactors_mul {β : Type*} [CommMonoid β] (m n : ℕ)
    (f : ℕ → β) :
    (m.gcd n).primeFactors.prod f * (m * n).primeFactors.prod f =
      m.primeFactors.prod f * n.primeFactors.prod f := by
  obtain rfl | hm₀ := eq_or_ne m 0
  · simp
  obtain rfl | hn₀ := eq_or_ne n 0
  · simp
  · 

Proof state:
case inr.inr
a b m✝ n✝ p : ℕ
β : Type u_1
inst✝ : CommMonoid β
m n : ℕ
f : ℕ → β
hm₀ : m ≠ 0
hn₀ : n ≠ 0
⊢ Finset.prod (gcd m n).primeFactors f * Finset.prod (m * n).primeFactors f =
    Finset.prod m.primeFactors f * Finset.prod n.primeFactors f

Next tactic:
rw [primeFactors_mul hm₀ hn₀, primeFactors_gcd hm₀ hn₀, mul_comm, Finset.prod_union_inter]
theorem setOf_pow_dvd_eq_Icc_factorization {n p : ℕ} (pp : p.Prime) (hn : n ≠ 0) :
    { i : ℕ | i ≠ 0 ∧ p ^ i ∣ n } = Set.Icc 1 (n.factorization p) := by
  

Proof state:
a b m n✝ p✝ n p : ℕ
pp : Prime p
hn : n ≠ 0
⊢ {i | i ≠ 0 ∧ p ^ i ∣ n} = Set.Icc 1 ((factorization n) p)

Next tactic:
ext
theorem setOf_pow_dvd_eq_Icc_factorization {n p : ℕ} (pp : p.Prime) (hn : n ≠ 0) :
    { i : ℕ | i ≠ 0 ∧ p ^ i ∣ n } = Set.Icc 1 (n.factorization p) := by
  ext
  

Proof state:
case h
a b m n✝ p✝ n p : ℕ
pp : Prime p
hn : n ≠ 0
x✝ : ℕ
⊢ x✝ ∈ {i | i ≠ 0 ∧ p ^ i ∣ n} ↔ x✝ ∈ Set.Icc 1 ((factorization n) p)

Next tactic:
simp [lt_succ_iff, one_le_iff_ne_zero, pp.pow_dvd_iff_le_factorization hn]
/-- The set of positive powers of prime `p` that divide `n` is exactly the set of
positive natural numbers up to `n.factorization p`. -/
theorem Icc_factorization_eq_pow_dvd (n : ℕ) {p : ℕ} (pp : Prime p) :
    Icc 1 (n.factorization p) = (Ico 1 n).filter fun i : ℕ => p ^ i ∣ n := by
  

Proof state:
a b m n✝ p✝ n p : ℕ
pp : Prime p
⊢ Icc 1 ((factorization n) p) = Finset.filter (fun i => p ^ i ∣ n) (Ico 1 n)

Next tactic:
rcases eq_or_ne n 0 with (rfl | hn)
/-- The set of positive powers of prime `p` that divide `n` is exactly the set of
positive natural numbers up to `n.factorization p`. -/
theorem Icc_factorization_eq_pow_dvd (n : ℕ) {p : ℕ} (pp : Prime p) :
    Icc 1 (n.factorization p) = (Ico 1 n).filter fun i : ℕ => p ^ i ∣ n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · 

Proof state:
case inl
a b m n p✝ p : ℕ
pp : Prime p
⊢ Icc 1 ((factorization 0) p) = Finset.filter (fun i => p ^ i ∣ 0) (Ico 1 0)

Next tactic:
simp
/-- The set of positive powers of prime `p` that divide `n` is exactly the set of
positive natural numbers up to `n.factorization p`. -/
theorem Icc_factorization_eq_pow_dvd (n : ℕ) {p : ℕ} (pp : Prime p) :
    Icc 1 (n.factorization p) = (Ico 1 n).filter fun i : ℕ => p ^ i ∣ n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  

Proof state:
case inr
a b m n✝ p✝ n p : ℕ
pp : Prime p
hn : n ≠ 0
⊢ Icc 1 ((factorization n) p) = Finset.filter (fun i => p ^ i ∣ n) (Ico 1 n)

Next tactic:
ext x
/-- The set of positive powers of prime `p` that divide `n` is exactly the set of
positive natural numbers up to `n.factorization p`. -/
theorem Icc_factorization_eq_pow_dvd (n : ℕ) {p : ℕ} (pp : Prime p) :
    Icc 1 (n.factorization p) = (Ico 1 n).filter fun i : ℕ => p ^ i ∣ n := by
  rcases eq_or_ne n 0 with (rfl | hn)
  · simp
  ext x
  

Proof state:
case inr.a
a b m n✝ p✝ n p : ℕ
pp : Prime p
hn : n ≠ 0
x : ℕ
⊢ x ∈ Icc 1 ((factorization n) p) ↔ x ∈ Finset.filter (fun i => p ^ i ∣ n) (Ico 1 n)

Next tactic:
simp only [mem_Icc, Finset.mem_filter, mem_Ico, and_assoc, and_congr_right_iff,
    pp.pow_dvd_iff_le_factorization hn, iff_and_self]