(*********************************************)
(* Laboratory Definitions required for list  *)
(*  and/or binary tree processing.           *)
(*                                           *)
(* Either 'cut and paste' this file into     *)
(*  ML interactive session, or put this file *)
(*  in your ML folder/directory and load     *)
(*  using the command:                       *)
(*     use "labdefs";  or  use "labdefs.ml"; *)
(*                                           *)
(* With PolyML, load these definitions and   *)
(*  then use the command:                    *)
(*                        PolyML.commit();   *)
(*   to save them for future sessions        *)
(*********************************************)

fun maxi(n,m):int = if n > m then n else m;

fun mini(n,m):int = if n < m then n else m;

fun maxr(n,m):real = if n > m then n else m;

fun minr(n,m):real = if n < m then n else m;

(* list processing  *)

exception first_has_nil_argument;
exception rest_has_nil_argument;

fun first (nil) = raise first_has_nil_argument
  | first (head :: rest) = head;

fun rest (nil) = raise rest_has_nil_argument
  | rest (_ :: rest_list) = rest_list;

fun append (list, item) = list @ (item :: []);

(* Binary tree processing *)

datatype 'a BinaryTree = bt_empty |
          bt of 'a * 'a BinaryTree * 'a BinaryTree ;

fun left_subtree bt_empty = bt_empty
    | left_subtree(bt(_,left,_)) = left;

fun right_subtree bt_empty = bt_empty
    | right_subtree(bt(_,_,right)) = right;

fun empty_bt bt_empty = true
 |  empty_bt ( _ )    = false;

exception label_has_nil_argument;

fun label bt_empty = raise label_has_nil_argument
    | label(bt(value,_,_)) = value;

(* Sample binary trees *)

val Tree1 = bt(3,bt_empty,bt_empty);

val Tree2 = bt(5,bt(10,bt_empty,bt_empty),bt_empty);

val Tree3 = bt(12,bt(4,bt_empty,bt_empty),bt(7,bt_empty,bt_empty));

val Tree4 = bt(34,bt(14,bt(7,bt_empty,bt_empty),bt_empty),
              bt(18,bt(3,bt_empty,bt_empty),bt(10,bt_empty,bt_empty)));

val Tree5 = bt(9,bt_empty,bt(12,bt_empty,bt(13,bt_empty,bt(7,bt_empty,
              bt(6,bt_empty,bt(4,bt_empty,bt_empty))))));

val Tree6 = bt(1,bt(2,bt(3,bt_empty,bt(5,bt_empty,bt_empty)),bt(4,
 bt(6,bt_empty,bt_empty),bt_empty)),bt(7,bt(8,bt_empty,bt(9,bt_empty,bt_empty)),bt_empty));

val Tree7 = bt(2,bt(1,bt(2,bt_empty,bt_empty),bt(3,bt_empty,bt_empty)),
              bt(3,bt(5,bt_empty,bt_empty),bt(1,bt_empty,bt_empty)));

val Tree8 = bt(16,bt(7,Tree3,Tree4),bt(12,Tree5,Tree6));

val Tree9 = bt(0,bt(5,bt(19,bt_empty,bt(~4,bt_empty,bt(8,bt_empty,bt_empty))),bt(32,bt(10,bt_empty,bt_empty),bt(3,bt_empty,bt_empty))),bt(7,bt(41,bt(2,bt_empty,bt(62,bt_empty,bt_empty)),bt_empty),bt(6,bt(10,bt_empty,bt_empty),bt_empty)));

val Tree10 = bt(~5,Tree7, Tree9);