l3lab/ntp-mathlib huggingface dataset:
theorem hermite_eq_deriv_gaussian (n : ℕ) (x : ℝ) : aeval x (hermite n) =
    (-1 : ℝ) ^ n * deriv^[n] (fun y => Real.exp (-(y ^ 2 / 2))) x / Real.exp (-(x ^ 2 / 2)) := by
  

Proof state:
n : ℕ
x : ℝ
⊢ (aeval x) (hermite n) = (-1) ^ n * deriv^[n] (fun y => Real.exp (-(y ^ 2 / 2))) x / Real.exp (-(x ^ 2 / 2))

Next tactic:
rw [deriv_gaussian_eq_hermite_mul_gaussian]
theorem hermite_eq_deriv_gaussian (n : ℕ) (x : ℝ) : aeval x (hermite n) =
    (-1 : ℝ) ^ n * deriv^[n] (fun y => Real.exp (-(y ^ 2 / 2))) x / Real.exp (-(x ^ 2 / 2)) := by
  rw [deriv_gaussian_eq_hermite_mul_gaussian]
  

Proof state:
n : ℕ
x : ℝ
⊢ (aeval x) (hermite n) =
    (-1) ^ n * ((-1) ^ n * (aeval x) (hermite n) * Real.exp (-(x ^ 2 / 2))) / Real.exp (-(x ^ 2 / 2))

Next tactic:
field_simp [Real.exp_ne_zero]
theorem hermite_eq_deriv_gaussian (n : ℕ) (x : ℝ) : aeval x (hermite n) =
    (-1 : ℝ) ^ n * deriv^[n] (fun y => Real.exp (-(y ^ 2 / 2))) x / Real.exp (-(x ^ 2 / 2)) := by
  rw [deriv_gaussian_eq_hermite_mul_gaussian]
  field_simp [Real.exp_ne_zero]
  

Proof state:
n : ℕ
x : ℝ
⊢ (aeval x) (hermite n) * Real.exp (-x ^ 2 / 2) = (-1) ^ n * ((-1) ^ n * (aeval x) (hermite n) * Real.exp (-x ^ 2 / 2))

Next tactic:
rw [← @smul_eq_mul ℝ _ ((-1) ^ n), ← inv_smul_eq_iff₀, mul_assoc, smul_eq_mul, ← inv_pow, ←
    neg_inv, inv_one]
theorem hermite_eq_deriv_gaussian (n : ℕ) (x : ℝ) : aeval x (hermite n) =
    (-1 : ℝ) ^ n * deriv^[n] (fun y => Real.exp (-(y ^ 2 / 2))) x / Real.exp (-(x ^ 2 / 2)) := by
  rw [deriv_gaussian_eq_hermite_mul_gaussian]
  field_simp [Real.exp_ne_zero]
  rw [← @smul_eq_mul ℝ _ ((-1) ^ n), ← inv_smul_eq_iff₀, mul_assoc, smul_eq_mul, ← inv_pow, ←
    neg_inv, inv_one]
  

Proof state:
case ha
n : ℕ
x : ℝ
⊢ (-1) ^ n ≠ 0

Next tactic:
exact pow_ne_zero _ (by norm_num)
theorem hermite_eq_deriv_gaussian (n : ℕ) (x : ℝ) : aeval x (hermite n) =
    (-1 : ℝ) ^ n * deriv^[n] (fun y => Real.exp (-(y ^ 2 / 2))) x / Real.exp (-(x ^ 2 / 2)) := by
  rw [deriv_gaussian_eq_hermite_mul_gaussian]
  field_simp [Real.exp_ne_zero]
  rw [← @smul_eq_mul ℝ _ ((-1) ^ n), ← inv_smul_eq_iff₀, mul_assoc, smul_eq_mul, ← inv_pow, ←
    neg_inv, inv_one]
  exact pow_ne_zero _ (by 

Proof state:
n : ℕ
x : ℝ
⊢ -1 ≠ 0

Next tactic:
norm_num
theorem hermite_eq_deriv_gaussian' (n : ℕ) (x : ℝ) : aeval x (hermite n) =
    (-1 : ℝ) ^ n * deriv^[n] (fun y => Real.exp (-(y ^ 2 / 2))) x * Real.exp (x ^ 2 / 2) := by
  

Proof state:
n : ℕ
x : ℝ
⊢ (aeval x) (hermite n) = (-1) ^ n * deriv^[n] (fun y => Real.exp (-(y ^ 2 / 2))) x * Real.exp (x ^ 2 / 2)

Next tactic:
rw [hermite_eq_deriv_gaussian, Real.exp_neg]
theorem hermite_eq_deriv_gaussian' (n : ℕ) (x : ℝ) : aeval x (hermite n) =
    (-1 : ℝ) ^ n * deriv^[n] (fun y => Real.exp (-(y ^ 2 / 2))) x * Real.exp (x ^ 2 / 2) := by
  rw [hermite_eq_deriv_gaussian, Real.exp_neg]
  

Proof state:
n : ℕ
x : ℝ
⊢ (-1) ^ n * deriv^[n] (fun y => Real.exp (-(y ^ 2 / 2))) x / (Real.exp (x ^ 2 / 2))⁻¹ =
    (-1) ^ n * deriv^[n] (fun y => Real.exp (-(y ^ 2 / 2))) x * Real.exp (x ^ 2 / 2)

Next tactic:
field_simp [Real.exp_ne_zero]
@[simp]
theorem gcd_add_mul_right_right (m n k : ℕ) : gcd m (n + k * m) = gcd m n := by
  

Proof state:
m n k : ℕ
⊢ gcd m (n + k * m) = gcd m n

Next tactic:
simp [gcd_rec m (n + k * m), gcd_rec m n]
@[simp]
theorem gcd_add_mul_left_right (m n k : ℕ) : gcd m (n + m * k) = gcd m n := by
  

Proof state:
m n k : ℕ
⊢ gcd m (n + m * k) = gcd m n

Next tactic:
simp [gcd_rec m (n + m * k), gcd_rec m n]
@[simp]
theorem gcd_mul_right_add_right (m n k : ℕ) : gcd m (k * m + n) = gcd m n := by 

Proof state:
m n k : ℕ
⊢ gcd m (k * m + n) = gcd m n

Next tactic:
simp [add_comm _ n]
@[simp]
theorem gcd_mul_left_add_right (m n k : ℕ) : gcd m (m * k + n) = gcd m n := by 

Proof state:
m n k : ℕ
⊢ gcd m (m * k + n) = gcd m n

Next tactic:
simp [add_comm _ n]
@[simp]
theorem gcd_add_mul_right_left (m n k : ℕ) : gcd (m + k * n) n = gcd m n := by
  

Proof state:
m n k : ℕ
⊢ gcd (m + k * n) n = gcd m n

Next tactic:
rw [gcd_comm, gcd_add_mul_right_right, gcd_comm]
@[simp]
theorem gcd_add_mul_left_left (m n k : ℕ) : gcd (m + n * k) n = gcd m n := by
  

Proof state:
m n k : ℕ
⊢ gcd (m + n * k) n = gcd m n

Next tactic:
rw [gcd_comm, gcd_add_mul_left_right, gcd_comm]
@[simp]
theorem gcd_mul_right_add_left (m n k : ℕ) : gcd (k * n + m) n = gcd m n := by
  

Proof state:
m n k : ℕ
⊢ gcd (k * n + m) n = gcd m n

Next tactic:
rw [gcd_comm, gcd_mul_right_add_right, gcd_comm]
@[simp]
theorem gcd_mul_left_add_left (m n k : ℕ) : gcd (n * k + m) n = gcd m n := by
  

Proof state:
m n k : ℕ
⊢ gcd (n * k + m) n = gcd m n

Next tactic:
rw [gcd_comm, gcd_mul_left_add_right, gcd_comm]
@[simp]
theorem gcd_add_self_right (m n : ℕ) : gcd m (n + m) = gcd m n :=
  Eq.trans (by 

Proof state:
m n : ℕ
⊢ gcd m (n + m) = gcd m (n + 1 * m)

Next tactic:
rw [one_mul]
@[simp]
theorem gcd_add_self_left (m n : ℕ) : gcd (m + n) n = gcd m n := by
  

Proof state:
m n : ℕ
⊢ gcd (m + n) n = gcd m n

Next tactic:
rw [gcd_comm, gcd_add_self_right, gcd_comm]
@[simp]
theorem gcd_self_add_left (m n : ℕ) : gcd (m + n) m = gcd n m := by 

Proof state:
m n : ℕ
⊢ gcd (m + n) m = gcd n m

Next tactic:
rw [add_comm, gcd_add_self_left]
@[simp]
theorem gcd_self_add_right (m n : ℕ) : gcd m (m + n) = gcd m n := by
  

Proof state:
m n : ℕ
⊢ gcd m (m + n) = gcd m n

Next tactic:
rw [add_comm, gcd_add_self_right]
@[simp]
theorem gcd_sub_self_left {m n : ℕ} (h : m ≤ n) : gcd (n - m) m = gcd n m := by
  

Proof state:
m n : ℕ
h : m ≤ n
⊢ gcd (n - m) m = gcd n m

Next tactic:
calc
    gcd (n - m) m = gcd (n - m + m) m := by rw [← gcd_add_self_left (n - m) m]
                _ = gcd n m := by rw [Nat.sub_add_cancel h]
@[simp]
theorem gcd_sub_self_left {m n : ℕ} (h : m ≤ n) : gcd (n - m) m = gcd n m := by
  calc
    gcd (n - m) m = gcd (n - m + m) m := by 

Proof state:
m n : ℕ
h : m ≤ n
⊢ gcd (n - m) m = gcd (n - m + m) m

Next tactic:
rw [← gcd_add_self_left (n - m) m]
@[simp]
theorem gcd_sub_self_left {m n : ℕ} (h : m ≤ n) : gcd (n - m) m = gcd n m := by
  calc
    gcd (n - m) m = gcd (n - m + m) m := by rw [← gcd_add_self_left (n - m) m]
                _ = gcd n m := by 

Proof state:
m n : ℕ
h : m ≤ n
⊢ gcd (n - m + m) m = gcd n m

Next tactic:
rw [Nat.sub_add_cancel h]
@[simp]
theorem gcd_sub_self_right {m n : ℕ} (h : m ≤ n) : gcd m (n - m) = gcd m n := by
  

Proof state:
m n : ℕ
h : m ≤ n
⊢ gcd m (n - m) = gcd m n

Next tactic:
rw [gcd_comm, gcd_sub_self_left h, gcd_comm]
@[simp]
theorem gcd_self_sub_left {m n : ℕ} (h : m ≤ n) : gcd (n - m) n = gcd m n := by
  

Proof state:
m n : ℕ
h : m ≤ n
⊢ gcd (n - m) n = gcd m n

Next tactic:
have := Nat.sub_add_cancel h
@[simp]
theorem gcd_self_sub_left {m n : ℕ} (h : m ≤ n) : gcd (n - m) n = gcd m n := by
  have := Nat.sub_add_cancel h
  

Proof state:
m n : ℕ
h : m ≤ n
this : n - m + m = n
⊢ gcd (n - m) n = gcd m n

Next tactic:
rw [gcd_comm m n, ← this, gcd_add_self_left (n - m) m]
@[simp]
theorem gcd_self_sub_left {m n : ℕ} (h : m ≤ n) : gcd (n - m) n = gcd m n := by
  have := Nat.sub_add_cancel h
  rw [gcd_comm m n, ← this, gcd_add_self_left (n - m) m]
  

Proof state:
m n : ℕ
h : m ≤ n
this : n - m + m = n
⊢ gcd (n - m + m - m) (n - m + m) = gcd (n - m) m

Next tactic:
have : gcd (n - m) n = gcd (n - m) m := by
    nth_rw 2 [← Nat.add_sub_cancel' h]
    rw [gcd_add_self_right, gcd_comm]
@[simp]
theorem gcd_self_sub_left {m n : ℕ} (h : m ≤ n) : gcd (n - m) n = gcd m n := by
  have := Nat.sub_add_cancel h
  rw [gcd_comm m n, ← this, gcd_add_self_left (n - m) m]
  have : gcd (n - m) n = gcd (n - m) m := by
    

Proof state:
m n : ℕ
h : m ≤ n
this : n - m + m = n
⊢ gcd (n - m) n = gcd (n - m) m

Next tactic:
nth_rw 2 [← Nat.add_sub_cancel' h]
@[simp]
theorem gcd_self_sub_left {m n : ℕ} (h : m ≤ n) : gcd (n - m) n = gcd m n := by
  have := Nat.sub_add_cancel h
  rw [gcd_comm m n, ← this, gcd_add_self_left (n - m) m]
  have : gcd (n - m) n = gcd (n - m) m := by
    nth_rw 2 [← Nat.add_sub_cancel' h]
    

Proof state:
m n : ℕ
h : m ≤ n
this : n - m + m = n
⊢ gcd (n - m) (m + (n - m)) = gcd (n - m) m

Next tactic:
rw [gcd_add_self_right, gcd_comm]
@[simp]
theorem gcd_self_sub_left {m n : ℕ} (h : m ≤ n) : gcd (n - m) n = gcd m n := by
  have := Nat.sub_add_cancel h
  rw [gcd_comm m n, ← this, gcd_add_self_left (n - m) m]
  have : gcd (n - m) n = gcd (n - m) m := by
    nth_rw 2 [← Nat.add_sub_cancel' h]
    rw [gcd_add_self_right, gcd_comm]
  

Proof state:
m n : ℕ
h : m ≤ n
this✝ : n - m + m = n
this : gcd (n - m) n = gcd (n - m) m
⊢ gcd (n - m + m - m) (n - m + m) = gcd (n - m) m

Next tactic:
convert this
@[simp]
theorem gcd_self_sub_right {m n : ℕ} (h : m ≤ n) : gcd n (n - m) = gcd n m := by
  

Proof state:
m n : ℕ
h : m ≤ n
⊢ gcd n (n - m) = gcd n m

Next tactic:
rw [gcd_comm, gcd_self_sub_left h, gcd_comm]
theorem lcm_pos {m n : ℕ} : 0 < m → 0 < n → 0 < m.lcm n := by
  

Proof state:
m n : ℕ
⊢ 0 < m → 0 < n → 0 < lcm m n

Next tactic:
simp_rw [pos_iff_ne_zero]
theorem lcm_pos {m n : ℕ} : 0 < m → 0 < n → 0 < m.lcm n := by
  simp_rw [pos_iff_ne_zero]
  

Proof state:
m n : ℕ
⊢ m ≠ 0 → n ≠ 0 → lcm m n ≠ 0

Next tactic:
exact lcm_ne_zero
theorem lcm_mul_left {m n k : ℕ} : (m * n).lcm (m * k) = m * n.lcm k := by
  

Proof state:
m n k : ℕ
⊢ lcm (m * n) (m * k) = m * lcm n k

Next tactic:
apply dvd_antisymm
theorem lcm_mul_left {m n k : ℕ} : (m * n).lcm (m * k) = m * n.lcm k := by
  apply dvd_antisymm
  · 

Proof state:
case a
m n k : ℕ
⊢ lcm (m * n) (m * k) ∣ m * lcm n k

Next tactic:
exact lcm_dvd (mul_dvd_mul_left m (dvd_lcm_left n k)) (mul_dvd_mul_left m (dvd_lcm_right n k))
theorem lcm_mul_left {m n k : ℕ} : (m * n).lcm (m * k) = m * n.lcm k := by
  apply dvd_antisymm
  · exact lcm_dvd (mul_dvd_mul_left m (dvd_lcm_left n k)) (mul_dvd_mul_left m (dvd_lcm_right n k))
  · 

Proof state:
case a
m n k : ℕ
⊢ m * lcm n k ∣ lcm (m * n) (m * k)

Next tactic:
have h : m ∣ lcm (m * n) (m * k) := (dvd_mul_right m n).trans (dvd_lcm_left (m * n) (m * k))
theorem lcm_mul_left {m n k : ℕ} : (m * n).lcm (m * k) = m * n.lcm k := by
  apply dvd_antisymm
  · exact lcm_dvd (mul_dvd_mul_left m (dvd_lcm_left n k)) (mul_dvd_mul_left m (dvd_lcm_right n k))
  · have h : m ∣ lcm (m * n) (m * k) := (dvd_mul_right m n).trans (dvd_lcm_left (m * n) (m * k))
    

Proof state:
case a
m n k : ℕ
h : m ∣ lcm (m * n) (m * k)
⊢ m * lcm n k ∣ lcm (m * n) (m * k)

Next tactic:
rw [← dvd_div_iff h, lcm_dvd_iff, dvd_div_iff h, dvd_div_iff h, ← lcm_dvd_iff]
theorem lcm_mul_right {m n k : ℕ} : (m * n).lcm (k * n) = m.lcm k * n := by
 

Proof state:
m n k : ℕ
⊢ lcm (m * n) (k * n) = lcm m k * n

Next tactic:
rw [mul_comm, mul_comm k n, lcm_mul_left, mul_comm]
theorem Coprime.lcm_eq_mul {m n : ℕ} (h : Coprime m n) : lcm m n = m * n := by
  

Proof state:
m n : ℕ
h : Coprime m n
⊢ lcm m n = m * n

Next tactic:
rw [← one_mul (lcm m n), ← h.gcd_eq_one, gcd_mul_lcm]
@[simp]
theorem coprime_add_self_right {m n : ℕ} : Coprime m (n + m) ↔ Coprime m n := by
  

Proof state:
m n : ℕ
⊢ Coprime m (n + m) ↔ Coprime m n

Next tactic:
rw [Coprime, Coprime, gcd_add_self_right]
@[simp]
theorem coprime_self_add_right {m n : ℕ} : Coprime m (m + n) ↔ Coprime m n := by
  

Proof state:
m n : ℕ
⊢ Coprime m (m + n) ↔ Coprime m n

Next tactic:
rw [add_comm, coprime_add_self_right]
@[simp]
theorem coprime_add_self_left {m n : ℕ} : Coprime (m + n) n ↔ Coprime m n := by
  

Proof state:
m n : ℕ
⊢ Coprime (m + n) n ↔ Coprime m n

Next tactic:
rw [Coprime, Coprime, gcd_add_self_left]
@[simp]
theorem coprime_self_add_left {m n : ℕ} : Coprime (m + n) m ↔ Coprime n m := by
  

Proof state:
m n : ℕ
⊢ Coprime (m + n) m ↔ Coprime n m

Next tactic:
rw [Coprime, Coprime, gcd_self_add_left]
@[simp]
theorem coprime_add_mul_right_right (m n k : ℕ) : Coprime m (n + k * m) ↔ Coprime m n := by
  

Proof state:
m n k : ℕ
⊢ Coprime m (n + k * m) ↔ Coprime m n

Next tactic:
rw [Coprime, Coprime, gcd_add_mul_right_right]
@[simp]
theorem coprime_add_mul_left_right (m n k : ℕ) : Coprime m (n + m * k) ↔ Coprime m n := by
  

Proof state:
m n k : ℕ
⊢ Coprime m (n + m * k) ↔ Coprime m n

Next tactic:
rw [Coprime, Coprime, gcd_add_mul_left_right]
@[simp]
theorem coprime_mul_right_add_right (m n k : ℕ) : Coprime m (k * m + n) ↔ Coprime m n := by
  

Proof state:
m n k : ℕ
⊢ Coprime m (k * m + n) ↔ Coprime m n

Next tactic:
rw [Coprime, Coprime, gcd_mul_right_add_right]
@[simp]
theorem coprime_mul_left_add_right (m n k : ℕ) : Coprime m (m * k + n) ↔ Coprime m n := by
  

Proof state:
m n k : ℕ
⊢ Coprime m (m * k + n) ↔ Coprime m n

Next tactic:
rw [Coprime, Coprime, gcd_mul_left_add_right]
@[simp]
theorem coprime_add_mul_right_left (m n k : ℕ) : Coprime (m + k * n) n ↔ Coprime m n := by
  

Proof state:
m n k : ℕ
⊢ Coprime (m + k * n) n ↔ Coprime m n

Next tactic:
rw [Coprime, Coprime, gcd_add_mul_right_left]
@[simp]
theorem coprime_add_mul_left_left (m n k : ℕ) : Coprime (m + n * k) n ↔ Coprime m n := by
  

Proof state:
m n k : ℕ
⊢ Coprime (m + n * k) n ↔ Coprime m n

Next tactic:
rw [Coprime, Coprime, gcd_add_mul_left_left]
@[simp]
theorem coprime_mul_right_add_left (m n k : ℕ) : Coprime (k * n + m) n ↔ Coprime m n := by
  

Proof state:
m n k : ℕ
⊢ Coprime (k * n + m) n ↔ Coprime m n

Next tactic:
rw [Coprime, Coprime, gcd_mul_right_add_left]
@[simp]
theorem coprime_mul_left_add_left (m n k : ℕ) : Coprime (n * k + m) n ↔ Coprime m n := by
  

Proof state:
m n k : ℕ
⊢ Coprime (n * k + m) n ↔ Coprime m n

Next tactic:
rw [Coprime, Coprime, gcd_mul_left_add_left]
@[simp]
theorem coprime_sub_self_left {m n : ℕ} (h : m ≤ n) : Coprime (n - m) m ↔ Coprime n m := by
  

Proof state:
m n : ℕ
h : m ≤ n
⊢ Coprime (n - m) m ↔ Coprime n m

Next tactic:
rw [Coprime, Coprime, gcd_sub_self_left h]
@[simp]
theorem coprime_sub_self_right {m n : ℕ} (h : m ≤ n) : Coprime m (n - m) ↔ Coprime m n := by
  

Proof state:
m n : ℕ
h : m ≤ n
⊢ Coprime m (n - m) ↔ Coprime m n

Next tactic:
rw [Coprime, Coprime, gcd_sub_self_right h]
@[simp]
theorem coprime_self_sub_left {m n : ℕ} (h : m ≤ n) : Coprime (n - m) n ↔ Coprime m n := by
  

Proof state:
m n : ℕ
h : m ≤ n
⊢ Coprime (n - m) n ↔ Coprime m n

Next tactic:
rw [Coprime, Coprime, gcd_self_sub_left h]
@[simp]
theorem coprime_self_sub_right {m n : ℕ} (h : m ≤ n) : Coprime n (n - m) ↔ Coprime n m := by
  

Proof state:
m n : ℕ
h : m ≤ n
⊢ Coprime n (n - m) ↔ Coprime n m

Next tactic:
rw [Coprime, Coprime, gcd_self_sub_right h]
@[simp]
theorem coprime_pow_left_iff {n : ℕ} (hn : 0 < n) (a b : ℕ) :
    Nat.Coprime (a ^ n) b ↔ Nat.Coprime a b := by
  

Proof state:
n : ℕ
hn : 0 < n
a b : ℕ
⊢ Coprime (a ^ n) b ↔ Coprime a b

Next tactic:
obtain ⟨n, rfl⟩ := exists_eq_succ_of_ne_zero hn.ne'
@[simp]
theorem coprime_pow_left_iff {n : ℕ} (hn : 0 < n) (a b : ℕ) :
    Nat.Coprime (a ^ n) b ↔ Nat.Coprime a b := by
  obtain ⟨n, rfl⟩ := exists_eq_succ_of_ne_zero hn.ne'
  

Proof state:
case intro
a b n : ℕ
hn : 0 < succ n
⊢ Coprime (a ^ succ n) b ↔ Coprime a b

Next tactic:
rw [pow_succ, Nat.coprime_mul_iff_left]
@[simp]
theorem coprime_pow_left_iff {n : ℕ} (hn : 0 < n) (a b : ℕ) :
    Nat.Coprime (a ^ n) b ↔ Nat.Coprime a b := by
  obtain ⟨n, rfl⟩ := exists_eq_succ_of_ne_zero hn.ne'
  rw [pow_succ, Nat.coprime_mul_iff_left]
  

Proof state:
case intro
a b n : ℕ
hn : 0 < succ n
⊢ Coprime (a ^ n) b ∧ Coprime a b ↔ Coprime a b

Next tactic:
exact ⟨And.right, fun hab => ⟨hab.pow_left _, hab⟩⟩
@[simp]
theorem coprime_pow_right_iff {n : ℕ} (hn : 0 < n) (a b : ℕ) :
    Nat.Coprime a (b ^ n) ↔ Nat.Coprime a b := by
  

Proof state:
n : ℕ
hn : 0 < n
a b : ℕ
⊢ Coprime a (b ^ n) ↔ Coprime a b

Next tactic:
rw [Nat.coprime_comm, coprime_pow_left_iff hn, Nat.coprime_comm]
theorem not_coprime_zero_zero : ¬Coprime 0 0 := by 

Proof state:
⊢ ¬Coprime 0 0

Next tactic:
simp
theorem coprime_one_left_iff (n : ℕ) : Coprime 1 n ↔ True := by 

Proof state:
n : ℕ
⊢ Coprime 1 n ↔ True

Next tactic:
simp [Coprime]
theorem coprime_one_right_iff (n : ℕ) : Coprime n 1 ↔ True := by 

Proof state:
n : ℕ
⊢ Coprime n 1 ↔ True

Next tactic:
simp [Coprime]
theorem gcd_mul_of_coprime_of_dvd {a b c : ℕ} (hac : Coprime a c) (b_dvd_c : b ∣ c) :
    gcd (a * b) c = b := by
  

Proof state:
a b c : ℕ
hac : Coprime a c
b_dvd_c : b ∣ c
⊢ gcd (a * b) c = b

Next tactic:
rcases exists_eq_mul_left_of_dvd b_dvd_c with ⟨d, rfl⟩
theorem gcd_mul_of_coprime_of_dvd {a b c : ℕ} (hac : Coprime a c) (b_dvd_c : b ∣ c) :
    gcd (a * b) c = b := by
  rcases exists_eq_mul_left_of_dvd b_dvd_c with ⟨d, rfl⟩
  

Proof state:
case intro
a b d : ℕ
hac : Coprime a (d * b)
b_dvd_c : b ∣ d * b
⊢ gcd (a * b) (d * b) = b

Next tactic:
rw [gcd_mul_right]
theorem gcd_mul_of_coprime_of_dvd {a b c : ℕ} (hac : Coprime a c) (b_dvd_c : b ∣ c) :
    gcd (a * b) c = b := by
  rcases exists_eq_mul_left_of_dvd b_dvd_c with ⟨d, rfl⟩
  rw [gcd_mul_right]
  

Proof state:
case intro
a b d : ℕ
hac : Coprime a (d * b)
b_dvd_c : b ∣ d * b
⊢ gcd a d * b = b

Next tactic:
convert one_mul b
theorem gcd_mul_of_coprime_of_dvd {a b c : ℕ} (hac : Coprime a c) (b_dvd_c : b ∣ c) :
    gcd (a * b) c = b := by
  rcases exists_eq_mul_left_of_dvd b_dvd_c with ⟨d, rfl⟩
  rw [gcd_mul_right]
  convert one_mul b
  

Proof state:
case h.e'_2.h.e'_5
a b d : ℕ
hac : Coprime a (d * b)
b_dvd_c : b ∣ d * b
⊢ gcd a d = 1

Next tactic:
exact Coprime.coprime_mul_right_right hac
/-- Represent a divisor of `m * n` as a product of a divisor of `m` and a divisor of `n`.

See `exists_dvd_and_dvd_of_dvd_mul` for the more general but less constructive version for other
`GCDMonoid`s. -/
def prodDvdAndDvdOfDvdProd {m n k : ℕ} (H : k ∣ m * n) :
    { d : { m' // m' ∣ m } × { n' // n' ∣ n } // k = d.1 * d.2 } := by
  

Proof state:
m n k : ℕ
H : k ∣ m * n
⊢ { d // k = ↑d.1 * ↑d.2 }

Next tactic:
cases h0 : gcd k m
/-- Represent a divisor of `m * n` as a product of a divisor of `m` and a divisor of `n`.

See `exists_dvd_and_dvd_of_dvd_mul` for the more general but less constructive version for other
`GCDMonoid`s. -/
def prodDvdAndDvdOfDvdProd {m n k : ℕ} (H : k ∣ m * n) :
    { d : { m' // m' ∣ m } × { n' // n' ∣ n } // k = d.1 * d.2 } := by
  cases h0 : gcd k m
  

Proof state:
case zero
m n k : ℕ
H : k ∣ m * n
h0 : gcd k m = zero
⊢ { d // k = ↑d.1 * ↑d.2 }
case succ m n k : ℕ H : k ∣ m * n n✝ : ℕ h0 : gcd k m = succ n✝ ⊢ { d // k = ↑d.1 * ↑d.2 }

Next tactic:
case zero =>
    obtain rfl : k = 0 := eq_zero_of_gcd_eq_zero_left h0
    obtain rfl : m = 0 := eq_zero_of_gcd_eq_zero_right h0
    exact ⟨⟨⟨0, dvd_refl 0⟩, ⟨n, dvd_refl n⟩⟩, (zero_mul n).symm⟩
/-- Represent a divisor of `m * n` as a product of a divisor of `m` and a divisor of `n`.

See `exists_dvd_and_dvd_of_dvd_mul` for the more general but less constructive version for other
`GCDMonoid`s. -/
def prodDvdAndDvdOfDvdProd {m n k : ℕ} (H : k ∣ m * n) :
    { d : { m' // m' ∣ m } × { n' // n' ∣ n } // k = d.1 * d.2 } := by
  cases h0 : gcd k m
  

Proof state:
m n k : ℕ
H : k ∣ m * n
h0 : gcd k m = zero
⊢ { d // k = ↑d.1 * ↑d.2 }

Next tactic:
case zero =>
    obtain rfl : k = 0 := eq_zero_of_gcd_eq_zero_left h0
    obtain rfl : m = 0 := eq_zero_of_gcd_eq_zero_right h0
    exact ⟨⟨⟨0, dvd_refl 0⟩, ⟨n, dvd_refl n⟩⟩, (zero_mul n).symm⟩
/-- Represent a divisor of `m * n` as a product of a divisor of `m` and a divisor of `n`.

See `exists_dvd_and_dvd_of_dvd_mul` for the more general but less constructive version for other
`GCDMonoid`s. -/
def prodDvdAndDvdOfDvdProd {m n k : ℕ} (H : k ∣ m * n) :
    { d : { m' // m' ∣ m } × { n' // n' ∣ n } // k = d.1 * d.2 } := by
  cases h0 : gcd k m
  case zero =>
    

Proof state:
m n k : ℕ
H : k ∣ m * n
h0 : gcd k m = zero
⊢ { d // k = ↑d.1 * ↑d.2 }

Next tactic:
obtain rfl : k = 0 := eq_zero_of_gcd_eq_zero_left h0
/-- Represent a divisor of `m * n` as a product of a divisor of `m` and a divisor of `n`.

See `exists_dvd_and_dvd_of_dvd_mul` for the more general but less constructive version for other
`GCDMonoid`s. -/
def prodDvdAndDvdOfDvdProd {m n k : ℕ} (H : k ∣ m * n) :
    { d : { m' // m' ∣ m } × { n' // n' ∣ n } // k = d.1 * d.2 } := by
  cases h0 : gcd k m
  case zero =>
    obtain rfl : k = 0 := eq_zero_of_gcd_eq_zero_left h0
    

Proof state:
m n : ℕ
H : 0 ∣ m * n
h0 : gcd 0 m = zero
⊢ { d // 0 = ↑d.1 * ↑d.2 }

Next tactic:
obtain rfl : m = 0 := eq_zero_of_gcd_eq_zero_right h0
/-- Represent a divisor of `m * n` as a product of a divisor of `m` and a divisor of `n`.

See `exists_dvd_and_dvd_of_dvd_mul` for the more general but less constructive version for other
`GCDMonoid`s. -/
def prodDvdAndDvdOfDvdProd {m n k : ℕ} (H : k ∣ m * n) :
    { d : { m' // m' ∣ m } × { n' // n' ∣ n } // k = d.1 * d.2 } := by
  cases h0 : gcd k m
  case zero =>
    obtain rfl : k = 0 := eq_zero_of_gcd_eq_zero_left h0
    obtain rfl : m = 0 := eq_zero_of_gcd_eq_zero_right h0
    

Proof state:
n : ℕ
H : 0 ∣ 0 * n
h0 : gcd 0 0 = zero
⊢ { d // 0 = ↑d.1 * ↑d.2 }

Next tactic:
exact ⟨⟨⟨0, dvd_refl 0⟩, ⟨n, dvd_refl n⟩⟩, (zero_mul n).symm⟩
/-- Represent a divisor of `m * n` as a product of a divisor of `m` and a divisor of `n`.

See `exists_dvd_and_dvd_of_dvd_mul` for the more general but less constructive version for other
`GCDMonoid`s. -/
def prodDvdAndDvdOfDvdProd {m n k : ℕ} (H : k ∣ m * n) :
    { d : { m' // m' ∣ m } × { n' // n' ∣ n } // k = d.1 * d.2 } := by
  cases h0 : gcd k m
  case zero =>
    obtain rfl : k = 0 := eq_zero_of_gcd_eq_zero_left h0
    obtain rfl : m = 0 := eq_zero_of_gcd_eq_zero_right h0
    exact ⟨⟨⟨0, dvd_refl 0⟩, ⟨n, dvd_refl n⟩⟩, (zero_mul n).symm⟩
  

Proof state:
case succ
m n k : ℕ
H : k ∣ m * n
n✝ : ℕ
h0 : gcd k m = succ n✝
⊢ { d // k = ↑d.1 * ↑d.2 }

Next tactic:
case succ tmp =>
    have hpos : 0 < gcd k m := h0.symm ▸ Nat.zero_lt_succ _; clear h0 tmp
    have hd : gcd k m * (k / gcd k m) = k := Nat.mul_div_cancel' (gcd_dvd_left k m)
    refine' ⟨⟨⟨gcd k m, gcd_dvd_right k m⟩, ⟨k / gcd k m, _⟩⟩, hd.symm⟩
    apply Nat.dvd_of_mul_dvd_mul_left hpos
    rw [hd, ← gcd_mul_right]
    exact dvd_gcd (dvd_mul_right _ _) H
/-- Represent a divisor of `m * n` as a product of a divisor of `m` and a divisor of `n`.

See `exists_dvd_and_dvd_of_dvd_mul` for the more general but less constructive version for other
`GCDMonoid`s. -/
def prodDvdAndDvdOfDvdProd {m n k : ℕ} (H : k ∣ m * n) :
    { d : { m' // m' ∣ m } × { n' // n' ∣ n } // k = d.1 * d.2 } := by
  cases h0 : gcd k m
  case zero =>
    obtain rfl : k = 0 := eq_zero_of_gcd_eq_zero_left h0
    obtain rfl : m = 0 := eq_zero_of_gcd_eq_zero_right h0
    exact ⟨⟨⟨0, dvd_refl 0⟩, ⟨n, dvd_refl n⟩⟩, (zero_mul n).symm⟩
  

Proof state:
m n k : ℕ
H : k ∣ m * n
tmp : ℕ
h0 : gcd k m = succ tmp
⊢ { d // k = ↑d.1 * ↑d.2 }

Next tactic:
case succ tmp =>
    have hpos : 0 < gcd k m := h0.symm ▸ Nat.zero_lt_succ _; clear h0 tmp
    have hd : gcd k m * (k / gcd k m) = k := Nat.mul_div_cancel' (gcd_dvd_left k m)
    refine' ⟨⟨⟨gcd k m, gcd_dvd_right k m⟩, ⟨k / gcd k m, _⟩⟩, hd.symm⟩
    apply Nat.dvd_of_mul_dvd_mul_left hpos
    rw [hd, ← gcd_mul_right]
    exact dvd_gcd (dvd_mul_right _ _) H
/-- Represent a divisor of `m * n` as a product of a divisor of `m` and a divisor of `n`.

See `exists_dvd_and_dvd_of_dvd_mul` for the more general but less constructive version for other
`GCDMonoid`s. -/
def prodDvdAndDvdOfDvdProd {m n k : ℕ} (H : k ∣ m * n) :
    { d : { m' // m' ∣ m } × { n' // n' ∣ n } // k = d.1 * d.2 } := by
  cases h0 : gcd k m
  case zero =>
    obtain rfl : k = 0 := eq_zero_of_gcd_eq_zero_left h0
    obtain rfl : m = 0 := eq_zero_of_gcd_eq_zero_right h0
    exact ⟨⟨⟨0, dvd_refl 0⟩, ⟨n, dvd_refl n⟩⟩, (zero_mul n).symm⟩
  case succ tmp =>
    

Proof state:
m n k : ℕ
H : k ∣ m * n
tmp : ℕ
h0 : gcd k m = succ tmp
⊢ { d // k = ↑d.1 * ↑d.2 }

Next tactic:
have hpos : 0 < gcd k m := h0.symm ▸ Nat.zero_lt_succ _
/-- Represent a divisor of `m * n` as a product of a divisor of `m` and a divisor of `n`.

See `exists_dvd_and_dvd_of_dvd_mul` for the more general but less constructive version for other
`GCDMonoid`s. -/
def prodDvdAndDvdOfDvdProd {m n k : ℕ} (H : k ∣ m * n) :
    { d : { m' // m' ∣ m } × { n' // n' ∣ n } // k = d.1 * d.2 } := by
  cases h0 : gcd k m
  case zero =>
    obtain rfl : k = 0 := eq_zero_of_gcd_eq_zero_left h0
    obtain rfl : m = 0 := eq_zero_of_gcd_eq_zero_right h0
    exact ⟨⟨⟨0, dvd_refl 0⟩, ⟨n, dvd_refl n⟩⟩, (zero_mul n).symm⟩
  case succ tmp =>
    have hpos : 0 < gcd k m := h0.symm ▸ Nat.zero_lt_succ _; 

Proof state:
m n k : ℕ
H : k ∣ m * n
tmp : ℕ
h0 : gcd k m = succ tmp
hpos : 0 < gcd k m
⊢ { d // k = ↑d.1 * ↑d.2 }

Next tactic:
clear h0 tmp