src/HOL/ex/Radix_Sort.thy
author nipkow
Tue, 29 May 2018 14:05:59 +0200
changeset 68312 e9b5f25f6712
parent 68249 949d93804740
child 68386 98cf1c823c48
permissions -rw-r--r--
canonical names
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
67612
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
     1
(* Author: Tobias Nipkow *)
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
     2
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
     3
theory Radix_Sort
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
     4
imports
68312
e9b5f25f6712 canonical names
nipkow
parents: 68249
diff changeset
     5
  "HOL-Library.List_Lexorder" 
67612
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
     6
  "HOL-Library.Sublist" 
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
     7
  "HOL-Library.Multiset" 
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
     8
begin
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
     9
68176
3e4af46a6f6a more sorted cleaning
nipkow
parents: 67688
diff changeset
    10
text \<open>The \<open>Radix_Sort\<close> locale provides a sorting function \<open>radix_sort\<close> that sorts
3e4af46a6f6a more sorted cleaning
nipkow
parents: 67688
diff changeset
    11
lists of lists. It is parameterized by a sorting function \<open>sort1 f\<close> that also sorts
3e4af46a6f6a more sorted cleaning
nipkow
parents: 67688
diff changeset
    12
lists of lists, but only w.r.t. the column selected by \<open>f\<close>.
3e4af46a6f6a more sorted cleaning
nipkow
parents: 67688
diff changeset
    13
Working with lists, \<open>f\<close> is instantiated with @{term"\<lambda>xs. xs ! n"} to select the \<open>n\<close>-th element.
3e4af46a6f6a more sorted cleaning
nipkow
parents: 67688
diff changeset
    14
A more efficient implementation would sort lists of arrays because arrays support
3e4af46a6f6a more sorted cleaning
nipkow
parents: 67688
diff changeset
    15
constant time access to every element.\<close>
3e4af46a6f6a more sorted cleaning
nipkow
parents: 67688
diff changeset
    16
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    17
locale Radix_Sort =
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    18
fixes sort1 :: "('a list \<Rightarrow> 'a::linorder) \<Rightarrow> 'a list list \<Rightarrow> 'a list list"
68176
3e4af46a6f6a more sorted cleaning
nipkow
parents: 67688
diff changeset
    19
assumes sorted: "sorted (map f (sort1 f xss))"
3e4af46a6f6a more sorted cleaning
nipkow
parents: 67688
diff changeset
    20
assumes mset: "mset (sort1 f xss) = mset xss"
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    21
assumes stable: "stable_sort_key sort1"
67612
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    22
begin
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    23
68176
3e4af46a6f6a more sorted cleaning
nipkow
parents: 67688
diff changeset
    24
lemma set_sort1[simp]: "set(sort1 f xss) = set xss"
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    25
by (metis mset set_mset_mset)
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    26
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    27
abbreviation "sort_col i xss \<equiv> sort1 (\<lambda>xs. xs ! i) xss"
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    28
abbreviation "sorted_col i xss \<equiv> sorted (map (\<lambda>xs. xs ! i) xss)"
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    29
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    30
fun radix_sort :: "nat \<Rightarrow> 'a list list \<Rightarrow> 'a list list" where
67612
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    31
"radix_sort 0 xss = xss" |
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    32
"radix_sort (Suc i) xss = radix_sort i (sort_col i xss)"
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    33
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    34
lemma mset_radix_sort: "mset (radix_sort i xss) = mset xss"
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    35
by(induction i arbitrary: xss) (auto simp: mset)
67612
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    36
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    37
abbreviation "sorted_from i xss \<equiv> sorted (map (drop i) xss)"
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    38
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    39
definition "cols xss n = (\<forall>xs \<in> set xss. length xs = n)"
67612
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    40
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    41
lemma cols_sort1: "cols xss n \<Longrightarrow> cols (sort1 f xss) n"
67612
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    42
by(simp add: cols_def)
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    43
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    44
lemma sorted_from_Suc2:
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    45
  "\<lbrakk> cols xss n; i < n;
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    46
    sorted_col i xss;
68249
949d93804740 First step to remove nonstandard "[x <- xs. P]" syntax: only input
nipkow
parents: 68176
diff changeset
    47
    \<And>x. sorted_from (i+1) (filter (\<lambda>ys. ys!i = x) xss) \<rbrakk>
67612
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    48
  \<Longrightarrow> sorted_from i xss"
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    49
proof(induction xss rule: induct_list012)
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    50
  case 1 show ?case by simp
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    51
next
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    52
  case 2 show ?case by simp
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    53
next
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    54
  case (3 xs1 xs2 xss)
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    55
  have lxs1: "length xs1 = n" and lxs2: "length xs2 = n"
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    56
    using "3.prems"(1) by(auto simp: cols_def)
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    57
  have *: "drop i xs1 \<le> drop i xs2"
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    58
  proof -
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    59
    have "drop i xs1 = xs1!i # drop (i+1) xs1"
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    60
      using \<open>i < n\<close> by (simp add: Cons_nth_drop_Suc lxs1)
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    61
    also have "\<dots> \<le> xs2!i # drop (i+1) xs2"
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    62
      using "3.prems"(3) "3.prems"(4)[of "xs2!i"] by(auto)
67612
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    63
    also have "\<dots> = drop i xs2"
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    64
      using \<open>i < n\<close> by (simp add: Cons_nth_drop_Suc lxs2)
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    65
    finally show ?thesis .
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    66
  qed
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    67
  have "sorted_from i (xs2 # xss)"
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    68
  proof(rule "3.IH"[OF _ "3.prems"(2)])
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    69
    show "cols (xs2 # xss) n" using "3.prems"(1) by(simp add: cols_def)
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    70
    show "sorted_col i (xs2 # xss)" using "3.prems"(3) by simp
68249
949d93804740 First step to remove nonstandard "[x <- xs. P]" syntax: only input
nipkow
parents: 68176
diff changeset
    71
    show "\<And>x. sorted_from (i+1) (filter (\<lambda>ys. ys ! i = x) (xs2 # xss))"
67612
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    72
      using "3.prems"(4)
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    73
        sorted_antimono_suffix[OF map_mono_suffix[OF filter_mono_suffix[OF suffix_ConsI[OF suffix_order.order.refl]]]]
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    74
      by fastforce
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    75
  qed
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    76
  with * show ?case by (auto)
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    77
qed
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    78
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    79
lemma sorted_from_radix_sort_step:
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    80
assumes "cols xss n" and "i < n" and "sorted_from (i+1) xss"
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    81
shows "sorted_from i (sort_col i xss)"
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    82
proof (rule sorted_from_Suc2[OF cols_sort1[OF assms(1)] assms(2)])
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    83
  show "sorted_col i (sort_col i xss)" by(simp add: sorted)
68249
949d93804740 First step to remove nonstandard "[x <- xs. P]" syntax: only input
nipkow
parents: 68176
diff changeset
    84
  fix x show "sorted_from (i+1) (filter (\<lambda>ys. ys ! i = x) (sort_col i xss))"
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    85
  proof -
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    86
    from assms(3)
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    87
    have "sorted_from (i+1) (filter (\<lambda>ys. ys!i = x) xss)"
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    88
      by(rule sorted_filter)
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    89
    thus "sorted (map (drop (i+1)) (filter (\<lambda>ys. ys!i = x) (sort_col i xss)))"
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    90
      by (metis stable stable_sort_key_def)
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    91
  qed
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    92
qed
67612
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    93
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
    94
lemma sorted_from_radix_sort:
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    95
  "\<lbrakk> cols xss n;  i \<le> n;  sorted_from i xss \<rbrakk> \<Longrightarrow> sorted_from 0 (radix_sort i xss)"
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    96
proof(induction i arbitrary: xss)
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    97
  case 0 thus ?case by simp
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    98
next
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
    99
  case (Suc i)
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
   100
  thus ?case by(simp add: sorted_from_radix_sort_step cols_sort1)
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
   101
qed
67612
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
   102
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
   103
corollary sorted_radix_sort: "cols xss n \<Longrightarrow> sorted (radix_sort n xss)"
67612
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
   104
apply(frule sorted_from_radix_sort[OF _ le_refl])
68176
3e4af46a6f6a more sorted cleaning
nipkow
parents: 67688
diff changeset
   105
 apply(auto simp add: cols_def sorted_iff_nth_mono)
67612
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
   106
done
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
   107
e4e57da0583a New theory ex/Radix_Sort.thy
nipkow
parents:
diff changeset
   108
end
67688
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
   109
b39f5bb7d422 simplified Radix_Sort
nipkow
parents: 67684
diff changeset
   110
end