Module docstring
{"# Construct a sorted list from a multiset. "}
{"# Construct a sorted list from a multiset. "}
Multiset.sort
      definition
     (s : Multiset α) : List α
        /-- `sort s` constructs a sorted list from the multiset `s`.
  (Uses merge sort algorithm.) -/
def sort (s : Multiset α) : List α :=
  Quot.liftOn s (mergeSort · (r · ·)) fun _ _ h =>
    eq_of_perm_of_sorted ((mergeSort_perm _ _).trans <| h.trans (mergeSort_perm _ _).symm)
      (sorted_mergeSort IsTrans.trans
        (fun a b => by simpa using IsTotal.total a b) _)
      (sorted_mergeSort IsTrans.trans
        (fun a b => by simpa using IsTotal.total a b) _)
        Multiset.coe_sort
      theorem
     (l : List α) : sort r l = mergeSort l (r · ·)
        
      Multiset.sort_sorted
      theorem
     (s : Multiset α) : Sorted r (sort r s)
        @[simp]
theorem sort_sorted (s : Multiset α) : Sorted r (sort r s) :=
  Quot.inductionOn s (sorted_mergeSort' _)
        Multiset.sort_eq
      theorem
     (s : Multiset α) : ↑(sort r s) = s
        @[simp]
theorem sort_eq (s : Multiset α) : ↑(sort r s) = s :=
  Quot.inductionOn s fun _ => Quot.sound <| mergeSort_perm _ _
        Multiset.mem_sort
      theorem
     {s : Multiset α} {a : α} : a ∈ sort r s ↔ a ∈ s
        @[simp]
theorem mem_sort {s : Multiset α} {a : α} : a ∈ sort r sa ∈ sort r s ↔ a ∈ s := by rw [← mem_coe, sort_eq]
        Multiset.length_sort
      theorem
     {s : Multiset α} : (sort r s).length = card s
        @[simp]
theorem length_sort {s : Multiset α} : (sort r s).length = card s :=
  Quot.inductionOn s <| length_mergeSort
        Multiset.sort_zero
      theorem
     : sort r 0 = []
        @[simp]
theorem sort_zero : sort r 0 = [] :=
  List.mergeSort_nil
        Multiset.sort_singleton
      theorem
     (a : α) : sort r { a } = [a]
        @[simp]
theorem sort_singleton (a : α) : sort r {a} = [a] :=
  List.mergeSort_singleton a
        Multiset.map_sort
      theorem
     (f : α → β) (s : Multiset α) (hs : ∀ a ∈ s, ∀ b ∈ s, r a b ↔ r' (f a) (f b)) : (s.sort r).map f = (s.map f).sort r'
        theorem map_sort (f : α → β) (s : Multiset α)
    (hs : ∀ a ∈ s, ∀ b ∈ s, r a b ↔ r' (f a) (f b)) :
    (s.sort r).map f = (s.map f).sort r' := by
  revert s
  exact Quot.ind fun l h => map_mergeSort (l := l) (by simpa using h)
        Multiset.sort_cons
      theorem
     (a : α) (s : Multiset α) : (∀ b ∈ s, r a b) → sort r (a ::ₘ s) = a :: sort r s
        theorem sort_cons (a : α) (s : Multiset α) :
    (∀ b ∈ s, r a b) → sort r (a ::ₘ s) = a :: sort r s := by
  refine Quot.inductionOn s fun l => ?_
  simpa [mergeSort_eq_insertionSort] using insertionSort_cons r (a := a) (l := l)
        Multiset.sort_range
      theorem
     (n : ℕ) : sort (· ≤ ·) (range n) = List.range n
        @[simp]
theorem sort_range (n : ℕ) : sort (· ≤ ·) (range n) = List.range n :=
  List.mergeSort_eq_self _ (sorted_le_range n)
        Multiset.instToExprOfToLevel
      instance
     {α : Type u} [Lean.ToLevel.{u}] [Lean.ToExpr α] : Lean.ToExpr (Multiset α)
        unsafe instance {α : Type u} [Lean.ToLevelLean.ToLevel.{u}] [Lean.ToExpr α] :
    Lean.ToExpr (Multiset α) :=
  haveI u' := Lean.toLevel.{u}
  haveI α' : Q(Type u') := Lean.toTypeExpr α
  { toTypeExpr := q(Multiset $α')
    toExpr s := show Q(Multiset $α') from
      if Multiset.card s = 0 then
        q(0)
      else
        mkSetLiteralQ (α := q($α')) q(Multiset $α') (s.unquot.map Lean.toExpr)}
        Multiset.instRepr
      instance
     [Repr α] : Repr (Multiset α)
        unsafe instance [Repr α] : Repr (Multiset α) where
  reprPrec s _ :=
    if Multiset.card s = 0 then
      "0"
    else
      Std.Format.bracket "{" (Std.Format.joinSep (s.unquot.map repr) ("," ++ Std.Format.line)) "}"