LustreAstHelpersSome helper functions on the surface level parsed AST
val expr_is_id : LustreAst.expr -> boolReturns whether or not the expression is an Ident variant
val expr_is_const : LustreAst.expr -> boolReturns whether or not the expression is a Const variant
val expr_is_true : LustreAst.expr -> boolReturns whether or not the expression is a Bool Const variant with the True value
val expr_is_false : LustreAst.expr -> boolReturns whether or not the expression is a Bool Const variant with the False value
val pos_of_expr : LustreAst.expr -> Lib.positionReturns the position of an expression
val id_of_expr : LustreAst.expr -> HString.t optionReturn a lustre id if the expression is an Ident variant or None otherwise
val expr_is_droppable : LustreAst.expr -> boolChecks whether the expression can be deleted from the AST without losing a proof obligation. The check is a conservative whitelist: an expression form it does not explicitly recognize as droppable, including any form added later, is reported as not droppable. Answering false is always sound, so a new expression form only needs to be listed as droppable if the caller should be allowed to delete it.
val expr_contains_call : LustreAst.expr -> boolChecks if the expression contains a call to a node
val expr_contains_id : LustreAst.ident -> LustreAst.expr -> boolChecks if the expression contains a particular identifier
val type_arity : LustreAst.lustre_type -> int * intReturns the arity of a type, a function (TArr) has arity `(a, b)` where `a` is the number of inputs and `b` is the number of outputs, every other type has arity `(0, 0)`
val substitute_naive :
HString.t ->
LustreAst.expr ->
LustreAst.expr ->
LustreAst.exprSubstitute second param for first param in third param. Bound variables introduced by match arms, quantifiers and any/choose are alpha-renamed when needed to avoid capture.
val apply_subst_in_expr :
(HString.t * LustreAst.expr) list ->
LustreAst.expr ->
LustreAst.exprapply_subst_in_expr s e applies the substitution defined by association list s to the expression e, including the expressions of the types it carries (e.g. explicit type arguments), as subst_in_type_exprs does. Bound variables introduced by match arms, quantifiers and any/choose are alpha-renamed when needed to avoid capture.
val apply_subst_in_node_item :
(HString.t * LustreAst.expr) list ->
LustreAst.node_item ->
LustreAst.node_itemapply_subst_in_node_item s i applies the substitution defined by association list s to every expression of the node item i, leaving the left-hand sides of its equations alone. Bound variables introduced by match block arms and by the indices of an array definition shadow s over the expressions they scope, and those of a match block arm are alpha-renamed when needed to avoid capture.
val apply_subst_in_type :
(HString.t * LustreAst.expr) list ->
LustreAst.lustre_type ->
LustreAst.lustre_typeapply_subst_in_type s t applies the substitution defined by association list s to the expressions of (possibly dependent) type t AnyOp and Quantifier are not supported due to introduction of bound variables.
val subst_in_type_exprs :
(HString.t * LustreAst.expr) list ->
LustreAst.lustre_type ->
LustreAst.lustre_typesubst_in_type_exprs s t applies the substitution s to every expression of type t. A refinement type's binder shadows s in its predicate, and is alpha-renamed when a substituted expression would be captured by it.
val apply_type_subst_in_type :
(HString.t * LustreAst.lustre_type) list ->
LustreAst.lustre_type ->
LustreAst.lustre_typeapply_type_subst_in_type s t applies the (type-level) substitution defined by association list s to type t.
val has_unguarded_pre : LustreAst.expr -> boolReturns true if the expression has unguareded pre's
val has_unguarded_pre_no_warn : LustreAst.expr -> boolReturns true if the expression has unguareded pre's. Does not print warning.
val has_pre_or_arrow : LustreAst.expr -> Lib.position optionReturns true if the expression has a `pre` or a `->`.
val contract_has_pre_or_arrow : LustreAst.contract -> Lib.position optionReturns true iff a contract mentions a `pre` or a `->`. Does not (cannot) check contract calls recursively, checks only inputs and outputs.
val node_local_decl_has_pre_or_arrow :
LustreAst.node_local_decl ->
Lib.position optionChecks whether a node local declaration has a `pre` or a `->`.
val node_item_has_pre_or_arrow : LustreAst.node_item -> Lib.position optionChecks whether a node equation has a `pre` or a `->`.
val lazy_construct :
LustreAst.expr ->
(LustreAst.expr * LustreAst.expr list) optionlazy_construct e returns the condition of e and the operands it guards, if e is a lazy construct: a when expression, and then, or else or ==>
val vars_of_node_calls : LustreAst.expr -> LustreAst.SI.tvars_of_node_calls e returns all variable identifiers within arguments of node calls that appear in the expression e (while excluding node call identifiers), within the restart conditions of restarted node calls, and within the conditions of the lazy constructs that guard node calls
val vars_without_node_call_ids : LustreAst.expr -> LustreAst.SI.tvars_without_node_call_ids e returns all variable identifiers that appear in the expression e while excluding node call identifiers
val vars_without_node_call_ids_current : LustreAst.expr -> LustreAst.SI.tvars_without_node_call_ids_current e is like vars_without_node_call_ids, but only those vars that are not under a 'pre' expression
val expr_is_time_invariant :
(LustreAst.ident -> bool) ->
LustreAst.expr ->
boolexpr_is_time_invariant is_invariant_var e holds when e contains no 'pre', '->' or node call, and every variable of e satisfies is_invariant_var. The normalizer rewrites 'pre (ai)' to '(pre a)i' only when this holds for i, and the syntax checks exempt such an index from the ban on quantified variables under 'pre', so is_invariant_var in the syntax checks must not accept a variable the normalizer rejects
val vars_of_struct_item_with_pos :
LustreAst.struct_item ->
(Lib.position * LustreAst.index) listreturns all variables that appear in a struct_item (the lhs of an equation) with associated positions
val vars_of_struct_item : LustreAst.struct_item -> LustreAst.SI.treturns all variables that appear in a struct_item (the lhs of an equation)
val defined_vars_with_pos :
LustreAst.node_item ->
(Lib.position * LustreAst.index) listreturns all the variables that appear in the lhs of the equation of the node body with associated positions
val vars_of_ty_ids : LustreAst.typed_ident -> LustreAst.SI.treturns a singleton set with the only identifier in a typed identifier declaration
val calls_of_expr : LustreAst.expr -> NodeId.Set.tcalls_of_expr e returns all node/function names for those nodes/functions called in e
val vars_of_type :
?into_ty_args:bool ->
LustreAst.lustre_type ->
LustreAst.SI.tvars_of_type ty returns all variable identifiers that appear in the type ty while excluding node call identifiers and refinement type bound variables. into_ty_args also descends into the type arguments of a user type
val rename_self_referencing_binders :
?expand:(LustreAst.lustre_type -> LustreAst.lustre_type) ->
(Lib.position * LustreAst.ident * LustreAst.lustre_type) list ->
LustreAst.expr ->
(Lib.position * LustreAst.ident * LustreAst.lustre_type) list
* LustreAst.exprrename_self_referencing_binders ~expand tis e alpha-renames, in the quantifier binders tis and body e, each variable whose name occurs in a binder type, after expansion by expand, where it does not denote the quantified variable
val add_exp :
Lib.position ->
LustreAst.expr ->
LustreAst.expr ->
LustreAst.exprReturn an AST that adds two expressions
val abs_diff :
Lib.position ->
LustreAst.expr ->
LustreAst.expr ->
LustreAst.exprreturns an AST which is the absolute difference of two expr ast
val extract_ip_ty :
LustreAst.const_clocked_typed_decl ->
LustreAst.ident * LustreAst.lustre_typereturns the pair of identifier and its type from the node input streams
val extract_op_ty :
LustreAst.clocked_typed_decl ->
LustreAst.ident * LustreAst.lustre_typereturns the pair of identifier and its type from the node output streams
val extract_loc_ty :
LustreAst.node_local_decl ->
LustreAst.ident * LustreAst.lustre_type * LustreAst.expr optionreturns the pair of identifier and its type from the node local streams
val is_const_arg : LustreAst.const_clocked_typed_decl -> boolReturns true if the node input stream is a constant
val is_type_or_const_decl : LustreAst.declaration -> boolreturns true if it is a type or a constant declaration
val flatten_group_types :
LustreAst.lustre_type list ->
LustreAst.lustre_type listFlatten group type structure
val split_program :
LustreAst.declaration list ->
LustreAst.declaration list * LustreAst.declaration listSplits the program into two. First component are the type and constant declarations and Second component are the nodes, contract and function declarations.
val abstract_pre_subexpressions : LustreAst.expr -> LustreAst.exprAbstracts out the pre expressions into a constant so that the built graph does not create a cycle.
val extract_node_equation :
LustreAst.node_item ->
(LustreAst.eq_lhs * LustreAst.expr) listExtracts out all the node equations as an associated list of rhs and lhs of the equation
val get_last_node_name : LustreAst.declaration list -> NodeId.t optionGets the name of the last node declared in the file.
val move_node_to_last :
NodeId.t ->
LustreAst.declaration list ->
LustreAst.declaration listMoves the node with given name to the end of the list
val sort_typed_ident : LustreAst.typed_ident list -> LustreAst.typed_ident listSort typed identifiers
val sort_idents : LustreAst.ident list -> LustreAst.ident listSort identifiers
val syn_expr_equal :
int option ->
LustreAst.expr ->
LustreAst.expr ->
(bool, unit) Stdlib.resultCheck syntactic equality o Lustre expressions (ignoring positions) up to a certain optional depth. If the depth is reached, then Error () is returned, otherwise Ok false if the two expressions are unequal and Ok true if they are equal.
val syn_type_equal :
int option ->
LustreAst.lustre_type ->
LustreAst.lustre_type ->
(bool, unit) Stdlib.resultCheck syntactic equality of Lustre types (ignoring positions) up to a certain optional depth. If the depth is reached, then Error () is returned, otherwise Ok false if the two expressions are unequal and Ok true if they are equal.
val hash : int option -> LustreAst.expr -> intCompute the hash of an AST expression to the given depth. After the depth limit is reached the same hash value is assigned to every sub expression. This function does not include position information in the hash.
val name_mode_refs :
LustreAst.expr ->
LustreAst.expr * (LustreAst.ident * Lib.position * LustreAst.ident list) listname_mode_refs e replaces each mode reference in e by an identifier of the same name, and returns the references that were replaced, each with the position and path it was written at.
val rename_contract_vars : LustreAst.expr -> LustreAst.exprRename contract variables from internal names (with format #_contract_var) to syntax names
val name_of_prop :
Lib.position ->
HString.t option ->
LustreAst.prop_kind ->
HString.tGet the name associated with a property
val get_const_num_value : LustreAst.expr -> int optionval fold_lustre_ty :
?into_ty_args:bool ->
(LustreAst.expr -> 'a) ->
'a ->
('a -> 'a -> 'a) ->
LustreAst.lustre_type ->
'a`fold_lustre_ty f init op ty` folds over the type `ty` with initial value `init`, combining sub-results with `op` and collecting (sub-)results from Lustre expressions within the types with `f`
val fold_label_or_index :
'a ->
('a -> 'a -> 'a) ->
(LustreAst.expr -> 'a) ->
LustreAst.label_or_index list ->
'a`fold_label_or_index empty union f idx` folds `f` over the index expressions of a label_or_index list, as used in the update part of a StructUpdate (e.g. the key of a map update `mk := v`). A Label carries no expression and contributes `empty`; every other kind holds an arbitrary expression that may reference variables or node calls.
val map_lustre_ty :
(LustreAst.expr -> LustreAst.expr) ->
LustreAst.lustre_type ->
LustreAst.lustre_type`map_lustre_ty f ty` applies function `f` to each Lustre expression within `ty`
val constants_to_calls :
LustreAst.ident list ->
LustreAst.expr ->
LustreAst.expr`constants_to_calls const_func_ids expr` converts each constant `C` in `expr` to a call `C()`, provided that `C` is in `const_func_ids`
val constants_to_calls_in_type :
LustreAst.ident list ->
LustreAst.lustre_type ->
LustreAst.lustre_type`constants_to_calls_in_type const_func_ids ty` applies constants_to_calls to the expressions of `ty`, except where a refinement type's bound variable shadows a constant
val contains_subtype_satisfying :
(LustreAst.lustre_type -> bool) ->
LustreAst.lustre_type ->
bool`contains_subtype_satisfying p ty` returns true iff `ty` contains some subtype satisfying `p ty`
val is_direct_self_reference : LustreAst.ident -> LustreAst.lustre_type -> bool`is_direct_self_reference type_name ty` returns true iff `ty` is a reference to the type named `type_name`
val is_directly_recursive_adt :
LustreAst.ident ->
(LustreAst.ident * (LustreAst.ident * LustreAst.lustre_type) list) list ->
bool`is_directly_recursive_adt type_name ctors` returns true iff some constructor in `ctors` (the constructors of the ADT named `type_name`) directly references `type_name` in one of its fields
val pos_of_type : LustreAst.lustre_type -> Lib.position`pos_of_type ty` returns the position of `ty`
val node_id_of_decl : LustreAst.declaration -> NodeId.t optionval is_recursive_function : LustreAst.declaration -> boolval pat_bound_vars : LustreAst.pattern -> LustreAst.SI.tval pat_bound_vars_with_pos :
LustreAst.pattern ->
(LustreAst.ident * Lib.position) listThe variables a pattern binds, each with the position it is bound at.
val rename_pat_var :
LustreAst.ident ->
LustreAst.ident ->
LustreAst.pattern ->
LustreAst.patternrename_pat_var i i' pat renames the variable i bound by pat to i'. Before type checking a variable pattern may name a nullary constructor rather than a binder, so a caller running that early must pass an i it knows is a binder.
val fresh_bound_ident : LustreAst.ident -> LustreAst.identA fresh name for an alpha-renamed binder, derived from its current name