package goblint
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=20d5b7332a9f6072ab9ba86c4a53b898eaf681286c56a8805c41850bbf3ddf41
sha512=7c7685cfcd9aa866bc40e813df2bfcb3c79b3d40e615d8d6d0939c5798b9d70dd7f2ba87a741f5ba0ce891e9d254627207fb28057f1f2f6611e4e0d128fd6a71
doc/goblint.lib/Goblint_lib/CongruenceClosure/index.html
Module Goblint_lib.CongruenceClosure
2-Pointer Logic
Domains for C2poAnalysis.
OCaml implementation of a quantitative congruence closure. It is used by the C-2PO Analysis and based on the UnionFind implementation.
include module type of struct include UnionFind end
The Union Find is used by the C-2PO Analysis. This file contains the code for a quantitative union find and the quantitative finite automata. They will be necessary in order to construct the congruence closure of terms.
module Tuple3 = Batteries.Tuple3module Tuple2 = Batteries.Tuple2type term = UnionFind.term = | Addr of DuplicateVars.Var.t| Aux of DuplicateVars.Var.t * GoblintCil.exp| Deref of term * Z.t * GoblintCil.exp
val equal_term : term -> term -> Ppx_deriving_runtime.boolval hash_term : term -> intval compare_term : term -> term -> Ppx_deriving_runtime.intTwo propositions are equal if they are syntactically equal or if one is t_1 = z + t_2 and the other t_2 = - z + t_1.
val equal_term_offset_relation :
term_offset_relation ->
term_offset_relation ->
Ppx_deriving_runtime.boolval hash_term_offset_relation : term_offset_relation -> intval compare_term_offset_relation :
term_offset_relation ->
term_offset_relation ->
Ppx_deriving_runtime.intval equal_block_relation :
block_relation ->
block_relation ->
Ppx_deriving_runtime.boolval hash_block_relation : block_relation -> intval compare_block_relation :
block_relation ->
block_relation ->
Ppx_deriving_runtime.inttype prop = UnionFind.prop = | Equal of term_offset_relation| Nequal of term_offset_relation| BlNequal of block_relation
val equal_prop : prop -> prop -> Ppx_deriving_runtime.boolval hash_prop : prop -> intval compare_prop : prop -> prop -> Ppx_deriving_runtime.intmodule T = UnionFind.TThe terms consist of address constants and dereferencing function with sum of an integer. The dereferencing function is parametrized by the size of the element in the memory. We store the CIL expression of the term in the data type, such that it it easier to find the types of the dereferenced elements. Also so that we can easily convert back from term to Cil expression.
module TMap = UnionFind.TMapmodule TSet = UnionFind.TSetmodule UnionFind = UnionFind.UnionFindQuantitative union find
module ZMap = UnionFind.ZMapmodule LookupMap = UnionFind.LookupMapFor each representative t' of an equivalence class, the LookupMap maps t' to a map that maps z to a term in the data structure that is equal to *(z + t').
module M = Messagesmodule TUF = UnionFindmodule LMap = LookupMapmodule BlDis : sig ... endmodule Disequalities : sig ... endmodule SSet : sig ... endSet of subterms which are present in the current data structure.
module MRMap : sig ... endMinimal representatives map. It maps each representative term of an equivalence class to the minimal term of this representative class. rep -> (t, z) means that t = rep + z
val get_transitions :
(((Goblint_lib__UnionFind.term * Z.t) * 'a) TUF.ValMap.t
* TUF.ValMap.key Stdlib__Map.Make(Z).t
Stdlib__Map.Make(Goblint_lib__UnionFind.T).t) ->
(Z.t * term * (Goblint_lib__UnionFind.term * Z.t)) listReturns a list of all the transition that are present in the automata.
val equal_data : data -> data -> Ppx_deriving_runtime.boolval compare_data : data -> data -> Ppx_deriving_runtime.intval hash_data : data -> intConverts the domain representation to a conjunction, using the function `get_normal_repr` to compute the representatives that need to be used in the conjunction.
module NormalFormEval : sig ... endmodule LazyNormalFormEval : sig ... endThis is the type for the abstract domain.
- `uf` is the union find tree
- `set` is the set of terms that are currently considered. It is the set of terms that have a mapping in the `uf` tree.
- `map` maps reference variables v to a map that maps integers z to terms that are equivalent to *(v + z). It represents the transitions of the quantitative finite automata.
- `normal_form` is the unique normal form of the domain element, it is a lazily computed when needed and stored such that it can be used again later.
- `diseq` represents the disequalities. It is a map from a term t1 to a map from an integer z to a set of terms T, which represents the disequality t1 != z + t2 for each t2 in T.
- `bldis` represents the block disequalities. It is a map that maps each term to a set of terms that are definitely in a different block.
val equal : t -> t -> Ppx_deriving_runtime.boolval compare : t -> t -> Ppx_deriving_runtime.intval hash : t -> intval get_normal_form : t -> NormalFormEval.resultReturns the canonical normal form of the data structure in form of a sorted list of conjunctions.
val show_normal_form : LazyNormalFormEval.t -> stringConverts the normal form to string, but only if it was already computed.
Returns a list of conjunctions that follow from the data structure in form of a sorted list of conjunctions. This is not a normal form, but it is useful to print information about the current state of the analysis.
Sets the normal_form to an uncomputed value, that will be lazily computed when it is needed.
val show_all : t -> stringval split :
prop list ->
term_offset_relation list * term_offset_relation list * block_relation listSplits the conjunction into three groups: the first one contains all equality propositions, the second one contains all inequality propositions and the third one contains all block disequality propositions.
val init_cc : unit -> dataReturns {uf, set, map, normal_form, bldis, diseq}, where all data structures are initialized with an empty map/set.
val congruence_neq : data -> term_offset_relation list -> dataComputes the closure of disequalities.
Update block disequalities with the new representatives.
val closure : data -> (TUF.ValMap.key * TUF.ValMap.key * Z.t) list -> dataParameters: cc conjunctions.
returns updated cc, where:
- `uf` is the new union find data structure after having added all equalities.
- `set` doesn't change
- `map` maps reference variables v to a map that maps integers z to terms that are equivalent to *(v + z).
- `diseq` doesn't change (it must be updated later to the new representatives).
- `bldis` are the block disequalities between the new representatives.
Throws "Unsat" if a contradiction is found. This does NOT update the disequalities. They need to be updated with `congruence_neq`.
val add_normalized_bl_diseqs :
data ->
(TUF.ValMap.key * TUF.ValMap.key) list ->
dataAdds the block disequalities to the cc, but first rewrites them such that they are disequalities between representatives. The cc should already contain all the terms that are present in those block disequalities.
Add a term to the data structure.
Returns (reference variable, offset), updated congruence closure
Add all terms in a specific set to the data structure.
Returns updated cc.
Returns true if t1 and t2 are equivalent.
Returns true if t1 and t2 are not equivalent.
val meet_pos_conjs :
data ->
(TUF.ValMap.key * TUF.ValMap.key * Z.t) list ->
dataAdds equalities to the data structure. Throws "Unsat" if a contradiction is found. Does not update disequalities.
Adds propositions to the data structure. Returns None if a contradiction is found.
Add proposition t1 = t2 + r to the data structure. Does not update the disequalities.
Adds block disequalities to cc: for each representative t in cc it adds the disequality bl(lterm) != bl(t)
val remove_terms_from_eq :
(Goblint_lib__UnionFind.term -> bool) ->
data ->
(term * Z.t) Stdlib__Map.Make(Goblint_lib__UnionFind.T).t * dataRemoves terms from the union find and the lookup map.
val find_new_root :
(TUF.ValMap.key * Z.t) TMap.t ->
((Goblint_lib__UnionFind.term * Z.t) * int) TUF.ValMap.t ->
TMap.key ->
((Goblint_lib__UnionFind.term * Z.t) * int) TUF.ValMap.t
* (Goblint_lib__UnionFind.term * Z.t) optionFind the representative term of the equivalence classes of an element that has already been deleted from the data structure. Returns None if there are no elements in the same equivalence class as t before it was deleted.
val join_eq :
data ->
data ->
data
* (Goblint_lib__UnionFind.term * Goblint_lib__UnionFind.term * Z.t,
TSet.elt * Z.t)
BatMap.tJoin version 1: by using the automaton. The product automaton of cc1 and cc2 is computed and then we add the terms to the right equivalence class. We also add new terms in order to have some terms for each state in the automaton.
val product_no_automata_over_terms :
data ->
data ->
TSet.t ->
data
* (Goblint_lib__UnionFind.term * Goblint_lib__UnionFind.term * Z.t,
TSet.elt * Z.t)
BatMap.tJoin version 2: just look at equivalence classes and not the automaton.
val join_eq_no_automata :
data ->
data ->
data
* (Goblint_lib__UnionFind.term * Goblint_lib__UnionFind.term * Z.t,
TSet.elt * Z.t)
BatMap.tHere we do the join without using the automata. We construct a new cc that contains the elements of cc1.set U cc2.set. and two elements are in the same equivalence class iff they are in the same eq. class both in cc1 and in cc2.
val widen_eq_no_automata :
data ->
data ->
data
* (Goblint_lib__UnionFind.term * Goblint_lib__UnionFind.term * Z.t,
TSet.elt * Z.t)
BatMap.tSame as join, but we only take the terms from the left argument.
val join_neq :
TSet.t ZMap.t TMap.t ->
TSet.t ZMap.t TMap.t ->
data ->
data ->
data ->
Stdlib__Set.Make(Goblint_lib__UnionFind.T).t Stdlib__Map.Make(Z).t
Stdlib__Map.Make(Goblint_lib__UnionFind.T).t ->
Stdlib__Set.Make(Goblint_lib__UnionFind.T).t Stdlib__Map.Make(Z).t
Stdlib__Map.Make(Goblint_lib__UnionFind.T).t ->
dataJoins the disequalities diseq1 and diseq2, given a congruence closure data structure.
This is done by checking for each disequality if it is implied by both cc.
val join_bldis :
TSet.t TMap.t ->
TSet.t TMap.t ->
data ->
data ->
data ->
Stdlib__Set.Make(Goblint_lib__UnionFind.T).t Stdlib__Map.Make(Z).t
Stdlib__Map.Make(Goblint_lib__UnionFind.T).t ->
Stdlib__Set.Make(Goblint_lib__UnionFind.T).t Stdlib__Map.Make(Z).t
Stdlib__Map.Make(Goblint_lib__UnionFind.T).t ->
dataJoins the block disequalities bldiseq1 and bldiseq2, given a congruence closure data structure.
This is done by checking for each block disequality if it is implied by both cc.
Check for equality of two congruence closures, by comparing the equivalence classes instead of computing the minimal_representative.
module MayBeEqual : sig ... endFind out if two addresses are not equal by using the MayPointTo query