/- 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 : 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 := 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, 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 end int -- TODO(Jeremy): add more facts specific to the integers