l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem edist_toL1_zero (f : α → β) (hf : Integrable f μ) :
    edist (hf.toL1 f) 0 = ∫⁻ a, edist (f a) 0 ∂μ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ ν : Measure α
inst✝² : MeasurableSpace δ
inst✝¹ : NormedAddCommGroup β
inst✝ : NormedAddCommGroup γ
f : α → β
hf : Integrable f
⊢ edist (toL1 f hf) 0 = ∫⁻ (a : α), edist (f a) 0 ∂μ

Next tactic:
simp only [toL1, Lp.edist_toLp_zero, snorm, one_ne_zero, snorm', one_toReal, ENNReal.rpow_one,
    ne_eq, not_false_eq_true, div_self, ite_false]
@[simp]
theorem edist_toL1_zero (f : α → β) (hf : Integrable f μ) :
    edist (hf.toL1 f) 0 = ∫⁻ a, edist (f a) 0 ∂μ := by
  simp only [toL1, Lp.edist_toLp_zero, snorm, one_ne_zero, snorm', one_toReal, ENNReal.rpow_one,
    ne_eq, not_false_eq_true, div_self, ite_false]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ ν : Measure α
inst✝² : MeasurableSpace δ
inst✝¹ : NormedAddCommGroup β
inst✝ : NormedAddCommGroup γ
f : α → β
hf : Integrable f
⊢ (if 1 = ⊤ then snormEssSup f μ else ∫⁻ (a : α), ↑‖f a‖₊ ∂μ) = ∫⁻ (a : α), edist (f a) 0 ∂μ

Next tactic:
simp [edist_eq_coe_nnnorm]
lemma HasFiniteIntegral.restrict (h : HasFiniteIntegral f μ) {s : Set α} :
    HasFiniteIntegral f (μ.restrict s) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ ν : Measure α
inst✝³ : MeasurableSpace δ
inst✝² : NormedAddCommGroup β
inst✝¹ : NormedAddCommGroup γ
E : Type u_5
inst✝ : NormedAddCommGroup E
f : α → E
h : HasFiniteIntegral f
s : Set α
⊢ HasFiniteIntegral f

Next tactic:
refine lt_of_le_of_lt ?_ h
lemma HasFiniteIntegral.restrict (h : HasFiniteIntegral f μ) {s : Set α} :
    HasFiniteIntegral f (μ.restrict s) := by
  refine lt_of_le_of_lt ?_ h
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ ν : Measure α
inst✝³ : MeasurableSpace δ
inst✝² : NormedAddCommGroup β
inst✝¹ : NormedAddCommGroup γ
E : Type u_5
inst✝ : NormedAddCommGroup E
f : α → E
h : HasFiniteIntegral f
s : Set α
⊢ ∫⁻ (a : α) in s, ↑‖f a‖₊ ∂μ ≤ ∫⁻ (a : α), ↑‖f a‖₊ ∂μ

Next tactic:
convert lintegral_mono_set (μ := μ) (s := s) (t := univ) (f := fun x ↦ ↑‖f x‖₊) (subset_univ s)
lemma HasFiniteIntegral.restrict (h : HasFiniteIntegral f μ) {s : Set α} :
    HasFiniteIntegral f (μ.restrict s) := by
  refine lt_of_le_of_lt ?_ h
  convert lintegral_mono_set (μ := μ) (s := s) (t := univ) (f := fun x ↦ ↑‖f x‖₊) (subset_univ s)
  

Proof state:
case h.e'_4.h.e'_3
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
m : MeasurableSpace α
μ ν : Measure α
inst✝³ : MeasurableSpace δ
inst✝² : NormedAddCommGroup β
inst✝¹ : NormedAddCommGroup γ
E : Type u_5
inst✝ : NormedAddCommGroup E
f : α → E
h : HasFiniteIntegral f
s : Set α
⊢ μ = Measure.restrict μ univ

Next tactic:
exact Measure.restrict_univ.symm
@[simp]
theorem factors_zero : factors 0 = [] := by 

Proof state:
⊢ factors 0 = []

Next tactic:
rw [factors]
@[simp]
theorem factors_one : factors 1 = [] := by 

Proof state:
⊢ factors 1 = []

Next tactic:
rw [factors]
theorem prime_of_mem_factors {n : ℕ} : ∀ {p : ℕ}, (h : p ∈ factors n) → Prime p := by
  

Proof state:
n : ℕ
⊢ ∀ {p : ℕ}, p ∈ factors n → Prime p

Next tactic:
match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      intro p h
      let m := minFac (k + 2)
      have : (k + 2) / m < (k + 2) := factors_lemma
      have h₁ : p = m ∨ p ∈ factors ((k + 2) / m) :=
        List.mem_cons.1 (by rwa [factors] at h)
      exact Or.casesOn h₁ (fun h₂ => h₂.symm ▸ minFac_prime (by simp)) prime_of_mem_factors
theorem prime_of_mem_factors {n : ℕ} : ∀ {p : ℕ}, (h : p ∈ factors n) → Prime p := by
  match n with
  | 0 => 

Proof state:
n : ℕ
⊢ ∀ {p : ℕ}, p ∈ factors 0 → Prime p

Next tactic:
simp
theorem prime_of_mem_factors {n : ℕ} : ∀ {p : ℕ}, (h : p ∈ factors n) → Prime p := by
  match n with
  | 0 => simp
  | 1 => 

Proof state:
n : ℕ
⊢ ∀ {p : ℕ}, p ∈ factors 1 → Prime p

Next tactic:
simp
theorem prime_of_mem_factors {n : ℕ} : ∀ {p : ℕ}, (h : p ∈ factors n) → Prime p := by
  match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      

Proof state:
n k : ℕ
⊢ ∀ {p : ℕ}, p ∈ factors (k + 2) → Prime p

Next tactic:
intro p h
theorem prime_of_mem_factors {n : ℕ} : ∀ {p : ℕ}, (h : p ∈ factors n) → Prime p := by
  match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      intro p h
      

Proof state:
n k p : ℕ
h : p ∈ factors (k + 2)
⊢ Prime p

Next tactic:
let m := minFac (k + 2)
theorem prime_of_mem_factors {n : ℕ} : ∀ {p : ℕ}, (h : p ∈ factors n) → Prime p := by
  match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      intro p h
      let m := minFac (k + 2)
      

Proof state:
n k p : ℕ
h : p ∈ factors (k + 2)
m : ℕ := minFac (k + 2)
⊢ Prime p

Next tactic:
have : (k + 2) / m < (k + 2) := factors_lemma
theorem prime_of_mem_factors {n : ℕ} : ∀ {p : ℕ}, (h : p ∈ factors n) → Prime p := by
  match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      intro p h
      let m := minFac (k + 2)
      have : (k + 2) / m < (k + 2) := factors_lemma
      

Proof state:
n k p : ℕ
h : p ∈ factors (k + 2)
m : ℕ := minFac (k + 2)
this : (k + 2) / m < k + 2
⊢ Prime p

Next tactic:
have h₁ : p = m ∨ p ∈ factors ((k + 2) / m) :=
        List.mem_cons.1 (by rwa [factors] at h)
theorem prime_of_mem_factors {n : ℕ} : ∀ {p : ℕ}, (h : p ∈ factors n) → Prime p := by
  match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      intro p h
      let m := minFac (k + 2)
      have : (k + 2) / m < (k + 2) := factors_lemma
      have h₁ : p = m ∨ p ∈ factors ((k + 2) / m) :=
        List.mem_cons.1 (by 

Proof state:
n k p : ℕ
h : p ∈ factors (k + 2)
m : ℕ := minFac (k + 2)
this : (k + 2) / m < k + 2
⊢ p ∈ m :: factors ((k + 2) / m)

Next tactic:
rwa [factors] at h
theorem prime_of_mem_factors {n : ℕ} : ∀ {p : ℕ}, (h : p ∈ factors n) → Prime p := by
  match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      intro p h
      let m := minFac (k + 2)
      have : (k + 2) / m < (k + 2) := factors_lemma
      have h₁ : p = m ∨ p ∈ factors ((k + 2) / m) :=
        List.mem_cons.1 (by rwa [factors] at h)
      

Proof state:
n k p : ℕ
h : p ∈ factors (k + 2)
m : ℕ := minFac (k + 2)
this : (k + 2) / m < k + 2
h₁ : p = m ∨ p ∈ factors ((k + 2) / m)
⊢ Prime p

Next tactic:
exact Or.casesOn h₁ (fun h₂ => h₂.symm ▸ minFac_prime (by simp)) prime_of_mem_factors
theorem prime_of_mem_factors {n : ℕ} : ∀ {p : ℕ}, (h : p ∈ factors n) → Prime p := by
  match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      intro p h
      let m := minFac (k + 2)
      have : (k + 2) / m < (k + 2) := factors_lemma
      have h₁ : p = m ∨ p ∈ factors ((k + 2) / m) :=
        List.mem_cons.1 (by rwa [factors] at h)
      exact Or.casesOn h₁ (fun h₂ => h₂.symm ▸ minFac_prime (by 

Proof state:
n k p : ℕ
h : p ∈ factors (k + 2)
m : ℕ := minFac (k + 2)
this : (k + 2) / m < k + 2
h₁ : p = m ∨ p ∈ factors ((k + 2) / m)
h₂ : p = m
⊢ k + 2 ≠ 1

Next tactic:
simp
theorem prod_factors : ∀ {n}, n ≠ 0 → List.prod (factors n) = n
  | 0 => by 

Proof state:
⊢ 0 ≠ 0 → List.prod (factors 0) = 0

Next tactic:
simp
theorem prod_factors : ∀ {n}, n ≠ 0 → List.prod (factors n) = n
  | 0 => by simp
  | 1 => by 

Proof state:
⊢ 1 ≠ 0 → List.prod (factors 1) = 1

Next tactic:
simp
theorem prod_factors : ∀ {n}, n ≠ 0 → List.prod (factors n) = n
  | 0 => by simp
  | 1 => by simp
  | k + 2 => fun _ =>
    let m := minFac (k + 2)
    have : (k + 2) / m < (k + 2) := factors_lemma
    show (factors (k + 2)).prod = (k + 2) by
      

Proof state:
k : ℕ
x✝ : k + 2 ≠ 0
m : ℕ := minFac (k + 2)
this : (k + 2) / m < k + 2
⊢ List.prod (factors (k + 2)) = k + 2

Next tactic:
have h₁ : (k + 2) / m ≠ 0 := fun h => by
        have : (k + 2) = 0 * m := (Nat.div_eq_iff_eq_mul_left (minFac_pos _) (minFac_dvd _)).1 h
        rw [zero_mul] at this; exact (show k + 2 ≠ 0 by simp) this
theorem prod_factors : ∀ {n}, n ≠ 0 → List.prod (factors n) = n
  | 0 => by simp
  | 1 => by simp
  | k + 2 => fun _ =>
    let m := minFac (k + 2)
    have : (k + 2) / m < (k + 2) := factors_lemma
    show (factors (k + 2)).prod = (k + 2) by
      have h₁ : (k + 2) / m ≠ 0 := fun h => by
        

Proof state:
k : ℕ
x✝ : k + 2 ≠ 0
m : ℕ := minFac (k + 2)
this : (k + 2) / m < k + 2
h : (k + 2) / m = 0
⊢ False

Next tactic:
have : (k + 2) = 0 * m := (Nat.div_eq_iff_eq_mul_left (minFac_pos _) (minFac_dvd _)).1 h
theorem prod_factors : ∀ {n}, n ≠ 0 → List.prod (factors n) = n
  | 0 => by simp
  | 1 => by simp
  | k + 2 => fun _ =>
    let m := minFac (k + 2)
    have : (k + 2) / m < (k + 2) := factors_lemma
    show (factors (k + 2)).prod = (k + 2) by
      have h₁ : (k + 2) / m ≠ 0 := fun h => by
        have : (k + 2) = 0 * m := (Nat.div_eq_iff_eq_mul_left (minFac_pos _) (minFac_dvd _)).1 h
        

Proof state:
k : ℕ
x✝ : k + 2 ≠ 0
m : ℕ := minFac (k + 2)
this✝ : (k + 2) / m < k + 2
h : (k + 2) / m = 0
this : k + 2 = 0 * m
⊢ False

Next tactic:
rw [zero_mul] at this
theorem prod_factors : ∀ {n}, n ≠ 0 → List.prod (factors n) = n
  | 0 => by simp
  | 1 => by simp
  | k + 2 => fun _ =>
    let m := minFac (k + 2)
    have : (k + 2) / m < (k + 2) := factors_lemma
    show (factors (k + 2)).prod = (k + 2) by
      have h₁ : (k + 2) / m ≠ 0 := fun h => by
        have : (k + 2) = 0 * m := (Nat.div_eq_iff_eq_mul_left (minFac_pos _) (minFac_dvd _)).1 h
        rw [zero_mul] at this; 

Proof state:
k : ℕ
x✝ : k + 2 ≠ 0
m : ℕ := minFac (k + 2)
this✝ : (k + 2) / m < k + 2
h : (k + 2) / m = 0
this : k + 2 = 0
⊢ False

Next tactic:
exact (show k + 2 ≠ 0 by simp) this
theorem prod_factors : ∀ {n}, n ≠ 0 → List.prod (factors n) = n
  | 0 => by simp
  | 1 => by simp
  | k + 2 => fun _ =>
    let m := minFac (k + 2)
    have : (k + 2) / m < (k + 2) := factors_lemma
    show (factors (k + 2)).prod = (k + 2) by
      have h₁ : (k + 2) / m ≠ 0 := fun h => by
        have : (k + 2) = 0 * m := (Nat.div_eq_iff_eq_mul_left (minFac_pos _) (minFac_dvd _)).1 h
        rw [zero_mul] at this; exact (show k + 2 ≠ 0 by 

Proof state:
k : ℕ
x✝ : k + 2 ≠ 0
m : ℕ := minFac (k + 2)
this✝ : (k + 2) / m < k + 2
h : (k + 2) / m = 0
this : k + 2 = 0
⊢ k + 2 ≠ 0

Next tactic:
simp
theorem prod_factors : ∀ {n}, n ≠ 0 → List.prod (factors n) = n
  | 0 => by simp
  | 1 => by simp
  | k + 2 => fun _ =>
    let m := minFac (k + 2)
    have : (k + 2) / m < (k + 2) := factors_lemma
    show (factors (k + 2)).prod = (k + 2) by
      have h₁ : (k + 2) / m ≠ 0 := fun h => by
        have : (k + 2) = 0 * m := (Nat.div_eq_iff_eq_mul_left (minFac_pos _) (minFac_dvd _)).1 h
        rw [zero_mul] at this; exact (show k + 2 ≠ 0 by simp) this
      

Proof state:
k : ℕ
x✝ : k + 2 ≠ 0
m : ℕ := minFac (k + 2)
this : (k + 2) / m < k + 2
h₁ : (k + 2) / m ≠ 0
⊢ List.prod (factors (k + 2)) = k + 2

Next tactic:
rw [factors, List.prod_cons, prod_factors h₁, Nat.mul_div_cancel' (minFac_dvd _)]
theorem factors_prime {p : ℕ} (hp : Nat.Prime p) : p.factors = [p] := by
  

Proof state:
p : ℕ
hp : Prime p
⊢ factors p = [p]

Next tactic:
have : p = p - 2 + 2 := (tsub_eq_iff_eq_add_of_le hp.two_le).mp rfl
theorem factors_prime {p : ℕ} (hp : Nat.Prime p) : p.factors = [p] := by
  have : p = p - 2 + 2 := (tsub_eq_iff_eq_add_of_le hp.two_le).mp rfl
  

Proof state:
p : ℕ
hp : Prime p
this : p = p - 2 + 2
⊢ factors p = [p]

Next tactic:
rw [this, Nat.factors]
theorem factors_prime {p : ℕ} (hp : Nat.Prime p) : p.factors = [p] := by
  have : p = p - 2 + 2 := (tsub_eq_iff_eq_add_of_le hp.two_le).mp rfl
  rw [this, Nat.factors]
  

Proof state:
p : ℕ
hp : Prime p
this : p = p - 2 + 2
⊢ (let m := minFac (p - 2 + 2);
    let_fun this := (_ : (p - 2 + 2) / minFac (p - 2 + 2) < p - 2 + 2);
    m :: factors ((p - 2 + 2) / m)) =
    [p - 2 + 2]

Next tactic:
simp only [Eq.symm this]
theorem factors_prime {p : ℕ} (hp : Nat.Prime p) : p.factors = [p] := by
  have : p = p - 2 + 2 := (tsub_eq_iff_eq_add_of_le hp.two_le).mp rfl
  rw [this, Nat.factors]
  simp only [Eq.symm this]
  

Proof state:
p : ℕ
hp : Prime p
this : p = p - 2 + 2
⊢ minFac p :: factors (p / minFac p) = [p]

Next tactic:
have : Nat.minFac p = p := (Nat.prime_def_minFac.mp hp).2
theorem factors_prime {p : ℕ} (hp : Nat.Prime p) : p.factors = [p] := by
  have : p = p - 2 + 2 := (tsub_eq_iff_eq_add_of_le hp.two_le).mp rfl
  rw [this, Nat.factors]
  simp only [Eq.symm this]
  have : Nat.minFac p = p := (Nat.prime_def_minFac.mp hp).2
  

Proof state:
p : ℕ
hp : Prime p
this✝ : p = p - 2 + 2
this : minFac p = p
⊢ minFac p :: factors (p / minFac p) = [p]

Next tactic:
simp only [this, Nat.factors, Nat.div_self (Nat.Prime.pos hp)]
theorem factors_chain {n : ℕ} :
    ∀ {a}, (∀ p, Prime p → p ∣ n → a ≤ p) → List.Chain (· ≤ ·) a (factors n) := by
  

Proof state:
n : ℕ
⊢ ∀ {a : ℕ}, (∀ (p : ℕ), Prime p → p ∣ n → a ≤ p) → List.Chain (fun x x_1 => x ≤ x_1) a (factors n)

Next tactic:
match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      intro a h
      let m := minFac (k + 2)
      have : (k + 2) / m < (k + 2) := factors_lemma
      rw [factors]
      refine' List.Chain.cons ((le_minFac.2 h).resolve_left (by simp)) (factors_chain _)
      exact fun p pp d => minFac_le_of_dvd pp.two_le (d.trans <| div_dvd_of_dvd <| minFac_dvd _)
theorem factors_chain {n : ℕ} :
    ∀ {a}, (∀ p, Prime p → p ∣ n → a ≤ p) → List.Chain (· ≤ ·) a (factors n) := by
  match n with
  | 0 => 

Proof state:
n : ℕ
⊢ ∀ {a : ℕ}, (∀ (p : ℕ), Prime p → p ∣ 0 → a ≤ p) → List.Chain (fun x x_1 => x ≤ x_1) a (factors 0)

Next tactic:
simp
theorem factors_chain {n : ℕ} :
    ∀ {a}, (∀ p, Prime p → p ∣ n → a ≤ p) → List.Chain (· ≤ ·) a (factors n) := by
  match n with
  | 0 => simp
  | 1 => 

Proof state:
n : ℕ
⊢ ∀ {a : ℕ}, (∀ (p : ℕ), Prime p → p ∣ 1 → a ≤ p) → List.Chain (fun x x_1 => x ≤ x_1) a (factors 1)

Next tactic:
simp
theorem factors_chain {n : ℕ} :
    ∀ {a}, (∀ p, Prime p → p ∣ n → a ≤ p) → List.Chain (· ≤ ·) a (factors n) := by
  match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      

Proof state:
n k : ℕ
⊢ ∀ {a : ℕ}, (∀ (p : ℕ), Prime p → p ∣ k + 2 → a ≤ p) → List.Chain (fun x x_1 => x ≤ x_1) a (factors (k + 2))

Next tactic:
intro a h
theorem factors_chain {n : ℕ} :
    ∀ {a}, (∀ p, Prime p → p ∣ n → a ≤ p) → List.Chain (· ≤ ·) a (factors n) := by
  match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      intro a h
      

Proof state:
n k a : ℕ
h : ∀ (p : ℕ), Prime p → p ∣ k + 2 → a ≤ p
⊢ List.Chain (fun x x_1 => x ≤ x_1) a (factors (k + 2))

Next tactic:
let m := minFac (k + 2)
theorem factors_chain {n : ℕ} :
    ∀ {a}, (∀ p, Prime p → p ∣ n → a ≤ p) → List.Chain (· ≤ ·) a (factors n) := by
  match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      intro a h
      let m := minFac (k + 2)
      

Proof state:
n k a : ℕ
h : ∀ (p : ℕ), Prime p → p ∣ k + 2 → a ≤ p
m : ℕ := minFac (k + 2)
⊢ List.Chain (fun x x_1 => x ≤ x_1) a (factors (k + 2))

Next tactic:
have : (k + 2) / m < (k + 2) := factors_lemma
theorem factors_chain {n : ℕ} :
    ∀ {a}, (∀ p, Prime p → p ∣ n → a ≤ p) → List.Chain (· ≤ ·) a (factors n) := by
  match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      intro a h
      let m := minFac (k + 2)
      have : (k + 2) / m < (k + 2) := factors_lemma
      

Proof state:
n k a : ℕ
h : ∀ (p : ℕ), Prime p → p ∣ k + 2 → a ≤ p
m : ℕ := minFac (k + 2)
this : (k + 2) / m < k + 2
⊢ List.Chain (fun x x_1 => x ≤ x_1) a (factors (k + 2))

Next tactic:
rw [factors]
theorem factors_chain {n : ℕ} :
    ∀ {a}, (∀ p, Prime p → p ∣ n → a ≤ p) → List.Chain (· ≤ ·) a (factors n) := by
  match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      intro a h
      let m := minFac (k + 2)
      have : (k + 2) / m < (k + 2) := factors_lemma
      rw [factors]
      

Proof state:
n k a : ℕ
h : ∀ (p : ℕ), Prime p → p ∣ k + 2 → a ≤ p
m : ℕ := minFac (k + 2)
this : (k + 2) / m < k + 2
⊢ List.Chain (fun x x_1 => x ≤ x_1) a
    (let m := minFac (k + 2);
    let_fun this := (_ : (k + 2) / minFac (k + 2) < k + 2);
    m :: factors ((k + 2) / m))

Next tactic:
refine' List.Chain.cons ((le_minFac.2 h).resolve_left (by simp)) (factors_chain _)
theorem factors_chain {n : ℕ} :
    ∀ {a}, (∀ p, Prime p → p ∣ n → a ≤ p) → List.Chain (· ≤ ·) a (factors n) := by
  match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      intro a h
      let m := minFac (k + 2)
      have : (k + 2) / m < (k + 2) := factors_lemma
      rw [factors]
      refine' List.Chain.cons ((le_minFac.2 h).resolve_left (by 

Proof state:
n k a : ℕ
h : ∀ (p : ℕ), Prime p → p ∣ k + 2 → a ≤ p
m : ℕ := minFac (k + 2)
this : (k + 2) / m < k + 2
⊢ ¬k + 2 = 1

Next tactic:
simp
theorem factors_chain {n : ℕ} :
    ∀ {a}, (∀ p, Prime p → p ∣ n → a ≤ p) → List.Chain (· ≤ ·) a (factors n) := by
  match n with
  | 0 => simp
  | 1 => simp
  | k + 2 =>
      intro a h
      let m := minFac (k + 2)
      have : (k + 2) / m < (k + 2) := factors_lemma
      rw [factors]
      refine' List.Chain.cons ((le_minFac.2 h).resolve_left (by simp)) (factors_chain _)
      

Proof state:
n k a : ℕ
h : ∀ (p : ℕ), Prime p → p ∣ k + 2 → a ≤ p
m : ℕ := minFac (k + 2)
this : (k + 2) / m < k + 2
⊢ ∀ (p : ℕ), Prime p → p ∣ (k + 2) / minFac (k + 2) → minFac (k + 2) ≤ p

Next tactic:
exact fun p pp d => minFac_le_of_dvd pp.two_le (d.trans <| div_dvd_of_dvd <| minFac_dvd _)
/-- `factors` can be constructed inductively by extracting `minFac`, for sufficiently large `n`. -/
theorem factors_add_two (n : ℕ) :
    factors (n + 2) = minFac (n + 2) :: factors ((n + 2) / minFac (n + 2)) := by 

Proof state:
n : ℕ
⊢ factors (n + 2) = minFac (n + 2) :: factors ((n + 2) / minFac (n + 2))

Next tactic:
rw [factors]
@[simp]
theorem factors_eq_nil (n : ℕ) : n.factors = [] ↔ n = 0 ∨ n = 1 := by
  

Proof state:
n : ℕ
⊢ factors n = [] ↔ n = 0 ∨ n = 1

Next tactic:
constructor
@[simp]
theorem factors_eq_nil (n : ℕ) : n.factors = [] ↔ n = 0 ∨ n = 1 := by
  constructor <;> 

Proof state:
case mp
n : ℕ
⊢ factors n = [] → n = 0 ∨ n = 1

Next tactic:
intro h
@[simp]
theorem factors_eq_nil (n : ℕ) : n.factors = [] ↔ n = 0 ∨ n = 1 := by
  constructor <;> 

Proof state:
case mpr
n : ℕ
⊢ n = 0 ∨ n = 1 → factors n = []

Next tactic:
intro h
@[simp]
theorem factors_eq_nil (n : ℕ) : n.factors = [] ↔ n = 0 ∨ n = 1 := by
  constructor <;> intro h
  · 

Proof state:
case mp
n : ℕ
h : factors n = []
⊢ n = 0 ∨ n = 1

Next tactic:
rcases n with (_ | _ | n)
@[simp]
theorem factors_eq_nil (n : ℕ) : n.factors = [] ↔ n = 0 ∨ n = 1 := by
  constructor <;> intro h
  · rcases n with (_ | _ | n)
    · 

Proof state:
case mp.zero
h : factors zero = []
⊢ zero = 0 ∨ zero = 1

Next tactic:
exact Or.inl rfl
@[simp]
theorem factors_eq_nil (n : ℕ) : n.factors = [] ↔ n = 0 ∨ n = 1 := by
  constructor <;> intro h
  · rcases n with (_ | _ | n)
    · exact Or.inl rfl
    · 

Proof state:
case mp.succ.zero
h : factors (succ zero) = []
⊢ succ zero = 0 ∨ succ zero = 1

Next tactic:
exact Or.inr rfl
@[simp]
theorem factors_eq_nil (n : ℕ) : n.factors = [] ↔ n = 0 ∨ n = 1 := by
  constructor <;> intro h
  · rcases n with (_ | _ | n)
    · exact Or.inl rfl
    · exact Or.inr rfl
    · 

Proof state:
case mp.succ.succ
n : ℕ
h : factors (succ (succ n)) = []
⊢ succ (succ n) = 0 ∨ succ (succ n) = 1

Next tactic:
rw [factors] at h
@[simp]
theorem factors_eq_nil (n : ℕ) : n.factors = [] ↔ n = 0 ∨ n = 1 := by
  constructor <;> intro h
  · rcases n with (_ | _ | n)
    · exact Or.inl rfl
    · exact Or.inr rfl
    · rw [factors] at h
      

Proof state:
case mp.succ.succ
n : ℕ
h :
  (let m := minFac (n + 2);
    let_fun this := (_ : (n + 2) / minFac (n + 2) < n + 2);
    m :: factors ((n + 2) / m)) =
    []
⊢ succ (succ n) = 0 ∨ succ (succ n) = 1

Next tactic:
injection h
@[simp]
theorem factors_eq_nil (n : ℕ) : n.factors = [] ↔ n = 0 ∨ n = 1 := by
  constructor <;> intro h
  · rcases n with (_ | _ | n)
    · exact Or.inl rfl
    · exact Or.inr rfl
    · rw [factors] at h
      injection h
  · 

Proof state:
case mpr
n : ℕ
h : n = 0 ∨ n = 1
⊢ factors n = []

Next tactic:
rcases h with (rfl | rfl)
@[simp]
theorem factors_eq_nil (n : ℕ) : n.factors = [] ↔ n = 0 ∨ n = 1 := by
  constructor <;> intro h
  · rcases n with (_ | _ | n)
    · exact Or.inl rfl
    · exact Or.inr rfl
    · rw [factors] at h
      injection h
  · rcases h with (rfl | rfl)
    · 

Proof state:
case mpr.inl
⊢ factors 0 = []

Next tactic:
exact factors_zero
@[simp]
theorem factors_eq_nil (n : ℕ) : n.factors = [] ↔ n = 0 ∨ n = 1 := by
  constructor <;> intro h
  · rcases n with (_ | _ | n)
    · exact Or.inl rfl
    · exact Or.inr rfl
    · rw [factors] at h
      injection h
  · rcases h with (rfl | rfl)
    · exact factors_zero
    · 

Proof state:
case mpr.inr
⊢ factors 1 = []

Next tactic:
exact factors_one
open scoped List in
theorem eq_of_perm_factors {a b : ℕ} (ha : a ≠ 0) (hb : b ≠ 0) (h : a.factors ~ b.factors) :
    a = b := by 

Proof state:
a b : ℕ
ha : a ≠ 0
hb : b ≠ 0
h : factors a ~ factors b
⊢ a = b

Next tactic:
simpa [prod_factors ha, prod_factors hb] using List.Perm.prod_eq h
theorem dvd_of_mem_factors {n p : ℕ} (h : p ∈ n.factors) : p ∣ n := by
  

Proof state:
n p : ℕ
h : p ∈ factors n
⊢ p ∣ n

Next tactic:
rcases n.eq_zero_or_pos with (rfl | hn)
theorem dvd_of_mem_factors {n p : ℕ} (h : p ∈ n.factors) : p ∣ n := by
  rcases n.eq_zero_or_pos with (rfl | hn)
  · 

Proof state:
case inl
p : ℕ
h : p ∈ factors 0
⊢ p ∣ 0

Next tactic:
exact dvd_zero p
theorem dvd_of_mem_factors {n p : ℕ} (h : p ∈ n.factors) : p ∣ n := by
  rcases n.eq_zero_or_pos with (rfl | hn)
  · exact dvd_zero p
  · 

Proof state:
case inr
n p : ℕ
h : p ∈ factors n
hn : n > 0
⊢ p ∣ n

Next tactic:
rwa [← mem_factors_iff_dvd hn.ne' (prime_of_mem_factors h)]
@[simp] lemma mem_factors' {n p} : p ∈ n.factors ↔ p.Prime ∧ p ∣ n ∧ n ≠ 0 := by
  

Proof state:
n p : ℕ
⊢ p ∈ factors n ↔ Prime p ∧ p ∣ n ∧ n ≠ 0

Next tactic:
cases n
@[simp] lemma mem_factors' {n p} : p ∈ n.factors ↔ p.Prime ∧ p ∣ n ∧ n ≠ 0 := by
  cases n <;> 

Proof state:
case zero
p : ℕ
⊢ p ∈ factors zero ↔ Prime p ∧ p ∣ zero ∧ zero ≠ 0

Next tactic:
simp [mem_factors, *]
@[simp] lemma mem_factors' {n p} : p ∈ n.factors ↔ p.Prime ∧ p ∣ n ∧ n ≠ 0 := by
  cases n <;> 

Proof state:
case succ
p n✝ : ℕ
⊢ p ∈ factors (succ n✝) ↔ Prime p ∧ p ∣ succ n✝ ∧ succ n✝ ≠ 0

Next tactic:
simp [mem_factors, *]
theorem le_of_mem_factors {n p : ℕ} (h : p ∈ n.factors) : p ≤ n := by
  

Proof state:
n p : ℕ
h : p ∈ factors n
⊢ p ≤ n

Next tactic:
rcases n.eq_zero_or_pos with (rfl | hn)
theorem le_of_mem_factors {n p : ℕ} (h : p ∈ n.factors) : p ≤ n := by
  rcases n.eq_zero_or_pos with (rfl | hn)
  · 

Proof state:
case inl
p : ℕ
h : p ∈ factors 0
⊢ p ≤ 0

Next tactic:
rw [factors_zero] at h
theorem le_of_mem_factors {n p : ℕ} (h : p ∈ n.factors) : p ≤ n := by
  rcases n.eq_zero_or_pos with (rfl | hn)
  · rw [factors_zero] at h
    

Proof state:
case inl
p : ℕ
h : p ∈ []
⊢ p ≤ 0

Next tactic:
cases h
theorem le_of_mem_factors {n p : ℕ} (h : p ∈ n.factors) : p ≤ n := by
  rcases n.eq_zero_or_pos with (rfl | hn)
  · rw [factors_zero] at h
    cases h
  · 

Proof state:
case inr
n p : ℕ
h : p ∈ factors n
hn : n > 0
⊢ p ≤ n

Next tactic:
exact le_of_dvd hn (dvd_of_mem_factors h)
/-- **Fundamental theorem of arithmetic**-/
theorem factors_unique {n : ℕ} {l : List ℕ} (h₁ : prod l = n) (h₂ : ∀ p ∈ l, Prime p) :
    l ~ factors n := by
  

Proof state:
n : ℕ
l : List ℕ
h₁ : prod l = n
h₂ : ∀ p ∈ l, Prime p
⊢ l ~ factors n

Next tactic:
refine' perm_of_prod_eq_prod _ _ _
/-- **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 _ _ _
  · 

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

Next tactic:
rw [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₁]
    

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

Next tactic:
refine' (prod_factors _).symm
/-- **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
    

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

Next tactic:
rintro rfl