|
| 1 | +/- |
| 2 | +Copyright (c) 2019 Scott Morrison. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Scott Morrison, Minchao Wu |
| 5 | +-/ |
| 6 | +import Mathlib.Order.BoundedOrder |
| 7 | + |
| 8 | +/-! |
| 9 | +# Lexicographic order |
| 10 | +
|
| 11 | +This file defines the lexicographic relation for pairs of orders, partial orders and linear orders. |
| 12 | +
|
| 13 | +## Main declarations |
| 14 | +
|
| 15 | +* `Prod.Lex.<pre/partial/linear>Order`: Instances lifting the orders on `α` and `β` to `α ×ₗ β`. |
| 16 | +
|
| 17 | +## Notation |
| 18 | +
|
| 19 | +* `α ×ₗ β`: `α × β` equipped with the lexicographic order |
| 20 | +
|
| 21 | +## See also |
| 22 | +
|
| 23 | +Related files are: |
| 24 | +* `Data.Finset.CoLex`: Colexicographic order on finite sets. |
| 25 | +* `Data.List.Lex`: Lexicographic order on lists. |
| 26 | +* `Data.Pi.Lex`: Lexicographic order on `Πₗ i, α i`. |
| 27 | +* `Data.PSigma.Order`: Lexicographic order on `Σ' i, α i`. |
| 28 | +* `Data.Sigma.Order`: Lexicographic order on `Σ i, α i`. |
| 29 | +-/ |
| 30 | + |
| 31 | + |
| 32 | +variable {α β γ : Type _} |
| 33 | + |
| 34 | +namespace Prod.Lex |
| 35 | + |
| 36 | +-- porting note: `Prod.Lex` is not protected in core, hence the `_root_.` prefix |
| 37 | +-- This will be fixed in nightly-2022-11-30 |
| 38 | +@[inherit_doc] notation:35 α " ×ₗ " β:34 => _root_.Lex (Prod α β) |
| 39 | + |
| 40 | +instance decidableEq (α β : Type _) [DecidableEq α] [DecidableEq β] : DecidableEq (α ×ₗ β) := |
| 41 | + instDecidableEqProd |
| 42 | +#align prod.lex.decidable_eq Prod.Lex.decidableEq |
| 43 | + |
| 44 | +instance inhabited (α β : Type _) [Inhabited α] [Inhabited β] : Inhabited (α ×ₗ β) := |
| 45 | + instInhabitedProd |
| 46 | +#align prod.lex.inhabited Prod.Lex.inhabited |
| 47 | + |
| 48 | +/-- Dictionary / lexicographic ordering on pairs. -/ |
| 49 | +instance instLE (α β : Type _) [LT α] [LE β] : LE (α ×ₗ β) where le := Prod.Lex (· < ·) (· ≤ ·) |
| 50 | +#align prod.lex.has_le Prod.Lex.instLE |
| 51 | + |
| 52 | +instance instLT (α β : Type _) [LT α] [LT β] : LT (α ×ₗ β) where lt := Prod.Lex (· < ·) (· < ·) |
| 53 | +#align prod.lex.has_lt Prod.Lex.instLT |
| 54 | + |
| 55 | +theorem le_iff [LT α] [LE β] (a b : α × β) : |
| 56 | + toLex a ≤ toLex b ↔ a.1 < b.1 ∨ a.1 = b.1 ∧ a.2 ≤ b.2 := |
| 57 | + Prod.lex_def (· < ·) (· ≤ ·) |
| 58 | +#align prod.lex.le_iff Prod.Lex.le_iff |
| 59 | + |
| 60 | +theorem lt_iff [LT α] [LT β] (a b : α × β) : |
| 61 | + toLex a < toLex b ↔ a.1 < b.1 ∨ a.1 = b.1 ∧ a.2 < b.2 := |
| 62 | + Prod.lex_def (· < ·) (· < ·) |
| 63 | +#align prod.lex.lt_iff Prod.Lex.lt_iff |
| 64 | + |
| 65 | +example (x : α) (y : β) : toLex (x, y) = toLex (x, y) := rfl |
| 66 | + |
| 67 | +/-- Dictionary / lexicographic preorder for pairs. -/ |
| 68 | +instance preorder (α β : Type _) [Preorder α] [Preorder β] : Preorder (α ×ₗ β) := |
| 69 | + { Prod.Lex.instLE α β, Prod.Lex.instLT α β with |
| 70 | + le_refl := refl_of <| Prod.Lex _ _, |
| 71 | + le_trans := fun _ _ _ => trans_of <| Prod.Lex _ _, |
| 72 | + lt_iff_le_not_le := fun x₁ x₂ => |
| 73 | + match x₁, x₂ with |
| 74 | + | (a₁, b₁), (a₂, b₂) => by |
| 75 | + constructor |
| 76 | + · rintro (⟨_, _, hlt⟩ | ⟨_, hlt⟩) |
| 77 | + · constructor |
| 78 | + · exact left _ _ hlt |
| 79 | + · rintro ⟨⟩ |
| 80 | + · apply lt_asymm hlt; assumption |
| 81 | + · exact lt_irrefl _ hlt |
| 82 | + · constructor |
| 83 | + · right |
| 84 | + rw [lt_iff_le_not_le] at hlt |
| 85 | + exact hlt.1 |
| 86 | + · rintro ⟨⟩ |
| 87 | + · apply lt_irrefl a₁ |
| 88 | + assumption |
| 89 | + · rw [lt_iff_le_not_le] at hlt |
| 90 | + apply hlt.2 |
| 91 | + assumption |
| 92 | + · rintro ⟨⟨⟩, h₂r⟩ |
| 93 | + · left |
| 94 | + assumption |
| 95 | + · right |
| 96 | + rw [lt_iff_le_not_le] |
| 97 | + constructor |
| 98 | + · assumption |
| 99 | + · intro h |
| 100 | + apply h₂r |
| 101 | + right |
| 102 | + exact h } |
| 103 | +#align prod.lex.preorder Prod.Lex.preorder |
| 104 | + |
| 105 | +section Preorder |
| 106 | + |
| 107 | +variable [PartialOrder α] [Preorder β] |
| 108 | + |
| 109 | +-- porting note: type class search sees right through the type synonrm for `α ×ₗ β` and uses the |
| 110 | +-- `Preorder` structure for `α × β` instead |
| 111 | +-- This is hopefully the same problems as in https://github.com/leanprover/lean4/issues/1891 |
| 112 | +-- and will be fixed in nightly-2022-11-30 |
| 113 | +theorem toLex_mono : @Monotone _ _ _ (Prod.Lex.preorder α β) (toLex : α × β → α ×ₗ β) := by |
| 114 | + rintro ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ ⟨ha, hb⟩ |
| 115 | + obtain rfl | ha : a₁ = a₂ ∨ _ := ha.eq_or_lt |
| 116 | + · exact right _ hb |
| 117 | + · exact left _ _ ha |
| 118 | +#align prod.lex.to_lex_mono Prod.Lex.toLex_mono |
| 119 | + |
| 120 | +-- porting note: type class search sees right through the type synonrm for `α ×ₗ β` and uses the |
| 121 | +-- `Preorder` structure for `α × β` instead |
| 122 | +-- This is hopefully the same problems as in https://github.com/leanprover/lean4/issues/1891 |
| 123 | +-- and will be fixed in nightly-2022-11-30 |
| 124 | +theorem toLex_strictMono : @StrictMono _ _ _ (Prod.Lex.preorder α β) (toLex : α × β → α ×ₗ β) := by |
| 125 | + rintro ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ h |
| 126 | + obtain rfl | ha : a₁ = a₂ ∨ _ := h.le.1.eq_or_lt |
| 127 | + · exact right _ (Prod.mk_lt_mk_iff_right.1 h) |
| 128 | + · exact left _ _ ha |
| 129 | + |
| 130 | +#align prod.lex.to_lex_strict_mono Prod.Lex.toLex_strictMono |
| 131 | + |
| 132 | +end Preorder |
| 133 | + |
| 134 | +/-- Dictionary / lexicographic partial order for pairs. -/ |
| 135 | +instance partialOrder (α β : Type _) [PartialOrder α] [PartialOrder β] : PartialOrder (α ×ₗ β) := |
| 136 | + { Prod.Lex.preorder α β with |
| 137 | + le_antisymm := by |
| 138 | + haveI : IsStrictOrder α (· < ·) := { irrefl := lt_irrefl, trans := fun _ _ _ => lt_trans } |
| 139 | + haveI : IsAntisymm β (· ≤ ·) := ⟨fun _ _ => le_antisymm⟩ |
| 140 | + exact @antisymm _ (Prod.Lex _ _) _ } |
| 141 | +#align prod.lex.partial_order Prod.Lex.partialOrder |
| 142 | + |
| 143 | +/-- Dictionary / lexicographic linear order for pairs. -/ |
| 144 | +instance linearOrder (α β : Type _) [LinearOrder α] [LinearOrder β] : LinearOrder (α ×ₗ β) := |
| 145 | + { Prod.Lex.partialOrder α β with |
| 146 | + le_total := total_of (Prod.Lex _ _), |
| 147 | + decidable_le := Prod.Lex.decidable _ _, |
| 148 | + decidable_lt := Prod.Lex.decidable _ _, |
| 149 | + decidable_eq := Lex.decidableEq _ _, } |
| 150 | +#align prod.lex.linear_order Prod.Lex.linearOrder |
| 151 | + |
| 152 | +instance orderBot [PartialOrder α] [Preorder β] [OrderBot α] [OrderBot β] : OrderBot (α ×ₗ β) where |
| 153 | + bot := toLex ⊥ |
| 154 | + bot_le _ := toLex_mono bot_le |
| 155 | +#align prod.lex.order_bot Prod.Lex.orderBot |
| 156 | + |
| 157 | +instance orderTop [PartialOrder α] [Preorder β] [OrderTop α] [OrderTop β] : OrderTop (α ×ₗ β) where |
| 158 | + top := toLex ⊤ |
| 159 | + le_top _ := toLex_mono le_top |
| 160 | +#align prod.lex.order_top Prod.Lex.orderTop |
| 161 | + |
| 162 | +instance boundedOrder [PartialOrder α] [Preorder β] [BoundedOrder α] [BoundedOrder β] : |
| 163 | + BoundedOrder (α ×ₗ β) := |
| 164 | + { Lex.orderBot, Lex.orderTop with } |
| 165 | +#align prod.lex.bounded_order Prod.Lex.boundedOrder |
| 166 | + |
| 167 | +instance [Preorder α] [Preorder β] [DenselyOrdered α] [DenselyOrdered β] : |
| 168 | + DenselyOrdered (α ×ₗ β) where |
| 169 | + dense := by |
| 170 | + rintro _ _ (@⟨a₁, b₁, a₂, b₂, h⟩ | @⟨a, b₁, b₂, h⟩) |
| 171 | + · obtain ⟨c, h₁, h₂⟩ := exists_between h |
| 172 | + exact ⟨(c, b₁), left _ _ h₁, left _ _ h₂⟩ |
| 173 | + · obtain ⟨c, h₁, h₂⟩ := exists_between h |
| 174 | + exact ⟨(a, c), right _ h₁, right _ h₂⟩ |
| 175 | + |
| 176 | +instance noMaxOrder_of_left [Preorder α] [Preorder β] [NoMaxOrder α] : NoMaxOrder (α ×ₗ β) where |
| 177 | + exists_gt := by |
| 178 | + rintro ⟨a, b⟩ |
| 179 | + obtain ⟨c, h⟩ := exists_gt a |
| 180 | + exact ⟨⟨c, b⟩, left _ _ h⟩ |
| 181 | +#align prod.lex.no_max_order_of_left Prod.Lex.noMaxOrder_of_left |
| 182 | + |
| 183 | +instance noMinOrder_of_left [Preorder α] [Preorder β] [NoMinOrder α] : NoMinOrder (α ×ₗ β) where |
| 184 | + exists_lt := by |
| 185 | + rintro ⟨a, b⟩ |
| 186 | + obtain ⟨c, h⟩ := exists_lt a |
| 187 | + exact ⟨⟨c, b⟩, left _ _ h⟩ |
| 188 | +#align prod.lex.no_min_order_of_left Prod.Lex.noMinOrder_of_left |
| 189 | + |
| 190 | +instance noMaxOrder_of_right [Preorder α] [Preorder β] [NoMaxOrder β] : NoMaxOrder (α ×ₗ β) where |
| 191 | + exists_gt := by |
| 192 | + rintro ⟨a, b⟩ |
| 193 | + obtain ⟨c, h⟩ := exists_gt b |
| 194 | + exact ⟨⟨a, c⟩, right _ h⟩ |
| 195 | +#align prod.lex.no_max_order_of_right Prod.Lex.noMaxOrder_of_right |
| 196 | + |
| 197 | +instance noMinOrder_of_right [Preorder α] [Preorder β] [NoMinOrder β] : NoMinOrder (α ×ₗ β) where |
| 198 | + exists_lt := by |
| 199 | + rintro ⟨a, b⟩ |
| 200 | + obtain ⟨c, h⟩ := exists_lt b |
| 201 | + exact ⟨⟨a, c⟩, right _ h⟩ |
| 202 | +#align prod.lex.no_min_order_of_right Prod.Lex.noMinOrder_of_right |
| 203 | + |
| 204 | +end Prod.Lex |
0 commit comments