thys2/Sort_ops.thy~
changeset 25 a5f5b9336007
equal deleted inserted replaced
24:77daf1b85cf0 25:a5f5b9336007
       
     1 theory Sort_ops
       
     2 imports Main
       
     3 begin
       
     4 
       
     5 ML {*
       
     6 local 
       
     7   open Array
       
     8 in
       
     9 
       
    10  fun swap i j a = let val ai = sub(a, i);
       
    11                        val _ = update(a, i, sub(a, j))
       
    12                        val _ = update(a, j, ai)
       
    13                    in
       
    14                         a
       
    15                    end
       
    16 
       
    17   fun pre_ops_of a = 
       
    18    getM :|-- (fn (l, r, piv, i, j) => let
       
    19        (* val _ = Output.tracing ("("^string_of_int i^","^string_of_int j^")") *)
       
    20     in
       
    21     if (j < i) then (returnM (swap l j a) |-- returnM [(l, j)])
       
    22     else (if (sub(a, i) <= piv andalso i <= r) then (setM (l, r, piv, i + 1, j)
       
    23                                                         |-- pre_ops_of a)
       
    24           else if (sub(a, j) > piv ) then (setM (l, r, piv, i, j - 1) |-- pre_ops_of a)
       
    25           else (pre_ops_of (swap i j a) :|-- (fn ops => returnM ((i,j)::ops))))
       
    26     end  
       
    27    )
       
    28 
       
    29   fun ops_of i j a = 
       
    30      if (j < i) then []
       
    31   else let
       
    32      val piv = sub(a, i)
       
    33      val (ops1, (_, _, _, i', j')) = pre_ops_of a (i, j, piv, i, j) |> normVal
       
    34      val ops2 = ops_of i (j' - 1) a
       
    35      val ops3 = ops_of (j' + 1) j a
       
    36   in
       
    37      ops1 @ ops2 @ ops3 
       
    38   end
       
    39 
       
    40   fun rem_sdup [] = []
       
    41     | rem_sdup [c] = [c]
       
    42     | rem_sdup ((i, j)::(i', j')::xs) = if ((i = i' andalso j = j') orelse
       
    43                                             (i = j' andalso j = i')) then rem_sdup (xs)
       
    44                             else (i, j)::rem_sdup ((i', j')::xs)
       
    45   fun sexec [] a = a
       
    46    | sexec ((i, j)::ops) a = sexec ops (swap i j a)
       
    47 
       
    48   fun swaps_of (l:int list) = 
       
    49     ops_of 0 (List.length l - 1) (fromList l) |> rem_sdup
       
    50       |> filter (fn (i, j) => i <> j)
       
    51 end
       
    52 
       
    53 *}
       
    54 
       
    55 text {* Examples *}
       
    56 
       
    57 ML {*
       
    58   val l = [8, 9, 10, 1, 12, 13, 14] 
       
    59   val ops = (swaps_of l)
       
    60   val a = (sexec ops (Array.fromList l))
       
    61   val l' = Array.vector a
       
    62   val a = sexec (rev ops) a
       
    63 *}
       
    64 
       
    65 end