File: .lake/packages/lean4/src/lean/Init/Data/Nat/Gcd.lean

full_name: Nat.gcd
code: /--
Computes the greatest common divisor of two natural numbers.

This reference implementation via the Euclidean algorithm
is overridden in both the kernel and the compiler to efficiently
evaluate using the "bignum" representation (see `Nat`).
The definition provided here is the logical model
(and it is soundness-critical that they coincide).

The GCD of two natural numbers is the largest natural number
that divides both arguments.
In particular, the GCD of a number and `0` is the number itself:
```
example : Nat.gcd 10 15 = 5 := rfl
example : Nat.gcd 0 5 = 5 := rfl
example : Nat.gcd 7 0 = 7 := rfl
```
-/
@[extern "lean_nat_gcd"]
def gcd (m n : @& Nat) : Nat 
goal: Nat

full_name: Nat.gcd_zero_left
code: @[simp] theorem gcd_zero_left (y : Nat) : gcd 0 y = y 
goal: Nat.gcd 0 y = y

full_name: Nat.gcd_succ
code: theorem gcd_succ (x y : Nat) : gcd (succ x) y = gcd (y % succ x) (succ x) 
goal: x.succ.gcd y = (y % x.succ).gcd x.succ

full_name: Nat.gcd_add_one
code: theorem gcd_add_one (x y : Nat) : gcd (x + 1) y = gcd (y % (x + 1)) (x + 1) 
goal: (x + 1).gcd y = (y % (x + 1)).gcd (x + 1)

full_name: Nat.gcd_one_left
code: @[simp] theorem gcd_one_left (n : Nat) : gcd 1 n = 1 
goal: Nat.gcd 1 n = 1

full_name: Nat.gcd_zero_right
code: @[simp] theorem gcd_zero_right (n : Nat) : gcd n 0 = n 
goal: n.gcd 0 = n

full_name: Nat.instLawfulIdentityGcdOfNat
code: instance : Std.LawfulIdentity gcd 0 
goal: Std.LawfulIdentity Nat.gcd 0

full_name: Nat.gcd_self
code: @[simp] theorem gcd_self (n : Nat) : gcd n n = n 
goal: n.gcd n = n

full_name: Nat.instIdempotentOpGcd
code: instance : Std.IdempotentOp gcd 
goal: Std.IdempotentOp Nat.gcd

full_name: Nat.gcd_rec
code: theorem gcd_rec (m n : Nat) : gcd m n = gcd (n % m) m 
goal: m.gcd n = (n % m).gcd m

full_name: Nat.gcd.induction
code: @[elab_as_elim] theorem gcd.induction {P : Nat → Nat → Prop} (m n : Nat)
    (H0 : ∀n, P 0 n) (H1 : ∀ m n, 0 < m → P (n % m) m → P m n) : P m n 
goal: P m n

full_name: Nat.gcd_dvd
code: theorem gcd_dvd (m n : Nat) : (gcd m n ∣ m) ∧ (gcd m n ∣ n) 
goal: m.gcd n ∣ m ∧ m.gcd n ∣ n

full_name: Nat.gcd_dvd_left
code: theorem gcd_dvd_left (m n : Nat) : gcd m n ∣ m 
goal: m.gcd n ∣ m

full_name: Nat.gcd_dvd_right
code: theorem gcd_dvd_right (m n : Nat) : gcd m n ∣ n 
goal: m.gcd n ∣ n

full_name: Nat.gcd_le_left
code: theorem gcd_le_left (n) (h : 0 < m) : gcd m n ≤ m 
goal: m.gcd n ≤ m

full_name: Nat.gcd_le_right
code: theorem gcd_le_right (n) (h : 0 < n) : gcd m n ≤ n 
goal: m.gcd n ≤ n

full_name: Nat.dvd_gcd
code: theorem dvd_gcd : k ∣ m → k ∣ n → k ∣ gcd m n 
goal: k ∣ m → k ∣ n → k ∣ m.gcd n

full_name: Nat.dvd_gcd_iff
code: theorem dvd_gcd_iff : k ∣ gcd m n ↔ k ∣ m ∧ k ∣ n 
goal: k ∣ m.gcd n ↔ k ∣ m ∧ k ∣ n

full_name: Nat.gcd_comm
code: theorem gcd_comm (m n : Nat) : gcd m n = gcd n m 
goal: m.gcd n = n.gcd m

full_name: Nat.instCommutativeGcd
code: instance : Std.Commutative gcd 
goal: Std.Commutative Nat.gcd

full_name: Nat.gcd_eq_left_iff_dvd
code: theorem gcd_eq_left_iff_dvd : m ∣ n ↔ gcd m n = m 
goal: m ∣ n ↔ m.gcd n = m

full_name: Nat.gcd_eq_right_iff_dvd
code: theorem gcd_eq_right_iff_dvd : m ∣ n ↔ gcd n m = m 
goal: m ∣ n ↔ n.gcd m = m

full_name: Nat.gcd_assoc
code: theorem gcd_assoc (m n k : Nat) : gcd (gcd m n) k = gcd m (gcd n k) 
goal: (m.gcd n).gcd k = m.gcd (n.gcd k)

full_name: Nat.gcd_one_right
code: @[simp] theorem gcd_one_right (n : Nat) : gcd n 1 = 1 
goal: n.gcd 1 = 1

full_name: Nat.gcd_mul_left
code: theorem gcd_mul_left (m n k : Nat) : gcd (m * n) (m * k) = m * gcd n k 
goal: (m * n).gcd (m * k) = m * n.gcd k

full_name: Nat.gcd_mul_right
code: theorem gcd_mul_right (m n k : Nat) : gcd (m * n) (k * n) = gcd m k * n 
goal: (m * n).gcd (k * n) = m.gcd k * n

full_name: Nat.gcd_pos_of_pos_left
code: theorem gcd_pos_of_pos_left {m : Nat} (n : Nat) (mpos : 0 < m) : 0 < gcd m n 
goal: 0 < m.gcd n

full_name: Nat.gcd_pos_of_pos_right
code: theorem gcd_pos_of_pos_right (m : Nat) {n : Nat} (npos : 0 < n) : 0 < gcd m n 
goal: 0 < m.gcd n

full_name: Nat.div_gcd_pos_of_pos_left
code: theorem div_gcd_pos_of_pos_left (b : Nat) (h : 0 < a) : 0 < a / a.gcd b 
goal: 0 < a / a.gcd b

full_name: Nat.div_gcd_pos_of_pos_right
code: theorem div_gcd_pos_of_pos_right (a : Nat) (h : 0 < b) : 0 < b / a.gcd b 
goal: 0 < b / a.gcd b

full_name: Nat.eq_zero_of_gcd_eq_zero_left
code: theorem eq_zero_of_gcd_eq_zero_left {m n : Nat} (H : gcd m n = 0) : m = 0 
goal: m = 0

full_name: Nat.eq_zero_of_gcd_eq_zero_right
code: theorem eq_zero_of_gcd_eq_zero_right {m n : Nat} (H : gcd m n = 0) : n = 0 
goal: n = 0

full_name: Nat.gcd_ne_zero_left
code: theorem gcd_ne_zero_left : m ≠ 0 → gcd m n ≠ 0 
goal: m ≠ 0 → m.gcd n ≠ 0

full_name: Nat.gcd_ne_zero_right
code: theorem gcd_ne_zero_right : n ≠ 0 → gcd m n ≠ 0 
goal: n ≠ 0 → m.gcd n ≠ 0

full_name: Nat.gcd_div
code: theorem gcd_div {m n k : Nat} (H1 : k ∣ m) (H2 : k ∣ n) :
    gcd (m / k) (n / k) = gcd m n / k 
goal: (m / k).gcd (n / k) = m.gcd n / k

full_name: Nat.gcd_dvd_gcd_of_dvd_left
code: theorem gcd_dvd_gcd_of_dvd_left {m k : Nat} (n : Nat) (H : m ∣ k) : gcd m n ∣ gcd k n 
goal: m.gcd n ∣ k.gcd n

full_name: Nat.gcd_dvd_gcd_of_dvd_right
code: theorem gcd_dvd_gcd_of_dvd_right {m k : Nat} (n : Nat) (H : m ∣ k) : gcd n m ∣ gcd n k 
goal: n.gcd m ∣ n.gcd k

full_name: Nat.gcd_dvd_gcd_mul_left
code: theorem gcd_dvd_gcd_mul_left (m n k : Nat) : gcd m n ∣ gcd (k * m) n 
goal: m.gcd n ∣ (k * m).gcd n

full_name: Nat.gcd_dvd_gcd_mul_right
code: theorem gcd_dvd_gcd_mul_right (m n k : Nat) : gcd m n ∣ gcd (m * k) n 
goal: m.gcd n ∣ (m * k).gcd n

full_name: Nat.gcd_dvd_gcd_mul_left_right
code: theorem gcd_dvd_gcd_mul_left_right (m n k : Nat) : gcd m n ∣ gcd m (k * n) 
goal: m.gcd n ∣ m.gcd (k * n)

full_name: Nat.gcd_dvd_gcd_mul_right_right
code: theorem gcd_dvd_gcd_mul_right_right (m n k : Nat) : gcd m n ∣ gcd m (n * k) 
goal: m.gcd n ∣ m.gcd (n * k)

full_name: Nat.gcd_eq_left
code: theorem gcd_eq_left {m n : Nat} (H : m ∣ n) : gcd m n = m 
goal: m.gcd n = m

full_name: Nat.gcd_eq_right
code: theorem gcd_eq_right {m n : Nat} (H : n ∣ m) : gcd m n = n 
goal: m.gcd n = n

full_name: Nat.gcd_mul_left_left
code: @[simp] theorem gcd_mul_left_left (m n : Nat) : gcd (m * n) n = n 
goal: (m * n).gcd n = n

full_name: Nat.gcd_mul_left_right
code: @[simp] theorem gcd_mul_left_right (m n : Nat) : gcd n (m * n) = n 
goal: n.gcd (m * n) = n

full_name: Nat.gcd_mul_right_left
code: @[simp] theorem gcd_mul_right_left (m n : Nat) : gcd (n * m) n = n 
goal: (n * m).gcd n = n

full_name: Nat.gcd_mul_right_right
code: @[simp] theorem gcd_mul_right_right (m n : Nat) : gcd n (n * m) = n 
goal: n.gcd (n * m) = n

full_name: Nat.gcd_gcd_self_right_left
code: @[simp] theorem gcd_gcd_self_right_left (m n : Nat) : gcd m (gcd m n) = gcd m n 
goal: m.gcd (m.gcd n) = m.gcd n

full_name: Nat.gcd_gcd_self_right_right
code: @[simp] theorem gcd_gcd_self_right_right (m n : Nat) : gcd m (gcd n m) = gcd n m 
goal: m.gcd (n.gcd m) = n.gcd m

full_name: Nat.gcd_gcd_self_left_right
code: @[simp] theorem gcd_gcd_self_left_right (m n : Nat) : gcd (gcd n m) m = gcd n m 
goal: (n.gcd m).gcd m = n.gcd m

full_name: Nat.gcd_gcd_self_left_left
code: @[simp] theorem gcd_gcd_self_left_left (m n : Nat) : gcd (gcd m n) m = gcd m n 
goal: (m.gcd n).gcd m = m.gcd n

full_name: Nat.gcd_add_mul_self
code: theorem gcd_add_mul_self (m n k : Nat) : gcd m (n + k * m) = gcd m n 
goal: m.gcd (n + k * m) = m.gcd n

full_name: Nat.gcd_eq_zero_iff
code: theorem gcd_eq_zero_iff {i j : Nat} : gcd i j = 0 ↔ i = 0 ∧ j = 0 
goal: i.gcd j = 0 ↔ i = 0 ∧ j = 0

full_name: Nat.gcd_eq_iff
code: /-- Characterization of the value of `Nat.gcd`. -/
theorem gcd_eq_iff (a b : Nat) :
    gcd a b = g ↔ g ∣ a ∧ g ∣ b ∧ (∀ c, c ∣ a → c ∣ b → c ∣ g) 
goal: a.gcd b = g ↔ g ∣ a ∧ g ∣ b ∧ ∀ (c : Nat), c ∣ a → c ∣ b → c ∣ g

full_name: Nat.prod_dvd_and_dvd_of_dvd_prod
code: /-- Represent a divisor of `m * n` as a product of a divisor of `m` and a divisor of `n`. -/
def prod_dvd_and_dvd_of_dvd_prod {k m n : Nat} (H : k ∣ m * n) :
    {d : {m' // m' ∣ m} × {n' // n' ∣ n} // k = d.1.val * d.2.val} 
goal: { d // k = d.fst.val * d.snd.val }

full_name: Nat.gcd_mul_dvd_mul_gcd
code: theorem gcd_mul_dvd_mul_gcd (k m n : Nat) : gcd k (m * n) ∣ gcd k m * gcd k n 
goal: k.gcd (m * n) ∣ k.gcd m * k.gcd n