123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154(**************************************************************************)(* *)(* This file is part of WP plug-in of Frama-C. *)(* *)(* Copyright (C) 2007-2023 *)(* CEA (Commissariat a l'energie atomique et aux energies *)(* alternatives) *)(* *)(* 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, version 2.1. *)(* *)(* It 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. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file licenses/LGPLv2.1). *)(* *)(**************************************************************************)moduletypeS=sigtypekeytype'atvalis_empty:'at->boolvalempty:'atvaladd:key->'a->'at->'atvalmem:key->'at->boolvalfind:key->'at->'avalremove:key->'at->'atvalcompare:('a->'a->int)->'at->'at->intvalequal:('a->'a->bool)->'at->'at->boolvaliter:(key->'a->unit)->'at->unitvalmap:(key->'a->'b)->'at->'btvalmapf:(key->'a->'boption)->'at->'btvalmapq:(key->'a->'aoption)->'at->'atvalfilter:(key->'a->bool)->'at->'atvalpartition:(key->'a->bool)->'at->'at*'atvalfold:(key->'a->'b->'b)->'at->'b->'bvalunion:(key->'a->'a->'a)->'at->'at->'atvalinter:(key->'a->'b->'c)->'at->'bt->'ctvalinterf:(key->'a->'b->'coption)->'at->'bt->'ctvalinterq:(key->'a->'a->'aoption)->'at->'at->'atvaldiffq:(key->'a->'a->'aoption)->'at->'at->'atvalmerge:(key->'aoption->'boption->'coption)->'at->'bt->'ctvaliter2:(key->'aoption->'boption->unit)->'at->'bt->unitvalsubset:(key->'a->'b->bool)->'at->'bt->bool(** [insert (fun key v old -> ...) key v map] *)valinsert:(key->'a->'a->'a)->key->'a->'at->'atvalchange:(key->'b->'aoption->'aoption)->key->'b->'at->'atendmoduletypeIndexedKey=sigtypetvalid:t->int(** unique per t *)endmoduleMake(K:IndexedKey)=structtypekey=K.ttype'at=(key*'a)Intmap.tletis_empty=Intmap.is_emptyletempty=Intmap.empty(* good sharing *)letaddkxm=Intmap.add(K.idk)(k,x)mlet_packk=functionNone->None|Somev->Some(k,v)let_packold((k,old)aso)w=ifw==oldthenoelsek,wlet_oldpacko=functionNone->None|Somew->Some(_packoldow)(* good sharing *)letinsertfkvm=Intmap.insert(fun_k(k,v)((_,old)aso)->_packoldo(fkvold))(K.idk)(k,v)m(* good sharing *)letchangefkvm=Intmap.change(fun_k(k,v)->function|None->_packk(fkvNone)|Some((_,old)aso)->_oldpacko(fkv(Someold)))(K.idk)(k,v)mletmemkm=Intmap.mem(K.idk)mletfindkm=snd(Intmap.find(K.idk)m)letcomparefm1m2=Intmap.compare(fun(_,a)(_,b)->fab)m1m2letequalfm1m2=Intmap.equal(fun(_,a)(_,b)->fab)m1m2letiterfm=Intmap.iter(fun(k,v)->fkv)mletfoldfmw=Intmap.fold(fun(k,v)w->fkvw)mwletmapfm=Intmap.map(fun(k,v)->k,fkv)mletmapffm=Intmap.mapf(fun_(k,v)->_packk(fkv))m(* good sharing *)letmapqf=Intmap.mapq(fun_((k,old)aso)->_oldpacko(fkold))(* good sharing *)letpartitionf=Intmap.partition(fun_(k,v)->fkv)(* good sharing *)letremovek=Intmap.remove(K.idk)(* good sharing *)letfilterf=Intmap.filter(fun_(k,v)->fkv)(* good sharing *)letunionf=Intmap.union(fun_((k,v)asx)((_,v')asy)->letw=fkvv'inifw==vthenxelseifw==vthenyelsek,w)letinterf=Intmap.inter(fun_(k,v)(_,v')->k,fkvv')letinterff=Intmap.interf(fun_(k,v)(_,v')->_packk(fkvv'))(* good sharing *)letinterqf=Intmap.interq(fun_((k,v)asx)((_,v')asy)->matchfkvv'withNone->None|Somew->Some(ifw==vthenxelseifw==vthenyelsek,w))(* good sharing *)letdiffqf=Intmap.diffq(fun_((k,v)asx)((_,v')asy)->matchfkvv'withNone->None|Somew->Some(ifw==vthenxelseifw==vthenyelsek,w))letmergefab=Intmap.merge(fun_uv->matchu,vwith|None,None->None|Some(k,v),None->_packk(fk(Somev)None)|None,Some(k,v)->_packk(fkNone(Somev))|Some(k,v),Some(_,v')->_packk(fk(Somev)(Somev')))abletiter2fab=Intmap.iter2(fun_uv->matchu,vwith|None,None->()|Some(k,v),None->fk(Somev)None|None,Some(k,v)->fkNone(Somev)|Some(k,v),Some(_,v')->fk(Somev)(Somev'))abexceptionSUPERSETletsubsetfab=tryIntmap.iter2(fun_uv->matchu,vwith|None,_->()|Some_,None->raiseSUPERSET|Some(k,v),Some(_,v')->ifnot(fkvv')thenraiseSUPERSET)ab;truewithSUPERSET->falseend