12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697(****************************************************************************)(* *)(* This file is part of MOPSA, a Modular Open Platform for Static Analysis. *)(* *)(* Copyright (C) 2017-2019 The MOPSA Project. *)(* *)(* This program is free software: you can redistribute it and/or modify *)(* it under the terms of the GNU Lesser General Public License as published *)(* by the Free Software Foundation, either version 3 of the License, or *)(* (at your option) any later version. *)(* *)(* This program is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* You should have received a copy of the GNU Lesser General Public License *)(* along with this program. If not, see <http://www.gnu.org/licenses/>. *)(* *)(****************************************************************************)(** Signature of partitioning domains.
*
* A partitioning domain lifts a domin D into a map K -> D, where K is the set
* of partitioning keys. K should verify the following conditions:
* - finite,
* - defines a total order and
* - there is no intersection between every pair of distinct keys.
*
* For the moment, we don't support modifying the partitioning keys during
* lattice operation (join, meet and widening)
*
* BEWARE: partitioning during evaluations and reduced product is *NOT SUPPORTED AND UNSOUND*:
* https://gitlab.com/mopsa/mopsa-analyzer/-/merge_requests/130#note_1833582309
*)openCore.AllopenMopsa_utils.LocationmoduletypePARTITIONING=sigtypetvalname:stringvalchecks:checklistvalprint:Format.formatter->t->unitvalcompare:t->t->intvalinit:tvaladd:marker->t->tvalexec:stmt->('a,t)man->'aflow->'apostoptionvaleval:expr->('a,t)man->'aflow->'aevaloptionvalask:('a,'r)query->('a,t)man->'aflow->('a,'r)casesoptionendletdomains:(modulePARTITIONING)listref=ref[]letregister_partitioningdom=domains:=dom::!domainsletfind_partitioningname=List.find(fundom->letmoduleD=(valdom:PARTITIONING)incompareD.namename=0)!domainsletmem_partitioningname=List.exists(fundom->letmoduleD=(valdom:PARTITIONING)incompareD.namename=0)!domainsletpartitioning_names()=List.map(fundom->letmoduleD=(valdom:PARTITIONING)inD.name)!domainstype('a,_)query+=Q_partition_predicate:range->('a,expr)querylet()=register_query{join=(letdoit:typear.query_pool->(a,r)query->r->r->r=funpoolqueryxy->matchquerywith|Q_partition_predicaterange->mk_binopxO_log_ory~etyp:T_boolrange|_->pool.pool_joinqueryxyindoit);meet=(letdoit:typear.query_pool->(a,r)query->r->r->r=funpoolqueryxy->matchquerywith|Q_partition_predicaterange->mk_binopxO_log_andy~etyp:T_boolrange|_->pool.pool_meetqueryxyindoit);}