evolution

The evolution of a Lean programmer

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 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