-
Notifications
You must be signed in to change notification settings - Fork 1k
[Merged by Bors] - feat(Order): order types #34034
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
117691e
e08c49b
6960dd6
c1c3030
128541e
9ee99e6
ffbea39
36dfe77
4ef3d57
a981b24
9b8172d
4e287b4
f08a940
1f43cc5
f18d7ef
e3fdcd3
1f2e93f
54b5adc
f2efcba
48c0458
7e7c6db
d2c7af2
5cce5a8
66c1281
ab2ce09
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,243 @@ | ||||||||||
| /- | ||||||||||
| Copyright (c) 2025 Yan Yablonovskiy. All rights reserved. | ||||||||||
| Released under Apache 2.0 license as described in the file LICENSE. | ||||||||||
| Authors: Yan Yablonovskiy | ||||||||||
| -/ | ||||||||||
| module | ||||||||||
|
|
||||||||||
| public import Mathlib.Order.Hom.Basic | ||||||||||
|
|
||||||||||
| /-! | ||||||||||
| # Order types | ||||||||||
|
|
||||||||||
| Order types are defined as the quotient of linear orders under order isomorphism. They are endowed | ||||||||||
| with a preorder, where an OrderType is ≤ to another when there is an order embedding | ||||||||||
| into it. | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| ## Main definitions | ||||||||||
|
|
||||||||||
| * `OrderType`: the type of order types (in a given universe) | ||||||||||
| * `OrderType.type α`: given a type `α` with a linear order, this is the corresponding OrderType, | ||||||||||
|
|
||||||||||
| A preorder with a bottom element is registered on order types, where `⊥` is | ||||||||||
| `0`, the order type corresponding to the empty type. | ||||||||||
|
|
||||||||||
| ## Notation | ||||||||||
|
|
||||||||||
| The following are notations in the `OrderType` namespace: | ||||||||||
|
|
||||||||||
| * `ω` is a notation for the order type of `ℕ` with its natural order. | ||||||||||
|
|
||||||||||
| ## References | ||||||||||
|
|
||||||||||
| * <https://en.wikipedia.org/wiki/Order_type> | ||||||||||
| * Dauben, J. W. Georg Cantor: His Mathematics and Philosophy of the Infinite. Princeton, | ||||||||||
| NJ: Princeton University Press, 1990. | ||||||||||
| * Enderton, Herbert B. Elements of Set Theory. United Kingdom: Academic Press, 1977. | ||||||||||
|
|
||||||||||
| ## Tags | ||||||||||
|
|
||||||||||
| order type, order isomorphism, linear order | ||||||||||
| -/ | ||||||||||
|
|
||||||||||
| public noncomputable section | ||||||||||
|
|
||||||||||
| open Function Set Equiv Order | ||||||||||
|
|
||||||||||
| universe u v w w' | ||||||||||
|
|
||||||||||
| variable {α : Type u} {β : Type v} {γ : Type w} {δ : Type w'} | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| /-- Equivalence relation on linear orders on arbitrary types in universe `u`, given by order | ||||||||||
| isomorphism. -/ | ||||||||||
| instance OrderType.instSetoid : Setoid LinOrd where | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| r := fun lin_ord₁ lin_ord₂ ↦ Nonempty (lin_ord₁ ≃o lin_ord₂) | ||||||||||
| iseqv := ⟨fun _ ↦ ⟨.refl _⟩, fun ⟨e⟩ ↦ ⟨e.symm⟩, fun ⟨e₁⟩ ⟨e₂⟩ ↦ ⟨e₁.trans e₂⟩⟩ | ||||||||||
|
|
||||||||||
| /-- `OrderType.{u}` is the type of linear orders in `Type u`, up to order isomorphism. -/ | ||||||||||
| @[pp_with_univ, no_expose] | ||||||||||
| def OrderType : Type (u + 1) := | ||||||||||
| Quotient OrderType.instSetoid | ||||||||||
|
|
||||||||||
| namespace OrderType | ||||||||||
|
|
||||||||||
| /-- A "canonical" type order-isomorphic to the order type `o`, living in the same universe. | ||||||||||
| This is defined through the axiom of choice. -/ | ||||||||||
| @[no_expose] | ||||||||||
| def ToType (o : OrderType) : Type u := | ||||||||||
| o.out.carrier | ||||||||||
|
|
||||||||||
| /-- The local instance for some arbitrary linear order on `Type u` , order isomorphic within | ||||||||||
| order type `o`. -/ | ||||||||||
| @[no_expose] | ||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe this is redundant, this we're not in an
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure this suggestion got applied |
||||||||||
| local instance (o : OrderType) : LinearOrder o.ToType := | ||||||||||
| o.out.str | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| /-! ### Basic properties of the order type -/ | ||||||||||
|
|
||||||||||
| /-- The order type of the linear order on `α`. -/ | ||||||||||
| @[no_expose] | ||||||||||
| def type (α : Type u) [LinearOrder α] : OrderType := | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
| ⟦⟨α⟩⟧ | ||||||||||
|
|
||||||||||
| @[no_expose] | ||||||||||
| instance : Zero OrderType where | ||||||||||
| zero := type PEmpty | ||||||||||
|
|
||||||||||
| instance inhabited : Inhabited OrderType := | ||||||||||
| ⟨0⟩ | ||||||||||
|
|
||||||||||
| @[no_expose] | ||||||||||
| instance : One OrderType where | ||||||||||
| one := type PUnit | ||||||||||
|
|
||||||||||
| @[simp] | ||||||||||
| theorem type_toType (o : OrderType) : type o.ToType = o := surjInv_eq Quot.exists_rep o | ||||||||||
|
|
||||||||||
| theorem type_eq {α β} [LinearOrder α] [LinearOrder β] : | ||||||||||
| type α = type β ↔ Nonempty (α ≃o β) := | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| Quotient.eq' | ||||||||||
|
|
||||||||||
| theorem _root_.RelIso.orderType_eq {α β} [LinearOrder α] | ||||||||||
| [LinearOrder β] (h : α ≃o β) : type α = type β := | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| type_eq.2 ⟨h⟩ | ||||||||||
|
|
||||||||||
| @[simp] | ||||||||||
| theorem type_of_isEmpty [LinearOrder α] [IsEmpty α] : type α = 0 := | ||||||||||
| (OrderIso.ofIsEmpty α PEmpty).orderType_eq | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| @[simp] | ||||||||||
| theorem type_eq_zero [LinearOrder α] : type α = 0 ↔ IsEmpty α := | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| ⟨fun h ↦ | ||||||||||
| let ⟨s⟩ := type_eq.1 h | ||||||||||
| s.toEquiv.isEmpty, | ||||||||||
| @type_of_isEmpty α _⟩ | ||||||||||
|
|
||||||||||
| theorem type_ne_zero_iff [LinearOrder α] : type α ≠ 0 ↔ Nonempty α := by simp | ||||||||||
|
||||||||||
|
|
||||||||||
| theorem type_ne_zero [LinearOrder α] [h : Nonempty α] : type α ≠ 0 := | ||||||||||
| type_ne_zero_iff.2 h | ||||||||||
|
|
||||||||||
| @[simp] | ||||||||||
| theorem type_of_unique [LinearOrder α] [Nonempty α] [Subsingleton α] : type α = 1 := by | ||||||||||
| cases nonempty_unique α | ||||||||||
| exact (OrderIso.ofUnique α _).orderType_eq | ||||||||||
|
|
||||||||||
| @[simp] | ||||||||||
| theorem type_eq_one [LinearOrder α] : type α = 1 ↔ Nonempty (Unique α) := | ||||||||||
YaelDillies marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| ⟨fun h ↦ let ⟨s⟩ := type_eq.1 h; ⟨s.toEquiv.unique⟩, | ||||||||||
| fun ⟨_⟩ ↦ type_of_unique⟩ | ||||||||||
|
|
||||||||||
| @[simp] | ||||||||||
| private theorem isEmpty_toType_iff {o : OrderType} : IsEmpty o.ToType ↔ o = 0 := by | ||||||||||
| rw [← @type_eq_zero o.ToType, type_toType] | ||||||||||
|
|
||||||||||
| @[simp] | ||||||||||
| private theorem nonempty_toType_iff {o : OrderType} : Nonempty o.ToType ↔ o ≠ 0 := by | ||||||||||
| rw [← @type_ne_zero_iff o.ToType, type_toType] | ||||||||||
|
|
||||||||||
| protected theorem one_ne_zero : (1 : OrderType) ≠ 0 := | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| type_ne_zero | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| instance nontrivial : Nontrivial OrderType.{u} := | ||||||||||
| ⟨⟨1, 0, OrderType.one_ne_zero⟩⟩ | ||||||||||
|
|
||||||||||
| /-- `Quotient.inductionOn` specialized to `OrderType`. -/ | ||||||||||
| @[elab_as_elim] | ||||||||||
| theorem inductionOn {C : OrderType → Prop} (o : OrderType) | ||||||||||
| (H : ∀ α [LinearOrder α], C (type α)) : C o := | ||||||||||
| Quot.inductionOn o (fun α ↦ H α) | ||||||||||
|
|
||||||||||
| /-- `Quotient.inductionOn₂` specialized to `OrderType`. -/ | ||||||||||
| @[elab_as_elim] | ||||||||||
| theorem inductionOn₂ {C : OrderType → OrderType → Prop} (o₁ o₂ : OrderType) | ||||||||||
| (H : ∀ α [LinearOrder α] β [LinearOrder β], C (type α) (type β)) : C o₁ o₂ := | ||||||||||
| Quotient.inductionOn₂ o₁ o₂ fun α β ↦ H α β | ||||||||||
|
|
||||||||||
| /-- `Quotient.inductionOn₃` specialized to `OrderType`. -/ | ||||||||||
| @[elab_as_elim] | ||||||||||
| theorem inductionOn₃ {C : OrderType → OrderType → OrderType → Prop} (o₁ o₂ o₃ : OrderType) | ||||||||||
| (H : ∀ α [LinearOrder α] β [LinearOrder β] γ [LinearOrder γ], | ||||||||||
| C (type α) (type β) (type γ)) : C o₁ o₂ o₃ := | ||||||||||
| Quotient.inductionOn₃ o₁ o₂ o₃ fun α β γ ↦ | ||||||||||
| H α β γ | ||||||||||
|
|
||||||||||
| /-- To define a function on `OrderType`, it suffices to define it on all linear orders. | ||||||||||
| -/ | ||||||||||
| def liftOn {δ : Sort v} (o : OrderType) (f : ∀ (α) [LinearOrder α], δ) | ||||||||||
| (c : ∀ (α) [LinearOrder α] (β) [LinearOrder β], | ||||||||||
| type α = type β → f α = f β) : δ := | ||||||||||
| Quotient.liftOn o (fun w ↦ f w) | ||||||||||
| fun w₁ w₂ h ↦ c w₁ w₂ (Quotient.sound h) | ||||||||||
|
|
||||||||||
| @[simp] | ||||||||||
| theorem liftOn_type {δ : Sort v} (f : ∀ (α) [LinearOrder α], δ) | ||||||||||
| (c : ∀ (α) [LinearOrder α] (β) [LinearOrder β], | ||||||||||
| type α = type β → f α = f β) {γ} [inst : LinearOrder γ] : | ||||||||||
| liftOn (type γ) f c = f γ := by rfl | ||||||||||
|
|
||||||||||
| /-! ### The order on `OrderType` -/ | ||||||||||
|
|
||||||||||
| /-- | ||||||||||
| The order is defined so that `type α ≤ type β` iff there exists an order embedding `α ↪o β`. | ||||||||||
| -/ | ||||||||||
| @[no_expose] | ||||||||||
YaelDillies marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
| instance : Preorder OrderType where | ||||||||||
| le o₁ o₂ := | ||||||||||
| Quotient.liftOn₂ o₁ o₂ (fun r s ↦ Nonempty (r ↪o s)) | ||||||||||
| fun _ _ _ _ ⟨f⟩ ⟨g⟩ ↦ propext | ||||||||||
| ⟨fun ⟨h⟩ ↦ ⟨(f.symm.toOrderEmbedding.trans h).trans g.toOrderEmbedding⟩, fun ⟨h⟩ ↦ | ||||||||||
| ⟨(f.toOrderEmbedding.trans h).trans g.symm.toOrderEmbedding⟩⟩ | ||||||||||
| le_refl o := inductionOn o (fun α _ ↦ ⟨(OrderIso.refl _).toOrderEmbedding⟩) | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| le_trans o₁ o₂ o₃ := inductionOn₃ o₁ o₂ o₃ fun _ _ _ _ _ _ ⟨f⟩ ⟨g⟩ ↦ ⟨f.trans g⟩ | ||||||||||
|
|
||||||||||
| instance instNeZeroOne : NeZero (1 : OrderType) := | ||||||||||
| ⟨OrderType.one_ne_zero⟩ | ||||||||||
|
|
||||||||||
| theorem type_le_type_iff {α β} [LinearOrder α] | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| [LinearOrder β] : type α ≤ type β ↔ Nonempty (α ↪o β) := | ||||||||||
| .rfl | ||||||||||
|
|
||||||||||
| theorem type_le_type {α β} | ||||||||||
| [LinearOrder α] [LinearOrder β] (h : α ↪o β) : type α ≤ type β := | ||||||||||
| ⟨h⟩ | ||||||||||
|
|
||||||||||
| theorem type_lt_type {α β} | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| [LinearOrder α] [LinearOrder β] (h : α ↪o β) (hne : ¬(Nonempty (β ↪o α))) : type α < type β := | ||||||||||
| ⟨⟨h⟩,hne⟩ | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| alias _root_.OrderEmbedding.type_le_type := type_le_type | ||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this be?
Suggested change
I do find this name extremely clunky. Perhaps we can stretch the naming conventions just a bit?
Suggested change
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current name is okay if we believe that
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's also |
||||||||||
|
|
||||||||||
| @[simp] | ||||||||||
| protected theorem zero_le (o : OrderType) : 0 ≤ o := | ||||||||||
| inductionOn o (fun _ ↦ OrderEmbedding.ofIsEmpty.type_le_type) | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| instance instOrdBot : OrderBot OrderType where | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| bot := 0 | ||||||||||
| bot_le := OrderType.zero_le | ||||||||||
|
|
||||||||||
| @[simp] | ||||||||||
| theorem bot_eq_zero : (⊥ : OrderType) = 0 := | ||||||||||
| rfl | ||||||||||
|
|
||||||||||
| @[simp] | ||||||||||
| protected theorem not_lt_zero (o : OrderType) : ¬o < 0 := | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
| not_lt_bot | ||||||||||
|
|
||||||||||
| @[simp] | ||||||||||
| theorem pos_iff_ne_zero (o : OrderType) : 0 < o ↔ o ≠ 0 := | ||||||||||
| ⟨ne_bot_of_gt, fun ho ↦ by | ||||||||||
| convert type_lt_type (α := PEmpty) (β := o.ToType) ⟨Function.Embedding.ofIsEmpty, by simp⟩ | ||||||||||
| (fun ⟨f⟩ ↦ PEmpty.elim (f (Classical.choice (OrderType.nonempty_toType_iff.mpr ho)))) | ||||||||||
| simp⟩ | ||||||||||
YanYablonovskiy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| /-- `ω` is the first infinite ordinal, defined as the order type of `ℕ`. -/ | ||||||||||
| -- TODO: define `OrderType.lift` and redefine this using it. | ||||||||||
| @[expose] | ||||||||||
| def omega0 : OrderType := type <| ULift ℕ | ||||||||||
|
|
||||||||||
YanYablonovskiy marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
| @[inherit_doc] | ||||||||||
| scoped notation "ω" => OrderType.omega0 | ||||||||||
| recommended_spelling "omega0" for "ω" in [omega0, «termω»] | ||||||||||
|
|
||||||||||
| end OrderType | ||||||||||
Uh oh!
There was an error while loading. Please reload this page.