123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210(****************************************************************************)(* *)(* 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 a value abstraction. *)openCore.All(*==========================================================================*)(** {2 Value manager} *)(*==========================================================================*)type('v,'t)value_man={bottom:'v;top:'v;is_bottom:'v->bool;subset:'v->'v->bool;join:'v->'v->'v;meet:'v->'v->'v;print:printer->'v->unit;get:'v->'t;set:'t->'v->'v;eval:expr->'v;avalue:'r.'ravalue_kind->'v->'r;ask:'a'r.('a,'r)query->'r;}(*==========================================================================*)(** {2 Valued expressions} *)(*==========================================================================*)type'vvexpr=|Mapof('v*'vvexpr)ExprMap.tletempty_vexpr=MapExprMap.emptyletsingleton_vexprevve=Map(ExprMap.singletone(v,ve))letroot_vexpr=function|Mapmap->Map(ExprMap.map(fun(v,ve)->(v,empty_vexpr))map)letadd_vexprevve=function|Mapmap->Map(ExprMap.adde(v,ve)map)letrefine_vexprev=function|Mapmap->letr=matchExprMap.find_optemapwith|Some(_,ve)->(v,ve)|None->(v,empty_vexpr)inMap(ExprMap.addermap)letrecfind_vexpre=function|Mapmap->tryExprMap.findemapwithNot_found->letreciter=function|[]->raiseNot_found|(_,(_,vee))::tl->tryfind_vexpreveewithNot_found->itertliniter(ExprMap.bindingsmap)letfind_vexpr_opteve=trySome(find_vexpreve)withNot_found->Noneletrecmap_vexprf=function|Mapmap->letmap'=ExprMap.map(fun(v,ve)->(fv,map_vexprfve))mapinMapmap'letfold_root_vexprfinit=function|Mapmap->ExprMap.fold(fune(v,ve)acc->faccevve)mapinitletrecfold_vexprfinit=function|Mapmap->ExprMap.fold(fune(v,ve)acc->fold_vexprf(faccevve)ve)mapinitletrecmap2_vexprf1f2fve1ve2=matchve1,ve2with|Mapm1,Mapm2->letm=ExprMap.map2o(fune(v1,ve1)->f1v1,map_vexprf1ve1)(fune(v2,ve2)->f2v2,map_vexprf2ve2)(fune(v1,ve1)(v2,ve2)->(fv1v2,map2_vexprf1f2fve1ve2))m1m2inMapmletrecmerge_vexprvmergeve1ve2=matchve1,ve2with|Mapm1,Mapm2->letm=ExprMap.map2zo(funeve1->ve1)(funeve2->ve2)(fune(v1,ve1)(v2,ve2)->(vmergev1v2,merge_vexprvmergeve1ve2))m1m2inMapm(*==========================================================================*)(** {2 Value domain} *)(*==========================================================================*)moduletypeVALUE=sigtypetvalid:tidvalaccept_type:typ->boolvalname:stringvaldisplay:stringvalbottom:tvaltop:tvalis_bottom:t->boolvalsubset:t->t->boolvaljoin:t->t->tvalmeet:t->t->tvalwiden:'actx->t->t->tvaleval:('v,t)value_man->expr->tvalavalue:'ravalue_kind->t->'roptionvalbackward:('v,t)value_man->expr->tvexpr->'v->tvexprvalfilter:bool->typ->t->tvalcompare:('v,t)value_man->operator->bool->expr->t->expr->t->(t*t)valeval_ext:('v,t)value_man->expr->'voptionvalbackward_ext:('v,t)value_man->expr->'vvexpr->'v->'vvexproptionvalcompare_ext:('v,t)value_man->operator->bool->expr->'v->expr->'v->('v*'v)optionvalask:('v,t)value_man->('a,'r)query->'roptionvalprint:printer->t->unitendletdefault_filterbtv=vletdefault_backwardmanevev=veletdefault_comparemanopbe1v1e2v2=(v1,v2)moduleDefaultValueFunctions=structletfilter=default_filterletbackward=default_backwardletcompare=default_compareleteval_extmane=Noneletbackward_extmanevev=Noneletcompare_extmanopbe1v1e2v2=Noneletavalueavkv=Noneletaskmanq=Noneend(*==========================================================================*)(** {2 Registration} *)(*==========================================================================*)letvalues:(moduleVALUE)listref=ref[]letregister_value_abstractiondom=values:=dom::!valuesletfind_value_abstractionname=List.find(fundom->letmoduleD=(valdom:VALUE)incompareD.namename=0)!valuesletmem_value_abstractionname=List.exists(fundom->letmoduleD=(valdom:VALUE)incompareD.namename=0)!valuesletvalue_abstraction_names()=List.map(fundom->letmoduleD=(valdom:VALUE)inD.name)!values