lean4-htt/library/init/data/int/order.lean

218 lines
8.4 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2016 Jeremy Avigad. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jeremy Avigad
The order relation on the integers.
-/
prelude
import init.data.int.basic
namespace int
private def nonneg (a : ) : Prop := int.cases_on a (take n, true) (take n, false)
protected def le (a b : ) : Prop := nonneg (b - a)
instance : has_le int := ⟨int.le⟩
protected def lt (a b : ) : Prop := (a + 1) ≤ b
instance : has_lt int := ⟨int.lt⟩
private def decidable_nonneg (a : ) : decidable (nonneg a) :=
int.cases_on a (take a, decidable.true) (take a, decidable.false)
instance decidable_le (a b : ) : decidable (a ≤ b) := decidable_nonneg _
instance decidable_lt (a b : ) : decidable (a < b) := decidable_nonneg _
lemma lt_iff_add_one_le (a b : ) : a < b ↔ a + 1 ≤ b := iff.refl _
private lemma nonneg.elim {a : } : nonneg a → ∃ n : , a = n :=
int.cases_on a (take n H, exists.intro n rfl) (take n', false.elim)
private lemma nonneg_or_nonneg_neg (a : ) : nonneg a nonneg (-a) :=
int.cases_on a (take n, or.inl trivial) (take n, or.inr trivial)
lemma le.intro {a b : } {n : } (h : a + n = b) : a ≤ b :=
have ↑n = b - a, begin rw -h, simp end,
show nonneg (b - a), from this ▸ trivial
lemma le.dest {a b : } (h : a ≤ b) : ∃ n : , a + n = b :=
match (nonneg.elim h) with
| ⟨n, h₁⟩ := exists.intro n begin rw [-h₁, add_comm], simp end
end
lemma le.elim {a b : } (h : a ≤ b) {P : Prop} (h' : ∀ n : , a + ↑n = b → P) : P :=
exists.elim (le.dest h) h'
protected lemma le_total (a b : ) : a ≤ b b ≤ a :=
or.imp_right
(assume H : nonneg (-(b - a)),
have -(b - a) = a - b, by simp,
show nonneg (a - b), from this ▸ H)
(nonneg_or_nonneg_neg (b - a))
lemma coe_nat_le_coe_nat_of_le {m n : } (h : m ≤ n) : (↑m : ) ≤ ↑n :=
match nat.le.dest h with
| ⟨k, (hk : m + k = n)⟩ := le.intro (begin rw [-hk], reflexivity end)
end
lemma le_of_coe_nat_le_coe_nat {m n : } (h : (↑m : ) ≤ ↑n) : m ≤ n :=
le.elim h (take k, assume hk : ↑m + ↑k = ↑n,
have m + k = n, from int.coe_nat_inj ((int.coe_nat_add m k)^.trans hk),
nat.le.intro this)
lemma coe_nat_le_coe_nat_iff (m n : ) : (↑m : ) ≤ ↑n ↔ m ≤ n :=
iff.intro le_of_coe_nat_le_coe_nat coe_nat_le_coe_nat_of_le
lemma lt_add_succ (a : ) (n : ) : a < a + ↑(nat.succ n) :=
le.intro (show a + 1 + n = a + nat.succ n, begin simp [int.coe_nat_eq], reflexivity end)
lemma lt.intro {a b : } {n : } (h : a + nat.succ n = b) : a < b :=
h ▸ lt_add_succ a n
lemma lt.dest {a b : } (h : a < b) : ∃ n : , a + ↑(nat.succ n) = b :=
le.elim h (take n, assume hn : a + 1 + n = b,
exists.intro n begin rw [-hn, add_assoc, add_comm (1 : int)], reflexivity end)
lemma lt.elim {a b : } (h : a < b) {P : Prop} (h' : ∀ n : , a + ↑(nat.succ n) = b → P) : P :=
exists.elim (lt.dest h) h'
lemma coe_nat_lt_coe_nat_iff (n m : ) : (↑n : ) < ↑m ↔ n < m :=
begin rw [lt_iff_add_one_le, -int.coe_nat_succ, coe_nat_le_coe_nat_iff], reflexivity end
lemma lt_of_coe_nat_lt_coe_nat {m n : } (h : (↑m : ) < ↑n) : m < n :=
(coe_nat_lt_coe_nat_iff _ _)^.mp h
lemma coe_nat_lt_coe_nat_of_lt {m n : } (h : m < n) : (↑m : ) < ↑n :=
(coe_nat_lt_coe_nat_iff _ _)^.mpr h
/- show that the integers form an ordered additive group -/
protected lemma le_refl (a : ) : a ≤ a :=
le.intro (add_zero a)
protected lemma le_trans {a b c : } (h₁ : a ≤ b) (h₂ : b ≤ c) : a ≤ c :=
le.elim h₁ (take n, assume hn : a + n = b,
le.elim h₂ (take m, assume hm : b + m = c,
begin apply le.intro, rw [-hm, -hn, add_assoc], reflexivity end))
protected lemma le_antisymm {a b : } (h₁ : a ≤ b) (h₂ : b ≤ a) : a = b :=
le.elim h₁ (take n, assume hn : a + n = b,
le.elim h₂ (take m, assume hm : b + m = a,
have a + ↑(n + m) = a + 0, by rw [int.coe_nat_add, -add_assoc, hn, hm, add_zero a],
have (↑(n + m) : ) = 0, from add_left_cancel this,
have n + m = 0, from int.coe_nat_inj this,
have n = 0, from nat.eq_zero_of_add_eq_zero_right this,
show a = b, begin rw [-hn, this, int.coe_nat_zero, add_zero a] end))
protected lemma lt_irrefl (a : ) : ¬ a < a :=
suppose a < a,
lt.elim this (take n, assume hn : a + nat.succ n = a,
have a + nat.succ n = a + 0, by rw [hn, add_zero],
have nat.succ n = 0, from int.coe_nat_inj (add_left_cancel this),
show false, from nat.succ_ne_zero _ this)
protected lemma ne_of_lt {a b : } (h : a < b) : a ≠ b :=
(suppose a = b, absurd (begin rewrite this at h, exact h end) (int.lt_irrefl b))
lemma le_of_lt {a b : } (h : a < b) : a ≤ b :=
lt.elim h (take n, assume hn : a + nat.succ n = b, le.intro hn)
protected lemma lt_iff_le_and_ne (a b : ) : a < b ↔ (a ≤ b ∧ a ≠ b) :=
iff.intro
(assume h, ⟨le_of_lt h, int.ne_of_lt h⟩)
(assume ⟨aleb, aneb⟩,
le.elim aleb (take n, assume hn : a + n = b,
have n ≠ 0,
from (suppose n = 0, aneb begin rw [-hn, this, int.coe_nat_zero, add_zero] end),
have n = nat.succ (nat.pred n),
from eq.symm (nat.succ_pred_eq_of_pos (nat.pos_of_ne_zero this)),
lt.intro (begin rewrite this at hn, exact hn end)))
protected lemma le_iff_lt_or_eq (a b : ) : a ≤ b ↔ (a < b a = b) :=
iff.intro
(assume h,
decidable.by_cases
(suppose a = b, or.inr this)
(suppose a ≠ b,
le.elim h (take n, assume hn : a + n = b,
have n ≠ 0, from
(suppose n = 0, a ≠ b begin rw [-hn, this, int.coe_nat_zero, add_zero] end),
have n = nat.succ (nat.pred n),
from eq.symm (nat.succ_pred_eq_of_pos (nat.pos_of_ne_zero this)),
or.inl (lt.intro (begin rewrite this at hn, exact hn end)))))
(assume h,
or.elim h
(assume h', le_of_lt h')
(assume h', h' ▸ int.le_refl a))
lemma lt_succ (a : ) : a < a + 1 :=
int.le_refl (a + 1)
protected lemma add_le_add_left {a b : } (h : a ≤ b) (c : ) : c + a ≤ c + b :=
le.elim h (take n, assume hn : a + n = b,
le.intro (show c + a + n = c + b, begin rw [add_assoc, hn] end))
protected lemma add_lt_add_left {a b : } (h : a < b) (c : ) : c + a < c + b :=
iff.mpr (int.lt_iff_le_and_ne _ _)
(and.intro
(int.add_le_add_left (le_of_lt h) _)
(take heq, int.lt_irrefl b begin rw add_left_cancel heq at h, exact h end))
protected lemma mul_nonneg {a b : } (ha : 0 ≤ a) (hb : 0 ≤ b) : 0 ≤ a * b :=
le.elim ha (take n, assume hn,
le.elim hb (take m, assume hm,
le.intro (show 0 + ↑n * ↑m = a * b, begin rw [-hn, -hm], repeat {rw zero_add} end)))
protected lemma mul_pos {a b : } (ha : 0 < a) (hb : 0 < b) : 0 < a * b :=
lt.elim ha (take n, assume hn,
lt.elim hb (take m, assume hm,
lt.intro (show 0 + ↑(nat.succ (nat.succ n * m + n)) = a * b,
begin rw [-hn, -hm], repeat {rw int.coe_nat_zero}, simp,
rw [-int.coe_nat_mul], simp [nat.mul_succ, nat.succ_add] end)))
protected lemma zero_lt_one : (0 : ) < 1 := trivial
protected lemma not_le_of_gt {a b : } (h : a < b) : ¬ b ≤ a :=
assume hba : b ≤ a,
have a = b, from int.le_antisymm (le_of_lt h) hba,
show false, from int.lt_irrefl b (begin rw this at h, exact h end)
protected lemma lt_of_lt_of_le {a b c : } (hab : a < b) (hbc : b ≤ c) : a < c :=
have hac : a ≤ c, from int.le_trans (le_of_lt hab) hbc,
iff.mpr
(int.lt_iff_le_and_ne _ _)
(and.intro hac (assume heq, int.not_le_of_gt begin rw -heq, assumption end hbc))
protected lemma lt_of_le_of_lt {a b c : } (hab : a ≤ b) (hbc : b < c) : a < c :=
have hac : a ≤ c, from int.le_trans hab (le_of_lt hbc),
iff.mpr
(int.lt_iff_le_and_ne _ _)
(and.intro hac (assume heq, int.not_le_of_gt begin rw heq, exact hbc end hab))
instance : linear_ordered_ring int :=
{ int.comm_ring with
le := int.le,
le_refl := int.le_refl,
le_trans := @int.le_trans,
le_antisymm := @int.le_antisymm,
lt := int.lt,
le_of_lt := @int.le_of_lt,
lt_of_lt_of_le := @int.lt_of_lt_of_le,
lt_of_le_of_lt := @int.lt_of_le_of_lt,
lt_irrefl := int.lt_irrefl,
add_le_add_left := @int.add_le_add_left,
add_lt_add_left := @int.add_lt_add_left,
zero_ne_one := int.zero_ne_one,
mul_nonneg := @int.mul_nonneg,
mul_pos := @int.mul_pos,
le_iff_lt_or_eq := int.le_iff_lt_or_eq,
le_total := int.le_total,
zero_lt_one := int.zero_lt_one }
end int
-- TODO(Jeremy): add more facts specific to the integers