(* Auto-tester for multapply function. *) use "tester.sml"; (* common utility functions *) (* Avoid "unbound variable or constructor" errors. *) datatype 'a LL = Nil | Node of 'a * 'a LL; fun multapply _ _ = raise Undefined; (* Load file. *) print "\n--> Loading file \"multapply.sml\"\n"; use "../multapply.sml" handle _ => (); (* 'map' for linked lists. *) fun LLmap f Nil = Nil | LLmap f (Node(a,t)) = Node(f a, LLmap f t); (* 'foldr' for linked lists. *) fun LLfoldr f init Nil = init | LLfoldr f init (Node(a,t)) = f(a, LLfoldr f init t); (* Convert a linked list to a string. *) fun LL2string L = "(" ^ LLfoldr (fn (a,t) => a ^ " -> " ^ t) "." L ^ ")"; (* Convert a linked list of functions to a string. *) fun fnLL2string (L:('a->'b) LL) = LL2string (LLmap (fn _ => "fn") L); (* Convert a linked list of strings to a string. *) val stringLL2string = LL2string o (LLmap string2string); (* Convert a linked list of ints to a string. *) val intLL2string = LL2string o (LLmap int2string); (* Convert a linked list of linked lists of strings to a string. *) val stringLLLL2string = LL2string o (LLmap stringLL2string); (* Convert a linked list of linked lists of ints to a string. *) val intLLLL2string = LL2string o (LLmap intLL2string); (* Return true iff both linked lists are equal. *) fun LL_eq eq (Nil,Nil) = true | LL_eq eq (Node(a,b),Node(c,d)) = eq (a,c) andalso LL_eq eq (b,d) | LL_eq eq (_,_) = false; (* Run test cases. *) ( print "\n--> Beginning test cases for function 'multapply'...\n"; runtests total grade (fn (funs,args) => multapply funs args) "multapply" (fn (funs,args) => fnLL2string funs ^ " " ^ intLL2string args) intLLLL2string (LL_eq (LL_eq (op =))) [ ((Nil, Nil), Nil, "(* no function, no argument *)", 0.3), ((Nil, Node(5,Nil)), Nil, "(* no function, non-empty argument *)", 0.3), ((Node(fn x => x+1,Nil), Nil), Node(Nil,Nil), "(* non-empty function, no argument *)", 0.3), ((Node(fn x => x+1,Nil), Node(5,Nil)), Node(Node(6,Nil),Nil), "(* function fn x => x+1, singleton argument *)", 0.3), ((Node(fn x => x+1,Nil), Node(5,Node(~2,Node(0,Nil)))), Node(Node(6,Node(~1,Node(1,Nil))),Nil), "(* function fn x => x+1, argument of length 3 *)", 0.4), ((Node(fn x => x+1,Node(fn x => 2*x,Nil)), Node(5,Nil)), Node(Node(6,Nil),Node(Node(10,Nil),Nil)), "(* functions fn x => x+1 and fn x => 2*x, singleton argument *)", 0.4), ((Node(fn x => x+1,Node(fn x => 2*x,Nil)), Node(5,Node(~2,Node(0,Nil)))), Node(Node(6,Node(~1,Node(1,Nil))), Node(Node(10,Node(~4,Node(0,Nil))),Nil)), "(* functions fn x => x+1 and fn x => 2*x, argument of length 3 *)", 0.5) ]; runtests total grade (fn (funs,args) => multapply funs args) "multapply" (fn (funs,args) => fnLL2string funs ^ " " ^ stringLL2string args) stringLLLL2string (LL_eq (LL_eq (op =))) [ ((Nil, Nil), Nil, "(* no function, no argument *)", 0.3), ((Nil, Node("blah",Nil)), Nil, "(* no function, non-empty argument *)", 0.3), ((Node(string_rev,Nil), Nil), Node(Nil,Nil), "(* non-empty function, no argument *)", 0.3), ((Node(string_rev,Nil), Node("blah",Nil)), Node(Node("halb",Nil),Nil), "(* function string_rev, singleton argument *)", 0.3), ((Node(string_rev,Nil), Node("blah",Node("",Node("hi",Nil)))), Node(Node("halb",Node("",Node("ih",Nil))),Nil), "(* function string_rev, argument of length 3 *)", 0.4), ((Node(string_rev,Node(int2string o size,Nil)), Node("blah",Nil)), Node(Node("halb",Nil),Node(Node("4",Nil),Nil)), "(* functions string_rev and int2string o size, singleton argument *)", 0.4), ((Node(string_rev,Node(int2string o size,Nil)), Node("blah",Node("x",Node("hi",Nil)))), Node(Node("halb",Node("x",Node("ih",Nil))), Node(Node("4",Node("1",Node("2",Nil))),Nil)), "(* functions string_rev and int2string o size, argument of length 3 *)", 0.5) ] ); (* Print total grade. *) print ("\n--> Grade = " ^ real2string (!grade) ^ " / " ^ real2string (!total) ^ "\n\n"); (* Quit the SML interpreter. *) exit 0;