lean4-htt/library/init/order.lean
2016-10-02 13:33:25 -07:00

223 lines
8.1 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 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
prelude
import init.logic
/- Make sure instances defined in this file have lower priority than the ones
defined for concrete structures -/
set_option default_priority 100
universe variable u
variables {A : Type u}
class weak_order (A : Type u) extends has_le A :=
(le_refl : ∀ a : A, a ≤ a)
(le_trans : ∀ a b c : A, a ≤ b → b ≤ c → a ≤ c)
(le_antisymm : ∀ a b : A, a ≤ b → b ≤ a → a = b)
class linear_weak_order (A : Type u) extends weak_order A :=
(le_total : ∀ a b : A, a ≤ b b ≤ a)
class strict_order (A : Type u) extends has_lt A :=
(lt_irrefl : ∀ a : A, ¬ a < a)
(lt_trans : ∀ a b c : A, a < b → b < c → a < c)
/- structures with a weak and a strict order -/
class order_pair (A : Type u) extends weak_order A, has_lt A :=
(le_of_lt : ∀ a b : A, a < b → a ≤ b)
(lt_of_lt_of_le : ∀ a b c : A, a < b → b ≤ c → a < c)
(lt_of_le_of_lt : ∀ a b c : A, a ≤ b → b < c → a < c)
(lt_irrefl : ∀ a : A, ¬ a < a)
class strong_order_pair (A : Type u) extends weak_order A, has_lt A :=
(le_iff_lt_or_eq : ∀ a b : A, a ≤ b ↔ a < b a = b)
(lt_irrefl : ∀ a : A, ¬ a < a)
class linear_order_pair (A : Type u) extends order_pair A, linear_weak_order A
class linear_strong_order_pair (A : Type u) extends strong_order_pair A, linear_weak_order A
class decidable_linear_order (A : Type u) extends linear_strong_order_pair A :=
(decidable_lt : decidable_rel lt)
lemma le_refl [weak_order A] : ∀ a : A, a ≤ a :=
weak_order.le_refl
lemma le_trans [weak_order A] : ∀ {a b c : A}, a ≤ b → b ≤ c → a ≤ c :=
weak_order.le_trans
lemma le_antisymm [weak_order A] : ∀ {a b : A}, a ≤ b → b ≤ a → a = b :=
weak_order.le_antisymm
lemma le_of_eq [weak_order A] {a b : A} : a = b → a ≤ b :=
λ h, h ▸ le_refl a
lemma ge_trans [weak_order A] : ∀ {a b c : A}, a ≥ b → b ≥ c → a ≥ c :=
λ a b c h₁ h₂, le_trans h₂ h₁
lemma le_total [linear_weak_order A] : ∀ a b : A, a ≤ b b ≤ a :=
linear_weak_order.le_total
lemma le_of_not_ge [linear_weak_order A] {a b : A} : ¬ a ≥ b → a ≤ b :=
or.resolve_left (le_total b a)
lemma lt_irrefl [strict_order A] : ∀ a : A, ¬ a < a :=
strict_order.lt_irrefl
lemma gt_irrefl [strict_order A] : ∀ a : A, ¬ a > a :=
lt_irrefl
lemma lt_trans [strict_order A] : ∀ {a b c : A}, a < b → b < c → a < c :=
strict_order.lt_trans
lemma gt_trans [strict_order A] : ∀ {a b c : A}, a > b → b > c → a > c :=
λ a b c h₁ h₂, lt_trans h₂ h₁
lemma ne_of_lt [strict_order A] {a b : A} (h : a < b) : a ≠ b :=
λ he, absurd h (he ▸ lt_irrefl a)
lemma ne_of_gt [strict_order A] {a b : A} (h : a > b) : a ≠ b :=
λ he, absurd h (he ▸ lt_irrefl a)
lemma lt_asymm [strict_order A] {a b : A} (h : a < b) : ¬ b < a :=
λ h1 : b < a, lt_irrefl a (lt_trans h h1)
lemma not_lt_of_gt [strict_order A] {a b : A} (h : a > b) : ¬ a < b :=
lt_asymm h
lemma le_of_lt [order_pair A] : ∀ {a b : A}, a < b → a ≤ b :=
order_pair.le_of_lt
lemma lt_of_lt_of_le [order_pair A] : ∀ {a b c : A}, a < b → b ≤ c → a < c :=
order_pair.lt_of_lt_of_le
lemma lt_of_le_of_lt [order_pair A] : ∀ {a b c : A}, a ≤ b → b < c → a < c :=
order_pair.lt_of_le_of_lt
lemma gt_of_gt_of_ge [order_pair A] {a b c : A} (h₁ : a > b) (h₂ : b ≥ c) : a > c :=
lt_of_le_of_lt h₂ h₁
lemma gt_of_ge_of_gt [order_pair A] {a b c : A} (h₁ : a ≥ b) (h₂ : b > c) : a > c :=
lt_of_lt_of_le h₂ h₁
instance order_pair.to_strict_order [s : order_pair A] : strict_order A :=
{ s with
lt_irrefl := order_pair.lt_irrefl,
lt_trans := λ a b c h₁ h₂, lt_of_lt_of_le h₁ (le_of_lt h₂) }
lemma not_le_of_gt [order_pair A] {a b : A} (h : a > b) : ¬ a ≤ b :=
λ h₁, lt_irrefl b (lt_of_lt_of_le h h₁)
lemma not_lt_of_ge [order_pair A] {a b : A} (h : a ≥ b) : ¬ a < b :=
λ h₁, lt_irrefl b (lt_of_le_of_lt h h₁)
lemma le_iff_lt_or_eq [strong_order_pair A] : ∀ {a b : A}, a ≤ b ↔ a < b a = b :=
strong_order_pair.le_iff_lt_or_eq
lemma lt_or_eq_of_le [strong_order_pair A] : ∀ {a b : A}, a ≤ b → a < b a = b :=
λ a b h, iff.mp le_iff_lt_or_eq h
lemma le_of_lt_or_eq [strong_order_pair A] : ∀ {a b : A}, (a < b a = b) → a ≤ b :=
λ a b h, iff.mpr le_iff_lt_or_eq h
lemma lt_of_le_of_ne [strong_order_pair A] {a b : A} : a ≤ b → a ≠ b → a < b :=
λ h₁ h₂, or.resolve_right (lt_or_eq_of_le h₁) h₂
private lemma lt_irrefl' [strong_order_pair A] : ∀ a : A, ¬ a < a :=
strong_order_pair.lt_irrefl
private lemma le_of_lt' [strong_order_pair A] ⦃a b : A⦄ (h : a < b) : a ≤ b :=
le_of_lt_or_eq (or.inl h)
private lemma lt_of_lt_of_le' [strong_order_pair A] (a b c : A) (h₁ : a < b) (h₂ : b ≤ c) : a < c :=
have a ≤ c, from le_trans (le_of_lt' h₁) h₂,
or.elim (lt_or_eq_of_le this)
(λ h : a < c, h)
(λ h : a = c,
have b ≤ a, from h^.symm ▸ h₂,
have a = b, from le_antisymm (le_of_lt' h₁) this,
absurd h₁ (this ▸ lt_irrefl' a))
private lemma lt_of_le_of_lt' [strong_order_pair A] (a b c : A) (h₁ : a ≤ b) (h₂ : b < c) : a < c :=
have a ≤ c, from le_trans h₁ (le_of_lt' h₂),
or.elim (lt_or_eq_of_le this)
(λ h : a < c, h)
(λ h : a = c,
have c ≤ b, from h ▸ h₁,
have c = b, from le_antisymm this (le_of_lt' h₂),
absurd h₂ (this ▸ lt_irrefl' c))
instance strong_order_pair.to_order_pair [s : strong_order_pair A] : order_pair A :=
{ s with
lt_irrefl := lt_irrefl',
le_of_lt := le_of_lt',
lt_of_le_of_lt := lt_of_le_of_lt',
lt_of_lt_of_le := lt_of_lt_of_le'}
instance linear_strong_order_pair.to_linear_order_pair [s : linear_strong_order_pair A] : linear_order_pair A :=
{ s with
lt_irrefl := lt_irrefl',
le_of_lt := le_of_lt',
lt_of_le_of_lt := lt_of_le_of_lt',
lt_of_lt_of_le := lt_of_lt_of_le'}
lemma lt_trichotomy [linear_strong_order_pair A] (a b : A) : a < b a = b b < a :=
or.elim (le_total a b)
(λ h : a ≤ b, or.elim (lt_or_eq_of_le h)
(λ h : a < b, or.inl h)
(λ h : a = b, or.inr (or.inl h)))
(λ h : b ≤ a, or.elim (lt_or_eq_of_le h)
(λ h : b < a, or.inr (or.inr h))
(λ h : b = a, or.inr (or.inl h^.symm)))
lemma le_of_not_gt [linear_strong_order_pair A] {a b : A} (h : ¬ a > b) : a ≤ b :=
match lt_trichotomy a b with
| or.inl hlt := le_of_lt hlt
| or.inr (or.inl heq) := heq ▸ le_refl a
| or.inr (or.inr hgt) := absurd hgt h
end
lemma lt_of_not_ge [linear_strong_order_pair A] {a b : A} (h : ¬ a ≥ b) : a < b :=
match lt_trichotomy a b with
| or.inl hlt := hlt
| or.inr (or.inl heq) := absurd (heq ▸ le_refl a : a ≥ b) h
| or.inr (or.inr hgt) := absurd (le_of_lt hgt) h
end
lemma lt_or_ge [linear_strong_order_pair A] (a b : A) : a < b a ≥ b :=
match lt_trichotomy a b with
| or.inl hlt := or.inl hlt
| or.inr (or.inl heq) := or.inr (heq ▸ le_refl a)
| or.inr (or.inr hgt) := or.inr (le_of_lt hgt)
end
lemma le_or_gt [linear_strong_order_pair A] (a b : A) : a ≤ b a > b :=
or.swap (lt_or_ge b a)
lemma lt_or_gt_of_ne [linear_strong_order_pair A] {a b : A} (h : a ≠ b) : a < b a > b :=
match lt_trichotomy a b with
| or.inl hlt := or.inl hlt
| or.inr (or.inl heq) := absurd heq h
| or.inr (or.inr hgt) := or.inr hgt
end
instance [decidable_linear_order A] (a b : A) : decidable (a < b) :=
decidable_linear_order.decidable_lt A a b
instance [decidable_linear_order A] (a b : A) : decidable (a ≤ b) :=
if h₁ : a < b then is_true (le_of_lt h₁)
else if h₂ : b < a then is_false (not_le_of_gt h₂)
else is_true (le_of_not_gt h₂)
instance [decidable_linear_order A] (a b : A) : decidable (a = b) :=
if h₁ : a ≤ b then
if h₂ : b ≤ a
then is_true (le_antisymm h₁ h₂)
else is_false (λ he : a = b, h₂ (he ▸ le_refl a))
else is_false (λ he : a = b, h₁ (he ▸ le_refl a))
lemma eq_or_lt_of_not_lt [decidable_linear_order A] {a b : A} (h : ¬ a < b) : a = b b < a :=
if h₁ : a = b then or.inl h₁
else or.inr (lt_of_not_ge (λ hge, h (lt_of_le_of_ne hge h₁)))