signature STLC = sig datatype stp = TpBase of string (* base type *) | TpFun of stp * stp (* function type *) | TpTup of stp list (* tuple type *) datatype ttm = TtmBool of bool (* boolean constant *) | TtmInt of int (* integer constant *) | TtmStr of string (* string constant *) | TtmVar of string (* variable *) | TtmIf of ttm * ttm * ttm (* if-then-else term *) | TtmOp of string * ttm list (* built-in operator *) | TtmLam of string * stp * ttm (* lambda abstraction *) | TtmApp of ttm * ttm (* application *) | TtmLet of string * ttm * ttm (* let-binding *) | TtmLetrec of string * stp * ttm * ttm (* letrec-binding *) | TtmTup of ttm list (* tuple *) | TtmPro of ttm * int (* projection *) | TtmFix of ttm (* fixed point *) | TtmAsc of ttm * stp (* ascription *) val parseString: string -> ttm val typeCheck: ttm -> bool datatype utm = (* for untyped term via deBruijn indices *) UtmBool of bool | UtmInt of int | UtmStr of string | UtmVar of int | UtmIf of utm * utm * utm | UtmOp of string * utm list | UtmLam of utm | UtmApp of utm * utm | UtmLet of utm * utm | UtmLetrec of utm * utm | UtmTup of utm list | UtmPro of utm * int | UtmFix of utm val erase: ttm -> utm val evaluate: utm -> utm end