Documentation

Init.Data.List.Sort.Lemmas

Basic properties of mergeSort. #

splitInTwo #

@[simp]
theorem List.splitInTwo_fst {α : Type u_1} {n : Nat} (l : { l : List α // l.length = n }) :
(List.splitInTwo l).fst = ⟨List.take ((n + 1) / 2) l.val, ⋯⟩
@[simp]
theorem List.splitInTwo_snd {α : Type u_1} {n : Nat} (l : { l : List α // l.length = n }) :
(List.splitInTwo l).snd = ⟨List.drop ((n + 1) / 2) l.val, ⋯⟩
theorem List.splitInTwo_fst_append_splitInTwo_snd {α : Type u_1} {n : Nat} (l : { l : List α // l.length = n }) :
(List.splitInTwo l).fst.val ++ (List.splitInTwo l).snd.val = l.val
theorem List.splitInTwo_cons_cons_enumFrom_fst {α : Type u_1} {a b : α} (i : Nat) (l : List α) :
(List.splitInTwo ⟨(i, a) :: (i + 1, b) :: List.enumFrom (i + 2) l, ⋯⟩).fst.val = List.enumFrom i (List.splitInTwo ⟨a :: b :: l, ⋯⟩).fst.val
theorem List.splitInTwo_cons_cons_enumFrom_snd {α : Type u_1} {a b : α} (i : Nat) (l : List α) :
(List.splitInTwo ⟨(i, a) :: (i + 1, b) :: List.enumFrom (i + 2) l, ⋯⟩).snd.val = List.enumFrom (i + (l.length + 3) / 2) (List.splitInTwo ⟨a :: b :: l, ⋯⟩).snd.val
theorem List.splitInTwo_fst_sorted {α : Type u_1} {n : Nat} {le : α → α → Prop} (l : { l : List α // l.length = n }) (h : List.Pairwise le l.val) :
theorem List.splitInTwo_snd_sorted {α : Type u_1} {n : Nat} {le : α → α → Prop} (l : { l : List α // l.length = n }) (h : List.Pairwise le l.val) :
theorem List.splitInTwo_fst_le_splitInTwo_snd {α : Type u_1} {n : Nat} {le : α → α → Prop} {l : { l : List α // l.length = n }} (h : List.Pairwise le l.val) (a b : α) :
a ∈ (List.splitInTwo l).fst.val → b ∈ (List.splitInTwo l).snd.val → le a b

enumLE #

theorem List.enumLE_trans {α : Type u_1} {le : α → α → Bool} (trans : ∀ (a b c : α), le a b = true → le b c = true → le a c = true) (a b c : Nat × α) :
List.enumLE le a b = true → List.enumLE le b c = true → List.enumLE le a c = true
theorem List.enumLE_total {α : Type u_1} {le : α → α → Bool} (total : ∀ (a b : α), (le a b || le b a) = true) (a b : Nat × α) :
(List.enumLE le a b || List.enumLE le b a) = true

merge #

theorem List.cons_merge_cons {α : Type u_1} (s : α → α → Bool) (a b : α) (l r : List α) :
(a :: l).merge (b :: r) s = if s a b = true then a :: l.merge (b :: r) s else b :: (a :: l).merge r s
@[simp]
theorem List.cons_merge_cons_pos {α : Type u_1} {a b : α} (s : α → α → Bool) (l r : List α) (h : s a b = true) :
(a :: l).merge (b :: r) s = a :: l.merge (b :: r) s
@[simp]
theorem List.cons_merge_cons_neg {α : Type u_1} {a b : α} (s : α → α → Bool) (l r : List α) (h : ¬s a b = true) :
(a :: l).merge (b :: r) s = b :: (a :: l).merge r s
@[simp, irreducible]
theorem List.length_merge {α : Type u_1} (s : α → α → Bool) (l r : List α) :
(l.merge r s).length = l.length + r.length
theorem List.mem_merge {α : Type u_1} {le : α → α → Bool} {a : α} {xs ys : List α} :
a ∈ xs.merge ys le ↔ a ∈ xs ∨ a ∈ ys

The elements of merge le xs ys are exactly the elements of xs and ys.

theorem List.mem_merge_left {α : Type u_1} {l : List α} {x : α} {r : List α} (s : α → α → Bool) (h : x ∈ l) :
x ∈ l.merge r s
theorem List.mem_merge_right {α : Type u_1} {r : List α} {x : α} {l : List α} (s : α → α → Bool) (h : x ∈ r) :
x ∈ l.merge r s
@[irreducible]
theorem List.merge_stable {α : Type u_1} {le : α → α → Bool} (xs ys : List (Nat × α)) :
(∀ (x y : Nat × α), x ∈ xs → y ∈ ys → x.fst ≤ y.fst) → List.map (fun (x : Nat × α) => x.snd) (xs.merge ys (List.enumLE le)) = (List.map (fun (x : Nat × α) => x.snd) xs).merge (List.map (fun (x : Nat × α) => x.snd) ys) le
theorem List.sorted_merge {α : Type u_1} {le : α → α → Bool} (trans : ∀ (a b c : α), le a b = true → le b c = true → le a c = true) (total : ∀ (a b : α), (le a b || le b a) = true) (l₁ l₂ : List α) (h₁ : List.Pairwise (fun (a b : α) => le a b = true) l₁) (h₂ : List.Pairwise (fun (a b : α) => le a b = true) l₂) :
List.Pairwise (fun (a b : α) => le a b = true) (l₁.merge l₂ le)

If the ordering relation le is transitive and total (i.e. le a b || le b a for all a, b) then the merge of two sorted lists is sorted.

theorem List.merge_of_le {α : Type u_1} {le : α → α → Bool} {xs ys : List α} :
(∀ (a b : α), a ∈ xs → b ∈ ys → le a b = true) → xs.merge ys le = xs ++ ys
@[irreducible]
theorem List.merge_perm_append {α : Type u_1} (le : α → α → Bool) {xs ys : List α} :
(xs.merge ys le).Perm (xs ++ ys)

mergeSort #

@[simp]
theorem List.mergeSort_nil {α✝ : Type u_1} {r : α✝ → α✝ → Bool} :
[].mergeSort r = []
@[simp]
theorem List.mergeSort_singleton {α : Type u_1} {r : α → α → Bool} (a : α) :
[a].mergeSort r = [a]
@[irreducible]
theorem List.mergeSort_perm {α : Type u_1} (l : List α) (le : α → α → Bool) :
(l.mergeSort le).Perm l
@[simp]
theorem List.length_mergeSort {α : Type u_1} {le : α → α → Bool} (l : List α) :
(l.mergeSort le).length = l.length
@[simp]
theorem List.mem_mergeSort {α : Type u_1} {le : α → α → Bool} {a : α} {l : List α} :
a ∈ l.mergeSort le ↔ a ∈ l
@[irreducible]
theorem List.sorted_mergeSort {α : Type u_1} {le : α → α → Bool} (trans : ∀ (a b c : α), le a b = true → le b c = true → le a c = true) (total : ∀ (a b : α), (le a b || le b a) = true) (l : List α) :
List.Pairwise (fun (a b : α) => le a b = true) (l.mergeSort le)

The result of mergeSort is sorted, as long as the comparison function is transitive (le a b → le b c → le a c) and total in the sense that le a b || le b a.

The comparison function need not be irreflexive, i.e. le a b and le b a is allowed even when a ≠ b.

@[reducible, inline, deprecated]
abbrev List.mergeSort_sorted {α : Type u_1} {le : α → α → Bool} (trans : ∀ (a b c : α), le a b = true → le b c = true → le a c = true) (total : ∀ (a b : α), (le a b || le b a) = true) (l : List α) :
List.Pairwise (fun (a b : α) => le a b = true) (l.mergeSort le)
Equations
Instances For
    @[irreducible]
    theorem List.mergeSort_of_sorted {α : Type u_1} {le : α → α → Bool} {l : List α} :
    List.Pairwise (fun (a b : α) => le a b = true) l → l.mergeSort le = l

    If the input list is already sorted, then mergeSort does not change the list.

    theorem List.mergeSort_enum {α : Type u_1} {le : α → α → Bool} {l : List α} :
    List.map (fun (x : Nat × α) => x.snd) (l.enum.mergeSort (List.enumLE le)) = l.mergeSort le

    This merge sort algorithm is stable, in the sense that breaking ties in the ordering function using the position in the list has no effect on the output.

    That is, elements which are equal with respect to the ordering function will remain in the same order in the output list as they were in the input list.

    See also:

    @[irreducible]
    theorem List.mergeSort_enum.go {α : Type u_1} {le : α → α → Bool} (i : Nat) (l : List α) :
    List.map (fun (x : Nat × α) => x.snd) ((List.enumFrom i l).mergeSort (List.enumLE le)) = l.mergeSort le
    theorem List.mergeSort_cons {α : Type u_1} {le : α → α → Bool} (trans : ∀ (a b c : α), le a b = true → le b c = true → le a c = true) (total : ∀ (a b : α), (le a b || le b a) = true) (a : α) (l : List α) :
    ∃ (l₁ : List α), ∃ (l₂ : List α), (a :: l).mergeSort le = l₁ ++ a :: l₂ ∧ l.mergeSort le = l₁ ++ l₂ ∧ ∀ (b : α), b ∈ l₁ → (!le a b) = true
    theorem List.sublist_mergeSort {α : Type u_1} {le : α → α → Bool} {l : List α} (trans : ∀ (a b c : α), le a b = true → le b c = true → le a c = true) (total : ∀ (a b : α), (le a b || le b a) = true) {c : List α} :
    List.Pairwise (fun (a b : α) => le a b = true) c → c.Sublist l → c.Sublist (l.mergeSort le)

    Another statement of stability of merge sort. If c is a sorted sublist of l, then c is still a sublist of mergeSort le l.

    @[reducible, inline, deprecated]
    abbrev List.mergeSort_stable {α : Type u_1} {le : α → α → Bool} {l : List α} (trans : ∀ (a b c : α), le a b = true → le b c = true → le a c = true) (total : ∀ (a b : α), (le a b || le b a) = true) {c : List α} :
    List.Pairwise (fun (a b : α) => le a b = true) c → c.Sublist l → c.Sublist (l.mergeSort le)
    Equations
    Instances For
      theorem List.pair_sublist_mergeSort {α : Type u_1} {le : α → α → Bool} {a b : α} {l : List α} (trans : ∀ (a b c : α), le a b = true → le b c = true → le a c = true) (total : ∀ (a b : α), (le a b || le b a) = true) (hab : le a b = true) (h : [a, b].Sublist l) :
      [a, b].Sublist (l.mergeSort le)

      Another statement of stability of merge sort. If a pair [a, b] is a sublist of l and le a b, then [a, b] is still a sublist of mergeSort le l.

      @[reducible, inline, deprecated]
      abbrev List.mergeSort_stable_pair {α : Type u_1} {le : α → α → Bool} {a b : α} {l : List α} (trans : ∀ (a b c : α), le a b = true → le b c = true → le a c = true) (total : ∀ (a b : α), (le a b || le b a) = true) (hab : le a b = true) (h : [a, b].Sublist l) :
      [a, b].Sublist (l.mergeSort le)
      Equations
      Instances For
        @[irreducible]
        theorem List.map_merge {α : Type u_2} {β : Type u_1} {f : α → β} {r : α → α → Bool} {s : β → β → Bool} {l l' : List α} (hl : ∀ (a : α), a ∈ l → ∀ (b : α), b ∈ l' → r a b = s (f a) (f b)) :
        List.map f (l.merge l' r) = (List.map f l).merge (List.map f l') s
        @[irreducible]
        theorem List.map_mergeSort {α : Type u_2} {β : Type u_1} {r : α → α → Bool} {s : β → β → Bool} {f : α → β} {l : List α} (hl : ∀ (a : α), a ∈ l → ∀ (b : α), b ∈ l → r a b = s (f a) (f b)) :
        List.map f (l.mergeSort r) = (List.map f l).mergeSort s