l3lab/ntp-mathlib huggingface dataset:
theorem add_num_den' (q r : ℚ) :
    (q + r).num * q.den * r.den = (q.num * r.den + r.num * q.den) * (q + r).den := by
  let s := divInt (q.num * r.den + r.num * q.den) (q.den * r.den : ℤ)
  have hs : (q.den * r.den : ℤ) ≠ 0 := Int.coe_nat_ne_zero_iff_pos.mpr (mul_pos q.pos r.pos)
  obtain ⟨c, ⟨c_mul_num, c_mul_den⟩⟩ :=
    exists_eq_mul_div_num_and_eq_mul_div_den (q.num * r.den + r.num * q.den) hs
  rw [c_mul_num, mul_assoc, mul_comm]
  nth_rw 1 [c_mul_den]
  repeat' rw [Int.mul_assoc]
  apply mul_eq_mul_left_iff.2
  rw [or_iff_not_imp_right]
  intro
  have h : _ = s :=
    @add_def'' q.num q.den r.num r.den (Int.coe_nat_ne_zero_iff_pos.mpr q.pos)
      (Int.coe_nat_ne_zero_iff_pos.mpr r.pos)
  rw [num_den, num_den] at h
  rw [h]
  rw [mul_comm]
  

Proof state:
case intro.intro
q r : ℚ
s : ℚ := (q.num * ↑r.den + r.num * ↑q.den) /. (↑q.den * ↑r.den)
hs : ↑q.den * ↑r.den ≠ 0
c : ℤ
c_mul_num : q.num * ↑r.den + r.num * ↑q.den = c * (↑(q.num * ↑r.den + r.num * ↑q.den) / ↑(↑q.den * ↑r.den)).num
c_mul_den : ↑q.den * ↑r.den = c * ↑(↑(q.num * ↑r.den + r.num * ↑q.den) / ↑(↑q.den * ↑r.den)).den
a✝ : ¬c = 0
h : q + r = s
⊢ s.num * ↑(↑(q.num * ↑r.den + r.num * ↑q.den) / ↑(↑q.den * ↑r.den)).den =
    (↑(q.num * ↑r.den + r.num * ↑q.den) / ↑(↑q.den * ↑r.den)).num * ↑s.den

Next tactic:
apply Rat.eq_iff_mul_eq_mul.mp
theorem add_num_den' (q r : ℚ) :
    (q + r).num * q.den * r.den = (q.num * r.den + r.num * q.den) * (q + r).den := by
  let s := divInt (q.num * r.den + r.num * q.den) (q.den * r.den : ℤ)
  have hs : (q.den * r.den : ℤ) ≠ 0 := Int.coe_nat_ne_zero_iff_pos.mpr (mul_pos q.pos r.pos)
  obtain ⟨c, ⟨c_mul_num, c_mul_den⟩⟩ :=
    exists_eq_mul_div_num_and_eq_mul_div_den (q.num * r.den + r.num * q.den) hs
  rw [c_mul_num, mul_assoc, mul_comm]
  nth_rw 1 [c_mul_den]
  repeat' rw [Int.mul_assoc]
  apply mul_eq_mul_left_iff.2
  rw [or_iff_not_imp_right]
  intro
  have h : _ = s :=
    @add_def'' q.num q.den r.num r.den (Int.coe_nat_ne_zero_iff_pos.mpr q.pos)
      (Int.coe_nat_ne_zero_iff_pos.mpr r.pos)
  rw [num_den, num_den] at h
  rw [h]
  rw [mul_comm]
  apply Rat.eq_iff_mul_eq_mul.mp
  

Proof state:
case intro.intro
q r : ℚ
s : ℚ := (q.num * ↑r.den + r.num * ↑q.den) /. (↑q.den * ↑r.den)
hs : ↑q.den * ↑r.den ≠ 0
c : ℤ
c_mul_num : q.num * ↑r.den + r.num * ↑q.den = c * (↑(q.num * ↑r.den + r.num * ↑q.den) / ↑(↑q.den * ↑r.den)).num
c_mul_den : ↑q.den * ↑r.den = c * ↑(↑(q.num * ↑r.den + r.num * ↑q.den) / ↑(↑q.den * ↑r.den)).den
a✝ : ¬c = 0
h : q + r = s
⊢ s = ↑(q.num * ↑r.den + r.num * ↑q.den) / ↑(↑q.den * ↑r.den)

Next tactic:
rw [← divInt_eq_div]
theorem substr_num_den' (q r : ℚ) :
    (q - r).num * q.den * r.den = (q.num * r.den - r.num * q.den) * (q - r).den := by
  

Proof state:
q r : ℚ
⊢ (q - r).num * ↑q.den * ↑r.den = (q.num * ↑r.den - r.num * ↑q.den) * ↑(q - r).den

Next tactic:
rw [sub_eq_add_neg, sub_eq_add_neg, ← neg_mul, ← num_neg_eq_neg_num, ← den_neg_eq_den r,
    add_num_den' q (-r)]
theorem inv_def'' {q : ℚ} : q⁻¹ = (q.den : ℚ) / q.num := by
  

Proof state:
q : ℚ
⊢ q⁻¹ = ↑q.den / ↑q.num

Next tactic:
conv_lhs => rw [← @num_den q]
theorem inv_def'' {q : ℚ} : q⁻¹ = (q.den : ℚ) / q.num := by
  conv_lhs => 

Proof state:
q : ℚ
| q⁻¹

Next tactic:
rw [← @num_den q]
theorem inv_def'' {q : ℚ} : q⁻¹ = (q.den : ℚ) / q.num := by
  conv_lhs => rw [← @num_den q]
  

Proof state:
q : ℚ
⊢ (q.num /. ↑q.den)⁻¹ = ↑q.den / ↑q.num

Next tactic:
rw [inv_def', divInt_eq_div]
theorem inv_def'' {q : ℚ} : q⁻¹ = (q.den : ℚ) / q.num := by
  conv_lhs => rw [← @num_den q]
  rw [inv_def', divInt_eq_div]; 

Proof state:
q : ℚ
⊢ ↑↑q.den / ↑q.num = ↑q.den / ↑q.num

Next tactic:
rfl
protected theorem inv_neg (q : ℚ) : (-q)⁻¹ = -q⁻¹ := by
  

Proof state:
q : ℚ
⊢ (-q)⁻¹ = -q⁻¹

Next tactic:
rw [← @num_den q]
protected theorem inv_neg (q : ℚ) : (-q)⁻¹ = -q⁻¹ := by
  rw [← @num_den q]
  

Proof state:
q : ℚ
⊢ (-(q.num /. ↑q.den))⁻¹ = -(q.num /. ↑q.den)⁻¹

Next tactic:
simp only [Rat.neg_def, Rat.inv_def', eq_self_iff_true, Rat.divInt_neg_den]
@[simp]
theorem mul_den_eq_num {q : ℚ} : q * q.den = q.num := by
  

Proof state:
q : ℚ
⊢ q * ↑q.den = ↑q.num

Next tactic:
suffices (q.num /. ↑q.den) * (↑q.den /. 1) = q.num /. 1 by
    conv => pattern (occs := 1) q; (rw [← @num_den q])
    simp only [coe_int_eq_divInt, coe_nat_eq_divInt, num_den] at this ⊢; assumption
@[simp]
theorem mul_den_eq_num {q : ℚ} : q * q.den = q.num := by
  suffices (q.num /. ↑q.den) * (↑q.den /. 1) = q.num /. 1 by
    

Proof state:
q : ℚ
this : q.num /. ↑q.den * (↑q.den /. 1) = q.num /. 1
⊢ q * ↑q.den = ↑q.num

Next tactic:
conv => pattern (occs := 1) q; (rw [← @num_den q])
@[simp]
theorem mul_den_eq_num {q : ℚ} : q * q.den = q.num := by
  suffices (q.num /. ↑q.den) * (↑q.den /. 1) = q.num /. 1 by
    conv => 

Proof state:
q : ℚ
this : q.num /. ↑q.den * (↑q.den /. 1) = q.num /. 1
| q * ↑q.den = ↑q.num

Next tactic:
pattern (occs := 1) q; (rw [← @num_den q])
@[simp]
theorem mul_den_eq_num {q : ℚ} : q * q.den = q.num := by
  suffices (q.num /. ↑q.den) * (↑q.den /. 1) = q.num /. 1 by
    conv => 

Proof state:
q : ℚ
this : q.num /. ↑q.den * (↑q.den /. 1) = q.num /. 1
| q * ↑q.den = ↑q.num

Next tactic:
pattern (occs := 1) q
@[simp]
theorem mul_den_eq_num {q : ℚ} : q * q.den = q.num := by
  suffices (q.num /. ↑q.den) * (↑q.den /. 1) = q.num /. 1 by
    conv => pattern (occs := 1) q; 

Proof state:
q : ℚ
this : q.num /. ↑q.den * (↑q.den /. 1) = q.num /. 1
| q

Next tactic:
(rw [← @num_den q])
@[simp]
theorem mul_den_eq_num {q : ℚ} : q * q.den = q.num := by
  suffices (q.num /. ↑q.den) * (↑q.den /. 1) = q.num /. 1 by
    conv => pattern (occs := 1) q; (

Proof state:
q : ℚ
this : q.num /. ↑q.den * (↑q.den /. 1) = q.num /. 1
| q

Next tactic:
rw [← @num_den q]
@[simp]
theorem mul_den_eq_num {q : ℚ} : q * q.den = q.num := by
  suffices (q.num /. ↑q.den) * (↑q.den /. 1) = q.num /. 1 by
    conv => pattern (occs := 1) q; (rw [← @num_den q])
    

Proof state:
q : ℚ
this : q.num /. ↑q.den * (↑q.den /. 1) = q.num /. 1
⊢ q.num /. ↑q.den * ↑q.den = ↑q.num

Next tactic:
simp only [coe_int_eq_divInt, coe_nat_eq_divInt, num_den] at this ⊢
@[simp]
theorem mul_den_eq_num {q : ℚ} : q * q.den = q.num := by
  suffices (q.num /. ↑q.den) * (↑q.den /. 1) = q.num /. 1 by
    conv => pattern (occs := 1) q; (rw [← @num_den q])
    simp only [coe_int_eq_divInt, coe_nat_eq_divInt, num_den] at this ⊢; 

Proof state:
q : ℚ
this : q * (↑q.den /. 1) = q.num /. 1
⊢ q * (↑q.den /. 1) = q.num /. 1

Next tactic:
assumption
@[simp]
theorem mul_den_eq_num {q : ℚ} : q * q.den = q.num := by
  suffices (q.num /. ↑q.den) * (↑q.den /. 1) = q.num /. 1 by
    conv => pattern (occs := 1) q; (rw [← @num_den q])
    simp only [coe_int_eq_divInt, coe_nat_eq_divInt, num_den] at this ⊢; assumption
  

Proof state:
q : ℚ
⊢ q.num /. ↑q.den * (↑q.den /. 1) = q.num /. 1

Next tactic:
have : (q.den : ℤ) ≠ 0 := ne_of_gt (mod_cast q.pos)
@[simp]
theorem mul_den_eq_num {q : ℚ} : q * q.den = q.num := by
  suffices (q.num /. ↑q.den) * (↑q.den /. 1) = q.num /. 1 by
    conv => pattern (occs := 1) q; (rw [← @num_den q])
    simp only [coe_int_eq_divInt, coe_nat_eq_divInt, num_den] at this ⊢; assumption
  have : (q.den : ℤ) ≠ 0 := ne_of_gt (mod_cast q.pos)
  

Proof state:
q : ℚ
this : ↑q.den ≠ 0
⊢ q.num /. ↑q.den * (↑q.den /. 1) = q.num /. 1

Next tactic:
rw [Rat.mul_def' this one_ne_zero, mul_comm (q.den : ℤ) 1, divInt_mul_right this]
theorem den_div_cast_eq_one_iff (m n : ℤ) (hn : n ≠ 0) : ((m : ℚ) / n).den = 1 ↔ n ∣ m := by
  

Proof state:
m n : ℤ
hn : n ≠ 0
⊢ (↑m / ↑n).den = 1 ↔ n ∣ m

Next tactic:
replace hn : (n : ℚ) ≠ 0
theorem den_div_cast_eq_one_iff (m n : ℤ) (hn : n ≠ 0) : ((m : ℚ) / n).den = 1 ↔ n ∣ m := by
  replace hn : (n : ℚ) ≠ 0
  · 

Proof state:
case hn
m n : ℤ
hn : n ≠ 0
⊢ ↑n ≠ 0

Next tactic:
rwa [Ne.def, ← Int.cast_zero, coe_int_inj]
theorem den_div_cast_eq_one_iff (m n : ℤ) (hn : n ≠ 0) : ((m : ℚ) / n).den = 1 ↔ n ∣ m := by
  replace hn : (n : ℚ) ≠ 0
  · rwa [Ne.def, ← Int.cast_zero, coe_int_inj]
  

Proof state:
m n : ℤ
hn : ↑n ≠ 0
⊢ (↑m / ↑n).den = 1 ↔ n ∣ m

Next tactic:
constructor
theorem den_div_cast_eq_one_iff (m n : ℤ) (hn : n ≠ 0) : ((m : ℚ) / n).den = 1 ↔ n ∣ m := by
  replace hn : (n : ℚ) ≠ 0
  · rwa [Ne.def, ← Int.cast_zero, coe_int_inj]
  constructor
  · 

Proof state:
case mp
m n : ℤ
hn : ↑n ≠ 0
⊢ (↑m / ↑n).den = 1 → n ∣ m

Next tactic:
intro h
theorem den_div_cast_eq_one_iff (m n : ℤ) (hn : n ≠ 0) : ((m : ℚ) / n).den = 1 ↔ n ∣ m := by
  replace hn : (n : ℚ) ≠ 0
  · rwa [Ne.def, ← Int.cast_zero, coe_int_inj]
  constructor
  · intro h
    -- Porting note: was `lift (m : ℚ) / n to ℤ using h with k hk`
    

Proof state:
case mp
m n : ℤ
hn : ↑n ≠ 0
h : (↑m / ↑n).den = 1
⊢ n ∣ m

Next tactic:
use ((m : ℚ) / n).num
theorem den_div_cast_eq_one_iff (m n : ℤ) (hn : n ≠ 0) : ((m : ℚ) / n).den = 1 ↔ n ∣ m := by
  replace hn : (n : ℚ) ≠ 0
  · rwa [Ne.def, ← Int.cast_zero, coe_int_inj]
  constructor
  · intro h
    -- Porting note: was `lift (m : ℚ) / n to ℤ using h with k hk`
    use ((m : ℚ) / n).num
    

Proof state:
case h
m n : ℤ
hn : ↑n ≠ 0
h : (↑m / ↑n).den = 1
⊢ m = n * (↑m / ↑n).num

Next tactic:
have hk := Rat.coe_int_num_of_den_eq_one h
theorem den_div_cast_eq_one_iff (m n : ℤ) (hn : n ≠ 0) : ((m : ℚ) / n).den = 1 ↔ n ∣ m := by
  replace hn : (n : ℚ) ≠ 0
  · rwa [Ne.def, ← Int.cast_zero, coe_int_inj]
  constructor
  · intro h
    -- Porting note: was `lift (m : ℚ) / n to ℤ using h with k hk`
    use ((m : ℚ) / n).num
    have hk := Rat.coe_int_num_of_den_eq_one h
    

Proof state:
case h
m n : ℤ
hn : ↑n ≠ 0
h : (↑m / ↑n).den = 1
hk : ↑(↑m / ↑n).num = ↑m / ↑n
⊢ m = n * (↑m / ↑n).num

Next tactic:
simp_rw [eq_div_iff_mul_eq hn, ← Int.cast_mul] at hk
theorem den_div_cast_eq_one_iff (m n : ℤ) (hn : n ≠ 0) : ((m : ℚ) / n).den = 1 ↔ n ∣ m := by
  replace hn : (n : ℚ) ≠ 0
  · rwa [Ne.def, ← Int.cast_zero, coe_int_inj]
  constructor
  · intro h
    -- Porting note: was `lift (m : ℚ) / n to ℤ using h with k hk`
    use ((m : ℚ) / n).num
    have hk := Rat.coe_int_num_of_den_eq_one h
    simp_rw [eq_div_iff_mul_eq hn, ← Int.cast_mul] at hk
    

Proof state:
case h
m n : ℤ
hn : ↑n ≠ 0
h : (↑m / ↑n).den = 1
hk : ↑((↑m / ↑n).num * n) = ↑m
⊢ m = n * (↑m / ↑n).num

Next tactic:
rwa [mul_comm, eq_comm, coe_int_inj] at hk
theorem den_div_cast_eq_one_iff (m n : ℤ) (hn : n ≠ 0) : ((m : ℚ) / n).den = 1 ↔ n ∣ m := by
  replace hn : (n : ℚ) ≠ 0
  · rwa [Ne.def, ← Int.cast_zero, coe_int_inj]
  constructor
  · intro h
    -- Porting note: was `lift (m : ℚ) / n to ℤ using h with k hk`
    use ((m : ℚ) / n).num
    have hk := Rat.coe_int_num_of_den_eq_one h
    simp_rw [eq_div_iff_mul_eq hn, ← Int.cast_mul] at hk
    rwa [mul_comm, eq_comm, coe_int_inj] at hk
  · 

Proof state:
case mpr
m n : ℤ
hn : ↑n ≠ 0
⊢ n ∣ m → (↑m / ↑n).den = 1

Next tactic:
rintro ⟨d, rfl⟩
theorem den_div_cast_eq_one_iff (m n : ℤ) (hn : n ≠ 0) : ((m : ℚ) / n).den = 1 ↔ n ∣ m := by
  replace hn : (n : ℚ) ≠ 0
  · rwa [Ne.def, ← Int.cast_zero, coe_int_inj]
  constructor
  · intro h
    -- Porting note: was `lift (m : ℚ) / n to ℤ using h with k hk`
    use ((m : ℚ) / n).num
    have hk := Rat.coe_int_num_of_den_eq_one h
    simp_rw [eq_div_iff_mul_eq hn, ← Int.cast_mul] at hk
    rwa [mul_comm, eq_comm, coe_int_inj] at hk
  · rintro ⟨d, rfl⟩
    

Proof state:
case mpr.intro
n : ℤ
hn : ↑n ≠ 0
d : ℤ
⊢ (↑(n * d) / ↑n).den = 1

Next tactic:
rw [Int.cast_mul, mul_comm, mul_div_cancel _ hn, Rat.coe_int_den]
theorem num_div_eq_of_coprime {a b : ℤ} (hb0 : 0 < b) (h : Nat.Coprime a.natAbs b.natAbs) :
    (a / b : ℚ).num = a := by
  -- Porting note: was `lift b to ℕ using le_of_lt hb0`
  

Proof state:
a b : ℤ
hb0 : 0 < b
h : Nat.Coprime (Int.natAbs a) (Int.natAbs b)
⊢ (↑a / ↑b).num = a

Next tactic:
rw [← Int.natAbs_of_nonneg hb0.le, ← Rat.divInt_eq_div,
    ← mk_eq_divInt _ _ (Int.natAbs_ne_zero.mpr hb0.ne') h]
theorem den_div_eq_of_coprime {a b : ℤ} (hb0 : 0 < b) (h : Nat.Coprime a.natAbs b.natAbs) :
    ((a / b : ℚ).den : ℤ) = b := by
  -- Porting note: was `lift b to ℕ using le_of_lt hb0`
  

Proof state:
a b : ℤ
hb0 : 0 < b
h : Nat.Coprime (Int.natAbs a) (Int.natAbs b)
⊢ ↑(↑a / ↑b).den = b

Next tactic:
rw [← Int.natAbs_of_nonneg hb0.le, ← Rat.divInt_eq_div,
    ← mk_eq_divInt _ _ (Int.natAbs_ne_zero.mpr hb0.ne') h]
theorem div_int_inj {a b c d : ℤ} (hb0 : 0 < b) (hd0 : 0 < d) (h1 : Nat.Coprime a.natAbs b.natAbs)
    (h2 : Nat.Coprime c.natAbs d.natAbs) (h : (a : ℚ) / b = (c : ℚ) / d) : a = c ∧ b = d := by
  

Proof state:
a b c d : ℤ
hb0 : 0 < b
hd0 : 0 < d
h1 : Nat.Coprime (Int.natAbs a) (Int.natAbs b)
h2 : Nat.Coprime (Int.natAbs c) (Int.natAbs d)
h : ↑a / ↑b = ↑c / ↑d
⊢ a = c ∧ b = d

Next tactic:
apply And.intro
theorem div_int_inj {a b c d : ℤ} (hb0 : 0 < b) (hd0 : 0 < d) (h1 : Nat.Coprime a.natAbs b.natAbs)
    (h2 : Nat.Coprime c.natAbs d.natAbs) (h : (a : ℚ) / b = (c : ℚ) / d) : a = c ∧ b = d := by
  apply And.intro
  · 

Proof state:
case left
a b c d : ℤ
hb0 : 0 < b
hd0 : 0 < d
h1 : Nat.Coprime (Int.natAbs a) (Int.natAbs b)
h2 : Nat.Coprime (Int.natAbs c) (Int.natAbs d)
h : ↑a / ↑b = ↑c / ↑d
⊢ a = c

Next tactic:
rw [← num_div_eq_of_coprime hb0 h1, h, num_div_eq_of_coprime hd0 h2]
theorem div_int_inj {a b c d : ℤ} (hb0 : 0 < b) (hd0 : 0 < d) (h1 : Nat.Coprime a.natAbs b.natAbs)
    (h2 : Nat.Coprime c.natAbs d.natAbs) (h : (a : ℚ) / b = (c : ℚ) / d) : a = c ∧ b = d := by
  apply And.intro
  · rw [← num_div_eq_of_coprime hb0 h1, h, num_div_eq_of_coprime hd0 h2]
  · 

Proof state:
case right
a b c d : ℤ
hb0 : 0 < b
hd0 : 0 < d
h1 : Nat.Coprime (Int.natAbs a) (Int.natAbs b)
h2 : Nat.Coprime (Int.natAbs c) (Int.natAbs d)
h : ↑a / ↑b = ↑c / ↑d
⊢ b = d

Next tactic:
rw [← den_div_eq_of_coprime hb0 h1, h, den_div_eq_of_coprime hd0 h2]
@[norm_cast]
theorem coe_int_div_self (n : ℤ) : ((n / n : ℤ) : ℚ) = n / n := by
  

Proof state:
n : ℤ
⊢ ↑(n / n) = ↑n / ↑n

Next tactic:
by_cases hn : n = 0
@[norm_cast]
theorem coe_int_div_self (n : ℤ) : ((n / n : ℤ) : ℚ) = n / n := by
  by_cases hn : n = 0
  · 

Proof state:
case pos
n : ℤ
hn : n = 0
⊢ ↑(n / n) = ↑n / ↑n

Next tactic:
subst hn
@[norm_cast]
theorem coe_int_div_self (n : ℤ) : ((n / n : ℤ) : ℚ) = n / n := by
  by_cases hn : n = 0
  · subst hn
    

Proof state:
case pos
⊢ ↑(0 / 0) = ↑0 / ↑0

Next tactic:
simp only [Int.cast_zero, Int.zero_div, zero_div, Int.ediv_zero]
@[norm_cast]
theorem coe_int_div_self (n : ℤ) : ((n / n : ℤ) : ℚ) = n / n := by
  by_cases hn : n = 0
  · subst hn
    simp only [Int.cast_zero, Int.zero_div, zero_div, Int.ediv_zero]
  · 

Proof state:
case neg
n : ℤ
hn : ¬n = 0
⊢ ↑(n / n) = ↑n / ↑n

Next tactic:
have : (n : ℚ) ≠ 0 := by rwa [← coe_int_inj] at hn
@[norm_cast]
theorem coe_int_div_self (n : ℤ) : ((n / n : ℤ) : ℚ) = n / n := by
  by_cases hn : n = 0
  · subst hn
    simp only [Int.cast_zero, Int.zero_div, zero_div, Int.ediv_zero]
  · have : (n : ℚ) ≠ 0 := by 

Proof state:
n : ℤ
hn : ¬n = 0
⊢ ↑n ≠ 0

Next tactic:
rwa [← coe_int_inj] at hn
@[norm_cast]
theorem coe_int_div_self (n : ℤ) : ((n / n : ℤ) : ℚ) = n / n := by
  by_cases hn : n = 0
  · subst hn
    simp only [Int.cast_zero, Int.zero_div, zero_div, Int.ediv_zero]
  · have : (n : ℚ) ≠ 0 := by rwa [← coe_int_inj] at hn
    

Proof state:
case neg
n : ℤ
hn : ¬n = 0
this : ↑n ≠ 0
⊢ ↑(n / n) = ↑n / ↑n

Next tactic:
simp only [Int.ediv_self hn, Int.cast_one, Ne.def, not_false_iff, div_self this]
theorem coe_int_div (a b : ℤ) (h : b ∣ a) : ((a / b : ℤ) : ℚ) = a / b := by
  

Proof state:
a b : ℤ
h : b ∣ a
⊢ ↑(a / b) = ↑a / ↑b

Next tactic:
rcases h with ⟨c, rfl⟩
theorem coe_int_div (a b : ℤ) (h : b ∣ a) : ((a / b : ℤ) : ℚ) = a / b := by
  rcases h with ⟨c, rfl⟩
  

Proof state:
case intro
b c : ℤ
⊢ ↑(b * c / b) = ↑(b * c) / ↑b

Next tactic:
rw [mul_comm b, Int.mul_ediv_assoc c (dvd_refl b), Int.cast_mul,
    coe_int_div_self, Int.cast_mul, mul_div_assoc]
theorem coe_nat_div (a b : ℕ) (h : b ∣ a) : ((a / b : ℕ) : ℚ) = a / b := by
  

Proof state:
a b : ℕ
h : b ∣ a
⊢ ↑(a / b) = ↑a / ↑b

Next tactic:
rcases h with ⟨c, rfl⟩
theorem coe_nat_div (a b : ℕ) (h : b ∣ a) : ((a / b : ℕ) : ℚ) = a / b := by
  rcases h with ⟨c, rfl⟩
  

Proof state:
case intro
b c : ℕ
⊢ ↑(b * c / b) = ↑(b * c) / ↑b

Next tactic:
simp only [mul_comm b, Nat.mul_div_assoc c (dvd_refl b), Nat.cast_mul, mul_div_assoc,
    coe_nat_div_self]
theorem inv_coe_int_num_of_pos {a : ℤ} (ha0 : 0 < a) : (a : ℚ)⁻¹.num = 1 := by
  

Proof state:
a : ℤ
ha0 : 0 < a
⊢ (↑a)⁻¹.num = 1

Next tactic:
rw [← ofInt_eq_cast, ofInt, mk_eq_divInt, Rat.inv_def', divInt_eq_div, Nat.cast_one]
theorem inv_coe_int_num_of_pos {a : ℤ} (ha0 : 0 < a) : (a : ℚ)⁻¹.num = 1 := by
  rw [← ofInt_eq_cast, ofInt, mk_eq_divInt, Rat.inv_def', divInt_eq_div, Nat.cast_one]
  

Proof state:
a : ℤ
ha0 : 0 < a
⊢ (↑1 / ↑a).num = 1

Next tactic:
apply num_div_eq_of_coprime ha0
theorem inv_coe_int_num_of_pos {a : ℤ} (ha0 : 0 < a) : (a : ℚ)⁻¹.num = 1 := by
  rw [← ofInt_eq_cast, ofInt, mk_eq_divInt, Rat.inv_def', divInt_eq_div, Nat.cast_one]
  apply num_div_eq_of_coprime ha0
  

Proof state:
a : ℤ
ha0 : 0 < a
⊢ Nat.Coprime (Int.natAbs 1) (Int.natAbs a)

Next tactic:
rw [Int.natAbs_one]
theorem inv_coe_int_num_of_pos {a : ℤ} (ha0 : 0 < a) : (a : ℚ)⁻¹.num = 1 := by
  rw [← ofInt_eq_cast, ofInt, mk_eq_divInt, Rat.inv_def', divInt_eq_div, Nat.cast_one]
  apply num_div_eq_of_coprime ha0
  rw [Int.natAbs_one]
  

Proof state:
a : ℤ
ha0 : 0 < a
⊢ Nat.Coprime 1 (Int.natAbs a)

Next tactic:
exact Nat.coprime_one_left _
theorem inv_coe_int_den_of_pos {a : ℤ} (ha0 : 0 < a) : ((a : ℚ)⁻¹.den : ℤ) = a := by
  

Proof state:
a : ℤ
ha0 : 0 < a
⊢ ↑(↑a)⁻¹.den = a

Next tactic:
rw [← ofInt_eq_cast, ofInt, mk_eq_divInt, Rat.inv_def', divInt_eq_div, Nat.cast_one]
theorem inv_coe_int_den_of_pos {a : ℤ} (ha0 : 0 < a) : ((a : ℚ)⁻¹.den : ℤ) = a := by
  rw [← ofInt_eq_cast, ofInt, mk_eq_divInt, Rat.inv_def', divInt_eq_div, Nat.cast_one]
  

Proof state:
a : ℤ
ha0 : 0 < a
⊢ ↑(↑1 / ↑a).den = a

Next tactic:
apply den_div_eq_of_coprime ha0
theorem inv_coe_int_den_of_pos {a : ℤ} (ha0 : 0 < a) : ((a : ℚ)⁻¹.den : ℤ) = a := by
  rw [← ofInt_eq_cast, ofInt, mk_eq_divInt, Rat.inv_def', divInt_eq_div, Nat.cast_one]
  apply den_div_eq_of_coprime ha0
  

Proof state:
a : ℤ
ha0 : 0 < a
⊢ Nat.Coprime (Int.natAbs 1) (Int.natAbs a)

Next tactic:
rw [Int.natAbs_one]
theorem inv_coe_int_den_of_pos {a : ℤ} (ha0 : 0 < a) : ((a : ℚ)⁻¹.den : ℤ) = a := by
  rw [← ofInt_eq_cast, ofInt, mk_eq_divInt, Rat.inv_def', divInt_eq_div, Nat.cast_one]
  apply den_div_eq_of_coprime ha0
  rw [Int.natAbs_one]
  

Proof state:
a : ℤ
ha0 : 0 < a
⊢ Nat.Coprime 1 (Int.natAbs a)

Next tactic:
exact Nat.coprime_one_left _
theorem inv_coe_nat_den_of_pos {a : ℕ} (ha0 : 0 < a) : (a : ℚ)⁻¹.den = a := by
  

Proof state:
a : ℕ
ha0 : 0 < a
⊢ (↑a)⁻¹.den = a

Next tactic:
rw [← Int.ofNat_inj, ← Int.cast_ofNat a, inv_coe_int_den_of_pos]
theorem inv_coe_nat_den_of_pos {a : ℕ} (ha0 : 0 < a) : (a : ℚ)⁻¹.den = a := by
  rw [← Int.ofNat_inj, ← Int.cast_ofNat a, inv_coe_int_den_of_pos]
  

Proof state:
a : ℕ
ha0 : 0 < a
⊢ 0 < ↑a

Next tactic:
rwa [Nat.cast_pos]
@[simp]
theorem inv_coe_int_num (a : ℤ) : (a : ℚ)⁻¹.num = Int.sign a := by
  

Proof state:
a : ℤ
⊢ (↑a)⁻¹.num = Int.sign a

Next tactic:
induction a using Int.induction_on
@[simp]
theorem inv_coe_int_num (a : ℤ) : (a : ℚ)⁻¹.num = Int.sign a := by
  induction a using Int.induction_on <;>
    

Proof state:
case hz
⊢ (↑0)⁻¹.num = Int.sign 0

Next tactic:
simp [← Int.negSucc_coe', Int.negSucc_coe, -neg_add_rev, Rat.inv_neg, Int.ofNat_add_one_out,
      -Nat.cast_succ, inv_coe_nat_num_of_pos, -Int.cast_negSucc, @eq_comm ℤ 1,
      Int.sign_eq_one_of_pos, ofInt_eq_cast]
@[simp]
theorem inv_coe_int_num (a : ℤ) : (a : ℚ)⁻¹.num = Int.sign a := by
  induction a using Int.induction_on <;>
    

Proof state:
case hp
i✝ : ℕ
a✝ : (↑↑i✝)⁻¹.num = Int.sign ↑i✝
⊢ (↑(↑i✝ + 1))⁻¹.num = Int.sign (↑i✝ + 1)

Next tactic:
simp [← Int.negSucc_coe', Int.negSucc_coe, -neg_add_rev, Rat.inv_neg, Int.ofNat_add_one_out,
      -Nat.cast_succ, inv_coe_nat_num_of_pos, -Int.cast_negSucc, @eq_comm ℤ 1,
      Int.sign_eq_one_of_pos, ofInt_eq_cast]
@[simp]
theorem inv_coe_int_num (a : ℤ) : (a : ℚ)⁻¹.num = Int.sign a := by
  induction a using Int.induction_on <;>
    

Proof state:
case hn
i✝ : ℕ
a✝ : (↑(-↑i✝))⁻¹.num = Int.sign (-↑i✝)
⊢ (↑(-↑i✝ - 1))⁻¹.num = Int.sign (-↑i✝ - 1)

Next tactic:
simp [← Int.negSucc_coe', Int.negSucc_coe, -neg_add_rev, Rat.inv_neg, Int.ofNat_add_one_out,
      -Nat.cast_succ, inv_coe_nat_num_of_pos, -Int.cast_negSucc, @eq_comm ℤ 1,
      Int.sign_eq_one_of_pos, ofInt_eq_cast]
@[simp]
theorem inv_coe_int_den (a : ℤ) : (a : ℚ)⁻¹.den = if a = 0 then 1 else a.natAbs := by
  

Proof state:
a : ℤ
⊢ (↑a)⁻¹.den = if a = 0 then 1 else Int.natAbs a

Next tactic:
induction a using Int.induction_on
@[simp]
theorem inv_coe_int_den (a : ℤ) : (a : ℚ)⁻¹.den = if a = 0 then 1 else a.natAbs := by
  induction a using Int.induction_on <;>
    

Proof state:
case hz
⊢ (↑0)⁻¹.den = if 0 = 0 then 1 else Int.natAbs 0

Next tactic:
simp [← Int.negSucc_coe', Int.negSucc_coe, -neg_add_rev, Rat.inv_neg, Int.ofNat_add_one_out,
      -Nat.cast_succ, inv_coe_nat_den_of_pos, -Int.cast_negSucc, ofInt_eq_cast]
@[simp]
theorem inv_coe_int_den (a : ℤ) : (a : ℚ)⁻¹.den = if a = 0 then 1 else a.natAbs := by
  induction a using Int.induction_on <;>
    

Proof state:
case hp
i✝ : ℕ
a✝ : (↑↑i✝)⁻¹.den = if ↑i✝ = 0 then 1 else Int.natAbs ↑i✝
⊢ (↑(↑i✝ + 1))⁻¹.den = if ↑i✝ + 1 = 0 then 1 else Int.natAbs (↑i✝ + 1)

Next tactic:
simp [← Int.negSucc_coe', Int.negSucc_coe, -neg_add_rev, Rat.inv_neg, Int.ofNat_add_one_out,
      -Nat.cast_succ, inv_coe_nat_den_of_pos, -Int.cast_negSucc, ofInt_eq_cast]
@[simp]
theorem inv_coe_int_den (a : ℤ) : (a : ℚ)⁻¹.den = if a = 0 then 1 else a.natAbs := by
  induction a using Int.induction_on <;>
    

Proof state:
case hn
i✝ : ℕ
a✝ : (↑(-↑i✝))⁻¹.den = if -↑i✝ = 0 then 1 else Int.natAbs (-↑i✝)
⊢ (↑(-↑i✝ - 1))⁻¹.den = if -↑i✝ - 1 = 0 then 1 else Int.natAbs (-↑i✝ - 1)

Next tactic:
simp [← Int.negSucc_coe', Int.negSucc_coe, -neg_add_rev, Rat.inv_neg, Int.ofNat_add_one_out,
      -Nat.cast_succ, inv_coe_nat_den_of_pos, -Int.cast_negSucc, ofInt_eq_cast]
@[simp]
theorem inv_coe_nat_den (a : ℕ) : (a : ℚ)⁻¹.den = if a = 0 then 1 else a := by
  

Proof state:
a : ℕ
⊢ (↑a)⁻¹.den = if a = 0 then 1 else a

Next tactic:
simpa [-inv_coe_int_den, ofInt_eq_cast] using inv_coe_int_den a
protected theorem «forall» {p : ℚ → Prop} : (∀ r, p r) ↔ ∀ a b : ℤ, p (a / b) :=
  ⟨fun h _ _ => h _,
   fun h q => by
    

Proof state:
p : ℚ → Prop
h : ∀ (a b : ℤ), p (↑a / ↑b)
q : ℚ
⊢ p q

Next tactic:
have := h q.num q.den
protected theorem «forall» {p : ℚ → Prop} : (∀ r, p r) ↔ ∀ a b : ℤ, p (a / b) :=
  ⟨fun h _ _ => h _,
   fun h q => by
    have := h q.num q.den
    

Proof state:
p : ℚ → Prop
h : ∀ (a b : ℤ), p (↑a / ↑b)
q : ℚ
this : p (↑q.num / ↑↑q.den)
⊢ p q

Next tactic:
rwa [Int.cast_ofNat, num_div_den q] at this
protected theorem «exists» {p : ℚ → Prop} : (∃ r, p r) ↔ ∃ a b : ℤ, p (a / b) :=
  ⟨fun ⟨r, hr⟩ => ⟨r.num, r.den, by 

Proof state:
p : ℚ → Prop
x✝ : ∃ r, p r
r : ℚ
hr : p r
⊢ p (↑r.num / ↑↑r.den)

Next tactic:
convert hr
protected theorem «exists» {p : ℚ → Prop} : (∃ r, p r) ↔ ∃ a b : ℤ, p (a / b) :=
  ⟨fun ⟨r, hr⟩ => ⟨r.num, r.den, by convert hr; 

Proof state:
case h.e'_1
p : ℚ → Prop
x✝ : ∃ r, p r
r : ℚ
hr : p r
⊢ ↑r.num / ↑↑r.den = r

Next tactic:
convert num_div_den r
theorem mul_toSubmodule_le (S T : Subalgebra R A) :
    (Subalgebra.toSubmodule S)* (Subalgebra.toSubmodule T) ≤ Subalgebra.toSubmodule (S ⊔ T) := by
  

Proof state:
R : Type u_1
A : Type u_2
inst✝² : CommSemiring R
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Subalgebra R A
⊢ toSubmodule S * toSubmodule T ≤ toSubmodule (S ⊔ T)

Next tactic:
rw [Submodule.mul_le]
theorem mul_toSubmodule_le (S T : Subalgebra R A) :
    (Subalgebra.toSubmodule S)* (Subalgebra.toSubmodule T) ≤ Subalgebra.toSubmodule (S ⊔ T) := by
  rw [Submodule.mul_le]
  

Proof state:
R : Type u_1
A : Type u_2
inst✝² : CommSemiring R
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Subalgebra R A
⊢ ∀ m ∈ toSubmodule S, ∀ n ∈ toSubmodule T, m * n ∈ toSubmodule (S ⊔ T)

Next tactic:
intro y hy z hz
theorem mul_toSubmodule_le (S T : Subalgebra R A) :
    (Subalgebra.toSubmodule S)* (Subalgebra.toSubmodule T) ≤ Subalgebra.toSubmodule (S ⊔ T) := by
  rw [Submodule.mul_le]
  intro y hy z hz
  

Proof state:
R : Type u_1
A : Type u_2
inst✝² : CommSemiring R
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Subalgebra R A
y : A
hy : y ∈ toSubmodule S
z : A
hz : z ∈ toSubmodule T
⊢ y * z ∈ toSubmodule (S ⊔ T)

Next tactic:
show y * z ∈ S ⊔ T