Module docstring
{"# Orders
Defines classes for linear orders and proves some basic lemmas about them.
","### Definition of LinearOrder and lemmas about types with a linear order
"}
{"# Orders
Defines classes for linear orders and proves some basic lemmas about them.
","### Definition of LinearOrder and lemmas about types with a linear order
"}
maxDefault
definition
[LE α] [DecidableLE α] (a b : α)
/-- Default definition of `max`. -/
def maxDefault [LE α] [DecidableLE α] (a b : α) :=
if a ≤ b then b else a
minDefault
definition
[LE α] [DecidableLE α] (a b : α)
/-- Default definition of `min`. -/
def minDefault [LE α] [DecidableLE α] (a b : α) :=
if a ≤ b then a else b
tacticCompareOfLessAndEq_rfl
definition
: Lean.ParserDescr✝
LinearOrder
structure
(α : Type*) extends PartialOrder α, Min α, Max α, Ord α
/-- A linear order is reflexive, transitive, antisymmetric and total relation `≤`.
We assume that every linear ordered type has decidable `(≤)`, `(<)`, and `(=)`. -/
class LinearOrder (α : Type*) extends PartialOrder α, Min α, Max α, Ord α where
/-- A linear order is total. -/
le_total (a b : α) : a ≤ b ∨ b ≤ a
/-- In a linearly ordered type, we assume the order relations are all decidable. -/
toDecidableLE : DecidableLE α
/-- In a linearly ordered type, we assume the order relations are all decidable. -/
toDecidableEq : DecidableEq α := @decidableEqOfDecidableLE _ _ toDecidableLE
/-- In a linearly ordered type, we assume the order relations are all decidable. -/
toDecidableLT : DecidableLT α := @decidableLTOfDecidableLE _ _ toDecidableLE
min := fun a b => if a ≤ b then a else b
max := fun a b => if a ≤ b then b else a
/-- The minimum function is equivalent to the one you get from `minOfLe`. -/
min_def : ∀ a b, min a b = if a ≤ b then a else b := by intros; rfl
/-- The minimum function is equivalent to the one you get from `maxOfLe`. -/
max_def : ∀ a b, max a b = if a ≤ b then b else a := by intros; rfl
compare a b := compareOfLessAndEq a b
/-- Comparison via `compare` is equal to the canonical comparison given decidable `<` and `=`. -/
compare_eq_compareOfLessAndEq : ∀ a b, compare a b = compareOfLessAndEq a b := by
compareOfLessAndEq_rfl
le_total
theorem
: ∀ a b : α, a ≤ b ∨ b ≤ a
lemma le_total : ∀ a b : α, a ≤ b ∨ b ≤ a := LinearOrder.le_total
le_of_not_ge
theorem
: ¬a ≥ b → a ≤ b
lemma le_of_not_ge : ¬a ≥ b → a ≤ b := (le_total b a).resolve_left
le_of_not_le
theorem
: ¬a ≤ b → b ≤ a
lemma le_of_not_le : ¬a ≤ b → b ≤ a := (le_total a b).resolve_left
lt_of_not_ge
theorem
(h : ¬a ≥ b) : a < b
lemma lt_of_not_ge (h : ¬a ≥ b) : a < b := lt_of_le_not_le (le_of_not_ge h) h
lt_trichotomy
theorem
(a b : α) : a < b ∨ a = b ∨ b < a
lemma lt_trichotomy (a b : α) : a < b ∨ a = b ∨ b < a :=
Or.elim (le_total a b)
(fun h : a ≤ b =>
Or.elim (Decidable.lt_or_eq_of_le h) (fun h : a < b => Or.inl h) fun h : a = b =>
Or.inr (Or.inl h))
fun h : b ≤ a =>
Or.elim (Decidable.lt_or_eq_of_le h) (fun h : b < a => Or.inr (Or.inr h)) fun h : b = a =>
Or.inr (Or.inl h.symm)
le_of_not_lt
theorem
(h : ¬b < a) : a ≤ b
le_of_not_gt
theorem
: ¬a > b → a ≤ b
lemma le_of_not_gt : ¬a > b → a ≤ b := le_of_not_lt
lt_or_le
theorem
(a b : α) : a < b ∨ b ≤ a
lemma lt_or_le (a b : α) : a < b ∨ b ≤ a :=
if hba : b ≤ a then Or.inr hba else Or.inl <| lt_of_not_ge hba
le_or_lt
theorem
(a b : α) : a ≤ b ∨ b < a
lemma le_or_lt (a b : α) : a ≤ b ∨ b < a := (lt_or_le b a).symm
lt_or_ge
theorem
: ∀ a b : α, a < b ∨ a ≥ b
lemma lt_or_ge : ∀ a b : α, a < b ∨ a ≥ b := lt_or_le
le_or_gt
theorem
: ∀ a b : α, a ≤ b ∨ a > b
lemma le_or_gt : ∀ a b : α, a ≤ b ∨ a > b := le_or_lt
lt_or_gt_of_ne
theorem
(h : a ≠ b) : a < b ∨ a > b
lemma lt_or_gt_of_ne (h : a ≠ b) : a < b ∨ a > b := by simpa [h] using lt_trichotomy a b
ne_iff_lt_or_gt
theorem
: a ≠ b ↔ a < b ∨ a > b
lemma ne_iff_lt_or_gt : a ≠ ba ≠ b ↔ a < b ∨ a > b := ⟨lt_or_gt_of_ne, (Or.elim · ne_of_lt ne_of_gt)⟩
lt_iff_not_ge
theorem
(x y : α) : x < y ↔ ¬x ≥ y
lemma lt_iff_not_ge (x y : α) : x < y ↔ ¬x ≥ y := ⟨not_le_of_gt, lt_of_not_ge⟩
not_lt
theorem
: ¬a < b ↔ b ≤ a
@[simp] lemma not_lt : ¬a < b¬a < b ↔ b ≤ a := ⟨le_of_not_gt, not_lt_of_ge⟩
not_le
theorem
: ¬a ≤ b ↔ b < a
@[simp] lemma not_le : ¬a ≤ b¬a ≤ b ↔ b < a := (lt_iff_not_ge _ _).symm
ltByCases
definition
(x y : α) {P : Sort*} (h₁ : x < y → P) (h₂ : x = y → P) (h₃ : y < x → P) : P
/-- Perform a case-split on the ordering of `x` and `y` in a decidable linear order. -/
def ltByCases (x y : α) {P : Sort*} (h₁ : x < y → P) (h₂ : x = y → P) (h₃ : y < x → P) : P :=
if h : x < y then h₁ h
else if h' : y < x then h₃ h' else h₂ (le_antisymm (le_of_not_gt h') (le_of_not_gt h))
le_imp_le_of_lt_imp_lt
theorem
{α β} [Preorder α] [LinearOrder β] {a b : α} {c d : β} (H : d < c → b < a) (h : a ≤ b) : c ≤ d
theorem le_imp_le_of_lt_imp_lt {α β} [Preorder α] [LinearOrder β] {a b : α} {c d : β}
(H : d < c → b < a) (h : a ≤ b) : c ≤ d :=
le_of_not_lt fun h' => not_le_of_gt (H h') h
min_def
theorem
(a b : α) : min a b = if a ≤ b then a else b
lemma min_def (a b : α) : min a b = if a ≤ b then a else b := by rw [LinearOrder.min_def a]
max_def
theorem
(a b : α) : max a b = if a ≤ b then b else a
lemma max_def (a b : α) : max a b = if a ≤ b then b else a := by rw [LinearOrder.max_def a]
min_le_left
theorem
(a b : α) : min a b ≤ a
lemma min_le_left (a b : α) : min a b ≤ a := by
if h : a ≤ b
then simp [min_def, if_pos h, le_refl]
else simpa [min_def, if_neg h] using le_of_not_le h
min_le_right
theorem
(a b : α) : min a b ≤ b
le_min
theorem
(h₁ : c ≤ a) (h₂ : c ≤ b) : c ≤ min a b
le_max_left
theorem
(a b : α) : a ≤ max a b
le_max_right
theorem
(a b : α) : b ≤ max a b
lemma le_max_right (a b : α) : b ≤ max a b := by
if h : a ≤ b
then simp [max_def, if_pos h, le_refl]
else simpa [max_def, if_neg h] using le_of_not_le h
max_le
theorem
(h₁ : a ≤ c) (h₂ : b ≤ c) : max a b ≤ c
min_comm
theorem
(a b : α) : min a b = min b a
lemma min_comm (a b : α) : min a b = min b a :=
eq_min (min_le_right a b) (min_le_left a b) fun h₁ h₂ => le_min h₂ h₁
min_assoc
theorem
(a b c : α) : min (min a b) c = min a (min b c)
lemma min_assoc (a b c : α) : min (min a b) c = min a (min b c) := by
apply eq_min
· apply le_trans (min_le_left ..) (min_le_left ..)
· apply le_min
· apply le_trans (min_le_left ..) (min_le_right ..)
· apply min_le_right
· intro d h₁ h₂; apply le_min
· apply le_min h₁; apply le_trans h₂; apply min_le_left
· apply le_trans h₂; apply min_le_right
min_left_comm
theorem
(a b c : α) : min a (min b c) = min b (min a c)
min_self
theorem
(a : α) : min a a = a
min_eq_left
theorem
(h : a ≤ b) : min a b = a
lemma min_eq_left (h : a ≤ b) : min a b = a := by
apply Eq.symm; apply eq_min (le_refl _) h; intros; assumption
min_eq_right
theorem
(h : b ≤ a) : min a b = b
lemma min_eq_right (h : b ≤ a) : min a b = b := min_comm b a ▸ min_eq_left h
max_comm
theorem
(a b : α) : max a b = max b a
lemma max_comm (a b : α) : max a b = max b a :=
eq_max (le_max_right a b) (le_max_left a b) fun h₁ h₂ => max_le h₂ h₁
max_assoc
theorem
(a b c : α) : max (max a b) c = max a (max b c)
lemma max_assoc (a b c : α) : max (max a b) c = max a (max b c) := by
apply eq_max
· apply le_trans (le_max_left a b) (le_max_left ..)
· apply max_le
· apply le_trans (le_max_right a b) (le_max_left ..)
· apply le_max_right
· intro d h₁ h₂; apply max_le
· apply max_le h₁; apply le_trans (le_max_left _ _) h₂
· apply le_trans (le_max_right _ _) h₂
max_left_comm
theorem
(a b c : α) : max a (max b c) = max b (max a c)
max_self
theorem
(a : α) : max a a = a
max_eq_left
theorem
(h : b ≤ a) : max a b = a
lemma max_eq_left (h : b ≤ a) : max a b = a := by
apply Eq.symm; apply eq_max (le_refl _) h; intros; assumption
max_eq_right
theorem
(h : a ≤ b) : max a b = b
lemma max_eq_right (h : a ≤ b) : max a b = b := max_comm b a ▸ max_eq_left h
min_eq_left_of_lt
theorem
(h : a < b) : min a b = a
lemma min_eq_left_of_lt (h : a < b) : min a b = a := min_eq_left (le_of_lt h)
min_eq_right_of_lt
theorem
(h : b < a) : min a b = b
lemma min_eq_right_of_lt (h : b < a) : min a b = b := min_eq_right (le_of_lt h)
max_eq_left_of_lt
theorem
(h : b < a) : max a b = a
lemma max_eq_left_of_lt (h : b < a) : max a b = a := max_eq_left (le_of_lt h)
max_eq_right_of_lt
theorem
(h : a < b) : max a b = b
lemma max_eq_right_of_lt (h : a < b) : max a b = b := max_eq_right (le_of_lt h)
lt_min
theorem
(h₁ : a < b) (h₂ : a < c) : a < min b c
lemma lt_min (h₁ : a < b) (h₂ : a < c) : a < min b c := by
cases le_total b c <;> simp [min_eq_left, min_eq_right, *]
max_lt
theorem
(h₁ : a < c) (h₂ : b < c) : max a b < c
lemma max_lt (h₁ : a < c) (h₂ : b < c) : max a b < c := by
cases le_total a b <;> simp [max_eq_left, max_eq_right, *]
compare_lt_iff_lt
theorem
: compare a b = .lt ↔ a < b
lemma compare_lt_iff_lt : comparecompare a b = .lt ↔ a < b := by
rw [LinearOrder.compare_eq_compareOfLessAndEq, compareOfLessAndEq]
split_ifs <;> simp only [*, lt_irrefl, reduceCtorEq]
compare_gt_iff_gt
theorem
: compare a b = .gt ↔ a > b
lemma compare_gt_iff_gt : comparecompare a b = .gt ↔ a > b := by
rw [LinearOrder.compare_eq_compareOfLessAndEq, compareOfLessAndEq]
split_ifs <;> simp only [*, lt_irrefl, not_lt_of_gt, reduceCtorEq]
case _ h₁ h₂ =>
have h : b < a := lt_trichotomy a b |>.resolve_left h₁ |>.resolve_left h₂
rwa [true_iff]
compare_eq_iff_eq
theorem
: compare a b = .eq ↔ a = b
lemma compare_eq_iff_eq : comparecompare a b = .eq ↔ a = b := by
rw [LinearOrder.compare_eq_compareOfLessAndEq, compareOfLessAndEq]
split_ifs <;> try simp only [reduceCtorEq]
case _ h => rw [false_iff]; exact ne_iff_lt_or_gt.2 <| .inl h
case _ _ h => rwa [true_iff]
case _ _ h => rwa [false_iff]
compare_le_iff_le
theorem
: compare a b ≠ .gt ↔ a ≤ b
lemma compare_le_iff_le : comparecompare a b ≠ .gtcompare a b ≠ .gt ↔ a ≤ b := by
cases h : compare a b <;> simp
· exact le_of_lt <| compare_lt_iff_lt.1 h
· exact le_of_eq <| compare_eq_iff_eq.1 h
· exact compare_gt_iff_gt.1 h
compare_ge_iff_ge
theorem
: compare a b ≠ .lt ↔ a ≥ b
lemma compare_ge_iff_ge : comparecompare a b ≠ .ltcompare a b ≠ .lt ↔ a ≥ b := by
cases h : compare a b <;> simp
· exact compare_lt_iff_lt.1 h
· exact le_of_eq <| (·.symm) <| compare_eq_iff_eq.1 h
· exact le_of_lt <| compare_gt_iff_gt.1 h
compare_iff
theorem
(a b : α) {o : Ordering} : compare a b = o ↔ o.Compares a b
lemma compare_iff (a b : α) {o : Ordering} : comparecompare a b = o ↔ o.Compares a b := by
cases o <;> simp only [Ordering.Compares]
· exact compare_lt_iff_lt
· exact compare_eq_iff_eq
· exact compare_gt_iff_gt
cmp_eq_compare
theorem
(a b : α) : cmp a b = compare a b
theorem cmp_eq_compare (a b : α) : cmp a b = compare a b := by
refine ((compare_iff ..).2 ?_).symm
unfold cmp cmpUsing; split_ifs with h1 h2
· exact h1
· exact h2
· exact le_antisymm (not_lt.1 h2) (not_lt.1 h1)
cmp_eq_compareOfLessAndEq
theorem
(a b : α) : cmp a b = compareOfLessAndEq a b
theorem cmp_eq_compareOfLessAndEq (a b : α) : cmp a b = compareOfLessAndEq a b :=
(cmp_eq_compare ..).trans (LinearOrder.compare_eq_compareOfLessAndEq ..)
instLawfulCmpCompare_mathlib
instance
: Batteries.LawfulCmp (compare (α := α))
instance : Batteries.LawfulCmp (compare (α := α)) where
symm a b := by
cases h : compare a b <;>
simp only [Ordering.swap] <;> symm
· exact compare_gt_iff_gt.2 <| compare_lt_iff_lt.1 h
· exact compare_eq_iff_eq.2 <| compare_eq_iff_eq.1 h |>.symm
· exact compare_lt_iff_lt.2 <| compare_gt_iff_gt.1 h
le_trans := fun h₁ h₂ ↦
compare_le_iff_le.2 <| le_trans (compare_le_iff_le.1 h₁) (compare_le_iff_le.1 h₂)
cmp_iff_beq := by simp [compare_eq_iff_eq]
cmp_iff_lt := by simp [compare_lt_iff_lt]
cmp_iff_le := by simp [compare_le_iff_le]