refactor(library): test simp and msimp in the standard library

This commit is contained in:
Leonardo de Moura 2015-12-30 11:22:58 -08:00
parent 251b53c669
commit dc6a3e30c0
8 changed files with 115 additions and 169 deletions

View file

@ -25,97 +25,86 @@ section division_ring
definition division_ring_has_div [reducible] [instance] : has_div A :=
has_div.mk algebra.div
lemma division.def (a b : A) : a / b = a * b⁻¹ :=
lemma division.def [simp] (a b : A) : a / b = a * b⁻¹ :=
rfl
theorem mul_inv_cancel (H : a ≠ 0) : a * a⁻¹ = 1 :=
theorem mul_inv_cancel [simp] (H : a ≠ 0) : a * a⁻¹ = 1 :=
division_ring.mul_inv_cancel H
theorem inv_mul_cancel (H : a ≠ 0) : a⁻¹ * a = 1 :=
theorem inv_mul_cancel [simp] (H : a ≠ 0) : a⁻¹ * a = 1 :=
division_ring.inv_mul_cancel H
theorem inv_eq_one_div (a : A) : a⁻¹ = 1 / a := !one_mul⁻¹
theorem div_eq_mul_one_div (a b : A) : a / b = a * (1 / b) :=
by rewrite [*division.def, one_mul]
by simp
theorem mul_one_div_cancel (H : a ≠ 0) : a * (1 / a) = 1 :=
by rewrite [-inv_eq_one_div, (mul_inv_cancel H)]
theorem mul_one_div_cancel [simp] (H : a ≠ 0) : a * (1 / a) = 1 :=
by simp
theorem one_div_mul_cancel (H : a ≠ 0) : (1 / a) * a = 1 :=
by rewrite [-inv_eq_one_div, (inv_mul_cancel H)]
theorem one_div_mul_cancel [simp] (H : a ≠ 0) : (1 / a) * a = 1 :=
by simp
theorem div_self (H : a ≠ 0) : a / a = 1 := mul_inv_cancel H
theorem div_self [simp] (H : a ≠ 0) : a / a = 1 :=
by simp
theorem one_div_one : 1 / 1 = (1:A) := div_self (ne.symm zero_ne_one)
theorem one_div_one [simp] : 1 / 1 = (1:A) :=
div_self (ne.symm zero_ne_one)
theorem mul_div_assoc (a b : A) : (a * b) / c = a * (b / c) := !mul.assoc
theorem mul_div_assoc (a b : A) : (a * b) / c = a * (b / c) :=
by simp
theorem one_div_ne_zero (H : a ≠ 0) : 1 / a ≠ 0 :=
assume H2 : 1 / a = 0,
have C1 : 0 = (1:A), from symm (by rewrite [-(mul_one_div_cancel H), H2, mul_zero]),
absurd C1 zero_ne_one
theorem one_inv_eq : 1⁻¹ = (1:A) :=
theorem one_inv_eq [simp] : 1⁻¹ = (1:A) :=
by rewrite [-mul_one, inv_mul_cancel (ne.symm (@zero_ne_one A _))]
theorem div_one (a : A) : a / 1 = a :=
by rewrite [*division.def, one_inv_eq, mul_one]
theorem div_one [simp] (a : A) : a / 1 = a :=
by simp
theorem zero_div (a : A) : 0 / a = 0 := !zero_mul
theorem zero_div [simp] (a : A) : 0 / a = 0 :=
by simp
-- note: integral domain has a "mul_ne_zero". A commutative division ring is an integral
-- domain, but let's not define that class for now.
theorem division_ring.mul_ne_zero (Ha : a ≠ 0) (Hb : b ≠ 0) : a * b ≠ 0 :=
assume H : a * b = 0,
have C1 : a = 0, by rewrite [-mul_one, -(mul_one_div_cancel Hb), -mul.assoc, H, zero_mul],
absurd C1 Ha
assume H : a * b = 0,
have C1 : a = 0, by rewrite [-mul_one, -(mul_one_div_cancel Hb), -mul.assoc, H, zero_mul],
absurd C1 Ha
theorem mul_ne_zero_comm (H : a * b ≠ 0) : b * a ≠ 0 :=
have H2 : a ≠ 0 ∧ b ≠ 0, from ne_zero_and_ne_zero_of_mul_ne_zero H,
division_ring.mul_ne_zero (and.right H2) (and.left H2)
have H2 : a ≠ 0 ∧ b ≠ 0, from ne_zero_and_ne_zero_of_mul_ne_zero H,
division_ring.mul_ne_zero (and.right H2) (and.left H2)
theorem eq_one_div_of_mul_eq_one (H : a * b = 1) : b = 1 / a :=
have a ≠ 0, from
(suppose a = 0,
have 0 = (1:A), by rewrite [-(zero_mul b), -this, H],
absurd this zero_ne_one),
show b = 1 / a, from symm (calc
1 / a = (1 / a) * 1 : mul_one
... = (1 / a) * (a * b) : H
... = (1 / a) * a * b : mul.assoc
... = 1 * b : one_div_mul_cancel this
... = b : one_mul)
assert a ≠ 0, from
suppose a = 0,
have 0 = (1:A), by msimp,
absurd this zero_ne_one,
by msimp
theorem eq_one_div_of_mul_eq_one_left (H : b * a = 1) : b = 1 / a :=
have a ≠ 0, from
(suppose a = 0,
have 0 = 1, from symm (calc
1 = b * a : symm H
... = b * 0 : this
... = 0 : mul_zero),
absurd this zero_ne_one),
show b = 1 / a, from symm (calc
1 / a = 1 * (1 / a) : one_mul
... = b * a * (1 / a) : H
... = b * (a * (1 / a)) : mul.assoc
... = b * 1 : mul_one_div_cancel this
... = b : mul_one)
assert a ≠ 0, from
suppose a = 0,
have 0 = (1:A), by msimp,
absurd this zero_ne_one,
by msimp
theorem division_ring.one_div_mul_one_div (Ha : a ≠ 0) (Hb : b ≠ 0) :
(1 / a) * (1 / b) = 1 / (b * a) :=
have (b * a) * ((1 / a) * (1 / b)) = 1, by
rewrite [mul.assoc, -(mul.assoc a), (mul_one_div_cancel Ha), one_mul,
(mul_one_div_cancel Hb)],
eq_one_div_of_mul_eq_one this
have (b * a) * ((1 / a) * (1 / b)) = 1, by msimp,
eq_one_div_of_mul_eq_one this
theorem one_div_neg_one_eq_neg_one : (1:A) / (-1) = -1 :=
have (-1) * (-1) = (1:A), by rewrite [-neg_eq_neg_one_mul, neg_neg],
symm (eq_one_div_of_mul_eq_one this)
have (-1) * (-1) = (1:A), by msimp,
symm (eq_one_div_of_mul_eq_one this)
theorem division_ring.one_div_neg_eq_neg_one_div (H : a ≠ 0) : 1 / (- a) = - (1 / a) :=
have -1 ≠ 0, from
(suppose -1 = 0, absurd (symm (calc
have -1 ≠ 0, from
(suppose -1 = 0, absurd (symm (calc
1 = -(-1) : neg_neg
... = -0 : this
... = (0:A) : neg_zero)) zero_ne_one),
@ -145,23 +134,22 @@ section division_ring
a = b :=
by rewrite [-(division_ring.one_div_one_div Ha), H, (division_ring.one_div_one_div Hb)]
theorem mul_inv_eq (Ha : a ≠ 0) (Hb : b ≠ 0) : (b * a)⁻¹ = a⁻¹ * b⁻¹ :=
theorem mul_inv_eq [simp] (Ha : a ≠ 0) (Hb : b ≠ 0) : (b * a)⁻¹ = a⁻¹ * b⁻¹ :=
eq.symm (calc
a⁻¹ * b⁻¹ = (1 / a) * b⁻¹ : inv_eq_one_div
... = (1 / a) * (1 / b) : inv_eq_one_div
... = (1 / (b * a)) : division_ring.one_div_mul_one_div Ha Hb
... = (b * a)⁻¹ : inv_eq_one_div)
a⁻¹ * b⁻¹ = (1 / a) * (1 / b) : by msimp
... = (1 / (b * a)) : division_ring.one_div_mul_one_div Ha Hb
... = (b * a)⁻¹ : by simp)
theorem mul_div_cancel (a : A) {b : A} (Hb : b ≠ 0) : a * b / b = a :=
by rewrite [*division.def, mul.assoc, (mul_inv_cancel Hb), mul_one]
by simp
theorem div_mul_cancel (a : A) {b : A} (Hb : b ≠ 0) : a / b * b = a :=
by rewrite [*division.def, mul.assoc, (inv_mul_cancel Hb), mul_one]
by simp
theorem div_add_div_same (a b c : A) : a / c + b / c = (a + b) / c := !right_distrib⁻¹
theorem div_sub_div_same (a b c : A) : (a / c) - (b / c) = (a - b) / c :=
by rewrite [sub_eq_add_neg, -neg_div, div_add_div_same]
by rewrite [sub_eq_add_neg, -neg_div, div_add_div_same]
theorem one_div_mul_add_mul_one_div_eq_one_div_add_one_div (Ha : a ≠ 0) (Hb : b ≠ 0) :
(1 / a) * (a + b) * (1 / b) = 1 / a + 1 / b :=
@ -175,13 +163,11 @@ section division_ring
theorem div_eq_one_iff_eq (a : A) {b : A} (Hb : b ≠ 0) : a / b = 1 ↔ a = b :=
iff.intro
(suppose a / b = 1, symm (calc
b = 1 * b : one_mul
... = a / b * b : this
... = a : div_mul_cancel _ Hb))
(suppose a = b, calc
a / b = b / b : this
... = 1 : div_self Hb)
(suppose a / b = 1, calc
a = a / b * b : by msimp
... = 1 * b : this
... = b : by simp)
(suppose a = b, by simp)
theorem eq_of_div_eq_one (a : A) {b : A} (Hb : b ≠ 0) : a / b = 1 → a = b :=
iff.mp (!div_eq_one_iff_eq Hb)
@ -202,10 +188,7 @@ section division_ring
(iff.elim_right (!eq_div_iff_mul_eq Hc)) this
theorem mul_mul_div (a : A) {c : A} (Hc : c ≠ 0) : a = a * c * (1 / c) :=
calc
a = a * 1 : mul_one
... = a * (c * (1 / c)) : mul_one_div_cancel Hc
... = a * c * (1 / c) : mul.assoc
by simp
-- There are many similar rules to these last two in the Isabelle library
-- that haven't been ported yet. Do as necessary.
@ -221,15 +204,11 @@ section field
by rewrite [(division_ring.one_div_mul_one_div Ha Hb), mul.comm b]
theorem field.div_mul_right (Hb : b ≠ 0) (H : a * b ≠ 0) : a / (a * b) = 1 / b :=
have a ≠ 0, from and.left (ne_zero_and_ne_zero_of_mul_ne_zero H),
assert a ≠ 0, from and.left (ne_zero_and_ne_zero_of_mul_ne_zero H),
symm (calc
1 / b = 1 * (1 / b) : one_mul
... = (a * a⁻¹) * (1 / b) : mul_inv_cancel this
... = a * (a⁻¹ * (1 / b)) : mul.assoc
... = a * ((1 / a) * (1 / b)) : inv_eq_one_div
1 / b = a * ((1 / a) * (1 / b)) : by msimp
... = a * (1 / (b * a)) : division_ring.one_div_mul_one_div this Hb
... = a * (1 / (a * b)) : mul.comm
... = a * (a * b)⁻¹ : inv_eq_one_div)
... = a * (a * b)⁻¹ : by msimp)
theorem field.div_mul_left (Ha : a ≠ 0) (H : a * b ≠ 0) : b / (a * b) = 1 / a :=
let H1 : b * a ≠ 0 := mul_ne_zero_comm H in
@ -248,7 +227,7 @@ section field
theorem field.div_mul_div (a : A) {b : A} (c : A) {d : A} (Hb : b ≠ 0) (Hd : d ≠ 0) :
(a / b) * (c / d) = (a * c) / (b * d) :=
by rewrite [*division.def, 2 mul.assoc, (mul.comm b⁻¹), mul.assoc, (mul_inv_eq Hd Hb)]
by msimp
theorem mul_div_mul_left (a : A) {b c : A} (Hb : b ≠ 0) (Hc : c ≠ 0) :
(c * a) / (c * b) = a / b :=

View file

@ -14,10 +14,10 @@ namespace bool
theorem dichotomy (b : bool) : b = ff b = tt :=
bool.cases_on b (or.inl rfl) (or.inr rfl)
theorem cond_ff {A : Type} (t e : A) : cond ff t e = e :=
theorem cond_ff [simp] {A : Type} (t e : A) : cond ff t e = e :=
rfl
theorem cond_tt {A : Type} (t e : A) : cond tt t e = t :=
theorem cond_tt [simp] {A : Type} (t e : A) : cond tt t e = t :=
rfl
theorem eq_tt_of_ne_ff : ∀ {a : bool}, a ≠ ff → a = tt
@ -31,27 +31,27 @@ namespace bool
theorem absurd_of_eq_ff_of_eq_tt {B : Prop} {a : bool} (H₁ : a = ff) (H₂ : a = tt) : B :=
absurd (H₁⁻¹ ⬝ H₂) ff_ne_tt
theorem tt_bor (a : bool) : bor tt a = tt :=
theorem tt_bor [simp] (a : bool) : bor tt a = tt :=
rfl
notation a || b := bor a b
theorem bor_tt (a : bool) : a || tt = tt :=
theorem bor_tt [simp] (a : bool) : a || tt = tt :=
bool.cases_on a rfl rfl
theorem ff_bor (a : bool) : ff || a = a :=
theorem ff_bor [simp] (a : bool) : ff || a = a :=
bool.cases_on a rfl rfl
theorem bor_ff (a : bool) : a || ff = a :=
theorem bor_ff [simp] (a : bool) : a || ff = a :=
bool.cases_on a rfl rfl
theorem bor_self (a : bool) : a || a = a :=
theorem bor_self [simp] (a : bool) : a || a = a :=
bool.cases_on a rfl rfl
theorem bor.comm (a b : bool) : a || b = b || a :=
theorem bor.comm [simp] (a b : bool) : a || b = b || a :=
by cases a; repeat (cases b | reflexivity)
theorem bor.assoc (a b c : bool) : (a || b) || c = a || (b || c) :=
theorem bor.assoc [simp] (a b c : bool) : (a || b) || c = a || (b || c) :=
match a with
| ff := by rewrite *ff_bor
| tt := by rewrite *tt_bor
@ -71,27 +71,27 @@ namespace bool
theorem bor_inr {a b : bool} (H : b = tt) : a || b = tt :=
bool.rec_on a (by rewrite H) (by rewrite H)
theorem ff_band (a : bool) : ff && a = ff :=
theorem ff_band [simp] (a : bool) : ff && a = ff :=
rfl
theorem tt_band (a : bool) : tt && a = a :=
theorem tt_band [simp] (a : bool) : tt && a = a :=
bool.cases_on a rfl rfl
theorem band_ff (a : bool) : a && ff = ff :=
theorem band_ff [simp] (a : bool) : a && ff = ff :=
bool.cases_on a rfl rfl
theorem band_tt (a : bool) : a && tt = a :=
theorem band_tt [simp] (a : bool) : a && tt = a :=
bool.cases_on a rfl rfl
theorem band_self (a : bool) : a && a = a :=
theorem band_self [simp] (a : bool) : a && a = a :=
bool.cases_on a rfl rfl
theorem band.comm (a b : bool) : a && b = b && a :=
theorem band.comm [simp] (a b : bool) : a && b = b && a :=
bool.cases_on a
(bool.cases_on b rfl rfl)
(bool.cases_on b rfl rfl)
theorem band.assoc (a b c : bool) : (a && b) && c = a && (b && c) :=
theorem band.assoc [simp] (a b c : bool) : (a && b) && c = a && (b && c) :=
match a with
| ff := by rewrite *ff_band
| tt := by rewrite *tt_band
@ -100,11 +100,7 @@ namespace bool
theorem band_elim_left {a b : bool} (H : a && b = tt) : a = tt :=
or.elim (dichotomy a)
(suppose a = ff,
absurd
(calc ff = ff && b : ff_band
... = a && b : this
... = tt : H)
ff_ne_tt)
absurd (by msimp) ff_ne_tt)
(suppose a = tt, this)
theorem band_intro {a b : bool} (H₁ : a = tt) (H₂ : b = tt) : a && b = tt :=
@ -113,13 +109,13 @@ namespace bool
theorem band_elim_right {a b : bool} (H : a && b = tt) : b = tt :=
band_elim_left (!band.comm ⬝ H)
theorem bnot_bnot (a : bool) : bnot (bnot a) = a :=
theorem bnot_bnot [simp] (a : bool) : bnot (bnot a) = a :=
bool.cases_on a rfl rfl
theorem bnot_false : bnot ff = tt :=
theorem bnot_false [simp] : bnot ff = tt :=
rfl
theorem bnot_true : bnot tt = ff :=
theorem bnot_true [simp] : bnot tt = ff :=
rfl
theorem eq_tt_of_bnot_eq_ff {a : bool} : bnot a = ff → a = tt :=

View file

@ -141,24 +141,14 @@ protected theorem add_right_comm : Π (n m k : ), n + m + k = n + k + m :=
right_comm nat.add_comm nat.add_assoc
protected theorem add_left_cancel {n m k : } : n + m = n + k → m = k :=
nat.induction_on n (by simp)
(take (n : ) (IH : n + m = n + k → m = k) (H : succ n + m = succ n + k),
have succ (n + m) = succ (n + k), by simp,
have n + m = n + k, from succ.inj this,
IH this)
nat.induction_on n (by simp) (by msimp)
protected theorem add_right_cancel {n m k : } (H : n + m = k + m) : n = k :=
have H2 : m + n = m + k, by simp,
nat.add_left_cancel H2
theorem eq_zero_of_add_eq_zero_right {n m : } : n + m = 0 → n = 0 :=
nat.induction_on n
(by simp)
(take k IH,
assume H : succ k + m = 0,
absurd
(show succ (k + m) = 0, by simp)
!succ_ne_zero)
nat.induction_on n (by simp) (by msimp)
theorem eq_zero_of_add_eq_zero_left {n m : } (H : n + m = 0) : m = 0 :=
eq_zero_of_add_eq_zero_right (!nat.add_comm ⬝ H)
@ -229,11 +219,9 @@ nat.cases_on n (by simp)
(take n',
nat.cases_on m
(by simp)
(take m', assume H : succ n' * succ m' = 0,
(take m', assume H,
absurd
(calc
0 = succ n' * succ m' : by simp
... = succ (succ n' * m' + n') : by simp)⁻¹
(show succ (succ n' * m' + n') = 0, by simp)
!succ_ne_zero))
protected definition comm_semiring [reducible] [trans_instance] : comm_semiring nat :=

View file

@ -27,13 +27,13 @@ has_div.mk nat.div
theorem div_def (x y : nat) : div x y = if 0 < y ∧ y ≤ x then div (x - y) y + 1 else 0 :=
congr_fun (fix_eq div.F x) y
protected theorem div_zero (a : ) : a / 0 = 0 :=
protected theorem div_zero [simp] (a : ) : a / 0 = 0 :=
div_def a 0 ⬝ if_neg (!not_and_of_not_left (lt.irrefl 0))
theorem div_eq_zero_of_lt {a b : } (h : a < b) : a / b = 0 :=
div_def a b ⬝ if_neg (!not_and_of_not_right (not_le_of_gt h))
protected theorem zero_div (b : ) : 0 / b = 0 :=
protected theorem zero_div [simp] (b : ) : 0 / b = 0 :=
div_def 0 b ⬝ if_neg (and.rec not_le_of_gt)
theorem div_eq_succ_sub_div {a b : } (h₁ : b > 0) (h₂ : a ≥ b) : a / b = succ ((a - b) / b) :=
@ -48,27 +48,25 @@ calc
theorem add_div_self_left {x : } (z : ) (H : x > 0) : (x + z) / x = succ (z / x) :=
!add.comm ▸ !add_div_self H
local attribute succ_mul [simp]
theorem add_mul_div_self {x y z : } (H : z > 0) : (x + y * z) / z = x / z + y :=
nat.induction_on y
(calc (x + 0 * z) / z = (x + 0) / z : zero_mul
... = x / z : add_zero
... = x / z + 0 : add_zero)
(by simp)
(take y,
assume IH : (x + y * z) / z = x / z + y, calc
(x + succ y * z) / z = (x + (y * z + z)) / z : succ_mul
... = (x + y * z + z) / z : add.assoc
... = succ ((x + y * z) / z) : !add_div_self H
... = succ (x / z + y) : IH)
(x + succ y * z) / z = (x + y * z + z) / z : by msimp
... = succ ((x + y * z) / z) : !add_div_self H
... = succ (x / z + y) : IH)
theorem add_mul_div_self_left (x z : ) {y : } (H : y > 0) : (x + y * z) / y = x / y + z :=
!mul.comm ▸ add_mul_div_self H
protected theorem mul_div_cancel (m : ) {n : } (H : n > 0) : m * n / n = m :=
calc
m * n / n = (0 + m * n) / n : zero_add
m * n / n = (0 + m * n) / n : by simp
... = 0 / n + m : add_mul_div_self H
... = 0 + m : nat.zero_div
... = m : zero_add
... = m : by simp
protected theorem mul_div_cancel_left {m : } (n : ) (H : m > 0) : m * n / m = n :=
!mul.comm ▸ !nat.mul_div_cancel H
@ -88,19 +86,19 @@ notation [priority nat.prio] a ≡ b `[mod `:0 c:0 `]` := a % c = b % c
theorem mod_def (x y : nat) : mod x y = if 0 < y ∧ y ≤ x then mod (x - y) y else x :=
congr_fun (fix_eq mod.F x) y
theorem mod_zero (a : ) : a % 0 = a :=
theorem mod_zero [simp] (a : ) : a % 0 = a :=
mod_def a 0 ⬝ if_neg (!not_and_of_not_left (lt.irrefl 0))
theorem mod_eq_of_lt {a b : } (h : a < b) : a % b = a :=
mod_def a b ⬝ if_neg (!not_and_of_not_right (not_le_of_gt h))
theorem zero_mod (b : ) : 0 % b = 0 :=
theorem zero_mod [simp] (b : ) : 0 % b = 0 :=
mod_def 0 b ⬝ if_neg (λ h, and.rec_on h (λ l r, absurd (lt_of_lt_of_le l r) (lt.irrefl 0)))
theorem mod_eq_sub_mod {a b : } (h₁ : b > 0) (h₂ : a ≥ b) : a % b = (a - b) % b :=
mod_def a b ⬝ if_pos (and.intro h₁ h₂)
theorem add_mod_self (x z : ) : (x + z) % z = x % z :=
theorem add_mod_self [simp] (x z : ) : (x + z) % z = x % z :=
by_cases_zero_pos z
(by rewrite add_zero)
(take z, assume H : z > 0,
@ -109,29 +107,23 @@ by_cases_zero_pos z
... = (x + z - z) % z : if_pos (and.intro H (le_add_left z x))
... = x % z : nat.add_sub_cancel)
theorem add_mod_self_left (x z : ) : (x + z) % x = z % x :=
theorem add_mod_self_left [simp] (x z : ) : (x + z) % x = z % x :=
!add.comm ▸ !add_mod_self
theorem add_mul_mod_self (x y z : ) : (x + y * z) % z = x % z :=
nat.induction_on y
(calc (x + 0 * z) % z = (x + 0) % z : zero_mul
... = x % z : add_zero)
(take y,
assume IH : (x + y * z) % z = x % z,
calc
(x + succ y * z) % z = (x + (y * z + z)) % z : succ_mul
... = (x + y * z + z) % z : add.assoc
... = (x + y * z) % z : !add_mod_self
... = x % z : IH)
local attribute succ_mul [simp]
theorem add_mul_mod_self_left (x y z : ) : (x + y * z) % y = x % y :=
!mul.comm ▸ !add_mul_mod_self
theorem add_mul_mod_self [simp] (x y z : ) : (x + y * z) % z = x % z :=
nat.induction_on y (by simp) (by msimp)
theorem mul_mod_left (m n : ) : (m * n) % n = 0 :=
by rewrite [-zero_add (m * n), add_mul_mod_self, zero_mod]
theorem add_mul_mod_self_left [simp] (x y z : ) : (x + y * z) % y = x % y :=
by msimp
theorem mul_mod_right (m n : ) : (m * n) % m = 0 :=
!mul.comm ▸ !mul_mod_left
theorem mul_mod_left [simp] (m n : ) : (m * n) % n = 0 :=
calc (m * n) % n = (0 + m * n) % n : by simp
... = 0 : by msimp
theorem mul_mod_right [simp] (m n : ) : (m * n) % m = 0 :=
by msimp
theorem mod_lt (x : ) {y : } (H : y > 0) : x % y < y :=
nat.case_strong_induction_on x

View file

@ -28,9 +28,9 @@ definition gcd.F : Π (p₁ : nat × nat), (Π p₂ : nat × nat, p₂ ≺ p₁
definition gcd (x y : nat) := fix gcd.F (x, y)
theorem gcd_zero_right (x : nat) : gcd x 0 = x := rfl
theorem gcd_zero_right [simp] (x : nat) : gcd x 0 = x := rfl
theorem gcd_succ (x y : nat) : gcd x (succ y) = gcd (succ y) (x % succ y) :=
theorem gcd_succ [simp] (x y : nat) : gcd x (succ y) = gcd (succ y) (x % succ y) :=
well_founded.fix_eq gcd.F (x, succ y)
theorem gcd_one_right (n : ) : gcd n 1 = 1 :=

View file

@ -48,9 +48,7 @@ theorem succ_sub_sub_succ [simp] (n m k : ) : succ n - m - succ k = n - m - k
by simp
theorem sub_self_add [simp] (n m : ) : n - (n + m) = 0 :=
calc
n - (n + m) = n - n - m : by topdown_simp
... = 0 : by simp
by msimp
protected theorem sub.right_comm (m n k : ) : m - n - k = m - k - n :=
by simp
@ -65,24 +63,17 @@ local attribute nat.succ_mul nat.mul_succ [simp]
/- interaction with multiplication -/
theorem mul_pred_left (n m : ) : pred n * m = n * m - m :=
theorem mul_pred_left [simp] (n m : ) : pred n * m = n * m - m :=
nat.induction_on n (by simp) (by simp)
theorem mul_pred_right (n m : ) : n * pred m = n * m - n :=
calc
n * pred m = pred m * n : by simp
... = m * n - n : mul_pred_left
... = n * m - n : by simp
attribute mul_pred_left mul_pred_right [simp]
theorem mul_pred_right [simp] (n m : ) : n * pred m = n * m - n :=
by msimp
protected theorem mul_sub_right_distrib [simp] (n m k : ) : (n - m) * k = n * k - m * k :=
nat.induction_on m (by simp) (by simp)
protected theorem mul_sub_left_distrib [simp] (n m k : ) : n * (m - k) = n * m - n * k :=
calc
n * (m - k) = (m - k) * n : by rewrite mul.comm
... = n * m - n * k : by simp
by msimp
protected theorem mul_self_sub_mul_self_eq (a b : nat) : a * a - b * b = (a + b) * (a - b) :=
by rewrite [nat.mul_sub_left_distrib, *right_distrib, mul.comm b a, add.comm (a*a) (a*b),

View file

@ -109,7 +109,7 @@ definition with_attributes_tac (o : expr) (n : identifier_list) (t : tactic) : t
definition simp : tactic := #tactic with_options [blast.strategy "simp"] blast
definition simp_nohyps : tactic := #tactic with_options [blast.strategy "simp_nohyps"] blast
definition topdown_simp : tactic := #tactic with_options [blast.strategy "simp", simplify.top_down true] blast
definition simp_topdown : tactic := #tactic with_options [blast.strategy "simp", simplify.top_down true] blast
definition msimp : tactic := #tactic with_options [blast.strategy "ematch_simp"] blast
definition cases (h : expr) (ids : opt_identifier_list) : tactic := builtin

View file

@ -69,7 +69,7 @@
"apply" "fapply" "eapply" "rename" "intro" "intros" "all_goals" "fold" "focus" "focus_at"
"generalize" "generalizes" "clear" "clears" "revert" "reverts" "back" "beta" "done" "exact" "rexact"
"refine" "repeat" "whnf" "rotate" "rotate_left" "rotate_right" "inversion" "cases" "rewrite"
"xrewrite" "krewrite" "blast" "simp" "simp_nohyps" "esimp" "unfold" "change" "check_expr" "contradiction"
"xrewrite" "krewrite" "blast" "simp" "simp_nohyps" "simp_topdown" "esimp" "unfold" "change" "check_expr" "contradiction"
"exfalso" "split" "existsi" "constructor" "fconstructor" "left" "right" "injection" "congruence" "reflexivity"
"symmetry" "transitivity" "state" "induction" "induction_using" "fail" "append"
"substvars" "now" "with_options" "with_attributes" "with_attrs" "note")