open MiniFun.TypeChecker open MiniFun.Types (* -------------------------------------------------------------------------- *) (* Error absent assignment program *) let program = Function (["a"], FunctionType ([IntegerType], IntegerType), Variable "x" ) ;; match typecheck program with Error (`AbsentAssignment _) -> Printf.printf "Error absent assignment program: error (success)\n" | _ -> Printf.printf "Error absent assignment program: failed\n" (* -------------------------------------------------------------------------- *) (* Error wrong arity program *) let program = Function (["a"], FunctionType ([IntegerType; IntegerType], IntegerType), (Variable "a") ) ;; match typecheck program with Error (`WrongTypeSpecification _) -> Printf.printf "Error wrong arity program 1: error (success)\n" | _ -> Printf.printf "Error wrong arity program 1: failed\n" let program = LetFun ("f", ["a"; "b"], FunctionType ([IntegerType; IntegerType], IntegerType), (Variable "a"), Function (["x"], FunctionType ([IntegerType], IntegerType), Application (Variable "f", [Integer 1; Integer 2; Variable "x"])) ) ;; match typecheck program with Error (`WrongArity _) -> Printf.printf "Error wrong arity program 2: error (success)\n" | _ -> Printf.printf "Error wrong arity program 2: failed\n" (* -------------------------------------------------------------------------- *) (* Error wrong return type program *) let program = Function (["a"], FunctionType ([IntegerType], BooleanType), (Variable "a") ) ;; match typecheck program with Error (`WrongTypeSpecification _) -> Printf.printf "Error wrong return type program: error (success)\n" | _ -> Printf.printf "Error wrong return type program: failed\n" (* -------------------------------------------------------------------------- *) (* Error wrong specification program *) let program = Function (["a"], IntegerType, (Variable "a") ) ;; match typecheck program with Error (`WrongTypeSpecification _) -> Printf.printf "Error wrong specification program: error (success)\n" | _ -> Printf.printf "Error wrong specification program: failed\n" (* -------------------------------------------------------------------------- *) (* Error wrong input type program *) let program = Application ( Function (["a"; "b"], FunctionType ([IntegerType; IntegerType], IntegerType), (Variable "a") ), [Boolean false] ) ;; match typecheck program with Error (`WrongType _) -> Printf.printf "Error wrong input type program: error (success)\n" | _ -> Printf.printf "Error wrong input type program: failed\n" (* -------------------------------------------------------------------------- *) (* Error not a function program *) let program = Application ( Integer 0, [Boolean false] ) ;; match typecheck program with Error (`WrongType _) -> Printf.printf "Error not a function program: error (success)\n" | _ -> Printf.printf "Error not a function program: failed\n" (* -------------------------------------------------------------------------- *) (* Error if branches with different types program *) let program = Function ( ["x"], FunctionType ([IntegerType], IntegerType), IfThenElse (Cmp (Integer 1, Integer 2), Boolean true, Integer 1) ) ;; match typecheck program with Error (`WrongType _) -> Printf.printf "Error if branches with different types program: error (success)\n" | _ -> Printf.printf "Error if branches with different types program: failed\n" (* -------------------------------------------------------------------------- *) (* Error if guard is not a boolean program *) let program = Function ( ["x"], FunctionType ([IntegerType], IntegerType), IfThenElse (Integer 1, Integer 2, Integer 1) ) ;; match typecheck program with Error (`WrongType _) -> Printf.printf "Error if guard is not a boolean program: error (success)\n" | _ -> Printf.printf "Error if guard is not a boolean program: failed\n" (* -------------------------------------------------------------------------- *) (* Identity program *) let program = Function (["a"], FunctionType ([IntegerType], IntegerType), (Variable "a") ) ;; match typecheck program with Ok _ -> Printf.printf "Identity program: success\n" | _ -> Printf.printf "Identity program: failed\n" (* -------------------------------------------------------------------------- *) (* Constant program *) let program = Function (["a"], FunctionType ([IntegerType], IntegerType), (Integer 1) ) ;; match typecheck program with Ok _ -> Printf.printf "Constant program: success\n" | _ -> Printf.printf "Constant program: failed\n" (* -------------------------------------------------------------------------- *) (* Partial application of function program *) let program = LetIn ("f", (Function (["x"; "y"], FunctionType ([IntegerType; IntegerType], IntegerType), Plus (Variable "x", Variable "y"))), (Application (Variable "f", [Integer 3])) ) ;; match typecheck program with Ok _ -> Printf.printf "Partial application of function program 1: success\n" | _ -> Printf.printf "Partial application of function program 1: failed\n" (* -------------------------------------------------------------------------- *) (* Partial application of function program *) let program = LetFun ("f", ["x"], FunctionType ([IntegerType], FunctionType ([IntegerType], IntegerType)), (Function (["y"], FunctionType ([IntegerType], IntegerType), Plus (Variable "x", Variable "y"))), (Application (Variable "f", [Integer 3])) ) ;; match typecheck program with Ok _ -> Printf.printf "Partial application of function program 2: success\n" | _ -> Printf.printf "Partial application of function program 2: failed\n" (* -------------------------------------------------------------------------- *) (* Passing functions to functions program *) let program = LetIn ("f", (Function ( ["z"], FunctionType ([FunctionType ([IntegerType], IntegerType)], FunctionType ([FunctionType ([IntegerType], IntegerType)], FunctionType ([IntegerType], IntegerType))), (Function ( ["y"], FunctionType ([FunctionType ([IntegerType], IntegerType)], FunctionType ([IntegerType], IntegerType)), Function ( ["x"], FunctionType ([IntegerType], IntegerType), (IfThenElse ( CmpLess (Variable "x", Integer 0), (Application (Variable "y", [Variable "x"])), (Application (Variable "z", [Variable "x"])) ))) )) )), (Application ( (Application (Variable "f", [Function (["x"], FunctionType ([IntegerType], IntegerType), Plus (Variable "x", Integer 1))] ) ), [Function (["x"], FunctionType ([IntegerType], IntegerType), Minus (Variable "x", Integer 1))] ) ) ) ;; match typecheck program with Ok _ -> Printf.printf "Passing functions to functions program: success\n" | _ -> Printf.printf "Passing functions to functions program: failed\n" (* -------------------------------------------------------------------------- *) (* Recursive function program *) let program = LetFun ("f", ["x"], FunctionType ([IntegerType], IntegerType), (IfThenElse (CmpLess (Variable "x", Integer 2),Integer 1, Plus (Variable "x", Application (Variable "f", [Minus (Variable "x", Integer 1)])))), (Variable "f") ) ;; match typecheck program with Ok _ -> Printf.printf "Recursive function program: success\n" | _ -> Printf.printf "Recursive function program: failed\n" (* -------------------------------------------------------------------------- *) (* Scope program *) let program = LetIn ("f", (LetIn ("a", Integer 1, (Function (["y"], FunctionType ([IntegerType], IntegerType), Plus (Variable "y", Variable "a"))))), (LetIn ("a", Integer 2, Variable "f")) ) ;; match typecheck program with Ok _ -> Printf.printf "Scope program: success\n" | _ -> Printf.printf "Scope program: failed\n" (* -------------------------------------------------------------------------- *) (* Factorial program *) let program = LetFun ( "f", ["x"], FunctionType ([IntegerType], IntegerType), (IfThenElse (CmpLessEq (Variable "x", Integer 0), Integer 1, Times (Variable "x", Application (Variable "f", [Minus (Variable "x", Integer 1)])))), (Variable "f") ) ;; match typecheck program with Ok _ -> Printf.printf "Factorial program: success\n" | _ -> Printf.printf "Factorial program: failed\n" (* -------------------------------------------------------------------------- *) (* Hailstone sequence's lenght program *) let program = LetFun ( "collatz", ["n"; "count"], FunctionType ([IntegerType; IntegerType], IntegerType), ( IfThenElse (BNot (Cmp (Variable "n", Integer 1)), (IfThenElse (Cmp (Modulo (Variable "n", Integer 2), Integer 0), Application (Variable "collatz", [Division (Variable "n", Integer 2); Plus (Integer 1, Variable "count")]), Application (Variable "collatz", [(Plus (Integer 1, Times (Integer 3, Variable "n"))); Plus (Integer 1, Variable "count")]))), (Variable "count")) ), (Function (["x"], FunctionType ([IntegerType], IntegerType), Application (Variable "collatz", [Variable "x"; Integer 1]))) ) ;; match typecheck program with Ok _ -> Printf.printf "Hailstone sequence's lenght program: success\n" | _ -> Printf.printf "Hailstone sequence's lenght program: failed\n" (* -------------------------------------------------------------------------- *) (* Sum multiples of 3 and 5 program *) let program = LetFun ( "sum", ["n"], FunctionType ([IntegerType], IntegerType), (IfThenElse ((BOr (Cmp (Modulo (Variable "n", Integer 3), Integer 0), Cmp (Modulo (Variable "n", Integer 5), Integer 0))), Plus (Variable "n", Application (Variable "sum", [Minus (Variable "n", Integer 1)])), (IfThenElse ((CmpLessEq (Variable "n", Integer 1)), (Integer 0), (Application (Variable "sum", [Minus (Variable "n", Integer 1)]))) )) ), (Variable "sum") ) ;; match typecheck program with Ok _ -> Printf.printf "Sum multiples of 3 and 5 program: success\n" | _ -> Printf.printf "Sum multiples of 3 and 5 program: failed\n" (* -------------------------------------------------------------------------- *) (* Rand program *) let program = Function ( ["x"], FunctionType ([IntegerType], IntegerType), Rand (Variable "x") ) ;; match typecheck program with Ok _ -> Printf.printf "Rand program: success\n" | _ -> Printf.printf "Rand program: failed\n" (* -------------------------------------------------------------------------- *) (* Fibonacci program *) let program = LetFun ( "fib", ["i"; "a"; "b"], FunctionType ([IntegerType; IntegerType; IntegerType], IntegerType), (IfThenElse (Cmp (Variable "i", Integer 0), Variable "a", Application (Variable "fib", [Minus (Variable "i", Integer 1); Variable "b"; Plus (Variable "a", Variable "b")]) )), Function (["x"], FunctionType ([IntegerType], IntegerType), (Application (Variable "fib", [Variable "x"; Integer 0; Integer 1]))) ) ;; match typecheck program with Ok _ -> Printf.printf "Fibonacci program: success\n" | _ -> Printf.printf "Fibonacci program: failed\n"