2014-12-01 04:34:12 +00:00
|
|
|
|
/-
|
|
|
|
|
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
Authors: Floris van Doorn, Leonardo de Moura
|
|
|
|
|
-/
|
|
|
|
|
prelude
|
2015-03-03 21:37:38 +00:00
|
|
|
|
import init.wf init.tactic init.num
|
2015-06-04 23:16:28 +00:00
|
|
|
|
open eq.ops decidable or
|
2014-11-22 08:15:51 +00:00
|
|
|
|
|
|
|
|
|
namespace nat
|
|
|
|
|
notation `ℕ` := nat
|
|
|
|
|
|
2015-06-04 23:16:28 +00:00
|
|
|
|
/- basic definitions on natural numbers -/
|
|
|
|
|
inductive le (a : ℕ) : ℕ → Prop :=
|
|
|
|
|
| refl : le a a
|
|
|
|
|
| step : Π {b}, le a b → le a (succ b)
|
2014-11-22 08:15:51 +00:00
|
|
|
|
|
2015-06-04 23:16:28 +00:00
|
|
|
|
infix `≤` := le
|
|
|
|
|
attribute le.refl [refl]
|
2014-11-22 08:15:51 +00:00
|
|
|
|
|
2015-06-04 23:16:28 +00:00
|
|
|
|
definition lt [reducible] (n m : ℕ) := succ n ≤ m
|
|
|
|
|
definition ge [reducible] (n m : ℕ) := m ≤ n
|
|
|
|
|
definition gt [reducible] (n m : ℕ) := succ m ≤ n
|
|
|
|
|
infix `<` := lt
|
|
|
|
|
infix `≥` := ge
|
|
|
|
|
infix `>` := gt
|
2014-11-22 08:15:51 +00:00
|
|
|
|
|
2015-07-07 23:37:06 +00:00
|
|
|
|
definition pred [unfold 1] (a : nat) : nat :=
|
2015-02-11 20:49:27 +00:00
|
|
|
|
nat.cases_on a zero (λ a₁, a₁)
|
2014-11-22 08:15:51 +00:00
|
|
|
|
|
2015-06-04 23:16:28 +00:00
|
|
|
|
-- add is defined in init.num
|
|
|
|
|
|
|
|
|
|
definition sub (a b : nat) : nat :=
|
2015-07-24 15:56:18 +00:00
|
|
|
|
nat.rec_on b a (λ b₁, pred)
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
|
|
|
|
definition mul (a b : nat) : nat :=
|
|
|
|
|
nat.rec_on b zero (λ b₁ r, r + a)
|
|
|
|
|
|
|
|
|
|
notation a - b := sub a b
|
|
|
|
|
notation a * b := mul a b
|
|
|
|
|
|
|
|
|
|
/- properties of ℕ -/
|
|
|
|
|
|
2014-11-22 08:15:51 +00:00
|
|
|
|
protected definition is_inhabited [instance] : inhabited nat :=
|
|
|
|
|
inhabited.mk zero
|
|
|
|
|
|
2015-02-26 00:20:44 +00:00
|
|
|
|
protected definition has_decidable_eq [instance] : ∀ x y : nat, decidable (x = y)
|
|
|
|
|
| has_decidable_eq zero zero := inl rfl
|
2015-05-01 04:26:52 +00:00
|
|
|
|
| has_decidable_eq (succ x) zero := inr (by contradiction)
|
|
|
|
|
| has_decidable_eq zero (succ y) := inr (by contradiction)
|
2015-02-26 00:20:44 +00:00
|
|
|
|
| has_decidable_eq (succ x) (succ y) :=
|
2015-05-02 01:18:29 +00:00
|
|
|
|
match has_decidable_eq x y with
|
|
|
|
|
| inl xeqy := inl (by rewrite xeqy)
|
2015-06-04 23:16:28 +00:00
|
|
|
|
| inr xney := inr (λ h : succ x = succ y, by injection h with xeqy; exact absurd xeqy xney)
|
2015-05-02 01:18:29 +00:00
|
|
|
|
end
|
2014-11-22 08:15:51 +00:00
|
|
|
|
|
2015-06-04 23:16:28 +00:00
|
|
|
|
/- properties of inequality -/
|
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem le_of_eq {n m : ℕ} (p : n = m) : n ≤ m := p ▸ !le.refl
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem le_succ (n : ℕ) : n ≤ succ n := le.step !le.refl
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem pred_le (n : ℕ) : pred n ≤ n := by cases n;repeat constructor
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-22 16:01:42 +00:00
|
|
|
|
theorem le_succ_iff_true [simp] (n : ℕ) : n ≤ succ n ↔ true :=
|
2015-07-13 20:39:53 +00:00
|
|
|
|
iff_true_intro (le_succ n)
|
|
|
|
|
|
2015-07-22 16:01:42 +00:00
|
|
|
|
theorem pred_le_iff_true [simp] (n : ℕ) : pred n ≤ n ↔ true :=
|
2015-07-13 20:39:53 +00:00
|
|
|
|
iff_true_intro (pred_le n)
|
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem le.trans [trans] {n m k : ℕ} (H1 : n ≤ m) : m ≤ k → n ≤ k :=
|
|
|
|
|
le.rec H1 (λp H2, le.step)
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
|
|
|
|
theorem le_succ_of_le {n m : ℕ} (H : n ≤ m) : n ≤ succ m := le.trans H !le_succ
|
|
|
|
|
|
|
|
|
|
theorem le_of_succ_le {n m : ℕ} (H : succ n ≤ m) : n ≤ m := le.trans !le_succ H
|
|
|
|
|
|
|
|
|
|
theorem le_of_lt {n m : ℕ} (H : n < m) : n ≤ m := le_of_succ_le H
|
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem succ_le_succ {n m : ℕ} : n ≤ m → succ n ≤ succ m :=
|
|
|
|
|
le.rec !le.refl (λa b, le.step)
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem pred_le_pred {n m : ℕ} : n ≤ m → pred n ≤ pred m :=
|
|
|
|
|
le.rec !le.refl (nat.rec (λa b, b) (λa b c, le.step))
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem le_of_succ_le_succ {n m : ℕ} : succ n ≤ succ m → n ≤ m :=
|
|
|
|
|
pred_le_pred
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem le_succ_of_pred_le {n m : ℕ} : pred n ≤ m → n ≤ succ m :=
|
|
|
|
|
nat.cases_on n le.step (λa, succ_le_succ)
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem not_succ_le_zero (n : ℕ) : ¬succ n ≤ zero :=
|
|
|
|
|
by intro H; cases H
|
|
|
|
|
|
|
|
|
|
theorem succ_le_zero_iff_false (n : ℕ) : succ n ≤ zero ↔ false :=
|
|
|
|
|
iff_false_intro !not_succ_le_zero
|
|
|
|
|
|
|
|
|
|
theorem not_succ_le_self : Π {n : ℕ}, ¬succ n ≤ n :=
|
|
|
|
|
nat.rec !not_succ_le_zero (λa b c, b (le_of_succ_le_succ c))
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-22 16:01:42 +00:00
|
|
|
|
theorem succ_le_self_iff_false [simp] (n : ℕ) : succ n ≤ n ↔ false :=
|
2015-07-13 20:39:53 +00:00
|
|
|
|
iff_false_intro not_succ_le_self
|
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem zero_le : ∀ (n : ℕ), 0 ≤ n :=
|
|
|
|
|
nat.rec !le.refl (λa, le.step)
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-22 16:01:42 +00:00
|
|
|
|
theorem zero_le_iff_true [simp] (n : ℕ) : 0 ≤ n ↔ true :=
|
2015-07-24 15:56:18 +00:00
|
|
|
|
iff_true_intro !zero_le
|
2015-07-13 20:39:53 +00:00
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem lt.step {n m : ℕ} : n < m → n < succ m := le.step
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
|
|
|
|
theorem zero_lt_succ (n : ℕ) : 0 < succ n :=
|
2015-07-24 15:56:18 +00:00
|
|
|
|
succ_le_succ !zero_le
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-22 16:01:42 +00:00
|
|
|
|
theorem zero_lt_succ_iff_true [simp] (n : ℕ) : 0 < succ n ↔ true :=
|
2015-07-13 20:39:53 +00:00
|
|
|
|
iff_true_intro (zero_lt_succ n)
|
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem lt.trans [trans] {n m k : ℕ} (H1 : n < m) : m < k → n < k :=
|
|
|
|
|
le.trans (le.step H1)
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem lt_of_le_of_lt [trans] {n m k : ℕ} (H1 : n ≤ m) : m < k → n < k :=
|
|
|
|
|
le.trans (succ_le_succ H1)
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem lt_of_lt_of_le [trans] {n m k : ℕ} : n < m → m ≤ k → n < k := le.trans
|
2015-07-13 20:39:53 +00:00
|
|
|
|
|
2015-06-04 23:16:28 +00:00
|
|
|
|
theorem lt.irrefl (n : ℕ) : ¬n < n := not_succ_le_self
|
|
|
|
|
|
2015-07-22 16:01:42 +00:00
|
|
|
|
theorem lt_self_iff_false [simp] (n : ℕ) : n < n ↔ false :=
|
2015-07-13 20:39:53 +00:00
|
|
|
|
iff_false_intro (lt.irrefl n)
|
|
|
|
|
|
2015-06-04 23:16:28 +00:00
|
|
|
|
theorem self_lt_succ (n : ℕ) : n < succ n := !le.refl
|
2015-07-13 20:39:53 +00:00
|
|
|
|
|
2015-07-22 16:01:42 +00:00
|
|
|
|
theorem self_lt_succ_iff_true [simp] (n : ℕ) : n < succ n ↔ true :=
|
2015-07-13 20:39:53 +00:00
|
|
|
|
iff_true_intro (self_lt_succ n)
|
|
|
|
|
|
2015-06-04 23:16:28 +00:00
|
|
|
|
theorem lt.base (n : ℕ) : n < succ n := !le.refl
|
|
|
|
|
|
|
|
|
|
theorem le_lt_antisymm {n m : ℕ} (H1 : n ≤ m) (H2 : m < n) : false :=
|
|
|
|
|
!lt.irrefl (lt_of_le_of_lt H1 H2)
|
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem le.antisymm {n m : ℕ} (H1 : n ≤ m) : m ≤ n → n = m :=
|
|
|
|
|
le.cases_on H1 (λa, rfl) (λa b c, absurd (lt_of_le_of_lt b c) !lt.irrefl)
|
|
|
|
|
|
2015-06-04 23:16:28 +00:00
|
|
|
|
theorem lt_le_antisymm {n m : ℕ} (H1 : n < m) (H2 : m ≤ n) : false :=
|
|
|
|
|
le_lt_antisymm H2 H1
|
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem lt.asymm {n m : ℕ} (H1 : n < m) : ¬ m < n :=
|
|
|
|
|
le_lt_antisymm (le_of_lt H1)
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem not_lt_zero (a : ℕ) : ¬ a < zero := !not_succ_le_zero
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-22 16:01:42 +00:00
|
|
|
|
theorem lt_zero_iff_false [simp] (a : ℕ) : a < zero ↔ false :=
|
2015-07-13 20:39:53 +00:00
|
|
|
|
iff_false_intro (not_lt_zero a)
|
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem eq_or_lt_of_le {a b : ℕ} (H : a ≤ b) : a = b ∨ a < b :=
|
|
|
|
|
le.cases_on H (inl rfl) (λn h, inr (succ_le_succ h))
|
|
|
|
|
|
|
|
|
|
theorem le_of_eq_or_lt {a b : ℕ} (H : a = b ∨ a < b) : a ≤ b :=
|
|
|
|
|
or.elim H !le_of_eq !le_of_lt
|
|
|
|
|
|
2014-11-22 08:15:51 +00:00
|
|
|
|
-- less-than is well-founded
|
2015-06-04 23:16:28 +00:00
|
|
|
|
definition lt.wf [instance] : well_founded lt :=
|
2015-07-24 15:56:18 +00:00
|
|
|
|
well_founded.intro (nat.rec
|
|
|
|
|
(!acc.intro (λn H, absurd H (not_lt_zero n)))
|
|
|
|
|
(λn IH, !acc.intro (λm H,
|
|
|
|
|
elim (eq_or_lt_of_le (le_of_succ_le_succ H))
|
|
|
|
|
(λe, eq.substr e IH) (acc.inv IH))))
|
|
|
|
|
|
|
|
|
|
definition measure {A : Type} : (A → ℕ) → A → A → Prop :=
|
|
|
|
|
inv_image lt
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
|
|
|
|
definition measure.wf {A : Type} (f : A → ℕ) : well_founded (measure f) :=
|
|
|
|
|
inv_image.wf f lt.wf
|
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem succ_lt_succ {a b : ℕ} : a < b → succ a < succ b :=
|
|
|
|
|
succ_le_succ
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem lt_of_succ_lt {a b : ℕ} : succ a < b → a < b :=
|
|
|
|
|
le_of_succ_le
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem lt_of_succ_lt_succ {a b : ℕ} : succ a < succ b → a < b :=
|
|
|
|
|
le_of_succ_le_succ
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
|
|
|
|
definition decidable_le [instance] : decidable_rel le :=
|
2015-07-24 15:56:18 +00:00
|
|
|
|
nat.rec (λm, (decidable.inl !zero_le))
|
|
|
|
|
(λn IH m, !nat.cases_on (decidable.inr (not_succ_le_zero n))
|
|
|
|
|
(λm, decidable.rec (λH, inl (succ_le_succ H))
|
|
|
|
|
(λH, inr (λa, H (le_of_succ_le_succ a))) (IH m)))
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
|
|
|
|
definition decidable_lt [instance] : decidable_rel lt := _
|
|
|
|
|
definition decidable_gt [instance] : decidable_rel gt := _
|
|
|
|
|
definition decidable_ge [instance] : decidable_rel ge := _
|
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem lt_or_ge (a b : ℕ) : a < b ∨ a ≥ b :=
|
|
|
|
|
nat.rec (inr !zero_le) (λn, or.rec
|
|
|
|
|
(λh, inl (le_succ_of_le h))
|
|
|
|
|
(λh, elim (eq_or_lt_of_le h) (λe, inl (eq.subst e !le.refl)) inr)) b
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-29 04:56:35 +00:00
|
|
|
|
definition lt_ge_by_cases {a b : ℕ} {P : Type} (H1 : a < b → P) (H2 : a ≥ b → P) : P :=
|
2015-07-24 15:56:18 +00:00
|
|
|
|
by_cases H1 (λh, H2 (elim !lt_or_ge (λa, absurd a h) (λa, a)))
|
|
|
|
|
|
|
|
|
|
definition lt.by_cases {a b : ℕ} {P : Type} (H1 : a < b → P) (H2 : a = b → P) (H3 : b < a → P) : P :=
|
|
|
|
|
lt_ge_by_cases H1 (λh₁,
|
|
|
|
|
lt_ge_by_cases H3 (λh₂, H2 (le.antisymm h₂ h₁)))
|
|
|
|
|
|
|
|
|
|
theorem lt.trichotomy (a b : ℕ) : a < b ∨ a = b ∨ b < a :=
|
|
|
|
|
lt.by_cases (λH, inl H) (λH, inr (inl H)) (λH, inr (inr H))
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
|
|
|
|
theorem eq_or_lt_of_not_lt {a b : ℕ} (hnlt : ¬ a < b) : a = b ∨ b < a :=
|
|
|
|
|
or.rec_on (lt.trichotomy a b)
|
|
|
|
|
(λ hlt, absurd hlt hnlt)
|
|
|
|
|
(λ h, h)
|
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem lt_succ_of_le {a b : ℕ} : a ≤ b → a < succ b :=
|
|
|
|
|
succ_le_succ
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
|
|
|
|
theorem lt_of_succ_le {a b : ℕ} (h : succ a ≤ b) : a < b := h
|
|
|
|
|
|
|
|
|
|
theorem succ_le_of_lt {a b : ℕ} (h : a < b) : succ a ≤ b := h
|
|
|
|
|
|
2015-07-22 16:01:42 +00:00
|
|
|
|
theorem succ_sub_succ_eq_sub [simp] (a b : ℕ) : succ a - succ b = a - b :=
|
2015-07-24 15:56:18 +00:00
|
|
|
|
nat.rec rfl (λ b, congr_arg pred) b
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
|
|
|
|
theorem sub_eq_succ_sub_succ (a b : ℕ) : a - b = succ a - succ b :=
|
2015-07-24 15:56:18 +00:00
|
|
|
|
eq.symm !succ_sub_succ_eq_sub
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-22 16:01:42 +00:00
|
|
|
|
theorem zero_sub_eq_zero [simp] (a : ℕ) : zero - a = zero :=
|
2015-07-24 15:56:18 +00:00
|
|
|
|
nat.rec rfl (λ a, congr_arg pred) a
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
|
|
|
|
theorem zero_eq_zero_sub (a : ℕ) : zero = zero - a :=
|
2015-07-24 15:56:18 +00:00
|
|
|
|
eq.symm !zero_sub_eq_zero
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
|
|
|
|
theorem sub_le (a b : ℕ) : a - b ≤ a :=
|
2015-07-24 15:56:18 +00:00
|
|
|
|
nat.rec_on b !le.refl (λ b₁, le.trans !pred_le)
|
2015-06-04 23:16:28 +00:00
|
|
|
|
|
2015-07-22 16:01:42 +00:00
|
|
|
|
theorem sub_le_iff_true [simp] (a b : ℕ) : a - b ≤ a ↔ true :=
|
2015-07-13 20:39:53 +00:00
|
|
|
|
iff_true_intro (sub_le a b)
|
|
|
|
|
|
2015-07-24 15:56:18 +00:00
|
|
|
|
theorem sub_lt {a b : ℕ} (H1 : zero < a) (H2 : zero < b) : a - b < a :=
|
|
|
|
|
!nat.cases_on (λh, absurd h !lt.irrefl)
|
|
|
|
|
(λa h, succ_le_succ (!nat.cases_on (λh, absurd h !lt.irrefl)
|
|
|
|
|
(λb c, eq.substr !succ_sub_succ_eq_sub !sub_le) H2)) H1
|
|
|
|
|
|
2015-07-13 20:39:53 +00:00
|
|
|
|
theorem sub_lt_succ (a b : ℕ) : a - b < succ a :=
|
2015-07-24 15:56:18 +00:00
|
|
|
|
lt_succ_of_le !sub_le
|
2015-07-13 20:39:53 +00:00
|
|
|
|
|
2015-07-22 16:01:42 +00:00
|
|
|
|
theorem sub_lt_succ_iff_true [simp] (a b : ℕ) : a - b < succ a ↔ true :=
|
2015-07-24 15:56:18 +00:00
|
|
|
|
iff_true_intro !sub_lt_succ
|
2014-11-22 08:15:51 +00:00
|
|
|
|
end nat
|
2015-08-04 11:20:13 +00:00
|
|
|
|
|
|
|
|
|
namespace nat_esimp
|
|
|
|
|
open nat
|
|
|
|
|
attribute add mul sub [unfold 2]
|
|
|
|
|
attribute of_num [unfold 1]
|
|
|
|
|
end nat_esimp
|