-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
import Mathlib.SetTheory.Cardinal.Order
noncomputable section
namespace Sorting
universe u
variable {α : Type u}
open Function Cardinal in
theorem nonempty_embedding_to_cardinal : Nonempty (α ↪ Cardinal.{u}) :=
(Embedding.total _ _).resolve_left fun ⟨⟨f, hf⟩⟩ =>
let g : α → Cardinal.{u} := invFun f
let ⟨x, (hx : g x = 2 ^ sum g)⟩ := invFun_surjective hf (2 ^ sum g)
have : g x ≤ sum g := le_sum.{u, u} g x
not_le_of_gt (by rw [hx]; exact cantor _) this
/-- An embedding of any type to the set of cardinals in its universe. -/
def embeddingToCardinal : α ↪ Cardinal.{u} :=
Classical.choice nonempty_embedding_to_cardinal
/-- Any type can be endowed with a well order, obtained by pulling back the well order over
cardinals by some embedding. -/
def WellOrderingRel : α → α → Prop :=
embeddingToCardinal ⁻¹'o (· < ·)
instance WellOrderingRel.isWellOrder : IsWellOrder α WellOrderingRel :=
(RelEmbedding.preimage _ _).isWellOrder
abbrev linearOrderOfSTO (r) [IsStrictTotalOrder α r] [DecidableRel r] : LinearOrder α :=
let hD : DecidableRel (fun x y => x = y ∨ r x y) := fun x y => decidable_of_iff (¬r y x)
⟨fun h => ((trichotomous_of r y x).resolve_left h).imp Eq.symm id, fun h =>
h.elim (fun h => h ▸ irrefl_of _ _) (asymm_of r)⟩
{ __ := partialOrderOfSO r
le_total := fun x y =>
match y, trichotomous_of r x y with
| _, Or.inl h => Or.inl (Or.inr h)
| _, Or.inr (Or.inl rfl) => Or.inl (Or.inl rfl)
| _, Or.inr (Or.inr h) => Or.inr (Or.inr h),
toMin := minOfLe,
toMax := maxOfLe,
toDecidableLE := hD }
open Classical in
instance : LinearOrder α := linearOrderOfSTO WellOrderingRel
theorem sortExists (xs : List α) : ∃ ys, ys.SortedLE ∧ xs.Perm ys := by
by_cases h : xs = []
· use []; grind
· let y := xs.min h
obtain ⟨ys, hys⟩ := sortExists (xs.erase y)
use y :: ys
constructor
· have : ∀ z ∈ xs.erase y, y ≤ z := fun z hz ↦ xs.min_le_of_mem (by grind)
cases ys <;> grind
· grind [xs.min_mem h]
termination_by xs.length
decreasing_by grind [List.length_erase_of_mem, List.min_mem]
end Sorting