l3lab/ntp-mathlib huggingface dataset:
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    

Proof state:
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : natSize (pos a * b) ≤ Nat.succ n
⊢ ↑(gcdAux (Nat.succ n) (pos a) b) = Nat.gcd ↑(pos a) ↑b

Next tactic:
simp only [gcdAux, cast_pos]
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    simp only [gcdAux, cast_pos]
    

Proof state:
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : natSize (pos a * b) ≤ Nat.succ n
⊢ ↑(gcdAux n (b % pos a) (pos a)) = Nat.gcd ↑a ↑b

Next tactic:
rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat]
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    simp only [gcdAux, cast_pos]
    rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat]
    · 

Proof state:
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : natSize (pos a * b) ≤ Nat.succ n
⊢ Nat.gcd (↑b % ↑(pos a)) ↑(pos a) = Nat.gcd (↑b % ↑a) ↑a

Next tactic:
rfl
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    simp only [gcdAux, cast_pos]
    rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat]
    · rfl
    · 

Proof state:
case a
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : natSize (pos a * b) ≤ Nat.succ n
⊢ b % pos a ≤ pos a

Next tactic:
rw [← le_to_nat, mod_to_nat]
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    simp only [gcdAux, cast_pos]
    rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat]
    · rfl
    · rw [← le_to_nat, mod_to_nat]
      

Proof state:
case a
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : natSize (pos a * b) ≤ Nat.succ n
⊢ ↑b % ↑(pos a) ≤ ↑(pos a)

Next tactic:
exact le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    simp only [gcdAux, cast_pos]
    rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat]
    · rfl
    · rw [← le_to_nat, mod_to_nat]
      exact le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))
    

Proof state:
case a
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : natSize (pos a * b) ≤ Nat.succ n
⊢ natSize (b % pos a * pos a) ≤ n

Next tactic:
rw [natSize_to_nat, mul_to_nat, Nat.size_le] at h ⊢
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    simp only [gcdAux, cast_pos]
    rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat]
    · rfl
    · rw [← le_to_nat, mod_to_nat]
      exact le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))
    rw [natSize_to_nat, mul_to_nat, Nat.size_le] at h ⊢
    

Proof state:
case a
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : ↑(pos a) * ↑b < 2 ^ Nat.succ n
⊢ ↑(b % pos a) * ↑(pos a) < 2 ^ n

Next tactic:
rw [mod_to_nat, mul_comm]
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    simp only [gcdAux, cast_pos]
    rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat]
    · rfl
    · rw [← le_to_nat, mod_to_nat]
      exact le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))
    rw [natSize_to_nat, mul_to_nat, Nat.size_le] at h ⊢
    rw [mod_to_nat, mul_comm]
    

Proof state:
case a
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : ↑(pos a) * ↑b < 2 ^ Nat.succ n
⊢ ↑(pos a) * (↑b % ↑(pos a)) < 2 ^ n

Next tactic:
rw [pow_succ', ← Nat.mod_add_div b (pos a)] at h
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    simp only [gcdAux, cast_pos]
    rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat]
    · rfl
    · rw [← le_to_nat, mod_to_nat]
      exact le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))
    rw [natSize_to_nat, mul_to_nat, Nat.size_le] at h ⊢
    rw [mod_to_nat, mul_comm]
    rw [pow_succ', ← Nat.mod_add_div b (pos a)] at h
    

Proof state:
case a
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : ↑(pos a) * (↑b % ↑(pos a) + ↑(pos a) * (↑b / ↑(pos a))) < 2 ^ n * 2
⊢ ↑(pos a) * (↑b % ↑(pos a)) < 2 ^ n

Next tactic:
refine' lt_of_mul_lt_mul_right (lt_of_le_of_lt _ h) (Nat.zero_le 2)
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    simp only [gcdAux, cast_pos]
    rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat]
    · rfl
    · rw [← le_to_nat, mod_to_nat]
      exact le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))
    rw [natSize_to_nat, mul_to_nat, Nat.size_le] at h ⊢
    rw [mod_to_nat, mul_comm]
    rw [pow_succ', ← Nat.mod_add_div b (pos a)] at h
    refine' lt_of_mul_lt_mul_right (lt_of_le_of_lt _ h) (Nat.zero_le 2)
    

Proof state:
case a
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : ↑(pos a) * (↑b % ↑(pos a) + ↑(pos a) * (↑b / ↑(pos a))) < 2 ^ n * 2
⊢ ↑(pos a) * (↑b % ↑(pos a)) * 2 ≤ ↑(pos a) * (↑b % ↑(pos a) + ↑(pos a) * (↑b / ↑(pos a)))

Next tactic:
rw [mul_two, mul_add]
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    simp only [gcdAux, cast_pos]
    rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat]
    · rfl
    · rw [← le_to_nat, mod_to_nat]
      exact le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))
    rw [natSize_to_nat, mul_to_nat, Nat.size_le] at h ⊢
    rw [mod_to_nat, mul_comm]
    rw [pow_succ', ← Nat.mod_add_div b (pos a)] at h
    refine' lt_of_mul_lt_mul_right (lt_of_le_of_lt _ h) (Nat.zero_le 2)
    rw [mul_two, mul_add]
    

Proof state:
case a
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : ↑(pos a) * (↑b % ↑(pos a) + ↑(pos a) * (↑b / ↑(pos a))) < 2 ^ n * 2
⊢ ↑(pos a) * (↑b % ↑(pos a)) + ↑(pos a) * (↑b % ↑(pos a)) ≤
    ↑(pos a) * (↑b % ↑(pos a)) + ↑(pos a) * (↑(pos a) * (↑b / ↑(pos a)))

Next tactic:
refine'
      add_le_add_left
        (Nat.mul_le_mul_left _ (le_trans (le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))) _)) _
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    simp only [gcdAux, cast_pos]
    rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat]
    · rfl
    · rw [← le_to_nat, mod_to_nat]
      exact le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))
    rw [natSize_to_nat, mul_to_nat, Nat.size_le] at h ⊢
    rw [mod_to_nat, mul_comm]
    rw [pow_succ', ← Nat.mod_add_div b (pos a)] at h
    refine' lt_of_mul_lt_mul_right (lt_of_le_of_lt _ h) (Nat.zero_le 2)
    rw [mul_two, mul_add]
    refine'
      add_le_add_left
        (Nat.mul_le_mul_left _ (le_trans (le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))) _)) _
    

Proof state:
case a
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : ↑(pos a) * (↑b % ↑(pos a) + ↑(pos a) * (↑b / ↑(pos a))) < 2 ^ n * 2
⊢ ↑a ≤ ↑(pos a) * (↑b / ↑(pos a))

Next tactic:
suffices 1 ≤ _ by simpa using Nat.mul_le_mul_left (pos a) this
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    simp only [gcdAux, cast_pos]
    rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat]
    · rfl
    · rw [← le_to_nat, mod_to_nat]
      exact le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))
    rw [natSize_to_nat, mul_to_nat, Nat.size_le] at h ⊢
    rw [mod_to_nat, mul_comm]
    rw [pow_succ', ← Nat.mod_add_div b (pos a)] at h
    refine' lt_of_mul_lt_mul_right (lt_of_le_of_lt _ h) (Nat.zero_le 2)
    rw [mul_two, mul_add]
    refine'
      add_le_add_left
        (Nat.mul_le_mul_left _ (le_trans (le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))) _)) _
    suffices 1 ≤ _ by 

Proof state:
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : ↑(pos a) * (↑b % ↑(pos a) + ↑(pos a) * (↑b / ↑(pos a))) < 2 ^ n * 2
this : 1 ≤ ?m.1262210
⊢ ↑a ≤ ↑(pos a) * (↑b / ↑(pos a))

Next tactic:
simpa using Nat.mul_le_mul_left (pos a) this
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    simp only [gcdAux, cast_pos]
    rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat]
    · rfl
    · rw [← le_to_nat, mod_to_nat]
      exact le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))
    rw [natSize_to_nat, mul_to_nat, Nat.size_le] at h ⊢
    rw [mod_to_nat, mul_comm]
    rw [pow_succ', ← Nat.mod_add_div b (pos a)] at h
    refine' lt_of_mul_lt_mul_right (lt_of_le_of_lt _ h) (Nat.zero_le 2)
    rw [mul_two, mul_add]
    refine'
      add_le_add_left
        (Nat.mul_le_mul_left _ (le_trans (le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))) _)) _
    suffices 1 ≤ _ by simpa using Nat.mul_le_mul_left (pos a) this
    

Proof state:
case a
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : ↑(pos a) * (↑b % ↑(pos a) + ↑(pos a) * (↑b / ↑(pos a))) < 2 ^ n * 2
⊢ 1 ≤ ↑b / ↑a

Next tactic:
rw [Nat.le_div_iff_mul_le a.cast_pos, one_mul]
theorem gcd_to_nat_aux :
    ∀ {n} {a b : Num}, a ≤ b → (a * b).natSize ≤ n → (gcdAux n a b : ℕ) = Nat.gcd a b
  | 0, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | 0, pos a, 0, ab, _h => (not_lt_of_ge ab).elim rfl
  | 0, pos a, pos b, _ab, h => (not_lt_of_le h).elim <| PosNum.natSize_pos _
  | Nat.succ n, 0, b, _ab, _h => (Nat.gcd_zero_left _).symm
  | Nat.succ n, pos a, b, ab, h => by
    simp only [gcdAux, cast_pos]
    rw [Nat.gcd_rec, gcd_to_nat_aux, mod_to_nat]
    · rfl
    · rw [← le_to_nat, mod_to_nat]
      exact le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))
    rw [natSize_to_nat, mul_to_nat, Nat.size_le] at h ⊢
    rw [mod_to_nat, mul_comm]
    rw [pow_succ', ← Nat.mod_add_div b (pos a)] at h
    refine' lt_of_mul_lt_mul_right (lt_of_le_of_lt _ h) (Nat.zero_le 2)
    rw [mul_two, mul_add]
    refine'
      add_le_add_left
        (Nat.mul_le_mul_left _ (le_trans (le_of_lt (Nat.mod_lt _ (PosNum.cast_pos _))) _)) _
    suffices 1 ≤ _ by simpa using Nat.mul_le_mul_left (pos a) this
    rw [Nat.le_div_iff_mul_le a.cast_pos, one_mul]
    

Proof state:
case a
n : ℕ
a : PosNum
b : Num
ab : pos a ≤ b
h : ↑(pos a) * (↑b % ↑(pos a) + ↑(pos a) * (↑b / ↑(pos a))) < 2 ^ n * 2
⊢ ↑a ≤ ↑b

Next tactic:
exact le_to_nat.2 ab
@[simp]
theorem gcd_to_nat : ∀ a b, (gcd a b : ℕ) = Nat.gcd a b := by
  

Proof state:
⊢ ∀ (a b : Num), ↑(gcd a b) = Nat.gcd ↑a ↑b

Next tactic:
have : ∀ a b : Num, (a * b).natSize ≤ a.natSize + b.natSize := by
    intros
    simp only [natSize_to_nat, cast_mul]
    rw [Nat.size_le, pow_add]
    exact mul_lt_mul'' (Nat.lt_size_self _) (Nat.lt_size_self _) (Nat.zero_le _) (Nat.zero_le _)
@[simp]
theorem gcd_to_nat : ∀ a b, (gcd a b : ℕ) = Nat.gcd a b := by
  have : ∀ a b : Num, (a * b).natSize ≤ a.natSize + b.natSize := by
    

Proof state:
⊢ ∀ (a b : Num), natSize (a * b) ≤ natSize a + natSize b

Next tactic:
intros
@[simp]
theorem gcd_to_nat : ∀ a b, (gcd a b : ℕ) = Nat.gcd a b := by
  have : ∀ a b : Num, (a * b).natSize ≤ a.natSize + b.natSize := by
    intros
    

Proof state:
a✝ b✝ : Num
⊢ natSize (a✝ * b✝) ≤ natSize a✝ + natSize b✝

Next tactic:
simp only [natSize_to_nat, cast_mul]
@[simp]
theorem gcd_to_nat : ∀ a b, (gcd a b : ℕ) = Nat.gcd a b := by
  have : ∀ a b : Num, (a * b).natSize ≤ a.natSize + b.natSize := by
    intros
    simp only [natSize_to_nat, cast_mul]
    

Proof state:
a✝ b✝ : Num
⊢ Nat.size (↑a✝ * ↑b✝) ≤ Nat.size ↑a✝ + Nat.size ↑b✝

Next tactic:
rw [Nat.size_le, pow_add]
@[simp]
theorem gcd_to_nat : ∀ a b, (gcd a b : ℕ) = Nat.gcd a b := by
  have : ∀ a b : Num, (a * b).natSize ≤ a.natSize + b.natSize := by
    intros
    simp only [natSize_to_nat, cast_mul]
    rw [Nat.size_le, pow_add]
    

Proof state:
a✝ b✝ : Num
⊢ ↑a✝ * ↑b✝ < 2 ^ Nat.size ↑a✝ * 2 ^ Nat.size ↑b✝

Next tactic:
exact mul_lt_mul'' (Nat.lt_size_self _) (Nat.lt_size_self _) (Nat.zero_le _) (Nat.zero_le _)
@[simp]
theorem gcd_to_nat : ∀ a b, (gcd a b : ℕ) = Nat.gcd a b := by
  have : ∀ a b : Num, (a * b).natSize ≤ a.natSize + b.natSize := by
    intros
    simp only [natSize_to_nat, cast_mul]
    rw [Nat.size_le, pow_add]
    exact mul_lt_mul'' (Nat.lt_size_self _) (Nat.lt_size_self _) (Nat.zero_le _) (Nat.zero_le _)
  

Proof state:
this : ∀ (a b : Num), natSize (a * b) ≤ natSize a + natSize b
⊢ ∀ (a b : Num), ↑(gcd a b) = Nat.gcd ↑a ↑b

Next tactic:
intros
@[simp]
theorem gcd_to_nat : ∀ a b, (gcd a b : ℕ) = Nat.gcd a b := by
  have : ∀ a b : Num, (a * b).natSize ≤ a.natSize + b.natSize := by
    intros
    simp only [natSize_to_nat, cast_mul]
    rw [Nat.size_le, pow_add]
    exact mul_lt_mul'' (Nat.lt_size_self _) (Nat.lt_size_self _) (Nat.zero_le _) (Nat.zero_le _)
  intros
  

Proof state:
this : ∀ (a b : Num), natSize (a * b) ≤ natSize a + natSize b
a✝ b✝ : Num
⊢ ↑(gcd a✝ b✝) = Nat.gcd ↑a✝ ↑b✝

Next tactic:
unfold gcd
@[simp]
theorem gcd_to_nat : ∀ a b, (gcd a b : ℕ) = Nat.gcd a b := by
  have : ∀ a b : Num, (a * b).natSize ≤ a.natSize + b.natSize := by
    intros
    simp only [natSize_to_nat, cast_mul]
    rw [Nat.size_le, pow_add]
    exact mul_lt_mul'' (Nat.lt_size_self _) (Nat.lt_size_self _) (Nat.zero_le _) (Nat.zero_le _)
  intros
  unfold gcd
  

Proof state:
this : ∀ (a b : Num), natSize (a * b) ≤ natSize a + natSize b
a✝ b✝ : Num
⊢ ↑(if a✝ ≤ b✝ then gcdAux (natSize a✝ + natSize b✝) a✝ b✝ else gcdAux (natSize b✝ + natSize a✝) b✝ a✝) =
    Nat.gcd ↑a✝ ↑b✝

Next tactic:
split_ifs with h
@[simp]
theorem gcd_to_nat : ∀ a b, (gcd a b : ℕ) = Nat.gcd a b := by
  have : ∀ a b : Num, (a * b).natSize ≤ a.natSize + b.natSize := by
    intros
    simp only [natSize_to_nat, cast_mul]
    rw [Nat.size_le, pow_add]
    exact mul_lt_mul'' (Nat.lt_size_self _) (Nat.lt_size_self _) (Nat.zero_le _) (Nat.zero_le _)
  intros
  unfold gcd
  split_ifs with h
  · 

Proof state:
case pos
this : ∀ (a b : Num), natSize (a * b) ≤ natSize a + natSize b
a✝ b✝ : Num
h : a✝ ≤ b✝
⊢ ↑(gcdAux (natSize a✝ + natSize b✝) a✝ b✝) = Nat.gcd ↑a✝ ↑b✝

Next tactic:
exact gcd_to_nat_aux h (this _ _)
@[simp]
theorem gcd_to_nat : ∀ a b, (gcd a b : ℕ) = Nat.gcd a b := by
  have : ∀ a b : Num, (a * b).natSize ≤ a.natSize + b.natSize := by
    intros
    simp only [natSize_to_nat, cast_mul]
    rw [Nat.size_le, pow_add]
    exact mul_lt_mul'' (Nat.lt_size_self _) (Nat.lt_size_self _) (Nat.zero_le _) (Nat.zero_le _)
  intros
  unfold gcd
  split_ifs with h
  · exact gcd_to_nat_aux h (this _ _)
  · 

Proof state:
case neg
this : ∀ (a b : Num), natSize (a * b) ≤ natSize a + natSize b
a✝ b✝ : Num
h : ¬a✝ ≤ b✝
⊢ ↑(gcdAux (natSize b✝ + natSize a✝) b✝ a✝) = Nat.gcd ↑a✝ ↑b✝

Next tactic:
rw [Nat.gcd_comm]
@[simp]
theorem gcd_to_nat : ∀ a b, (gcd a b : ℕ) = Nat.gcd a b := by
  have : ∀ a b : Num, (a * b).natSize ≤ a.natSize + b.natSize := by
    intros
    simp only [natSize_to_nat, cast_mul]
    rw [Nat.size_le, pow_add]
    exact mul_lt_mul'' (Nat.lt_size_self _) (Nat.lt_size_self _) (Nat.zero_le _) (Nat.zero_le _)
  intros
  unfold gcd
  split_ifs with h
  · exact gcd_to_nat_aux h (this _ _)
  · rw [Nat.gcd_comm]
    

Proof state:
case neg
this : ∀ (a b : Num), natSize (a * b) ≤ natSize a + natSize b
a✝ b✝ : Num
h : ¬a✝ ≤ b✝
⊢ ↑(gcdAux (natSize b✝ + natSize a✝) b✝ a✝) = Nat.gcd ↑b✝ ↑a✝

Next tactic:
exact gcd_to_nat_aux (le_of_not_le h) (this _ _)
theorem dvd_iff_mod_eq_zero {m n : Num} : m ∣ n ↔ n % m = 0 := by
  

Proof state:
m n : Num
⊢ m ∣ n ↔ n % m = 0

Next tactic:
rw [← dvd_to_nat, Nat.dvd_iff_mod_eq_zero, ← to_nat_inj, mod_to_nat]
theorem dvd_iff_mod_eq_zero {m n : Num} : m ∣ n ↔ n % m = 0 := by
  rw [← dvd_to_nat, Nat.dvd_iff_mod_eq_zero, ← to_nat_inj, mod_to_nat]; 

Proof state:
m n : Num
⊢ ↑n % ↑m = 0 ↔ ↑n % ↑m = ↑0

Next tactic:
rfl
@[simp]
protected theorem div_zero (n : ZNum) : n / 0 = 0 :=
  show n.div 0 = 0 by 

Proof state:
n : ZNum
⊢ div n 0 = 0

Next tactic:
cases n
@[simp]
protected theorem div_zero (n : ZNum) : n / 0 = 0 :=
  show n.div 0 = 0 by cases n <;> 

Proof state:
case zero
⊢ div zero 0 = 0

Next tactic:
rfl
@[simp]
protected theorem div_zero (n : ZNum) : n / 0 = 0 :=
  show n.div 0 = 0 by cases n <;> 

Proof state:
case pos
a✝ : PosNum
⊢ div (pos a✝) 0 = 0

Next tactic:
rfl
@[simp]
protected theorem div_zero (n : ZNum) : n / 0 = 0 :=
  show n.div 0 = 0 by cases n <;> 

Proof state:
case neg
a✝ : PosNum
⊢ div (neg a✝) 0 = 0

Next tactic:
rfl
@[simp, norm_cast]
theorem div_to_int : ∀ n d, ((n / d : ZNum) : ℤ) = n / d
  | 0, 0 => by 

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

Next tactic:
simp [Int.ediv_zero]
@[simp, norm_cast]
theorem div_to_int : ∀ n d, ((n / d : ZNum) : ℤ) = n / d
  | 0, 0 => by simp [Int.ediv_zero]
  | 0, pos d => (Int.zero_ediv _).symm
  | 0, neg d => (Int.zero_ediv _).symm
  | pos n, 0 => (Int.ediv_zero _).symm
  | neg n, 0 => (Int.ediv_zero _).symm
  | pos n, pos d => (Num.cast_toZNum _).trans <| by 

Proof state:
n d : PosNum
⊢ ↑(PosNum.div' n d) = ↑(pos n) / ↑(pos d)

Next tactic:
rw [← Num.to_nat_to_int]
@[simp, norm_cast]
theorem div_to_int : ∀ n d, ((n / d : ZNum) : ℤ) = n / d
  | 0, 0 => by simp [Int.ediv_zero]
  | 0, pos d => (Int.zero_ediv _).symm
  | 0, neg d => (Int.zero_ediv _).symm
  | pos n, 0 => (Int.ediv_zero _).symm
  | neg n, 0 => (Int.ediv_zero _).symm
  | pos n, pos d => (Num.cast_toZNum _).trans <| by rw [← Num.to_nat_to_int]; 

Proof state:
n d : PosNum
⊢ ↑↑(PosNum.div' n d) = ↑(pos n) / ↑(pos d)

Next tactic:
simp
@[simp, norm_cast]
theorem div_to_int : ∀ n d, ((n / d : ZNum) : ℤ) = n / d
  | 0, 0 => by simp [Int.ediv_zero]
  | 0, pos d => (Int.zero_ediv _).symm
  | 0, neg d => (Int.zero_ediv _).symm
  | pos n, 0 => (Int.ediv_zero _).symm
  | neg n, 0 => (Int.ediv_zero _).symm
  | pos n, pos d => (Num.cast_toZNum _).trans <| by rw [← Num.to_nat_to_int]; simp
  | pos n, neg d => (Num.cast_toZNumNeg _).trans <| by 

Proof state:
n d : PosNum
⊢ -↑(PosNum.div' n d) = ↑(pos n) / ↑(neg d)

Next tactic:
rw [← Num.to_nat_to_int]
@[simp, norm_cast]
theorem div_to_int : ∀ n d, ((n / d : ZNum) : ℤ) = n / d
  | 0, 0 => by simp [Int.ediv_zero]
  | 0, pos d => (Int.zero_ediv _).symm
  | 0, neg d => (Int.zero_ediv _).symm
  | pos n, 0 => (Int.ediv_zero _).symm
  | neg n, 0 => (Int.ediv_zero _).symm
  | pos n, pos d => (Num.cast_toZNum _).trans <| by rw [← Num.to_nat_to_int]; simp
  | pos n, neg d => (Num.cast_toZNumNeg _).trans <| by rw [← Num.to_nat_to_int]; 

Proof state:
n d : PosNum
⊢ -↑↑(PosNum.div' n d) = ↑(pos n) / ↑(neg d)

Next tactic:
simp
@[simp, norm_cast]
theorem div_to_int : ∀ n d, ((n / d : ZNum) : ℤ) = n / d
  | 0, 0 => by simp [Int.ediv_zero]
  | 0, pos d => (Int.zero_ediv _).symm
  | 0, neg d => (Int.zero_ediv _).symm
  | pos n, 0 => (Int.ediv_zero _).symm
  | neg n, 0 => (Int.ediv_zero _).symm
  | pos n, pos d => (Num.cast_toZNum _).trans <| by rw [← Num.to_nat_to_int]; simp
  | pos n, neg d => (Num.cast_toZNumNeg _).trans <| by rw [← Num.to_nat_to_int]; simp
  | neg n, pos d =>
    show -_ = -_ / ↑d by
      

Proof state:
n d : PosNum
⊢ -↑(Num.succ' (PosNum.pred' n / Num.pos d)) = -↑n / ↑d

Next tactic:
rw [n.to_int_eq_succ_pred, d.to_int_eq_succ_pred, ← PosNum.to_nat_to_int, Num.succ'_to_nat,
        Num.div_to_nat]
@[simp, norm_cast]
theorem div_to_int : ∀ n d, ((n / d : ZNum) : ℤ) = n / d
  | 0, 0 => by simp [Int.ediv_zero]
  | 0, pos d => (Int.zero_ediv _).symm
  | 0, neg d => (Int.zero_ediv _).symm
  | pos n, 0 => (Int.ediv_zero _).symm
  | neg n, 0 => (Int.ediv_zero _).symm
  | pos n, pos d => (Num.cast_toZNum _).trans <| by rw [← Num.to_nat_to_int]; simp
  | pos n, neg d => (Num.cast_toZNumNeg _).trans <| by rw [← Num.to_nat_to_int]; simp
  | neg n, pos d =>
    show -_ = -_ / ↑d by
      rw [n.to_int_eq_succ_pred, d.to_int_eq_succ_pred, ← PosNum.to_nat_to_int, Num.succ'_to_nat,
        Num.div_to_nat]
      

Proof state:
n d : PosNum
⊢ -↑(↑(PosNum.pred' n) / ↑(Num.pos d) + 1) = -(↑↑(PosNum.pred' n) + 1) / (↑↑(PosNum.pred' d) + 1)

Next tactic:
change -[n.pred' / ↑d+1] = -[n.pred' / (d.pred' + 1)+1]
@[simp, norm_cast]
theorem div_to_int : ∀ n d, ((n / d : ZNum) : ℤ) = n / d
  | 0, 0 => by simp [Int.ediv_zero]
  | 0, pos d => (Int.zero_ediv _).symm
  | 0, neg d => (Int.zero_ediv _).symm
  | pos n, 0 => (Int.ediv_zero _).symm
  | neg n, 0 => (Int.ediv_zero _).symm
  | pos n, pos d => (Num.cast_toZNum _).trans <| by rw [← Num.to_nat_to_int]; simp
  | pos n, neg d => (Num.cast_toZNumNeg _).trans <| by rw [← Num.to_nat_to_int]; simp
  | neg n, pos d =>
    show -_ = -_ / ↑d by
      rw [n.to_int_eq_succ_pred, d.to_int_eq_succ_pred, ← PosNum.to_nat_to_int, Num.succ'_to_nat,
        Num.div_to_nat]
      change -[n.pred' / ↑d+1] = -[n.pred' / (d.pred' + 1)+1]
      

Proof state:
n d : PosNum
⊢ -[↑(PosNum.pred' n) / ↑d+1] = -[↑(PosNum.pred' n) / (↑(PosNum.pred' d) + 1)+1]

Next tactic:
rw [d.to_nat_eq_succ_pred]