type variable = string module VariableMap = Map.Make(String) type ftype = IntegerType | BooleanType | TupleType of ftype * ftype | FunctionType of ftype * ftype type t_exp = Integer of int (* x := a *) | Boolean of bool (* v *) | Variable of variable (* x *) | Tuple of t_exp * t_exp (* (a, b) *) | Function of variable * ftype * t_exp (* lambda x: t. x *) | Application of t_exp * t_exp (* x x *) | Plus of t_exp * t_exp (* x + x *) | Minus of t_exp * t_exp (* x - x *) | Times of t_exp * t_exp (* x * x *) | Division of t_exp * t_exp (* x / x *) | Modulo of t_exp * t_exp (* x % x *) | Power of t_exp * t_exp (* x ^ x *) | PowerMod of t_exp * t_exp * t_exp (* (x ^ x) % x *) | Rand of t_exp (* rand(0, x) *) | BAnd of t_exp * t_exp (* x && x *) | BOr of t_exp * t_exp (* x || x *) | BNot of t_exp (* not x *) | First of t_exp (* fst x *) | Second of t_exp (* scn x *) | Cmp of t_exp * t_exp (* x == x *) | CmpLess of t_exp * t_exp (* x < x *) | CmpLessEq of t_exp * t_exp (* x <= x *) | CmpGreater of t_exp * t_exp (* x > x *) | CmpGreaterEq of t_exp * t_exp (* x >= x *) | IfThenElse of t_exp * t_exp * t_exp (* if b then c else c *) | LetIn of variable * t_exp * t_exp (* let x = x in x *) | LetFun of variable * variable * ftype * t_exp * t_exp (* let rec x. y: t. x in x*) type permittedValues = IntegerPermitted of int | BooleanPermitted of bool | TuplePermitted of permittedValues * permittedValues | FunctionPermitted of closure and closure = { input: variable; body: t_exp; assignments: permittedValues VariableMap.t; recursiveness: variable option } type memory = { assignments: permittedValues VariableMap.t } type error = [ `AbsentAssignment of string | `WrongType of string | `DivisionByZero of string | `WrongTypeSpecification of string ]