refactor(init/data/nat/gcd): define gcd using eqn compiler

This commit is contained in:
Mario Carneiro 2017-06-22 19:49:02 -04:00 committed by Leonardo de Moura
parent bae50f8ce6
commit c06c62c03e
2 changed files with 20 additions and 25 deletions

View file

@ -6,7 +6,7 @@ Authors: Jeremy Avigad, Leonardo de Moura, Mario Carneiro
Definitions and properties of gcd, lcm, and coprime.
-/
prelude
import init.data.nat.lemmas init.wf
import init.data.nat.lemmas init.meta.well_founded_tactics
open well_founded
@ -14,35 +14,30 @@ namespace nat
/- gcd -/
def gcd.F : Π (y : ), (Π (y' : ), y' < y → nat → nat) → nat → nat
| 0 f x := x
| (succ y) f x := f (x % succ y) (mod_lt _ $ succ_pos _) (succ y)
def gcd : nat → nat → nat
| 0 y := y
| (succ x) y := have y % succ x < succ x, from mod_lt _ $ succ_pos _,
gcd (y % succ x) (succ x)
def gcd (x y : nat) := fix lt_wf gcd.F y x
@[simp] theorem gcd_zero_right (x : nat) : gcd x 0 = x := congr_fun (fix_eq lt_wf gcd.F 0) x
@[simp] theorem gcd_zero_left (x : nat) : gcd 0 x = x := by simp [gcd]
@[simp] theorem gcd_succ (x y : nat) : gcd x (succ y) = gcd (succ y) (x % succ y) :=
congr_fun (fix_eq lt_wf gcd.F (succ y)) x
@[simp] theorem gcd_succ (x y : nat) : gcd (succ x) y = gcd (y % succ x) (succ x) :=
by simp [gcd]
theorem gcd_one_right (n : ) : gcd n 1 = 1 :=
eq.trans (gcd_succ n 0) (by rw [mod_one, gcd_zero_right])
@[simp] theorem gcd_one_left (n : ) : gcd 1 n = 1 := by simp [gcd]
theorem gcd_def (x : ) : Π (y : ), gcd x y = if y = 0 then x else gcd y (x % y)
| 0 := gcd_zero_right _
| (succ y) := (gcd_succ x y).trans (if_neg (succ_ne_zero y)).symm
theorem gcd_def (x y : ) : gcd x y = if x = 0 then y else gcd (y % x) x :=
by cases x; simp [gcd, succ_ne_zero]
theorem gcd_self : Π (n : ), gcd n n = n
| 0 := gcd_zero_right _
| (succ n₁) := (gcd_succ (succ n₁) n₁).trans (by rw [mod_self, gcd_zero_right])
@[simp] theorem gcd_self (n : ) : gcd n n = n :=
by cases n; simp [gcd, mod_self]
theorem gcd_zero_left : Π (n : ), gcd 0 n = n
| 0 := gcd_zero_right _
| (succ n₁) := (gcd_succ 0 n₁).trans (by rw [zero_mod, gcd_zero_right])
@[simp] theorem gcd_zero_right (n : ) : gcd n 0 = n :=
by cases n; simp [gcd]
theorem gcd_rec (m : ) : Π (n : ), gcd m n = gcd n (m % n)
| 0 := by rw [mod_zero, gcd_zero_left, gcd_zero_right]
| (succ n₁) := gcd_succ _ _
theorem gcd_rec (m n : ) : gcd m n = gcd (n % m) m :=
by cases m; simp [gcd]
@[elab_as_eliminator]
theorem gcd.induction {P : → Prop}

View file

@ -884,7 +884,7 @@ nat.strong_induction_on a $ λ n,
lemma mod_def (x y : nat) : x % y = if 0 < y ∧ y ≤ x then (x - y) % y else x :=
by have h := mod_def_aux x y; rwa [dif_eq_if] at h
lemma mod_zero (a : nat) : a % 0 = a :=
@[simp] lemma mod_zero (a : nat) : a % 0 = a :=
begin
rw mod_def,
have h : ¬ (0 < 0 ∧ 0 ≤ a),
@ -951,10 +951,10 @@ by rw [-(zero_add (m*n)), add_mul_mod_self_left, zero_mod]
@[simp] theorem mul_mod_left (m n : ) : (m * n) % n = 0 :=
by rw [mul_comm, mul_mod_right]
theorem mod_self (n : nat) : n % n = 0 :=
@[simp] theorem mod_self (n : nat) : n % n = 0 :=
by rw [mod_eq_sub_mod (le_refl _), nat.sub_self, zero_mod]
lemma mod_one (n : ) : n % 1 = 0 :=
@[simp] lemma mod_one (n : ) : n % 1 = 0 :=
have n % 1 < 1, from (mod_lt n) (succ_pos 0),
eq_zero_of_le_zero (le_of_lt_succ this)