Goblint_lib.CongruenceClosureDomains 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 endThe 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 = UnionFind.Tuple3module Tuple2 = UnionFind.Tuple2type term = UnionFind.term = | Addr of DuplicateVars.Var.t| Aux of DuplicateVars.Var.t * GoblintCil.exp| Deref of term * Z.t * GoblintCil.expval hash_term : term -> 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_relationval hash_prop : prop -> 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 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.
val 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:
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