l3lab/ntp-mathlib huggingface dataset:
/-- **Fundamental theorem of arithmetic**-/
theorem factors_unique {n : ℕ} {l : List ℕ} (h₁ : prod l = n) (h₂ : ∀ p ∈ l, Prime p) :
    l ~ factors n := by
  refine' perm_of_prod_eq_prod _ _ _
  · rw [h₁]
    refine' (prod_factors _).symm
    rintro rfl
    

Proof state:
case refine'_1
l : List ℕ
h₂ : ∀ p ∈ l, Prime p
h₁ : prod l = 0
⊢ False

Next tactic:
rw [prod_eq_zero_iff] at h₁
/-- **Fundamental theorem of arithmetic**-/
theorem factors_unique {n : ℕ} {l : List ℕ} (h₁ : prod l = n) (h₂ : ∀ p ∈ l, Prime p) :
    l ~ factors n := by
  refine' perm_of_prod_eq_prod _ _ _
  · rw [h₁]
    refine' (prod_factors _).symm
    rintro rfl
    rw [prod_eq_zero_iff] at h₁
    

Proof state:
case refine'_1
l : List ℕ
h₂ : ∀ p ∈ l, Prime p
h₁ : 0 ∈ l
⊢ False

Next tactic:
exact Prime.ne_zero (h₂ 0 h₁) rfl
/-- **Fundamental theorem of arithmetic**-/
theorem factors_unique {n : ℕ} {l : List ℕ} (h₁ : prod l = n) (h₂ : ∀ p ∈ l, Prime p) :
    l ~ factors n := by
  refine' perm_of_prod_eq_prod _ _ _
  · rw [h₁]
    refine' (prod_factors _).symm
    rintro rfl
    rw [prod_eq_zero_iff] at h₁
    exact Prime.ne_zero (h₂ 0 h₁) rfl
  · 

Proof state:
case refine'_2
n : ℕ
l : List ℕ
h₁ : prod l = n
h₂ : ∀ p ∈ l, Prime p
⊢ ∀ p ∈ l, _root_.Prime p

Next tactic:
simp_rw [← prime_iff]
/-- **Fundamental theorem of arithmetic**-/
theorem factors_unique {n : ℕ} {l : List ℕ} (h₁ : prod l = n) (h₂ : ∀ p ∈ l, Prime p) :
    l ~ factors n := by
  refine' perm_of_prod_eq_prod _ _ _
  · rw [h₁]
    refine' (prod_factors _).symm
    rintro rfl
    rw [prod_eq_zero_iff] at h₁
    exact Prime.ne_zero (h₂ 0 h₁) rfl
  · simp_rw [← prime_iff]
    

Proof state:
case refine'_2
n : ℕ
l : List ℕ
h₁ : prod l = n
h₂ : ∀ p ∈ l, Prime p
⊢ ∀ p ∈ l, Prime p

Next tactic:
exact h₂
/-- **Fundamental theorem of arithmetic**-/
theorem factors_unique {n : ℕ} {l : List ℕ} (h₁ : prod l = n) (h₂ : ∀ p ∈ l, Prime p) :
    l ~ factors n := by
  refine' perm_of_prod_eq_prod _ _ _
  · rw [h₁]
    refine' (prod_factors _).symm
    rintro rfl
    rw [prod_eq_zero_iff] at h₁
    exact Prime.ne_zero (h₂ 0 h₁) rfl
  · simp_rw [← prime_iff]
    exact h₂
  · 

Proof state:
case refine'_3
n : ℕ
l : List ℕ
h₁ : prod l = n
h₂ : ∀ p ∈ l, Prime p
⊢ ∀ p ∈ factors n, _root_.Prime p

Next tactic:
simp_rw [← prime_iff]
/-- **Fundamental theorem of arithmetic**-/
theorem factors_unique {n : ℕ} {l : List ℕ} (h₁ : prod l = n) (h₂ : ∀ p ∈ l, Prime p) :
    l ~ factors n := by
  refine' perm_of_prod_eq_prod _ _ _
  · rw [h₁]
    refine' (prod_factors _).symm
    rintro rfl
    rw [prod_eq_zero_iff] at h₁
    exact Prime.ne_zero (h₂ 0 h₁) rfl
  · simp_rw [← prime_iff]
    exact h₂
  · simp_rw [← prime_iff]
    

Proof state:
case refine'_3
n : ℕ
l : List ℕ
h₁ : prod l = n
h₂ : ∀ p ∈ l, Prime p
⊢ ∀ p ∈ factors n, Prime p

Next tactic:
exact fun p => prime_of_mem_factors
theorem Prime.factors_pow {p : ℕ} (hp : p.Prime) (n : ℕ) :
    (p ^ n).factors = List.replicate n p := by
  

Proof state:
p : ℕ
hp : Prime p
n : ℕ
⊢ factors (p ^ n) = replicate n p

Next tactic:
symm
theorem Prime.factors_pow {p : ℕ} (hp : p.Prime) (n : ℕ) :
    (p ^ n).factors = List.replicate n p := by
  symm
  

Proof state:
p : ℕ
hp : Prime p
n : ℕ
⊢ replicate n p = factors (p ^ n)

Next tactic:
rw [← List.replicate_perm]
theorem Prime.factors_pow {p : ℕ} (hp : p.Prime) (n : ℕ) :
    (p ^ n).factors = List.replicate n p := by
  symm
  rw [← List.replicate_perm]
  

Proof state:
p : ℕ
hp : Prime p
n : ℕ
⊢ replicate n p ~ factors (p ^ n)

Next tactic:
apply Nat.factors_unique (List.prod_replicate n p)
theorem Prime.factors_pow {p : ℕ} (hp : p.Prime) (n : ℕ) :
    (p ^ n).factors = List.replicate n p := by
  symm
  rw [← List.replicate_perm]
  apply Nat.factors_unique (List.prod_replicate n p)
  

Proof state:
p : ℕ
hp : Prime p
n : ℕ
⊢ ∀ p_1 ∈ replicate n p, Prime p_1

Next tactic:
intro q hq
theorem Prime.factors_pow {p : ℕ} (hp : p.Prime) (n : ℕ) :
    (p ^ n).factors = List.replicate n p := by
  symm
  rw [← List.replicate_perm]
  apply Nat.factors_unique (List.prod_replicate n p)
  intro q hq
  

Proof state:
p : ℕ
hp : Prime p
n q : ℕ
hq : q ∈ replicate n p
⊢ Prime q

Next tactic:
rwa [eq_of_mem_replicate hq]
theorem eq_prime_pow_of_unique_prime_dvd {n p : ℕ} (hpos : n ≠ 0)
    (h : ∀ {d}, Nat.Prime d → d ∣ n → d = p) : n = p ^ n.factors.length := by
  

Proof state:
n p : ℕ
hpos : n ≠ 0
h : ∀ {d : ℕ}, Prime d → d ∣ n → d = p
⊢ n = p ^ length (factors n)

Next tactic:
set k := n.factors.length
theorem eq_prime_pow_of_unique_prime_dvd {n p : ℕ} (hpos : n ≠ 0)
    (h : ∀ {d}, Nat.Prime d → d ∣ n → d = p) : n = p ^ n.factors.length := by
  set k := n.factors.length
  

Proof state:
n p : ℕ
hpos : n ≠ 0
h : ∀ {d : ℕ}, Prime d → d ∣ n → d = p
k : ℕ := length (factors n)
⊢ n = p ^ k

Next tactic:
rw [← prod_factors hpos, ← prod_replicate k p,
    eq_replicate_of_mem fun d hd => h (prime_of_mem_factors hd) (dvd_of_mem_factors hd)]
/-- For positive `a` and `b`, the prime factors of `a * b` are the union of those of `a` and `b` -/
theorem perm_factors_mul {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) :
    (a * b).factors ~ a.factors ++ b.factors := by
  

Proof state:
a b : ℕ
ha : a ≠ 0
hb : b ≠ 0
⊢ factors (a * b) ~ factors a ++ factors b

Next tactic:
refine' (factors_unique _ _).symm
/-- For positive `a` and `b`, the prime factors of `a * b` are the union of those of `a` and `b` -/
theorem perm_factors_mul {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) :
    (a * b).factors ~ a.factors ++ b.factors := by
  refine' (factors_unique _ _).symm
  · 

Proof state:
case refine'_1
a b : ℕ
ha : a ≠ 0
hb : b ≠ 0
⊢ prod (factors a ++ factors b) = a * b

Next tactic:
rw [List.prod_append, prod_factors ha, prod_factors hb]
/-- For positive `a` and `b`, the prime factors of `a * b` are the union of those of `a` and `b` -/
theorem perm_factors_mul {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) :
    (a * b).factors ~ a.factors ++ b.factors := by
  refine' (factors_unique _ _).symm
  · rw [List.prod_append, prod_factors ha, prod_factors hb]
  · 

Proof state:
case refine'_2
a b : ℕ
ha : a ≠ 0
hb : b ≠ 0
⊢ ∀ p ∈ factors a ++ factors b, Prime p

Next tactic:
intro p hp
/-- For positive `a` and `b`, the prime factors of `a * b` are the union of those of `a` and `b` -/
theorem perm_factors_mul {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) :
    (a * b).factors ~ a.factors ++ b.factors := by
  refine' (factors_unique _ _).symm
  · rw [List.prod_append, prod_factors ha, prod_factors hb]
  · intro p hp
    

Proof state:
case refine'_2
a b : ℕ
ha : a ≠ 0
hb : b ≠ 0
p : ℕ
hp : p ∈ factors a ++ factors b
⊢ Prime p

Next tactic:
rw [List.mem_append] at hp
/-- For positive `a` and `b`, the prime factors of `a * b` are the union of those of `a` and `b` -/
theorem perm_factors_mul {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) :
    (a * b).factors ~ a.factors ++ b.factors := by
  refine' (factors_unique _ _).symm
  · rw [List.prod_append, prod_factors ha, prod_factors hb]
  · intro p hp
    rw [List.mem_append] at hp
    

Proof state:
case refine'_2
a b : ℕ
ha : a ≠ 0
hb : b ≠ 0
p : ℕ
hp : p ∈ factors a ∨ p ∈ factors b
⊢ Prime p

Next tactic:
cases' hp with hp' hp'
/-- For positive `a` and `b`, the prime factors of `a * b` are the union of those of `a` and `b` -/
theorem perm_factors_mul {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) :
    (a * b).factors ~ a.factors ++ b.factors := by
  refine' (factors_unique _ _).symm
  · rw [List.prod_append, prod_factors ha, prod_factors hb]
  · intro p hp
    rw [List.mem_append] at hp
    cases' hp with hp' hp' <;> 

Proof state:
case refine'_2.inl
a b : ℕ
ha : a ≠ 0
hb : b ≠ 0
p : ℕ
hp' : p ∈ factors a
⊢ Prime p

Next tactic:
exact prime_of_mem_factors hp'
/-- For positive `a` and `b`, the prime factors of `a * b` are the union of those of `a` and `b` -/
theorem perm_factors_mul {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) :
    (a * b).factors ~ a.factors ++ b.factors := by
  refine' (factors_unique _ _).symm
  · rw [List.prod_append, prod_factors ha, prod_factors hb]
  · intro p hp
    rw [List.mem_append] at hp
    cases' hp with hp' hp' <;> 

Proof state:
case refine'_2.inr
a b : ℕ
ha : a ≠ 0
hb : b ≠ 0
p : ℕ
hp' : p ∈ factors b
⊢ Prime p

Next tactic:
exact prime_of_mem_factors hp'
/-- For coprime `a` and `b`, the prime factors of `a * b` are the union of those of `a` and `b` -/
theorem perm_factors_mul_of_coprime {a b : ℕ} (hab : Coprime a b) :
    (a * b).factors ~ a.factors ++ b.factors := by
  

Proof state:
a b : ℕ
hab : Coprime a b
⊢ factors (a * b) ~ factors a ++ factors b

Next tactic:
rcases a.eq_zero_or_pos with (rfl | ha)
/-- For coprime `a` and `b`, the prime factors of `a * b` are the union of those of `a` and `b` -/
theorem perm_factors_mul_of_coprime {a b : ℕ} (hab : Coprime a b) :
    (a * b).factors ~ a.factors ++ b.factors := by
  rcases a.eq_zero_or_pos with (rfl | ha)
  · 

Proof state:
case inl
b : ℕ
hab : Coprime 0 b
⊢ factors (0 * b) ~ factors 0 ++ factors b

Next tactic:
simp [(coprime_zero_left _).mp hab]
/-- For coprime `a` and `b`, the prime factors of `a * b` are the union of those of `a` and `b` -/
theorem perm_factors_mul_of_coprime {a b : ℕ} (hab : Coprime a b) :
    (a * b).factors ~ a.factors ++ b.factors := by
  rcases a.eq_zero_or_pos with (rfl | ha)
  · simp [(coprime_zero_left _).mp hab]
  

Proof state:
case inr
a b : ℕ
hab : Coprime a b
ha : a > 0
⊢ factors (a * b) ~ factors a ++ factors b

Next tactic:
rcases b.eq_zero_or_pos with (rfl | hb)
/-- For coprime `a` and `b`, the prime factors of `a * b` are the union of those of `a` and `b` -/
theorem perm_factors_mul_of_coprime {a b : ℕ} (hab : Coprime a b) :
    (a * b).factors ~ a.factors ++ b.factors := by
  rcases a.eq_zero_or_pos with (rfl | ha)
  · simp [(coprime_zero_left _).mp hab]
  rcases b.eq_zero_or_pos with (rfl | hb)
  · 

Proof state:
case inr.inl
a : ℕ
ha : a > 0
hab : Coprime a 0
⊢ factors (a * 0) ~ factors a ++ factors 0

Next tactic:
simp [(coprime_zero_right _).mp hab]
/-- For coprime `a` and `b`, the prime factors of `a * b` are the union of those of `a` and `b` -/
theorem perm_factors_mul_of_coprime {a b : ℕ} (hab : Coprime a b) :
    (a * b).factors ~ a.factors ++ b.factors := by
  rcases a.eq_zero_or_pos with (rfl | ha)
  · simp [(coprime_zero_left _).mp hab]
  rcases b.eq_zero_or_pos with (rfl | hb)
  · simp [(coprime_zero_right _).mp hab]
  

Proof state:
case inr.inr
a b : ℕ
hab : Coprime a b
ha : a > 0
hb : b > 0
⊢ factors (a * b) ~ factors a ++ factors b

Next tactic:
exact perm_factors_mul ha.ne' hb.ne'
theorem factors_sublist_right {n k : ℕ} (h : k ≠ 0) : n.factors <+ (n * k).factors := by
  

Proof state:
n k : ℕ
h : k ≠ 0
⊢ factors n <+ factors (n * k)

Next tactic:
cases' n with hn
theorem factors_sublist_right {n k : ℕ} (h : k ≠ 0) : n.factors <+ (n * k).factors := by
  cases' n with hn
  · 

Proof state:
case zero
k : ℕ
h : k ≠ 0
⊢ factors zero <+ factors (zero * k)

Next tactic:
simp [zero_mul]
theorem factors_sublist_right {n k : ℕ} (h : k ≠ 0) : n.factors <+ (n * k).factors := by
  cases' n with hn
  · simp [zero_mul]
  

Proof state:
case succ
k : ℕ
h : k ≠ 0
hn : ℕ
⊢ factors (succ hn) <+ factors (succ hn * k)

Next tactic:
apply sublist_of_subperm_of_sorted _ (factors_sorted _) (factors_sorted _)
theorem factors_sublist_right {n k : ℕ} (h : k ≠ 0) : n.factors <+ (n * k).factors := by
  cases' n with hn
  · simp [zero_mul]
  apply sublist_of_subperm_of_sorted _ (factors_sorted _) (factors_sorted _)
  

Proof state:
k : ℕ
h : k ≠ 0
hn : ℕ
⊢ factors (succ hn) <+~ factors (succ hn * k)

Next tactic:
simp only [(perm_factors_mul (Nat.succ_ne_zero _) h).subperm_left]
theorem factors_sublist_right {n k : ℕ} (h : k ≠ 0) : n.factors <+ (n * k).factors := by
  cases' n with hn
  · simp [zero_mul]
  apply sublist_of_subperm_of_sorted _ (factors_sorted _) (factors_sorted _)
  simp only [(perm_factors_mul (Nat.succ_ne_zero _) h).subperm_left]
  

Proof state:
k : ℕ
h : k ≠ 0
hn : ℕ
⊢ factors (succ hn) <+~ factors (succ hn) ++ factors k

Next tactic:
exact (sublist_append_left _ _).subperm
theorem factors_sublist_of_dvd {n k : ℕ} (h : n ∣ k) (h' : k ≠ 0) : n.factors <+ k.factors := by
  

Proof state:
n k : ℕ
h : n ∣ k
h' : k ≠ 0
⊢ factors n <+ factors k

Next tactic:
obtain ⟨a, rfl⟩ := h
theorem factors_sublist_of_dvd {n k : ℕ} (h : n ∣ k) (h' : k ≠ 0) : n.factors <+ k.factors := by
  obtain ⟨a, rfl⟩ := h
  

Proof state:
case intro
n a : ℕ
h' : n * a ≠ 0
⊢ factors n <+ factors (n * a)

Next tactic:
exact factors_sublist_right (right_ne_zero_of_mul h')
theorem dvd_of_factors_subperm {a b : ℕ} (ha : a ≠ 0) (h : a.factors <+~ b.factors) : a ∣ b := by
  

Proof state:
a b : ℕ
ha : a ≠ 0
h : factors a <+~ factors b
⊢ a ∣ b

Next tactic:
rcases b.eq_zero_or_pos with (rfl | hb)
theorem dvd_of_factors_subperm {a b : ℕ} (ha : a ≠ 0) (h : a.factors <+~ b.factors) : a ∣ b := by
  rcases b.eq_zero_or_pos with (rfl | hb)
  · 

Proof state:
case inl
a : ℕ
ha : a ≠ 0
h : factors a <+~ factors 0
⊢ a ∣ 0

Next tactic:
exact dvd_zero _
theorem dvd_of_factors_subperm {a b : ℕ} (ha : a ≠ 0) (h : a.factors <+~ b.factors) : a ∣ b := by
  rcases b.eq_zero_or_pos with (rfl | hb)
  · exact dvd_zero _
  

Proof state:
case inr
a b : ℕ
ha : a ≠ 0
h : factors a <+~ factors b
hb : b > 0
⊢ a ∣ b

Next tactic:
rcases a with (_ | _ | a)
theorem dvd_of_factors_subperm {a b : ℕ} (ha : a ≠ 0) (h : a.factors <+~ b.factors) : a ∣ b := by
  rcases b.eq_zero_or_pos with (rfl | hb)
  · exact dvd_zero _
  rcases a with (_ | _ | a)
  · 

Proof state:
case inr.zero
b : ℕ
hb : b > 0
ha : zero ≠ 0
h : factors zero <+~ factors b
⊢ zero ∣ b

Next tactic:
exact (ha rfl).elim
theorem dvd_of_factors_subperm {a b : ℕ} (ha : a ≠ 0) (h : a.factors <+~ b.factors) : a ∣ b := by
  rcases b.eq_zero_or_pos with (rfl | hb)
  · exact dvd_zero _
  rcases a with (_ | _ | a)
  · exact (ha rfl).elim
  · 

Proof state:
case inr.succ.zero
b : ℕ
hb : b > 0
ha : succ zero ≠ 0
h : factors (succ zero) <+~ factors b
⊢ succ zero ∣ b

Next tactic:
exact one_dvd _
theorem dvd_of_factors_subperm {a b : ℕ} (ha : a ≠ 0) (h : a.factors <+~ b.factors) : a ∣ b := by
  rcases b.eq_zero_or_pos with (rfl | hb)
  · exact dvd_zero _
  rcases a with (_ | _ | a)
  · exact (ha rfl).elim
  · exact one_dvd _
  --Porting note: previous proof
  --use (b.factors.diff a.succ.succ.factors).prod
  

Proof state:
case inr.succ.succ
b : ℕ
hb : b > 0
a : ℕ
ha : succ (succ a) ≠ 0
h : factors (succ (succ a)) <+~ factors b
⊢ succ (succ a) ∣ b

Next tactic:
use (@List.diff _ instBEq b.factors a.succ.succ.factors).prod
theorem dvd_of_factors_subperm {a b : ℕ} (ha : a ≠ 0) (h : a.factors <+~ b.factors) : a ∣ b := by
  rcases b.eq_zero_or_pos with (rfl | hb)
  · exact dvd_zero _
  rcases a with (_ | _ | a)
  · exact (ha rfl).elim
  · exact one_dvd _
  --Porting note: previous proof
  --use (b.factors.diff a.succ.succ.factors).prod
  use (@List.diff _ instBEq b.factors a.succ.succ.factors).prod
  

Proof state:
case h
b : ℕ
hb : b > 0
a : ℕ
ha : succ (succ a) ≠ 0
h : factors (succ (succ a)) <+~ factors b
⊢ b = succ (succ a) * prod (List.diff (factors b) (factors (succ (succ a))))

Next tactic:
nth_rw 1 [← Nat.prod_factors ha]
theorem dvd_of_factors_subperm {a b : ℕ} (ha : a ≠ 0) (h : a.factors <+~ b.factors) : a ∣ b := by
  rcases b.eq_zero_or_pos with (rfl | hb)
  · exact dvd_zero _
  rcases a with (_ | _ | a)
  · exact (ha rfl).elim
  · exact one_dvd _
  --Porting note: previous proof
  --use (b.factors.diff a.succ.succ.factors).prod
  use (@List.diff _ instBEq b.factors a.succ.succ.factors).prod
  nth_rw 1 [← Nat.prod_factors ha]
  

Proof state:
case h
b : ℕ
hb : b > 0
a : ℕ
ha : succ (succ a) ≠ 0
h : factors (succ (succ a)) <+~ factors b
⊢ b = prod (factors (succ (succ a))) * prod (List.diff (factors b) (factors (succ (succ a))))

Next tactic:
rw [← List.prod_append,
    List.Perm.prod_eq <| List.subperm_append_diff_self_of_count_le <| List.subperm_ext_iff.mp h,
    Nat.prod_factors hb.ne']
theorem mem_factors_mul {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) {p : ℕ} :
    p ∈ (a * b).factors ↔ p ∈ a.factors ∨ p ∈ b.factors := by
  

Proof state:
a b : ℕ
ha : a ≠ 0
hb : b ≠ 0
p : ℕ
⊢ p ∈ factors (a * b) ↔ p ∈ factors a ∨ p ∈ factors b

Next tactic:
rw [mem_factors (mul_ne_zero ha hb), mem_factors ha, mem_factors hb, ← and_or_left]
theorem mem_factors_mul {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) {p : ℕ} :
    p ∈ (a * b).factors ↔ p ∈ a.factors ∨ p ∈ b.factors := by
  rw [mem_factors (mul_ne_zero ha hb), mem_factors ha, mem_factors hb, ← and_or_left]
  

Proof state:
a b : ℕ
ha : a ≠ 0
hb : b ≠ 0
p : ℕ
⊢ Prime p ∧ p ∣ a * b ↔ Prime p ∧ (p ∣ a ∨ p ∣ b)

Next tactic:
simpa only [and_congr_right_iff] using Prime.dvd_mul
/-- The sets of factors of coprime `a` and `b` are disjoint -/
theorem coprime_factors_disjoint {a b : ℕ} (hab : a.Coprime b) :
    List.Disjoint a.factors b.factors := by
  

Proof state:
a b : ℕ
hab : Coprime a b
⊢ List.Disjoint (factors a) (factors b)

Next tactic:
intro q hqa hqb
/-- The sets of factors of coprime `a` and `b` are disjoint -/
theorem coprime_factors_disjoint {a b : ℕ} (hab : a.Coprime b) :
    List.Disjoint a.factors b.factors := by
  intro q hqa hqb
  

Proof state:
a b : ℕ
hab : Coprime a b
q : ℕ
hqa : q ∈ factors a
hqb : q ∈ factors b
⊢ False

Next tactic:
apply not_prime_one
/-- The sets of factors of coprime `a` and `b` are disjoint -/
theorem coprime_factors_disjoint {a b : ℕ} (hab : a.Coprime b) :
    List.Disjoint a.factors b.factors := by
  intro q hqa hqb
  apply not_prime_one
  

Proof state:
a b : ℕ
hab : Coprime a b
q : ℕ
hqa : q ∈ factors a
hqb : q ∈ factors b
⊢ Prime 1

Next tactic:
rw [← eq_one_of_dvd_coprimes hab (dvd_of_mem_factors hqa) (dvd_of_mem_factors hqb)]
/-- The sets of factors of coprime `a` and `b` are disjoint -/
theorem coprime_factors_disjoint {a b : ℕ} (hab : a.Coprime b) :
    List.Disjoint a.factors b.factors := by
  intro q hqa hqb
  apply not_prime_one
  rw [← eq_one_of_dvd_coprimes hab (dvd_of_mem_factors hqa) (dvd_of_mem_factors hqb)]
  

Proof state:
a b : ℕ
hab : Coprime a b
q : ℕ
hqa : q ∈ factors a
hqb : q ∈ factors b
⊢ Prime q

Next tactic:
exact prime_of_mem_factors hqa
theorem mem_factors_mul_of_coprime {a b : ℕ} (hab : Coprime a b) (p : ℕ) :
    p ∈ (a * b).factors ↔ p ∈ a.factors ∪ b.factors := by
  

Proof state:
a b : ℕ
hab : Coprime a b
p : ℕ
⊢ p ∈ factors (a * b) ↔ p ∈ factors a ∪ factors b

Next tactic:
rcases a.eq_zero_or_pos with (rfl | ha)
theorem mem_factors_mul_of_coprime {a b : ℕ} (hab : Coprime a b) (p : ℕ) :
    p ∈ (a * b).factors ↔ p ∈ a.factors ∪ b.factors := by
  rcases a.eq_zero_or_pos with (rfl | ha)
  · 

Proof state:
case inl
b p : ℕ
hab : Coprime 0 b
⊢ p ∈ factors (0 * b) ↔ p ∈ factors 0 ∪ factors b

Next tactic:
simp [(coprime_zero_left _).mp hab]
theorem mem_factors_mul_of_coprime {a b : ℕ} (hab : Coprime a b) (p : ℕ) :
    p ∈ (a * b).factors ↔ p ∈ a.factors ∪ b.factors := by
  rcases a.eq_zero_or_pos with (rfl | ha)
  · simp [(coprime_zero_left _).mp hab]
  

Proof state:
case inr
a b : ℕ
hab : Coprime a b
p : ℕ
ha : a > 0
⊢ p ∈ factors (a * b) ↔ p ∈ factors a ∪ factors b

Next tactic:
rcases b.eq_zero_or_pos with (rfl | hb)
theorem mem_factors_mul_of_coprime {a b : ℕ} (hab : Coprime a b) (p : ℕ) :
    p ∈ (a * b).factors ↔ p ∈ a.factors ∪ b.factors := by
  rcases a.eq_zero_or_pos with (rfl | ha)
  · simp [(coprime_zero_left _).mp hab]
  rcases b.eq_zero_or_pos with (rfl | hb)
  · 

Proof state:
case inr.inl
a p : ℕ
ha : a > 0
hab : Coprime a 0
⊢ p ∈ factors (a * 0) ↔ p ∈ factors a ∪ factors 0

Next tactic:
simp [(coprime_zero_right _).mp hab]
theorem mem_factors_mul_of_coprime {a b : ℕ} (hab : Coprime a b) (p : ℕ) :
    p ∈ (a * b).factors ↔ p ∈ a.factors ∪ b.factors := by
  rcases a.eq_zero_or_pos with (rfl | ha)
  · simp [(coprime_zero_left _).mp hab]
  rcases b.eq_zero_or_pos with (rfl | hb)
  · simp [(coprime_zero_right _).mp hab]
  

Proof state:
case inr.inr
a b : ℕ
hab : Coprime a b
p : ℕ
ha : a > 0
hb : b > 0
⊢ p ∈ factors (a * b) ↔ p ∈ factors a ∪ factors b

Next tactic:
rw [mem_factors_mul ha.ne' hb.ne', List.mem_union_iff]
/-- If `p` is a prime factor of `a` then `p` is also a prime factor of `a * b` for any `b > 0` -/
theorem mem_factors_mul_left {p a b : ℕ} (hpa : p ∈ a.factors) (hb : b ≠ 0) :
    p ∈ (a * b).factors := by
  

Proof state:
p a b : ℕ
hpa : p ∈ factors a
hb : b ≠ 0
⊢ p ∈ factors (a * b)

Next tactic:
rcases eq_or_ne a 0 with (rfl | ha)
/-- If `p` is a prime factor of `a` then `p` is also a prime factor of `a * b` for any `b > 0` -/
theorem mem_factors_mul_left {p a b : ℕ} (hpa : p ∈ a.factors) (hb : b ≠ 0) :
    p ∈ (a * b).factors := by
  rcases eq_or_ne a 0 with (rfl | ha)
  · 

Proof state:
case inl
p b : ℕ
hb : b ≠ 0
hpa : p ∈ factors 0
⊢ p ∈ factors (0 * b)

Next tactic:
simp at hpa
/-- If `p` is a prime factor of `a` then `p` is also a prime factor of `a * b` for any `b > 0` -/
theorem mem_factors_mul_left {p a b : ℕ} (hpa : p ∈ a.factors) (hb : b ≠ 0) :
    p ∈ (a * b).factors := by
  rcases eq_or_ne a 0 with (rfl | ha)
  · simp at hpa
  

Proof state:
case inr
p a b : ℕ
hpa : p ∈ factors a
hb : b ≠ 0
ha : a ≠ 0
⊢ p ∈ factors (a * b)

Next tactic:
apply (mem_factors_mul ha hb).2 (Or.inl hpa)
/-- If `p` is a prime factor of `b` then `p` is also a prime factor of `a * b` for any `a > 0` -/
theorem mem_factors_mul_right {p a b : ℕ} (hpb : p ∈ b.factors) (ha : a ≠ 0) :
    p ∈ (a * b).factors := by
  

Proof state:
p a b : ℕ
hpb : p ∈ factors b
ha : a ≠ 0
⊢ p ∈ factors (a * b)

Next tactic:
rw [mul_comm]
/-- If `p` is a prime factor of `b` then `p` is also a prime factor of `a * b` for any `a > 0` -/
theorem mem_factors_mul_right {p a b : ℕ} (hpb : p ∈ b.factors) (ha : a ≠ 0) :
    p ∈ (a * b).factors := by
  rw [mul_comm]
  

Proof state:
p a b : ℕ
hpb : p ∈ factors b
ha : a ≠ 0
⊢ p ∈ factors (b * a)

Next tactic:
exact mem_factors_mul_left hpb ha
theorem four_dvd_or_exists_odd_prime_and_dvd_of_two_lt {n : ℕ} (n2 : 2 < n) :
    4 ∣ n ∨ ∃ p, Prime p ∧ p ∣ n ∧ Odd p := by
  

Proof state:
n : ℕ
n2 : 2 < n
⊢ 4 ∣ n ∨ ∃ p, Prime p ∧ p ∣ n ∧ Odd p

Next tactic:
obtain ⟨_ | _ | k, rfl⟩ | ⟨p, hp, hdvd, hodd⟩ := n.eq_two_pow_or_exists_odd_prime_and_dvd
theorem four_dvd_or_exists_odd_prime_and_dvd_of_two_lt {n : ℕ} (n2 : 2 < n) :
    4 ∣ n ∨ ∃ p, Prime p ∧ p ∣ n ∧ Odd p := by
  obtain ⟨_ | _ | k, rfl⟩ | ⟨p, hp, hdvd, hodd⟩ := n.eq_two_pow_or_exists_odd_prime_and_dvd
  · 

Proof state:
case inl.intro.zero
n2 : 2 < 2 ^ zero
⊢ 4 ∣ 2 ^ zero ∨ ∃ p, Prime p ∧ p ∣ 2 ^ zero ∧ Odd p

Next tactic:
contradiction
theorem four_dvd_or_exists_odd_prime_and_dvd_of_two_lt {n : ℕ} (n2 : 2 < n) :
    4 ∣ n ∨ ∃ p, Prime p ∧ p ∣ n ∧ Odd p := by
  obtain ⟨_ | _ | k, rfl⟩ | ⟨p, hp, hdvd, hodd⟩ := n.eq_two_pow_or_exists_odd_prime_and_dvd
  · contradiction
  · 

Proof state:
case inl.intro.succ.zero
n2 : 2 < 2 ^ succ zero
⊢ 4 ∣ 2 ^ succ zero ∨ ∃ p, Prime p ∧ p ∣ 2 ^ succ zero ∧ Odd p

Next tactic:
contradiction
theorem four_dvd_or_exists_odd_prime_and_dvd_of_two_lt {n : ℕ} (n2 : 2 < n) :
    4 ∣ n ∨ ∃ p, Prime p ∧ p ∣ n ∧ Odd p := by
  obtain ⟨_ | _ | k, rfl⟩ | ⟨p, hp, hdvd, hodd⟩ := n.eq_two_pow_or_exists_odd_prime_and_dvd
  · contradiction
  · contradiction
  · 

Proof state:
case inl.intro.succ.succ
k : ℕ
n2 : 2 < 2 ^ succ (succ k)
⊢ 4 ∣ 2 ^ succ (succ k) ∨ ∃ p, Prime p ∧ p ∣ 2 ^ succ (succ k) ∧ Odd p

Next tactic:
simp [pow_succ, mul_assoc]
theorem four_dvd_or_exists_odd_prime_and_dvd_of_two_lt {n : ℕ} (n2 : 2 < n) :
    4 ∣ n ∨ ∃ p, Prime p ∧ p ∣ n ∧ Odd p := by
  obtain ⟨_ | _ | k, rfl⟩ | ⟨p, hp, hdvd, hodd⟩ := n.eq_two_pow_or_exists_odd_prime_and_dvd
  · contradiction
  · contradiction
  · simp [pow_succ, mul_assoc]
  · 

Proof state:
case inr.intro.intro.intro
n : ℕ
n2 : 2 < n
p : ℕ
hp : Prime p
hdvd : p ∣ n
hodd : Odd p
⊢ 4 ∣ n ∨ ∃ p, Prime p ∧ p ∣ n ∧ Odd p

Next tactic:
exact Or.inr ⟨p, hp, hdvd, hodd⟩
@[simp]
theorem Equiv.asEmbedding_range {α β : Sort _} {p : β → Prop} (e : α ≃ Subtype p) :
    Set.range e.asEmbedding = setOf p :=
  Set.ext fun x ↦ ⟨fun ⟨y, h⟩ ↦ h ▸ Subtype.coe_prop (e y), fun hs ↦ ⟨e.symm ⟨x, hs⟩, by 

Proof state:
α✝ : Sort u
β✝ : Sort v
f : α✝ ≃ β✝
α : Sort u_1
β : Type u_2
p : β → Prop
e : α ≃ Subtype p
x : β
hs : x ∈ setOf p
⊢ (asEmbedding e) (e.symm { val := x, property := hs }) = x

Next tactic:
simp