src/HOL/Library/Sorting_Algorithms.thy
author nipkow
Tue, 17 Jun 2025 14:11:40 +0200
changeset 82733 8b537e1af2ec
parent 82393 88064da0ae76
permissions -rw-r--r--
reinstated intersection of lists as inter_list_set
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
     1
(*  Title:      HOL/Library/Sorting_Algorithms.thy
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
     2
    Author:     Florian Haftmann, TU Muenchen
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
     3
*)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
     4
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
     5
theory Sorting_Algorithms
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
     6
  imports Main Multiset Comparator
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
     7
begin
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
     8
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
     9
section \<open>Stably sorted lists\<close>
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    10
82388
haftmann
parents: 69250
diff changeset
    11
abbreviation (input) stable_segment :: \<open>'a comparator \<Rightarrow> 'a \<Rightarrow> 'a list \<Rightarrow> 'a list\<close>
haftmann
parents: 69250
diff changeset
    12
  where \<open>stable_segment cmp x \<equiv> filter (\<lambda>y. compare cmp x y = Equiv)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    13
82388
haftmann
parents: 69250
diff changeset
    14
fun sorted :: \<open>'a comparator \<Rightarrow> 'a list \<Rightarrow> bool\<close>
haftmann
parents: 69250
diff changeset
    15
  where sorted_Nil: \<open>sorted cmp [] \<longleftrightarrow> True\<close>
haftmann
parents: 69250
diff changeset
    16
  | sorted_single: \<open>sorted cmp [x] \<longleftrightarrow> True\<close>
haftmann
parents: 69250
diff changeset
    17
  | sorted_rec: \<open>sorted cmp (y # x # xs) \<longleftrightarrow> compare cmp y x \<noteq> Greater \<and> sorted cmp (x # xs)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    18
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    19
lemma sorted_ConsI:
82388
haftmann
parents: 69250
diff changeset
    20
  \<open>sorted cmp (x # xs)\<close> if \<open>sorted cmp xs\<close>
haftmann
parents: 69250
diff changeset
    21
    and \<open>\<And>y ys. xs = y # ys \<Longrightarrow> compare cmp x y \<noteq> Greater\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
    22
  using that by (cases xs) simp_all
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
    23
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
    24
lemma sorted_Cons_imp_sorted:
82388
haftmann
parents: 69250
diff changeset
    25
  \<open>sorted cmp xs\<close> if \<open>sorted cmp (x # xs)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    26
  using that by (cases xs) simp_all
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    27
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
    28
lemma sorted_Cons_imp_not_less:
82388
haftmann
parents: 69250
diff changeset
    29
  \<open>compare cmp y x \<noteq> Greater\<close> if \<open>sorted cmp (y # xs)\<close>
haftmann
parents: 69250
diff changeset
    30
    and \<open>x \<in> set xs\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
    31
  using that by (induction xs arbitrary: y) (auto dest: compare.trans_not_greater)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
    32
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    33
lemma sorted_induct [consumes 1, case_names Nil Cons, induct pred: sorted]:
82388
haftmann
parents: 69250
diff changeset
    34
  \<open>P xs\<close> if \<open>sorted cmp xs\<close> and \<open>P []\<close>
haftmann
parents: 69250
diff changeset
    35
    and *: \<open>\<And>x xs. sorted cmp xs \<Longrightarrow> P xs
haftmann
parents: 69250
diff changeset
    36
      \<Longrightarrow> (\<And>y. y \<in> set xs \<Longrightarrow> compare cmp x y \<noteq> Greater) \<Longrightarrow> P (x # xs)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    37
using \<open>sorted cmp xs\<close> proof (induction xs)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    38
  case Nil
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    39
  show ?case
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    40
    by (rule \<open>P []\<close>)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    41
next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    42
  case (Cons x xs)
82388
haftmann
parents: 69250
diff changeset
    43
  from \<open>sorted cmp (x # xs)\<close> have \<open>sorted cmp xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    44
    by (cases xs) simp_all
82388
haftmann
parents: 69250
diff changeset
    45
  moreover have \<open>P xs\<close> using \<open>sorted cmp xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    46
    by (rule Cons.IH)
82388
haftmann
parents: 69250
diff changeset
    47
  moreover have \<open>compare cmp x y \<noteq> Greater\<close> if \<open>y \<in> set xs\<close> for y
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    48
  using that \<open>sorted cmp (x # xs)\<close> proof (induction xs)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    49
    case Nil
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    50
    then show ?case
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    51
      by simp
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    52
  next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    53
    case (Cons z zs)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    54
    then show ?case
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    55
    proof (cases zs)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    56
      case Nil
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    57
      with Cons.prems show ?thesis
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    58
        by simp
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    59
    next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    60
      case (Cons w ws)
82388
haftmann
parents: 69250
diff changeset
    61
      with Cons.prems have \<open>compare cmp z w \<noteq> Greater\<close> \<open>compare cmp x z \<noteq> Greater\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    62
        by auto
82388
haftmann
parents: 69250
diff changeset
    63
      then have \<open>compare cmp x w \<noteq> Greater\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
    64
        by (auto dest: compare.trans_not_greater)
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    65
      with Cons show ?thesis
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    66
        using Cons.prems Cons.IH by auto
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    67
    qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    68
  qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    69
  ultimately show ?case
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    70
    by (rule *)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    71
qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    72
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    73
lemma sorted_induct_remove1 [consumes 1, case_names Nil minimum]:
82388
haftmann
parents: 69250
diff changeset
    74
  \<open>P xs\<close> if \<open>sorted cmp xs\<close> and \<open>P []\<close>
haftmann
parents: 69250
diff changeset
    75
    and *: \<open>\<And>x xs. sorted cmp xs \<Longrightarrow> P (remove1 x xs)
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
    76
      \<Longrightarrow> x \<in> set xs \<Longrightarrow> hd (stable_segment cmp x xs) = x \<Longrightarrow> (\<And>y. y \<in> set xs \<Longrightarrow> compare cmp x y \<noteq> Greater)
82388
haftmann
parents: 69250
diff changeset
    77
    \<Longrightarrow> P xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    78
using \<open>sorted cmp xs\<close> proof (induction xs)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    79
  case Nil
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    80
  show ?case
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    81
    by (rule \<open>P []\<close>)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    82
next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    83
  case (Cons x xs)
82388
haftmann
parents: 69250
diff changeset
    84
  then have \<open>sorted cmp (x # xs)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    85
    by (simp add: sorted_ConsI)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    86
  moreover note Cons.IH
82388
haftmann
parents: 69250
diff changeset
    87
  moreover have \<open>\<And>y. compare cmp x y = Greater \<Longrightarrow> y \<in> set xs \<Longrightarrow> False\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    88
    using Cons.hyps by simp
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    89
  ultimately show ?case
82388
haftmann
parents: 69250
diff changeset
    90
    by (auto intro!: * [of \<open>x # xs\<close> x]) blast
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    91
qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    92
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    93
lemma sorted_remove1:
82388
haftmann
parents: 69250
diff changeset
    94
  \<open>sorted cmp (remove1 x xs)\<close> if \<open>sorted cmp xs\<close>
haftmann
parents: 69250
diff changeset
    95
proof (cases \<open>x \<in> set xs\<close>)
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    96
  case False
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    97
  with that show ?thesis
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    98
    by (simp add: remove1_idem)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
    99
next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   100
  case True
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   101
  with that show ?thesis proof (induction xs)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   102
    case Nil
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   103
    then show ?case
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   104
      by simp
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   105
  next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   106
    case (Cons y ys)
82388
haftmann
parents: 69250
diff changeset
   107
    show ?case proof (cases \<open>x = y\<close>)
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   108
      case True
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   109
      with Cons.hyps show ?thesis
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   110
        by simp
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   111
    next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   112
      case False
82388
haftmann
parents: 69250
diff changeset
   113
      then have \<open>sorted cmp (remove1 x ys)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   114
        using Cons.IH Cons.prems by auto
82388
haftmann
parents: 69250
diff changeset
   115
      then have \<open>sorted cmp (y # remove1 x ys)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   116
      proof (rule sorted_ConsI)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   117
        fix z zs
82388
haftmann
parents: 69250
diff changeset
   118
        assume \<open>remove1 x ys = z # zs\<close>
haftmann
parents: 69250
diff changeset
   119
        with \<open>x \<noteq> y\<close> have \<open>z \<in> set ys\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   120
          using notin_set_remove1 [of z ys x] by auto
82388
haftmann
parents: 69250
diff changeset
   121
        then show \<open>compare cmp y z \<noteq> Greater\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   122
          by (rule Cons.hyps(2))
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   123
      qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   124
      with False show ?thesis
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   125
        by simp
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   126
    qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   127
  qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   128
qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   129
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   130
lemma sorted_stable_segment:
82388
haftmann
parents: 69250
diff changeset
   131
  \<open>sorted cmp (stable_segment cmp x xs)\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   132
proof (induction xs)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   133
  case Nil
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   134
  show ?case
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   135
    by simp
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   136
next
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   137
  case (Cons y ys)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   138
  then show ?case
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   139
    by (auto intro!: sorted_ConsI simp add: filter_eq_Cons_iff compare.sym)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   140
      (auto dest: compare.trans_equiv simp add: compare.sym compare.greater_iff_sym_less)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   141
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   142
qed
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   143
82388
haftmann
parents: 69250
diff changeset
   144
primrec insort :: \<open>'a comparator \<Rightarrow> 'a \<Rightarrow> 'a list \<Rightarrow> 'a list\<close>
haftmann
parents: 69250
diff changeset
   145
  where \<open>insort cmp y [] = [y]\<close>
haftmann
parents: 69250
diff changeset
   146
  | \<open>insort cmp y (x # xs) = (if compare cmp y x \<noteq> Greater
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   147
       then y # x # xs
82388
haftmann
parents: 69250
diff changeset
   148
       else x # insort cmp y xs)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   149
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   150
lemma mset_insort [simp]:
82388
haftmann
parents: 69250
diff changeset
   151
  \<open>mset (insort cmp x xs) = add_mset x (mset xs)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   152
  by (induction xs) simp_all
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   153
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   154
lemma length_insort [simp]:
82388
haftmann
parents: 69250
diff changeset
   155
  \<open>length (insort cmp x xs) = Suc (length xs)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   156
  by (induction xs) simp_all
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   157
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   158
lemma sorted_insort:
82388
haftmann
parents: 69250
diff changeset
   159
  \<open>sorted cmp (insort cmp x xs)\<close> if \<open>sorted cmp xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   160
using that proof (induction xs)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   161
  case Nil
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   162
  then show ?case
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   163
    by simp
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   164
next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   165
  case (Cons y ys)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   166
  then show ?case by (cases ys)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   167
    (auto, simp_all add: compare.greater_iff_sym_less)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   168
qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   169
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   170
lemma stable_insort_equiv:
82388
haftmann
parents: 69250
diff changeset
   171
  \<open>stable_segment cmp y (insort cmp x xs) = x # stable_segment cmp y xs\<close>
haftmann
parents: 69250
diff changeset
   172
    if \<open>compare cmp y x = Equiv\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   173
proof (induction xs)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   174
  case Nil
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   175
  from that show ?case
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   176
    by simp
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   177
next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   178
  case (Cons z xs)
82388
haftmann
parents: 69250
diff changeset
   179
  moreover from that have \<open>compare cmp y z = Equiv \<Longrightarrow> compare cmp z x = Equiv\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   180
    by (auto intro: compare.trans_equiv simp add: compare.sym)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   181
  ultimately show ?case
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   182
    using that by (auto simp add: compare.greater_iff_sym_less)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   183
qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   184
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   185
lemma stable_insort_not_equiv:
82388
haftmann
parents: 69250
diff changeset
   186
  \<open>stable_segment cmp y (insort cmp x xs) = stable_segment cmp y xs\<close>
haftmann
parents: 69250
diff changeset
   187
    if \<open>compare cmp y x \<noteq> Equiv\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   188
  using that by (induction xs) simp_all
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   189
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   190
lemma remove1_insort_same_eq [simp]:
82388
haftmann
parents: 69250
diff changeset
   191
  \<open>remove1 x (insort cmp x xs) = xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   192
  by (induction xs) simp_all
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   193
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   194
lemma insort_eq_ConsI:
82388
haftmann
parents: 69250
diff changeset
   195
  \<open>insort cmp x xs = x # xs\<close>
haftmann
parents: 69250
diff changeset
   196
    if \<open>sorted cmp xs\<close> \<open>\<And>y. y \<in> set xs \<Longrightarrow> compare cmp x y \<noteq> Greater\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   197
  using that by (induction xs) (simp_all add: compare.greater_iff_sym_less)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   198
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   199
lemma remove1_insort_not_same_eq [simp]:
82388
haftmann
parents: 69250
diff changeset
   200
  \<open>remove1 y (insort cmp x xs) = insort cmp x (remove1 y xs)\<close>
haftmann
parents: 69250
diff changeset
   201
    if \<open>sorted cmp xs\<close> \<open>x \<noteq> y\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   202
using that proof (induction xs)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   203
  case Nil
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   204
  then show ?case
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   205
    by simp
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   206
next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   207
  case (Cons z zs)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   208
  show ?case
82388
haftmann
parents: 69250
diff changeset
   209
  proof (cases \<open>compare cmp x z = Greater\<close>)
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   210
    case True
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   211
    with Cons show ?thesis
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   212
      by simp
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   213
  next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   214
    case False
82388
haftmann
parents: 69250
diff changeset
   215
    then have \<open>compare cmp x y \<noteq> Greater\<close> if \<open>y \<in> set zs\<close> for y
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   216
      using that Cons.hyps
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   217
      by (auto dest: compare.trans_not_greater)
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   218
    with Cons show ?thesis
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   219
      by (simp add: insort_eq_ConsI)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   220
  qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   221
qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   222
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   223
lemma insort_remove1_same_eq:
82388
haftmann
parents: 69250
diff changeset
   224
  \<open>insort cmp x (remove1 x xs) = xs\<close>
haftmann
parents: 69250
diff changeset
   225
    if \<open>sorted cmp xs\<close> and \<open>x \<in> set xs\<close> and \<open>hd (stable_segment cmp x xs) = x\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   226
using that proof (induction xs)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   227
  case Nil
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   228
  then show ?case
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   229
    by simp
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   230
next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   231
  case (Cons y ys)
82388
haftmann
parents: 69250
diff changeset
   232
  then have \<open>compare cmp x y \<noteq> Less\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   233
    by (auto simp add: compare.greater_iff_sym_less)
82388
haftmann
parents: 69250
diff changeset
   234
  then consider \<open>compare cmp x y = Greater\<close> | \<open>compare cmp x y = Equiv\<close>
haftmann
parents: 69250
diff changeset
   235
    by (cases \<open>compare cmp x y\<close>) auto
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   236
  then show ?case proof cases
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   237
    case 1
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   238
    with Cons.prems Cons.IH show ?thesis
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   239
      by auto
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   240
  next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   241
    case 2
82388
haftmann
parents: 69250
diff changeset
   242
    with Cons.prems have \<open>x = y\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   243
      by simp
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   244
    with Cons.hyps show ?thesis
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   245
      by (simp add: insort_eq_ConsI)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   246
  qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   247
qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   248
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   249
lemma sorted_append_iff:
82388
haftmann
parents: 69250
diff changeset
   250
  \<open>sorted cmp (xs @ ys) \<longleftrightarrow> sorted cmp xs \<and> sorted cmp ys
haftmann
parents: 69250
diff changeset
   251
     \<and> (\<forall>x \<in> set xs. \<forall>y \<in> set ys. compare cmp x y \<noteq> Greater)\<close> (is \<open>?P \<longleftrightarrow> ?R \<and> ?S \<and> ?Q\<close>)
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   252
proof
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   253
  assume ?P
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   254
  have ?R
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   255
    using \<open>?P\<close> by (induction xs)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   256
      (auto simp add: sorted_Cons_imp_not_less,
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   257
        auto simp add: sorted_Cons_imp_sorted intro: sorted_ConsI)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   258
  moreover have ?S
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   259
    using \<open>?P\<close> by (induction xs) (auto dest: sorted_Cons_imp_sorted)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   260
  moreover have ?Q
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   261
    using \<open>?P\<close> by (induction xs) (auto simp add: sorted_Cons_imp_not_less,
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   262
      simp add: sorted_Cons_imp_sorted)
82388
haftmann
parents: 69250
diff changeset
   263
  ultimately show \<open>?R \<and> ?S \<and> ?Q\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   264
    by simp
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   265
next
82388
haftmann
parents: 69250
diff changeset
   266
  assume \<open>?R \<and> ?S \<and> ?Q\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   267
  then have ?R ?S ?Q
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   268
    by simp_all
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   269
  then show ?P
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   270
    by (induction xs)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   271
      (auto simp add: append_eq_Cons_conv intro!: sorted_ConsI)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   272
qed
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   273
82388
haftmann
parents: 69250
diff changeset
   274
definition sort :: \<open>'a comparator \<Rightarrow> 'a list \<Rightarrow> 'a list\<close>
haftmann
parents: 69250
diff changeset
   275
  where \<open>sort cmp xs = foldr (insort cmp) xs []\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   276
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   277
lemma sort_simps [simp]:
82388
haftmann
parents: 69250
diff changeset
   278
  \<open>sort cmp [] = []\<close>
haftmann
parents: 69250
diff changeset
   279
  \<open>sort cmp (x # xs) = insort cmp x (sort cmp xs)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   280
  by (simp_all add: sort_def)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   281
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   282
lemma mset_sort [simp]:
82388
haftmann
parents: 69250
diff changeset
   283
  \<open>mset (sort cmp xs) = mset xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   284
  by (induction xs) simp_all
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   285
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   286
lemma length_sort [simp]:
82388
haftmann
parents: 69250
diff changeset
   287
  \<open>length (sort cmp xs) = length xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   288
  by (induction xs) simp_all
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   289
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   290
lemma sorted_sort [simp]:
82388
haftmann
parents: 69250
diff changeset
   291
  \<open>sorted cmp (sort cmp xs)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   292
  by (induction xs) (simp_all add: sorted_insort)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   293
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   294
lemma stable_sort:
82388
haftmann
parents: 69250
diff changeset
   295
  \<open>stable_segment cmp x (sort cmp xs) = stable_segment cmp x xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   296
  by (induction xs) (simp_all add: stable_insort_equiv stable_insort_not_equiv)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   297
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   298
lemma sort_remove1_eq [simp]:
82388
haftmann
parents: 69250
diff changeset
   299
  \<open>sort cmp (remove1 x xs) = remove1 x (sort cmp xs)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   300
  by (induction xs) simp_all
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   301
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   302
lemma set_insort [simp]:
82388
haftmann
parents: 69250
diff changeset
   303
  \<open>set (insort cmp x xs) = insert x (set xs)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   304
  by (induction xs) auto
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   305
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   306
lemma set_sort [simp]:
82388
haftmann
parents: 69250
diff changeset
   307
  \<open>set (sort cmp xs) = set xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   308
  by (induction xs) auto
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   309
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   310
lemma sort_eqI:
82388
haftmann
parents: 69250
diff changeset
   311
  \<open>sort cmp ys = xs\<close>
haftmann
parents: 69250
diff changeset
   312
    if permutation: \<open>mset ys = mset xs\<close>
haftmann
parents: 69250
diff changeset
   313
    and sorted: \<open>sorted cmp xs\<close>
haftmann
parents: 69250
diff changeset
   314
    and stable: \<open>\<And>y. y \<in> set ys \<Longrightarrow>
haftmann
parents: 69250
diff changeset
   315
      stable_segment cmp y ys = stable_segment cmp y xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   316
proof -
82388
haftmann
parents: 69250
diff changeset
   317
  have stable': \<open>stable_segment cmp y ys =
haftmann
parents: 69250
diff changeset
   318
    stable_segment cmp y xs\<close> for y
haftmann
parents: 69250
diff changeset
   319
  proof (cases \<open>\<exists>x\<in>set ys. compare cmp y x = Equiv\<close>)
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   320
    case True
82388
haftmann
parents: 69250
diff changeset
   321
    then obtain z where \<open>z \<in> set ys\<close> and \<open>compare cmp y z = Equiv\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   322
      by auto
82388
haftmann
parents: 69250
diff changeset
   323
    then have \<open>compare cmp y x = Equiv \<longleftrightarrow> compare cmp z x = Equiv\<close> for x
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   324
      by (meson compare.sym compare.trans_equiv)
82388
haftmann
parents: 69250
diff changeset
   325
    moreover have \<open>stable_segment cmp z ys =
haftmann
parents: 69250
diff changeset
   326
      stable_segment cmp z xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   327
      using \<open>z \<in> set ys\<close> by (rule stable)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   328
    ultimately show ?thesis
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   329
      by simp
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   330
  next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   331
    case False
82388
haftmann
parents: 69250
diff changeset
   332
    moreover from permutation have \<open>set ys = set xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   333
      by (rule mset_eq_setD)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   334
    ultimately show ?thesis
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   335
      by simp
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   336
  qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   337
  show ?thesis
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   338
  using sorted permutation stable' proof (induction xs arbitrary: ys rule: sorted_induct_remove1)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   339
    case Nil
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   340
    then show ?case
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   341
      by simp
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   342
  next
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   343
    case (minimum x xs)
82388
haftmann
parents: 69250
diff changeset
   344
    from \<open>mset ys = mset xs\<close> have ys: \<open>set ys = set xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   345
      by (rule mset_eq_setD)
82388
haftmann
parents: 69250
diff changeset
   346
    then have \<open>compare cmp x y \<noteq> Greater\<close> if \<open>y \<in> set ys\<close> for y
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   347
      using that minimum.hyps by simp
82388
haftmann
parents: 69250
diff changeset
   348
    from minimum.prems have stable: \<open>stable_segment cmp x ys = stable_segment cmp x xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   349
      by simp
82388
haftmann
parents: 69250
diff changeset
   350
    have \<open>sort cmp (remove1 x ys) = remove1 x xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   351
      by (rule minimum.IH) (simp_all add: minimum.prems filter_remove1)
82388
haftmann
parents: 69250
diff changeset
   352
    then have \<open>remove1 x (sort cmp ys) = remove1 x xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   353
      by simp
82388
haftmann
parents: 69250
diff changeset
   354
    then have \<open>insort cmp x (remove1 x (sort cmp ys)) =
haftmann
parents: 69250
diff changeset
   355
      insort cmp x (remove1 x xs)\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   356
      by simp
82388
haftmann
parents: 69250
diff changeset
   357
    also from minimum.hyps ys stable have \<open>insort cmp x (remove1 x (sort cmp ys)) = sort cmp ys\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   358
      by (simp add: stable_sort insort_remove1_same_eq)
82388
haftmann
parents: 69250
diff changeset
   359
    also from minimum.hyps have \<open>insort cmp x (remove1 x xs) = xs\<close>
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   360
      by (simp add: insort_remove1_same_eq)
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   361
    finally show ?case .
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   362
  qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   363
qed
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   364
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   365
lemma filter_insort:
82388
haftmann
parents: 69250
diff changeset
   366
  \<open>filter P (insort cmp x xs) = insort cmp x (filter P xs)\<close>
haftmann
parents: 69250
diff changeset
   367
    if \<open>sorted cmp xs\<close> and \<open>P x\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   368
  using that by (induction xs)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   369
    (auto simp add: compare.trans_not_greater insort_eq_ConsI)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   370
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   371
lemma filter_insort_triv:
82388
haftmann
parents: 69250
diff changeset
   372
  \<open>filter P (insort cmp x xs) = filter P xs\<close>
haftmann
parents: 69250
diff changeset
   373
    if \<open>\<not> P x\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   374
  using that by (induction xs) simp_all
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   375
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   376
lemma filter_sort:
82388
haftmann
parents: 69250
diff changeset
   377
  \<open>filter P (sort cmp xs) = sort cmp (filter P xs)\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   378
  by (induction xs) (auto simp add: filter_insort filter_insort_triv)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   379
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   380
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   381
section \<open>Alternative sorting algorithms\<close>
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   382
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   383
subsection \<open>Quicksort\<close>
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   384
82388
haftmann
parents: 69250
diff changeset
   385
definition quicksort :: \<open>'a comparator \<Rightarrow> 'a list \<Rightarrow> 'a list\<close>
haftmann
parents: 69250
diff changeset
   386
  where quicksort_is_sort [simp]: \<open>quicksort = sort\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   387
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   388
lemma sort_by_quicksort:
82388
haftmann
parents: 69250
diff changeset
   389
  \<open>sort = quicksort\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   390
  by simp
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   391
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   392
lemma sort_by_quicksort_rec:
82388
haftmann
parents: 69250
diff changeset
   393
  \<open>sort cmp xs = sort cmp [x\<leftarrow>xs. compare cmp x (xs ! (length xs div 2)) = Less]
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   394
    @ stable_segment cmp (xs ! (length xs div 2)) xs
82388
haftmann
parents: 69250
diff changeset
   395
    @ sort cmp [x\<leftarrow>xs. compare cmp x (xs ! (length xs div 2)) = Greater]\<close> (is \<open>_ = ?rhs\<close>)
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   396
proof (rule sort_eqI)
82388
haftmann
parents: 69250
diff changeset
   397
  show \<open>mset xs = mset ?rhs\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   398
    by (rule multiset_eqI) (auto simp add: compare.sym intro: comp.exhaust)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   399
next
82388
haftmann
parents: 69250
diff changeset
   400
  show \<open>sorted cmp ?rhs\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   401
    by (auto simp add: sorted_append_iff sorted_stable_segment compare.equiv_subst_right dest: compare.trans_greater)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   402
next
82388
haftmann
parents: 69250
diff changeset
   403
  let ?pivot = \<open>xs ! (length xs div 2)\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   404
  fix l
82388
haftmann
parents: 69250
diff changeset
   405
  have \<open>compare cmp x ?pivot = comp \<and> compare cmp l x = Equiv
haftmann
parents: 69250
diff changeset
   406
    \<longleftrightarrow> compare cmp l ?pivot = comp \<and> compare cmp l x = Equiv\<close> for x comp
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   407
  proof -
82388
haftmann
parents: 69250
diff changeset
   408
    have \<open>compare cmp x ?pivot = comp \<longleftrightarrow> compare cmp l ?pivot = comp\<close>
haftmann
parents: 69250
diff changeset
   409
      if \<open>compare cmp l x = Equiv\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   410
      using that by (simp add: compare.equiv_subst_left compare.sym)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   411
    then show ?thesis by blast
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   412
  qed
82388
haftmann
parents: 69250
diff changeset
   413
  then show \<open>stable_segment cmp l xs = stable_segment cmp l ?rhs\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   414
    by (simp add: stable_sort compare.sym [of _ ?pivot])
82388
haftmann
parents: 69250
diff changeset
   415
      (cases \<open>compare cmp l ?pivot\<close>, simp_all)
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   416
qed
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   417
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   418
context
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   419
begin
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   420
82388
haftmann
parents: 69250
diff changeset
   421
qualified definition partition :: \<open>'a comparator \<Rightarrow> 'a \<Rightarrow> 'a list \<Rightarrow> 'a list \<times> 'a list \<times> 'a list\<close>
haftmann
parents: 69250
diff changeset
   422
  where \<open>partition cmp pivot xs =
haftmann
parents: 69250
diff changeset
   423
    ([x \<leftarrow> xs. compare cmp x pivot = Less], stable_segment cmp pivot xs, [x \<leftarrow> xs. compare cmp x pivot = Greater])\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   424
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   425
qualified lemma partition_code [code]:
82388
haftmann
parents: 69250
diff changeset
   426
  \<open>partition cmp pivot [] = ([], [], [])\<close>
haftmann
parents: 69250
diff changeset
   427
  \<open>partition cmp pivot (x # xs) =
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   428
    (let (lts, eqs, gts) = partition cmp pivot xs
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   429
     in case compare cmp x pivot of
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   430
       Less \<Rightarrow> (x # lts, eqs, gts)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   431
     | Equiv \<Rightarrow> (lts, x # eqs, gts)
82388
haftmann
parents: 69250
diff changeset
   432
     | Greater \<Rightarrow> (lts, eqs, x # gts))\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   433
  using comp.exhaust by (auto simp add: partition_def Let_def compare.sym [of _ pivot])
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   434
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   435
lemma quicksort_code [code]:
82388
haftmann
parents: 69250
diff changeset
   436
  \<open>quicksort cmp xs =
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   437
    (case xs of
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   438
      [] \<Rightarrow> []
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   439
    | [x] \<Rightarrow> xs
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   440
    | [x, y] \<Rightarrow> (if compare cmp x y \<noteq> Greater then xs else [y, x])
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   441
    | _ \<Rightarrow>
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   442
        let (lts, eqs, gts) = partition cmp (xs ! (length xs div 2)) xs
82388
haftmann
parents: 69250
diff changeset
   443
        in quicksort cmp lts @ eqs @ quicksort cmp gts)\<close>
haftmann
parents: 69250
diff changeset
   444
proof (cases \<open>length xs \<ge> 3\<close>)
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   445
  case False
82388
haftmann
parents: 69250
diff changeset
   446
  then have \<open>length xs \<in> {0, 1, 2}\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   447
    by (auto simp add: not_le le_less less_antisym)
82388
haftmann
parents: 69250
diff changeset
   448
  then consider \<open>xs = []\<close> | x where \<open>xs = [x]\<close> | x y where \<open>xs = [x, y]\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   449
    by (auto simp add: length_Suc_conv numeral_2_eq_2)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   450
  then show ?thesis
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   451
    by cases simp_all
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   452
next
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   453
  case True
82388
haftmann
parents: 69250
diff changeset
   454
  then obtain x y z zs where \<open>xs = x # y # z # zs\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   455
    by (metis le_0_eq length_0_conv length_Cons list.exhaust not_less_eq_eq numeral_3_eq_3)
82388
haftmann
parents: 69250
diff changeset
   456
  moreover have \<open>quicksort cmp xs =
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   457
    (let (lts, eqs, gts) = partition cmp (xs ! (length xs div 2)) xs
82388
haftmann
parents: 69250
diff changeset
   458
    in quicksort cmp lts @ eqs @ quicksort cmp gts)\<close>
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   459
    using sort_by_quicksort_rec [of cmp xs] by (simp add: partition_def)
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   460
  ultimately show ?thesis
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   461
    by simp
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   462
qed
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   463
69194
6d514e128a85 dedicated theory for sorting algorithms
haftmann
parents:
diff changeset
   464
end
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   465
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   466
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   467
subsection \<open>Mergesort\<close>
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   468
82388
haftmann
parents: 69250
diff changeset
   469
definition mergesort :: \<open>'a comparator \<Rightarrow> 'a list \<Rightarrow> 'a list\<close>
haftmann
parents: 69250
diff changeset
   470
  where mergesort_is_sort [simp]: \<open>mergesort = sort\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   471
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   472
lemma sort_by_mergesort:
82388
haftmann
parents: 69250
diff changeset
   473
  \<open>sort = mergesort\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   474
  by simp
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   475
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   476
context
82388
haftmann
parents: 69250
diff changeset
   477
  fixes cmp :: \<open>'a comparator\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   478
begin
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   479
82388
haftmann
parents: 69250
diff changeset
   480
qualified function merge :: \<open>'a list \<Rightarrow> 'a list \<Rightarrow> 'a list\<close>
haftmann
parents: 69250
diff changeset
   481
  where \<open>merge [] ys = ys\<close>
haftmann
parents: 69250
diff changeset
   482
  | \<open>merge xs [] = xs\<close>
haftmann
parents: 69250
diff changeset
   483
  | \<open>merge (x # xs) (y # ys) = (if compare cmp x y = Greater
haftmann
parents: 69250
diff changeset
   484
      then y # merge (x # xs) ys else x # merge xs (y # ys))\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   485
  by pat_completeness auto
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   486
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   487
qualified termination by lexicographic_order
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   488
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   489
lemma mset_merge:
82388
haftmann
parents: 69250
diff changeset
   490
  \<open>mset (merge xs ys) = mset xs + mset ys\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   491
  by (induction xs ys rule: merge.induct) simp_all
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   492
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   493
lemma merge_eq_Cons_imp:
82388
haftmann
parents: 69250
diff changeset
   494
  \<open>xs \<noteq> [] \<and> z = hd xs \<or> ys \<noteq> [] \<and> z = hd ys\<close>
haftmann
parents: 69250
diff changeset
   495
    if \<open>merge xs ys = z # zs\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   496
  using that by (induction xs ys rule: merge.induct) (auto split: if_splits)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   497
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   498
lemma filter_merge:
82388
haftmann
parents: 69250
diff changeset
   499
  \<open>filter P (merge xs ys) = merge (filter P xs) (filter P ys)\<close>
haftmann
parents: 69250
diff changeset
   500
    if \<open>sorted cmp xs\<close> and \<open>sorted cmp ys\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   501
using that proof (induction xs ys rule: merge.induct)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   502
  case (1 ys)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   503
  then show ?case
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   504
    by simp
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   505
next
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   506
  case (2 xs)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   507
  then show ?case
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   508
    by simp
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   509
next
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   510
  case (3 x xs y ys)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   511
  show ?case
82388
haftmann
parents: 69250
diff changeset
   512
  proof (cases \<open>compare cmp x y = Greater\<close>)
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   513
    case True
82388
haftmann
parents: 69250
diff changeset
   514
    with 3 have hyp: \<open>filter P (merge (x # xs) ys) =
haftmann
parents: 69250
diff changeset
   515
      merge (filter P (x # xs)) (filter P ys)\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   516
      by (simp add: sorted_Cons_imp_sorted)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   517
    show ?thesis
82388
haftmann
parents: 69250
diff changeset
   518
    proof (cases \<open>\<not> P x \<and> P y\<close>)
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   519
      case False
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   520
      with \<open>compare cmp x y = Greater\<close> show ?thesis
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   521
        by (auto simp add: hyp)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   522
    next
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   523
      case True
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   524
      from \<open>compare cmp x y = Greater\<close> "3.prems"
82388
haftmann
parents: 69250
diff changeset
   525
      have *: \<open>compare cmp z y = Greater\<close> if \<open>z \<in> set (filter P xs)\<close> for z
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   526
        using that by (auto dest: compare.trans_not_greater sorted_Cons_imp_not_less)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   527
      from \<open>compare cmp x y = Greater\<close> show ?thesis
82388
haftmann
parents: 69250
diff changeset
   528
        by (cases \<open>filter P xs\<close>) (simp_all add: hyp *)
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   529
    qed
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   530
  next
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   531
    case False
82388
haftmann
parents: 69250
diff changeset
   532
    with 3 have hyp: \<open>filter P (merge xs (y # ys)) =
haftmann
parents: 69250
diff changeset
   533
      merge (filter P xs) (filter P (y # ys))\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   534
      by (simp add: sorted_Cons_imp_sorted)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   535
    show ?thesis
82388
haftmann
parents: 69250
diff changeset
   536
    proof (cases \<open>P x \<and> \<not> P y\<close>)
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   537
      case False
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   538
      with \<open>compare cmp x y \<noteq> Greater\<close> show ?thesis
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   539
        by (auto simp add: hyp)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   540
    next
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   541
      case True
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   542
      from \<open>compare cmp x y \<noteq> Greater\<close> "3.prems"
82388
haftmann
parents: 69250
diff changeset
   543
      have *: \<open>compare cmp x z \<noteq> Greater\<close> if \<open>z \<in> set (filter P ys)\<close> for z
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   544
        using that by (auto dest: compare.trans_not_greater sorted_Cons_imp_not_less)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   545
      from \<open>compare cmp x y \<noteq> Greater\<close> show ?thesis
82388
haftmann
parents: 69250
diff changeset
   546
        by (cases \<open>filter P ys\<close>) (simp_all add: hyp *)
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   547
    qed
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   548
  qed
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   549
qed
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   550
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   551
lemma sorted_merge:
82388
haftmann
parents: 69250
diff changeset
   552
  \<open>sorted cmp (merge xs ys)\<close> if \<open>sorted cmp xs\<close> and \<open>sorted cmp ys\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   553
using that proof (induction xs ys rule: merge.induct)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   554
  case (1 ys)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   555
  then show ?case
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   556
    by simp
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   557
next
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   558
  case (2 xs)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   559
  then show ?case
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   560
    by simp
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   561
next
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   562
  case (3 x xs y ys)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   563
  show ?case
82388
haftmann
parents: 69250
diff changeset
   564
  proof (cases \<open>compare cmp x y = Greater\<close>)
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   565
    case True
82388
haftmann
parents: 69250
diff changeset
   566
    with 3 have \<open>sorted cmp (merge (x # xs) ys)\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   567
      by (simp add: sorted_Cons_imp_sorted)
82388
haftmann
parents: 69250
diff changeset
   568
    then have \<open>sorted cmp (y # merge (x # xs) ys)\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   569
    proof (rule sorted_ConsI)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   570
      fix z zs
82388
haftmann
parents: 69250
diff changeset
   571
      assume \<open>merge (x # xs) ys = z # zs\<close>
haftmann
parents: 69250
diff changeset
   572
      with 3(4) True show \<open>compare cmp y z \<noteq> Greater\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   573
        by (clarsimp simp add: sorted_Cons_imp_sorted dest!: merge_eq_Cons_imp)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   574
          (auto simp add: compare.asym_greater sorted_Cons_imp_not_less)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   575
    qed
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   576
    with True show ?thesis
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   577
      by simp
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   578
  next
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   579
    case False
82388
haftmann
parents: 69250
diff changeset
   580
    with 3 have \<open>sorted cmp (merge xs (y # ys))\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   581
      by (simp add: sorted_Cons_imp_sorted)
82388
haftmann
parents: 69250
diff changeset
   582
    then have \<open>sorted cmp (x # merge xs (y # ys))\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   583
    proof (rule sorted_ConsI)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   584
      fix z zs
82388
haftmann
parents: 69250
diff changeset
   585
      assume \<open>merge xs (y # ys) = z # zs\<close>
haftmann
parents: 69250
diff changeset
   586
      with 3(3) False show \<open>compare cmp x z \<noteq> Greater\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   587
        by (clarsimp simp add: sorted_Cons_imp_sorted dest!: merge_eq_Cons_imp)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   588
          (auto simp add: compare.asym_greater sorted_Cons_imp_not_less)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   589
    qed
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   590
    with False show ?thesis
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   591
      by simp
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   592
  qed
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   593
qed
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   594
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   595
lemma merge_eq_appendI:
82388
haftmann
parents: 69250
diff changeset
   596
  \<open>merge xs ys = xs @ ys\<close>
haftmann
parents: 69250
diff changeset
   597
    if \<open>\<And>x y. x \<in> set xs \<Longrightarrow> y \<in> set ys \<Longrightarrow> compare cmp x y \<noteq> Greater\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   598
  using that by (induction xs ys rule: merge.induct) simp_all
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   599
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   600
lemma merge_stable_segments:
82388
haftmann
parents: 69250
diff changeset
   601
  \<open>merge (stable_segment cmp l xs) (stable_segment cmp l ys) =
haftmann
parents: 69250
diff changeset
   602
     stable_segment cmp l xs @ stable_segment cmp l ys\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   603
  by (rule merge_eq_appendI) (auto dest: compare.trans_equiv_greater)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   604
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   605
lemma sort_by_mergesort_rec:
82388
haftmann
parents: 69250
diff changeset
   606
  \<open>sort cmp xs =
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   607
    merge (sort cmp (take (length xs div 2) xs))
82388
haftmann
parents: 69250
diff changeset
   608
      (sort cmp (drop (length xs div 2) xs))\<close> (is \<open>_ = ?rhs\<close>)
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   609
proof (rule sort_eqI)
82388
haftmann
parents: 69250
diff changeset
   610
  have \<open>mset (take (length xs div 2) xs) + mset (drop (length xs div 2) xs) =
haftmann
parents: 69250
diff changeset
   611
    mset (take (length xs div 2) xs @ drop (length xs div 2) xs)\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   612
    by (simp only: mset_append)
82388
haftmann
parents: 69250
diff changeset
   613
  then show \<open>mset xs = mset ?rhs\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   614
    by (simp add: mset_merge)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   615
next
82388
haftmann
parents: 69250
diff changeset
   616
  show \<open>sorted cmp ?rhs\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   617
    by (simp add: sorted_merge)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   618
next
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   619
  fix l
82388
haftmann
parents: 69250
diff changeset
   620
  have \<open>stable_segment cmp l (take (length xs div 2) xs) @ stable_segment cmp l (drop (length xs div 2) xs)
haftmann
parents: 69250
diff changeset
   621
    = stable_segment cmp l xs\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   622
    by (simp only: filter_append [symmetric] append_take_drop_id)
82388
haftmann
parents: 69250
diff changeset
   623
  have \<open>merge (stable_segment cmp l (take (length xs div 2) xs))
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   624
    (stable_segment cmp l (drop (length xs div 2) xs)) =
82388
haftmann
parents: 69250
diff changeset
   625
    stable_segment cmp l (take (length xs div 2) xs) @ stable_segment cmp l (drop (length xs div 2) xs)\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   626
    by (rule merge_eq_appendI) (auto simp add: compare.trans_equiv_greater)
82388
haftmann
parents: 69250
diff changeset
   627
  also have \<open>\<dots> = stable_segment cmp l xs\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   628
    by (simp only: filter_append [symmetric] append_take_drop_id)
82388
haftmann
parents: 69250
diff changeset
   629
  finally show \<open>stable_segment cmp l xs = stable_segment cmp l ?rhs\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   630
    by (simp add: stable_sort filter_merge)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   631
qed
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   632
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   633
lemma mergesort_code [code]:
82388
haftmann
parents: 69250
diff changeset
   634
  \<open>mergesort cmp xs =
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   635
    (case xs of
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   636
      [] \<Rightarrow> []
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   637
    | [x] \<Rightarrow> xs
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   638
    | [x, y] \<Rightarrow> (if compare cmp x y \<noteq> Greater then xs else [y, x])
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   639
    | _ \<Rightarrow>
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   640
        let
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   641
          half = length xs div 2;
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   642
          ys = take half xs;
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   643
          zs = drop half xs
82388
haftmann
parents: 69250
diff changeset
   644
        in merge (mergesort cmp ys) (mergesort cmp zs))\<close>
haftmann
parents: 69250
diff changeset
   645
proof (cases \<open>length xs \<ge> 3\<close>)
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   646
  case False
82388
haftmann
parents: 69250
diff changeset
   647
  then have \<open>length xs \<in> {0, 1, 2}\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   648
    by (auto simp add: not_le le_less less_antisym)
82388
haftmann
parents: 69250
diff changeset
   649
  then consider \<open>xs = []\<close> | x where \<open>xs = [x]\<close> | x y where \<open>xs = [x, y]\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   650
    by (auto simp add: length_Suc_conv numeral_2_eq_2)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   651
  then show ?thesis
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   652
    by cases simp_all
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   653
next
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   654
  case True
82388
haftmann
parents: 69250
diff changeset
   655
  then obtain x y z zs where \<open>xs = x # y # z # zs\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   656
    by (metis le_0_eq length_0_conv length_Cons list.exhaust not_less_eq_eq numeral_3_eq_3)
82388
haftmann
parents: 69250
diff changeset
   657
  moreover have \<open>mergesort cmp xs =
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   658
    (let
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   659
       half = length xs div 2;
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   660
       ys = take half xs;
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   661
       zs = drop half xs
82388
haftmann
parents: 69250
diff changeset
   662
     in merge (mergesort cmp ys) (mergesort cmp zs))\<close>
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   663
    using sort_by_mergesort_rec [of xs] by (simp add: Let_def)
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   664
  ultimately show ?thesis
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   665
    by simp
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   666
qed
69246
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   667
c1fe9dcc274a concrecte sorting algorithms beyond insertion sort
haftmann
parents: 69194
diff changeset
   668
end
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   669
82393
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   670
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   671
subsection \<open>Lexicographic products\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   672
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   673
lemma sorted_prod_lex_imp_sorted_fst:
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   674
  \<open>sorted (key fst cmp1) ps\<close> if \<open>sorted (prod_lex cmp1 cmp2) ps\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   675
using that proof (induction rule: sorted_induct)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   676
  case Nil
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   677
  then show ?case
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   678
    by simp
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   679
next
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   680
  case (Cons p ps)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   681
  have \<open>compare (key fst cmp1) p q \<noteq> Greater\<close> if \<open>ps = q # qs\<close> for q qs
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   682
    using that Cons.hyps(2) [of q] by (simp add: compare_prod_lex_apply split: comp.splits)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   683
  with Cons.IH show ?case
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   684
    by (rule sorted_ConsI) simp
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   685
qed
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   686
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   687
lemma sorted_prod_lex_imp_sorted_snd:
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   688
  \<open>sorted (key snd cmp2) ps\<close> if \<open>sorted (prod_lex cmp1 cmp2) ps\<close> \<open>\<And>a' b'. (a', b') \<in> set ps \<Longrightarrow> compare cmp1 a a' = Equiv\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   689
using that proof (induction rule: sorted_induct)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   690
  case Nil
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   691
  then show ?case
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   692
    by simp
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   693
next
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   694
  case (Cons p ps)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   695
  then show ?case 
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   696
    apply (cases p)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   697
    apply (rule sorted_ConsI)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   698
     apply (simp_all add: compare_prod_lex_apply)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   699
     apply (auto cong del: comp.case_cong_weak)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   700
    apply (metis comp.simps(8) compare.equiv_subst_left)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   701
    done
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   702
qed
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   703
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   704
lemma sort_comp_fst_snd_eq_sort_prod_lex:
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   705
  \<open>sort (key fst cmp1) \<circ> sort (key snd cmp2) = sort (prod_lex cmp1 cmp2)\<close>  (is \<open>sort ?cmp1 \<circ> sort ?cmp2 = sort ?cmp\<close>)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   706
proof
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   707
  fix ps :: \<open>('a \<times> 'b) list\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   708
  have \<open>sort ?cmp1 (sort ?cmp2 ps) = sort ?cmp ps\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   709
  proof (rule sort_eqI)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   710
    show \<open>mset (sort ?cmp2 ps) = mset (sort ?cmp ps)\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   711
      by simp
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   712
    show \<open>sorted ?cmp1 (sort ?cmp ps)\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   713
      by (rule sorted_prod_lex_imp_sorted_fst [of _ cmp2]) simp
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   714
  next
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   715
    fix p :: \<open>'a \<times> 'b\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   716
    define a b where ab: \<open>a = fst p\<close> \<open>b = snd p\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   717
    moreover assume \<open>p \<in> set (sort ?cmp2 ps)\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   718
    ultimately have \<open>(a, b) \<in> set (sort ?cmp2 ps)\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   719
      by simp
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   720
    let ?qs = \<open>filter (\<lambda>(a', _). compare cmp1 a a' = Equiv) ps\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   721
    have \<open>sort ?cmp2 ?qs = sort ?cmp ?qs\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   722
    proof (rule sort_eqI)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   723
      show \<open>mset ?qs = mset (sort ?cmp ?qs)\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   724
        by simp
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   725
      show \<open>sorted ?cmp2 (sort ?cmp ?qs)\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   726
        by (rule sorted_prod_lex_imp_sorted_snd) auto
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   727
    next
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   728
      fix q :: \<open>'a \<times> 'b\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   729
      define c d where \<open>c = fst q\<close> \<open>d = snd q\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   730
      moreover assume \<open>q \<in> set ?qs\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   731
      ultimately have \<open>(c, d) \<in> set ?qs\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   732
        by simp
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   733
      from sorted_stable_segment [of ?cmp \<open>(a, d)\<close> ps]
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   734
      have \<open>sorted ?cmp (filter (\<lambda>(c, b). compare (prod_lex cmp1 cmp2) (a, d) (c, b) = Equiv) ps)\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   735
        by (simp only: case_prod_unfold prod.collapse)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   736
      also have \<open>(\<lambda>(c, b). compare (prod_lex cmp1 cmp2) (a, d) (c, b) = Equiv) =
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   737
        (\<lambda>(c, b). compare cmp1 a c = Equiv \<and> compare cmp2 d b = Equiv)\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   738
        by (simp add: fun_eq_iff compare_prod_lex_apply split: comp.split)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   739
      finally have *: \<open>sorted ?cmp (filter (\<lambda>(c, b). compare cmp1 a c = Equiv \<and> compare cmp2 d b = Equiv) ps)\<close> .
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   740
      let ?rs = \<open>filter (\<lambda>(_, d'). compare cmp2 d d' = Equiv) ?qs\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   741
      have \<open>sort ?cmp ?rs = ?rs\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   742
        by (rule sort_eqI) (use * in \<open>simp_all add: case_prod_unfold\<close>)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   743
      then show \<open>filter (\<lambda>r. compare ?cmp2 q r = Equiv) ?qs =
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   744
        filter (\<lambda>r. compare ?cmp2 q r = Equiv) (sort ?cmp ?qs)\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   745
        by (simp add: filter_sort case_prod_unfold flip: \<open>d = snd q\<close>)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   746
    qed      
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   747
    then show \<open>filter (\<lambda>q. compare ?cmp1 p q = Equiv) (sort ?cmp2 ps) =
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   748
      filter (\<lambda>q. compare ?cmp1 p q = Equiv) (sort ?cmp ps)\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   749
      by (simp add: filter_sort case_prod_unfold flip: ab)
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   750
  qed
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   751
  then show \<open>(sort (key fst cmp1) \<circ> sort (key snd cmp2)) ps = sort (prod_lex cmp1 cmp2) ps\<close>
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   752
    by simp
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   753
qed
88064da0ae76 more on sorting
haftmann
parents: 82388
diff changeset
   754
69250
1011f0b46af7 generic merge sort
haftmann
parents: 69246
diff changeset
   755
end