Camelot Example Programs

List Examples

let gen a b = if a = b+1 then []
              else a::(gen (a+1) b)
(* Generate list [a..b] *)

let len l = match l with [] -> 0 | h::t -> 1 + len t
let hd l = match l with [] -> 0  | h::_ -> h
let tl l = match l with [] -> [] | _::t -> t

let append l m = 
  match l with [] -> m 
             | h::t -> h::(append t m)

let rev' l acc = 
  match l with [] -> acc 
             | h::t -> rev' t (h::acc)

let rev l = 
  match l with [] -> []
             | h::t -> append (rev t) [h]

let take l n = match l with  [] -> []
                         | h::t -> if n > 0 
                                   then h::(take t (n-1))
                                   else []

let drop l n = match l with [] -> []
                          | h::t -> if n > 0 then drop t (n-1)
			            else l

(* Insertion sort *)
let insert n l = 
  match l with [] -> [n]
             | h::t -> if n <= h then n::l
                       else h::(insert n t)
let sort l = 
  match l with [] -> []
             | h::t -> insert h (sort t)

(* Quick sort (from Paulson) *)
let qsort l = 
  match l with
  | [] -> []
  | h::t -> 
      begin
        match t with 
	| [] -> l 
        | x::y -> partition h [] [] t
      end
	
and partition a left right l =
  match l with [] -> append (qsort left) (a::(qsort right))
             | x::xs -> 
               if x <= a then partition a (x::left) right xs
               else partition a left (x::right) xs

(* Merge sort. Again from Paulson *)
let merge lx ly = 
  match lx with [] -> ly
              | x::xs -> 
		  begin
                    match ly with [] -> lx
                    | y::ys -> 
                        if x <= y 
                        then x::(merge xs (y::ys))
                        else y::(merge (x::xs) ys)
		  end

let mergesort l = 
  match l with [] -> []
             | h::t ->
		 begin
		   match t with 
		     [] -> l
                   | _::_ -> 
		       let k = (len l)/2 
		       in
		       merge (mergesort (take l k)) (mergesort (drop l k))
		 end

let member n l = 
  match l with [] -> false
             | h::t -> if n = h then true
                       else member n t


let listToString' l = 
        match l with 
          [] -> ""
        | h::t ->
	    begin
	      match t with [] -> string_of_int h 
              | h'::t' -> (string_of_int h) 
              ^ ", " 
              ^ (listToString' t)
	    end

let listToString l = 
           "[" ^ (listToString' l) ^ "]"


let stringListToIntList l = match l with
    [] -> []
  | h::t -> (int_of_string h) :: (stringListToIntList t)

let sq x = x*x
let treble x = x+x+x

let start args =
	let l = stringListToIntList args
     in let _ = print_string ("List has length " 
                             ^ string_of_int(len l)  
                             ^"\n")
     in let _ = print_string ("Original list: " 
                             ^ (listToString l) 
                             ^ "\n")
     in let _ = print_string ("Reversed list: " 
                             ^ (listToString (rev' l [])) 
                             ^ "\n")
     in let _ = print_string ("First 4 elements of list: " 
                             ^ (listToString (take l 4)) 
                             ^ "\n")
     in let _ = print_string ("All but first 4 elements of list: " 
                             ^ (listToString (drop l 4)) 
                             ^ "\n")
     in let _ = print_string ("Insertion sorted list:   " 
                              ^ (listToString (sort l)) 
                              ^ "\n")
     in let _ = print_string ("Quick sorted list:   " 
                              ^ (listToString (qsort l)) 
                              ^ "\n")
     in let _ = print_string ("Merge sorted list:   " 
                              ^ (listToString (mergesort l)) 
                              ^ "\n")

     in ()

Sorting Algorithms

Insertion Sort

type iList = !Nil | Cons of int * iList

let ins a l = 
	match l with 
	  Nil -> Cons(a,Nil)
	| Cons(x,t)@_ -> 
	    if a < x then Cons(a,Cons(x,t))
		else Cons(x, ins a t)

let sort l = 
  match l with 
    Nil -> Nil
  | Cons(a,t)@_ -> ins a (sort t)

Heap Sort

(* Linear in-place heapsort code for database program *)

type iList = !Nil | Cons of int * iList
type iresult = !None | Some of int * iTree
type iTree = !Leaf | Node of int * iTree * iTree

(* Message after copy_strings *)
(* Odd error if you use -n option.  item seems to be assigned two 
   types:  Object and Item.  This appears to be reolved in DataFlow.sml,  
   but if we turn this off then we get a Grail error. *)

let string_less v w = string_compare v w <= 0

(* all trees are supposed to be heaps. Leaf is a heap and
t=Node(w,t1,t2) is a heap if w is the largest element of t and
moreover t1, t2 are heaps and 0<=|t1|-|t2|<=1 *)

(* insert a new element into a heap *)

let insert x t = 
 match t with 
        Leaf ->  Node(x,Leaf,Leaf)
      | Node(z,left,right)@_ ->
            if x < z
               then Node(x, insert z right, left)
               else Node(z, insert x right, left)

(* siftdown w t1 t2 assumes that t1, t2 are heaps and that 0 <= |t1|-|t2| <= 1. 
   It returns a heap consisting of the elements of Node(w,t1,t2) *)

let siftdown w t1 t2 = 
	match t1 with Leaf -> Node(w,Leaf,Leaf)
      | Node(v,t11,t12)@_ -> 
	begin
	   match t2 with 
           Leaf ->
                if w < v then 
                     Node(w, Node(v,Leaf,Leaf), Leaf) else 
                     Node(v, Node(w,Leaf,Leaf), Leaf)
         | Node(u, t21,t22)@_ -> 
              if w < u & w < v then 
                    Node(w, Node(v,t11,t12), Node(u,t21,t22)) 
              else if u < w & u < v then 
                    Node(u, Node(v,t11,t12), siftdown w t21 t22) 
              else  Node(v, siftdown w t11 t12, Node(u,t21,t22))
        end  

(* removes an arbitrary element from t and returns it as well as the
   resulting heap *) 

let removesome t = 
    match t with Leaf -> None
  | Node(x, left, right)@_ -> 
      begin
        match removesome left with 
          None -> Some(x, right) (* actually, right=Leaf, here *) 
        | Some(z, left')@_ -> Some(z, Node(x, right, left'))
      end


(* removes the largest element from a heap *)

let removetop t = 
    match t with 
    Leaf -> None
 |  Node(x,left,right)@_ -> 
     begin
       match removesome left with 
	 None -> Some(x, right) (* actually, right=Leaf here *)
       | Some(z, left')@_ -> Some(x, siftdown z right left')
     end


let make_heap l = match l with Nil -> Leaf 
|  Cons(h, t)@_ -> 
    let hp = make_heap t 
    in insert h hp

let extract h = match removetop h with 
                 None -> Nil
               | Some(h,t)@_ -> Cons(h, extract t)


let sort l = extract (make_heap l)