Mlsem_system.AstThe functional core language.
The full language of Mlsem_lang.Ast is compiled down to this small lambda-calculus, which is what Checker and Reconstruction work on.
Terms are expected to be alpha-converted (every binder introduces a distinct Mlsem_common.Variable.t) and to carry pairwise distinct Eid.ts.
type pcustom = {pname : string;pdom : Mlsem_types.Ty.t -> Mlsem_types.Ty.t;proj : Mlsem_types.Ty.t -> Mlsem_types.Ty.t;pgen : bool;}A user-defined projection. proj computes the type of the result from the type of the argument and must be monotonic; pdom t is the largest argument type whose projection is below t; pgen says whether the projection is generalizable, i.e. free of effects (cf. Checker.generalize).
type ccustom = {cname : string;cdom : Mlsem_types.Ty.t -> Mlsem_types.Ty.t list list;cons : Mlsem_types.Ty.t list -> Mlsem_types.Ty.t;cgen : bool;}A user-defined constructor. cons computes the type of the result from the types of the arguments and must be monotonic; cdom t returns the alternative argument-type tuples whose construction is below t, each of which must have the constructor's arity; cgen as in pcustom.
A user-defined operation, typed by the arrow scheme ofun returns. ogen as in pcustom.
type projection = | Pi of int * int| PiField of string| PiFieldOpt of string| Hd| Tl| PiTag of Mlsem_types.Tag.t| PCustom of pcustomtype constructor = | Tuple of int| Cons| Rec of string list * bool| Tag of Mlsem_types.Tag.t| Enum of Mlsem_types.Enum.t| Join of int| Meet of int| Ternary of Mlsem_types.Ty.t| Voidify of Mlsem_types.Ty.t| Normalize| CCustom of ccustomtype operation = | RecUpd of string| RecDel of string| Ignore of Mlsem_types.Ty.t| OCustom of ocustomtype alt_settings = {aname : string;amask : Mlsem_common.Env.t -> bool list;aerror : Mlsem_common.Env.t -> string;}Settings of an Alt expression. amask env selects the branches that may be typed under env: it must return exactly one boolean per branch of the Alt, in the same order. aerror env builds the error message reported when no branch could be typed.
type param_annot = Mlsem_types.GTy.t optiontype e = | Value of Mlsem_types.GTy.t| Var of Mlsem_common.Variable.t| Constructor of constructor * t list| Lambda of param_annot * Mlsem_common.Variable.t * t| LambdaRec of (param_annot * Mlsem_common.Variable.t * t) list| Ite of t * Mlsem_types.GTy.t * t * t| App of t * t| Operation of operation * t| Projection of projection * t| Let of Mlsem_types.Ty.t list * Mlsem_common.Variable.t * t * tThe type list is a suggested decomposition of the bound variable: the body is typed once per cell and the results are joined, which is what lets a single definition be used at several types in a same scope. An empty list disables partitioning; note that only a partitioned Let propagates the divergence of its definition (an empty definition type makes every cell vanish).
| TypeCast of t * Mlsem_types.GTy.t * check| TypeCoerce of t * Mlsem_types.GTy.t * check| Alt of alt_settings * t listand t = Mlsem_common.Eid.t * eBottom-up: f is applied to a node after its children have been rewritten, and is not re-applied to the node it returns.
Top-down with early stop: f is applied to a node first, and when it returns Some e' the node is replaced by e' without descending into it. Returning None recurses into the children.
Top-down traversal, as map': descends into a node only if f returns true on it.
val fv : t -> Mlsem_common.VarSet.tFree variables, computed as "used minus bound" over the whole term. This is only correct because terms are alpha-converted, so a variable bound in one sub-term cannot occur free in another.
val vars : t -> Mlsem_common.VarSet.tAll variables, used or bound.
Substitutes type variables in the type annotations of the term. The types embedded in Ternary, Voidify, Ignore and in the pcustom / ccustom / ocustom closures are not traversed: they are required to be free of type variables.
Refreshes all Eid.t, preserving localization data. Useful when duplicating an expression.
val pp_raw : Stdlib.Format.formatter -> t -> unitPrints the term as a data structure, annotations included; pp prints it as source-like syntax.
val pp : Stdlib.Format.formatter -> t -> unitPrints the term as a data structure, annotations included; pp prints it as source-like syntax.
val pp_e : Stdlib.Format.formatter -> e -> unitval pp_check : Stdlib.Format.formatter -> check -> unitval pp_projection : Stdlib.Format.formatter -> projection -> unitval pp_constructor : Stdlib.Format.formatter -> constructor -> unitval pp_operation : Stdlib.Format.formatter -> operation -> unitval pp_alt_settings : Stdlib.Format.formatter -> alt_settings -> unitval pp_param_annot : Stdlib.Format.formatter -> param_annot -> unitval pp_pcustom : Stdlib.Format.formatter -> pcustom -> unitval pp_ccustom : Stdlib.Format.formatter -> ccustom -> unitval domain_of_proj : projection -> Mlsem_types.Ty.t -> Mlsem_types.Ty.tdomain_of_proj p t is the largest argument type whose projection by p is below t. In particular domain_of_proj p Ty.any is the domain of p.
val proj : projection -> Mlsem_types.Ty.t -> Mlsem_types.Ty.tThe type of the projection of an argument of the given type. Monotonic; only meaningful on a type within the projection's domain.
val domains_of_construct :
constructor ->
Mlsem_types.Ty.t ->
Mlsem_types.Ty.t list listdomains_of_construct c t returns the alternative argument-type tuples whose construction by c is below t; the empty list means c cannot produce a value in t. Each tuple has the arity of c.
val construct : constructor -> Mlsem_types.Ty.t list -> Mlsem_types.Ty.tThe type of the construction of arguments of the given types. Monotonic.
val fun_of_operation :
Mlsem_common.Env.t ->
operation ->
Mlsem_types.TyScheme.tThe arrow scheme an operation is typed with; an operation is applied like a function whose type is fixed rather than inferred.
val coerce :
?coercion_id:Mlsem_common.Eid.t ->
?duplicate_arrows:bool ->
check ->
Mlsem_types.GTy.t ->
t ->
tcoerce c ty e wraps e in a TypeCoerce to ty, pushing the coercion inwards as far as the shape of e allows: coercing a lambda to an arrow type coerces its body and annotates its parameter, coercing a constructor coerces its arguments, and so on. This is what lets a user signature guide the reconstruction inside a definition instead of only constraining its result. The outer coercion is always kept as well, under coercion_id if given and under a refreshed id otherwise; sub-terms whose shape does not match the target type are simply left alone. If duplicate_arrows is set to true, Lambda expressions may be duplicated when necessary to allow pushing coercions inside (for intersections of arrows).