lean4-htt/library/init/data/int/order.lean
Leonardo de Moura bb9e3ddae2 feat(library/init/meta/interactive): rw [-h] ==> rw [← h]
@Armael: this change may affect your project.

The file `doc/changes.md` explains the motivation for the change.
2017-07-05 11:42:55 -07:00

360 lines
14 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 init.data.nat.find
namespace int
private def nonneg (a : ) : Prop := int.cases_on a (assume n, true) (assume 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 (assume a, decidable.true) (assume 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 (assume n H, exists.intro n rfl) (assume n', false.elim)
private lemma nonneg_or_nonneg_neg (a : ) : nonneg a nonneg (-a) :=
int.cases_on a (assume n, or.inl trivial) (assume n, or.inr trivial)
lemma le.intro_sub {a b : } {n : } (h : b - a = n) : a ≤ b :=
show nonneg (b - a), by rw h; trivial
lemma le.intro {a b : } {n : } (h : a + n = b) : a ≤ b :=
le.intro_sub (by rw [← h]; simp)
lemma le.dest_sub {a b : } (h : a ≤ b) : ∃ n : , b - a = n := nonneg.elim h
lemma le.dest {a b : } (h : a ≤ b) : ∃ n : , a + n = b :=
match (le.dest_sub 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 (assume 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 coe_zero_le (n : ) : 0 ≤ (↑n : ) :=
coe_nat_le_coe_nat_of_le n.zero_le
lemma eq_coe_of_zero_le {a : } (h : 0 ≤ a) : ∃ n : , a = n :=
by have t := le.dest_sub h; simp at t; exact t
lemma eq_succ_of_zero_lt {a : } (h : 0 < a) : ∃ n : , a = n.succ :=
let ⟨n, (h : ↑(1+n) = a)⟩ := le.dest h in
⟨n, by rw add_comm at h; exact h.symm⟩
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 (assume 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₁ (assume n, assume hn : a + n = b,
le.elim h₂ (assume 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₁ (assume n, assume hn : a + n = b,
le.elim h₂ (assume 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 :=
assume : a < a,
lt.elim this (assume 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 :=
(assume : 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 (assume 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 (assume n, assume hn : a + n = b,
have n ≠ 0,
from (assume : 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
(assume : a = b, or.inr this)
(assume : a ≠ b,
le.elim h (assume n, assume hn : a + n = b,
have n ≠ 0, from
(assume : 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 (assume 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) _)
(assume 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 (assume n, assume hn,
le.elim hb (assume 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 (assume n, assume hn,
lt.elim hb (assume 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 (by rwa [← heq]) 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 : decidable_linear_ordered_comm_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 := 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,
decidable_eq := int.decidable_eq,
decidable_le := int.decidable_le,
decidable_lt := int.decidable_lt }
instance : decidable_linear_ordered_comm_group int :=
by apply_instance
lemma eq_nat_abs_of_zero_le {a : } (h : 0 ≤ a) : a = nat_abs a :=
let ⟨n, e⟩ := eq_coe_of_zero_le h in by rw e; refl
lemma le_nat_abs {a : } : a ≤ nat_abs a :=
or.elim (le_total 0 a)
(λh, by rw eq_nat_abs_of_zero_le h; refl)
(λh, le_trans h (coe_zero_le _))
lemma neg_succ_lt_zero (n : ) : -[1+ n] < 0 :=
lt_of_not_ge $ λ h, let ⟨m, h⟩ := eq_coe_of_zero_le h in by contradiction
lemma eq_neg_succ_of_lt_zero : ∀ {a : }, a < 0 → ∃ n : , a = -[1+ n]
| (n : ) h := absurd h (not_lt_of_ge (coe_zero_le _))
| -[1+ n] h := ⟨n, rfl⟩
/- more facts specific to int -/
theorem of_nat_nonneg (n : ) : 0 ≤ of_nat n := trivial
theorem coe_succ_pos (n : nat) : (nat.succ n : ) > 0 :=
coe_nat_lt_coe_nat_of_lt (nat.succ_pos _)
theorem exists_eq_neg_of_nat {a : } (H : a ≤ 0) : ∃n : , a = -n :=
let ⟨n, h⟩ := eq_coe_of_zero_le (neg_nonneg_of_nonpos H) in
⟨n, eq_neg_of_eq_neg h.symm⟩
theorem nat_abs_of_nonneg {a : } (H : a ≥ 0) : (nat_abs a : ) = a :=
match a, eq_coe_of_zero_le H with ._, ⟨n, rfl⟩ := rfl end
theorem of_nat_nat_abs_of_nonpos {a : } (H : a ≤ 0) : (nat_abs a : ) = -a :=
by rw [← nat_abs_neg, nat_abs_of_nonneg (neg_nonneg_of_nonpos H)]
theorem abs_eq_nat_abs : ∀ a : , abs a = nat_abs a
| (n : ) := abs_of_nonneg $ coe_zero_le _
| -[1+ n] := abs_of_nonpos $ le_of_lt $ neg_succ_lt_zero _
theorem nat_abs_abs (a : ) : nat_abs (abs a) = nat_abs a :=
by rw [abs_eq_nat_abs]; refl
theorem lt_of_add_one_le {a b : } (H : a + 1 ≤ b) : a < b := H
theorem add_one_le_of_lt {a b : } (H : a < b) : a + 1 ≤ b := H
theorem lt_add_one_of_le {a b : } (H : a ≤ b) : a < b + 1 :=
add_le_add_right H 1
theorem le_of_lt_add_one {a b : } (H : a < b + 1) : a ≤ b :=
le_of_add_le_add_right H
theorem sub_one_le_of_lt {a b : } (H : a ≤ b) : a - 1 < b :=
sub_right_lt_of_lt_add $ lt_add_one_of_le H
theorem lt_of_sub_one_le {a b : } (H : a - 1 < b) : a ≤ b :=
le_of_lt_add_one $ lt_add_of_sub_right_lt H
theorem le_sub_one_of_lt {a b : } (H : a < b) : a ≤ b - 1 :=
le_sub_right_of_add_le H
theorem lt_of_le_sub_one {a b : } (H : a ≤ b - 1) : a < b :=
add_le_of_le_sub_right H
theorem sign_of_succ (n : nat) : sign (nat.succ n) = 1 := rfl
theorem sign_eq_one_of_pos {a : } (h : 0 < a) : sign a = 1 :=
match a, eq_succ_of_zero_lt h with ._, ⟨n, rfl⟩ := rfl end
theorem sign_eq_neg_one_of_neg {a : } (h : a < 0) : sign a = -1 :=
match a, eq_neg_succ_of_lt_zero h with ._, ⟨n, rfl⟩ := rfl end
lemma eq_zero_of_sign_eq_zero : Π {a : }, sign a = 0 → a = 0
| 0 _ := rfl
theorem pos_of_sign_eq_one : ∀ {a : }, sign a = 1 → 0 < a
| (n+1:) _ := coe_nat_lt_coe_nat_of_lt (nat.succ_pos _)
theorem neg_of_sign_eq_neg_one : ∀ {a : }, sign a = -1 → a < 0
| (n+1:) h := match h with end
| 0 h := match h with end
| -[1+ n] _ := neg_succ_lt_zero _
theorem sign_eq_one_iff_pos (a : ) : sign a = 1 ↔ 0 < a :=
⟨pos_of_sign_eq_one, sign_eq_one_of_pos⟩
theorem sign_eq_neg_one_iff_neg (a : ) : sign a = -1 ↔ a < 0 :=
⟨neg_of_sign_eq_neg_one, sign_eq_neg_one_of_neg⟩
theorem sign_eq_zero_iff_zero (a : ) : sign a = 0 ↔ a = 0 :=
⟨eq_zero_of_sign_eq_zero, λ h, by rw [h, sign_zero]⟩
theorem sign_mul_abs (a : ) : sign a * abs a = a :=
by rw [abs_eq_nat_abs, sign_mul_nat_abs]
theorem eq_one_of_mul_eq_self_left {a b : } (Hpos : a ≠ 0) (H : b * a = a) : b = 1 :=
eq_of_mul_eq_mul_right Hpos (by rw [one_mul, H])
theorem eq_one_of_mul_eq_self_right {a b : } (Hpos : b ≠ 0) (H : b * a = b) : a = 1 :=
eq_of_mul_eq_mul_left Hpos (by rw [mul_one, H])
theorem exists_least_of_bdd {P : → Prop} [HP : decidable_pred P]
(Hbdd : ∃ b : , ∀ z : , z < b → ¬ P z)
(Hinh : ∃ z : , P z) : ∃ lb : , P lb ∧ (∀ z : , z < lb → ¬ P z) :=
let ⟨b, Hb⟩ := Hbdd in
have EX : ∃ n : , P (b + n), from
let ⟨elt, Helt⟩ := Hinh in
match elt, le.dest (le_of_not_gt (λ h : elt < b, Hb _ h Helt)), Helt with
| ._, ⟨n, rfl⟩, Hn := ⟨n, Hn⟩
end,
⟨b + (nat.find EX : ), nat.find_spec EX, λ z h,
if zl : z < b then Hb _ zl else
match z, le.dest (le_of_not_gt zl), h with
| ._, ⟨n, rfl⟩, h := nat.find_min EX $
lt_of_coe_nat_lt_coe_nat $ lt_of_add_lt_add_left h
end⟩
theorem exists_greatest_of_bdd {P : → Prop} [HP : decidable_pred P]
(Hbdd : ∃ b : , ∀ z : , z > b → ¬ P z)
(Hinh : ∃ z : , P z) : ∃ ub : , P ub ∧ (∀ z : , z > ub → ¬ P z) :=
have Hbdd' : ∃ (b : ), ∀ (z : ), z < b → ¬P (-z), from
let ⟨b, Hb⟩ := Hbdd in ⟨-b, λ z h, Hb _ (lt_neg_of_lt_neg h)⟩,
have Hinh' : ∃ z : , P (-z), from
let ⟨elt, Helt⟩ := Hinh in ⟨-elt, by rw [neg_neg]; exact Helt⟩,
let ⟨lb, Plb, al⟩ := exists_least_of_bdd Hbdd' Hinh' in
⟨-lb, Plb, λ z h, by rw [← neg_neg z]; exact al _ (neg_lt_of_neg_lt h)⟩
end int