Frama-C API - Logic_utils
 Utilities for ACSL constructs.
exception Not_well_formed of Cil_types.location * stringexception raised when a parsed logic expression is syntactically not well-formed.
Split a long-identifier into the list of its components. eg. "A::B::(<:)" is split into ["A";"B";"(<:)"]. Returns a singleton for regular identifiers.
basic utilities for logic terms and predicates. See also Logic_const to build terms and predicates.
val mem_logic_function : Cil_types.logic_info -> boolCheck if there is a logic function with same profile in the environment.
val add_logic_function : Cil_types.logic_info -> unitAdd a logic function in the environment. Replaces any existing logic function with the same profile. See Logic_env.add_logic_function_gen
val remove_logic_function : Cil_types.logic_info -> unitremove any logic function with the same profile from the environment. See Logic_env.remove_logic_function_gen
Types
val is_instance_of : string list -> Cil_types.logic_type -> Cil_types.logic_type -> boolis_instance_of poly t1 t2 returns true if t1 can be derived from t2 by instantiating some of the type variable in poly.
tests and extraction of element type
tests for an individual (non set) type
plain_xxx t returns true iff t is a xxx
val plain_arithmetic_type : Cil_types.logic_type -> boolval plain_integral_type : Cil_types.logic_type -> boolval plain_fun_ptr : Cil_types.logic_type -> boolval plain_array_type : Cil_types.logic_type -> boolval plain_pointer_type : Cil_types.logic_type -> booltests for potential sets
is_xxx t returns true iff t is a xxx _or_ a set of xxx
val is_arithmetic_type : Cil_types.logic_type -> boolval is_integral_type : Cil_types.logic_type -> boolval is_fun_ptr : Cil_types.logic_type -> boolval is_array_type : Cil_types.logic_type -> boolval is_pointer_type : Cil_types.logic_type -> boolsets and lists
val is_list_type : Cil_types.logic_type -> boolval is_set_type : Cil_types.logic_type -> boolextract elements
val type_of_set_elem : Cil_types.logic_type -> Cil_types.logic_typeval type_of_list_elem : Cil_types.logic_type -> Cil_types.logic_typeval type_of_pointed : Cil_types.logic_type -> Cil_types.logic_typereturns the type of the element pointed to by the type. If the source type is a set of pointers, returns a set of elements.
val type_of_array_elem : Cil_types.logic_type -> Cil_types.logic_typesame as type_of_pointed but for arrays (or set of arrays).
Predefined tests over types
val isLogicType : (Cil_types.typ -> bool) -> Cil_types.logic_type -> boolisLogicType test typ is false for pure logic types and the result of test for C types. In case of a set type, the function tests the element type.
val isLogicArrayType : Cil_types.logic_type -> boolval isLogicCharType : Cil_types.logic_type -> boolval isLogicAnyCharType : Cil_types.logic_type -> boolval isLogicVoidType : Cil_types.logic_type -> boolval isLogicPointerType : Cil_types.logic_type -> boolval isLogicVoidPointerType : Cil_types.logic_type -> boolType conversions
val logicCType : Cil_types.logic_type -> Cil_types.typval array_to_ptr : Cil_types.logic_type -> Cil_types.logic_typetransforms an array into pointer.
val logic_type_remove_qualifiers : Cil_types.logic_type -> Cil_types.logic_typeremoves qualifiers if logic_type is a C type, identity otherwise.
val coerce_type : Cil_types.typ -> Cil_types.logic_typeC type to logic type, with implicit conversion for arithmetic types.
Predicates
val translate_old_label : Cil_types.stmt -> Cil_types.predicate -> Cil_types.predicatetransforms \old and \at(,Old) into \at(,L) for L a label pointing to the given statement, creating one if needed.
Terms
val is_C_array : Cil_types.term -> booltrue if the term denotes a C array.
val mk_logic_StartOf : Cil_types.term -> Cil_types.termcreates a TStartOf from an TLval.
val mk_logic_AddrOf : ?loc:Cil_types.location -> Cil_types.term_lval -> Cil_types.logic_type -> Cil_types.termcreates an AddrOf from a TLval. The given logic type is the type of the lval.
val isLogicPointer : Cil_types.term -> booltrue if the term is a pointer.
val mk_logic_pointer_or_StartOf : Cil_types.term -> Cil_types.termcreates either a TStartOf or the corresponding TLval.
val mk_cast : ?loc:Cil_types.location -> ?force:bool -> Cil_types.typ -> Cil_types.term -> Cil_types.termcreates a logic cast if required, with some automatic simplifications being performed automatically. If force is true, the cast will always be inserted. Otherwise (which is the default), mk_cast typ t will return t if it is already of type typ
val array_with_range : Cil_types.exp -> Cil_types.term -> Cil_types.termarray_with_range arr size returns the logic term array'+{0..(size-1)}, array' being array cast to a pointer to char
val remove_logic_coerce : Cil_types.term -> Cil_types.termRemoves TLogic_coerce at head of term.
val numeric_coerce : Cil_types.logic_type -> Cil_types.term -> Cil_types.termnumeric_coerce typ t returns a term with the same value as t and of type typ. typ which should be Linteger or Lreal. numeric_coerce tries to avoid unnecessary type conversions in t. In particular, numeric_coerce (int)cst Linteger, where cst fits in int will be directly cst, without any coercion.
Also coerce recursively the sub-terms of t-set expressions (range, union, inter and comprehension) and lift the associated set type.
Predicates
val pointer_comparable : ?loc:Cil_types.location -> ?label:Cil_types.logic_label -> Cil_types.term -> Cil_types.term -> Cil_types.predicate\pointer_comparable. label defaults to Logic_const.here_label
Conversion from exp to term
val expr_to_term : ?coerce:bool -> Cil_types.exp -> Cil_types.termReturns a logic term that has exactly the same semantics as the original C-expression. The type of the resulting term is determined by the ~coerce flag as follows:
- when ~coerce:falseis given (the default) the term has the same c-type as the original expression.
- when ~coerce:trueis given, if the original expression has an int or float type, then the returned term is coerced into the integer or real logic type, respectively.
Remark: when the original expression is a comparison, it is evaluated as an int or an integer depending on the ~coerce flag. To obtain a boolean or predicate, use expr_to_boolean or expr_to_predicate instead.
val expr_to_predicate : Cil_types.exp -> Cil_types.predicateReturns a predicate semantically equivalent to the condition of the original C-expression.
This is different from expr_to_term e |> scalar_term_to_predicate since C-relations are translated into logic ones.
val expr_to_ipredicate : Cil_types.exp -> Cil_types.identified_predicateReturns a predicate semantically equivalent to the condition of the original C-expression.
Identical to expr_to_predicate e |> Logic_const.new_predicate.
val expr_to_boolean : Cil_types.exp -> Cil_types.termReturns a boolean term semantically equivalent to the condition of the original C-expression.
This is different from expr_to_term e |> scalar_term_to_predicate since C-relations are translated into logic ones.
val is_zero_comparable : Cil_types.term -> booltrue if the given term has a type for which a comparison to 0 exists (i.e. scalar C types, logic integers and reals).
val scalar_term_to_boolean : Cil_types.term -> Cil_types.termCompare the given term with the constant 0 (of the appropriate type) to return the result of the comparison e <> 0 as a boolean term.
val scalar_term_to_predicate : Cil_types.term -> Cil_types.predicateCompare the given term with the constant 0 (of the appropriate type) to return the result of the comparison e <> 0.
val lval_to_term_lval : Cil_types.lval -> Cil_types.term_lvalval host_to_term_lhost : Cil_types.lhost -> Cil_types.term_lhostval offset_to_term_offset : Cil_types.offset -> Cil_types.term_offsetval constant_to_lconstant : Cil_types.constant -> Cil_types.logic_constantval lconstant_to_constant : Cil_types.logic_constant -> Cil_types.constantval parse_float : ?loc:Cil_types.location -> string -> Cil_types.termParse the given string as a float or real logic constant.
The parsed literal is always kept as it is in the resulting term. The returned term is either a real constant or real constant casted into a C-float type.
Unsuffixed literals are considered as real numbers. Literals suffixed by f|d|l or F|D|L are considered as float constants of the associated kind.
Various Utilities
val remove_term_offset : Cil_types.term_offset -> Cil_types.term_offset * Cil_types.term_offsetremove_term_offset o returns o without its last offset and this last offset.
val lval_contains_result : Cil_types.term_lhost -> booltrue if \result is included in the lval.
val loffset_contains_result : Cil_types.term_offset -> booltrue if \result is included in the offset.
val contains_result : Cil_types.term -> booltrue if \result is included in the term
val get_pred_body : Cil_types.logic_info -> Cil_types.predicatereturns the body of the given predicate.
val is_result : Cil_types.term -> booltrue if the term is \result or an offset of \result.
val lhost_c_type : Cil_types.term_lhost -> Cil_types.typval is_trivially_true : Cil_types.predicate -> booltrue if the predicate is Ptrue.
val is_trivially_false : Cil_types.predicate -> booltrue if the predicate is Pfalse
Code annotations
val is_annot_next_stmt : Cil_types.code_annotation -> boolDoes the annotation apply to the next statement (e.g. a statement contract). Also false for loop-related annotations.
Global annotations
val add_attribute_glob_annot : Cil_types.attribute -> Cil_types.global_annotation -> Cil_types.global_annotationadd an attribute to a global annotation
Contracts
val behavior_has_only_assigns : Cil_types.behavior -> booltrue if the behavior has only an assigns clause.
val funspec_has_only_assigns : Cil_types.funspec -> booltrue if the only non-empty fields of the contract are assigns clauses
Structural equality between annotations
val is_same_logic_label : Cil_types.logic_label -> Cil_types.logic_label -> boolval is_same_pconstant : Logic_ptree.constant -> Logic_ptree.constant -> boolval is_same_type : Cil_types.logic_type -> Cil_types.logic_type -> boolval is_same_var : Cil_types.logic_var -> Cil_types.logic_var -> boolval is_same_logic_signature : Cil_types.logic_info -> Cil_types.logic_info -> boolval is_same_logic_profile : Cil_types.logic_info -> Cil_types.logic_info -> boolval is_same_builtin_profile : Cil_types.builtin_logic_info -> Cil_types.builtin_logic_info -> boolval is_same_logic_ctor_info : Cil_types.logic_ctor_info -> Cil_types.logic_ctor_info -> boolval is_same_term : Cil_types.term -> Cil_types.term -> boolval is_same_logic_info : Cil_types.logic_info -> Cil_types.logic_info -> boolval is_same_logic_body : Cil_types.logic_body -> Cil_types.logic_body -> boolval is_same_indcase : (string * Cil_types.logic_label list * string list * Cil_types.predicate) -> (string * Cil_types.logic_label list * string list * Cil_types.predicate) -> boolval is_same_tlval : Cil_types.term_lval -> Cil_types.term_lval -> boolval is_same_lhost : Cil_types.term_lhost -> Cil_types.term_lhost -> boolval is_same_offset : Cil_types.term_offset -> Cil_types.term_offset -> boolval is_same_predicate_node : Cil_types.predicate_node -> Cil_types.predicate_node -> boolval is_same_predicate : Cil_types.predicate -> Cil_types.predicate -> boolval is_same_identified_predicate : Cil_types.identified_predicate -> Cil_types.identified_predicate -> boolval is_same_identified_term : Cil_types.identified_term -> Cil_types.identified_term -> boolval is_same_deps : Cil_types.deps -> Cil_types.deps -> boolval is_same_allocation : Cil_types.allocation -> Cil_types.allocation -> boolval is_same_assigns : Cil_types.assigns -> Cil_types.assigns -> boolval is_same_variant : Cil_types.variant -> Cil_types.variant -> boolval is_same_post_cond : (Cil_types.termination_kind * Cil_types.identified_predicate) -> (Cil_types.termination_kind * Cil_types.identified_predicate) -> boolval is_same_behavior : Cil_types.funbehavior -> Cil_types.funbehavior -> boolval is_same_spec : Cil_types.funspec -> Cil_types.funspec -> boolval is_same_logic_type_def : Cil_types.logic_type_def -> Cil_types.logic_type_def -> boolval is_same_logic_type_info : Cil_types.logic_type_info -> Cil_types.logic_type_info -> boolval is_same_code_annotation : Cil_types.code_annotation -> Cil_types.code_annotation -> boolval is_same_global_annotation : Cil_types.global_annotation -> Cil_types.global_annotation -> boolval is_same_axiomatic : Cil_types.global_annotation list -> Cil_types.global_annotation list -> boolval is_same_model_info : Cil_types.model_info -> Cil_types.model_info -> boolval is_same_lexpr : Logic_ptree.lexpr -> Logic_ptree.lexpr -> boolval hash_term : Cil_types.term -> inthash function compatible with is_same_term
val compare_term : Cil_types.term -> Cil_types.term -> intcomparison compatible with is_same_term
val hash_predicate : Cil_types.predicate -> intval compare_predicate : Cil_types.predicate -> Cil_types.predicate -> intMerging contracts
val get_behavior_names : Cil_types.spec -> string listval concat_assigns : Cil_types.assigns -> Cil_types.assigns -> Cil_types.assignsConcatenates two assigns if both are defined, returns WritesAny if one (or both) of them is WritesAny.
val merge_assigns : Cil_types.assigns -> Cil_types.assigns -> Cil_types.assignsmerge assigns: take the one that is defined and select an arbitrary one if both are, emitting a warning unless both are syntactically the same.
val concat_allocation : Cil_types.allocation -> Cil_types.allocation -> Cil_types.allocationConcatenates two allocation clauses if both are defined, returns FreeAllocAny if one (or both) of them is FreeAllocAny.
val merge_allocation : Cil_types.allocation -> Cil_types.allocation -> Cil_types.allocationmerge allocation: take the one that is defined and select an arbitrary one if both are, emitting a warning unless both are syntactically the same.
val merge_behaviors : ?oldloc:Cil_types.location -> silent:bool -> Cil_types.funbehavior list -> Cil_types.funbehavior list -> Cil_types.funbehavior listval merge_funspec : ?oldloc:Cil_types.location -> ?silent_about_merging_behav:bool -> Cil_types.funspec -> Cil_types.funspec -> unitmerge_funspec ?oldloc oldspec newspec merges newspec into oldspec. If the funspec belongs to a kernel function, do not forget to call Kernel_function.set_spec after merging.
val clear_funspec : Cil_types.funspec -> unitReset the given funspec to empty.
Discriminating code_annotations
val use_predicate : Cil_types.predicate_kind -> boolChecks if a predicate kind can be used as an hypothesis or requirement. It is true for `Admit` and `Assert`, and false for `Check`.
val verify_predicate : Cil_types.predicate_kind -> boolChecks if a predicate kind shall be put under verification. It is true for `Assert` and `Check`, and false for `Admit`.
The functions below allow testing for specific kinds of code_annotation. Use them in conjunction with iterators in Annotations to retrieve a particular kind of annotation associated to a statement.
val is_assert : Cil_types.code_annotation -> boolval is_check : Cil_types.code_annotation -> boolval is_admit : Cil_types.code_annotation -> boolval is_contract : Cil_types.code_annotation -> boolval is_stmt_invariant : Cil_types.code_annotation -> boolval is_loop_invariant : Cil_types.code_annotation -> boolval is_invariant : Cil_types.code_annotation -> boolval is_variant : Cil_types.code_annotation -> boolval is_allocation : Cil_types.code_annotation -> boolval is_assigns : Cil_types.code_annotation -> boolval is_loop_annot : Cil_types.code_annotation -> boolval is_trivial_annotation : Cil_types.code_annotation -> boolval extract_contract : Cil_types.code_annotation list -> (string list * Cil_types.funspec) listConstant folding
val constFoldTermToInt : ?machdep:bool -> Cil_types.term -> Z.t optionclass simplify_const_lval : (Cil_types.varinfo -> Cil_types.init_or_str option) -> Frama_c_kernel.Cil.cilVisitorA cilVisitor (by copy) that simplifies expressions of the type const int x = v, where v is an integer and x is a global variable. Requires a mapping from varinfo to init_or_str option (e.g. based on Globals.Vars.find).
Type-checking hackery
val complete_types : Cil_types.file -> unitgive complete types to terms that refer to a variable whose type has been completed after its use in an annotation. Internal use only.
