open Types type calling_conv = | Boxed | Unboxed type repr = | RInt | RBool | RBox of typ | RTuple of repr list | RSum of repr * repr | RFun of calling_conv * repr list * repr type var = string type term = | Var of var | Int of int | Bool of bool | Tuple of term list | Proj of int * term | Inl of repr * repr * term | Inr of repr * repr * term | Case of term * (var * term) * (var * term) | Lam of calling_conv * (var * repr) list * repr * term | App of term * term list | Let of var * term * term | LetRec of var * repr * term * term | EqInt of term * term | EqBool of term * term | If of term * term * term | Box of typ * term | Unbox of term | Roll of typ * term | Unroll of term | WorkerWrapper of worker_wrapper | Halt of term and worker_wrapper = { wrapper : var; worker : var; boxed_arg : typ; unboxed_args : repr list; result_repr : repr; wrap_body : term; worker_body : term; in_term : term; } type value = | VInt of int | VBool of bool | VTuple of value list | VInl of repr * repr * value | VInr of repr * repr * value | VLam of calling_conv * (var * repr) list * repr * term | VBox of typ * value | VRoll of typ * term type outcome = | Value of value | Stuck of string | Diverged of int type trace = { steps : term list; outcome : outcome; } val string_of_repr : repr -> string val string_of_term : term -> string val string_of_value : value -> string val is_value : term -> bool val step : term -> (term, string) result val evaluate : ?fuel:int -> term -> trace val observe : ?fuel:int -> term -> outcome