123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798(** Map domains. *)modulePretty=GoblintCil.PrettyopenPrettymoduletypePS=sigincludePrintable.Stypekey(** The type of the map keys. *)typevalue(** The type of the values. *)valadd:key->value->t->tvalremove:key->t->tvalfind:key->t->valuevalfind_opt:key->t->valueoptionvalmem:key->t->boolvaliter:(key->value->unit)->t->unitvalmap:(value->value)->t->tvalfilter:(key->value->bool)->t->tvalmapi:(key->value->value)->t->tvalfold:(key->value->'a->'a)->t->'a->'avaladd_list:(key*value)list->t->tvaladd_list_set:keylist->value->t->tvaladd_list_fun:keylist->(key->value)->t->tvalfor_all:(key->value->bool)->t->boolvalmap2:(value->value->value)->t->t->tvallong_map2:(value->value->value)->t->t->tvalmerge:(key->valueoption->valueoption->valueoption)->t->t->t(* TODO: unused, remove? *)valcardinal:t->intvalchoose:t->key*valuevalsingleton:key->value->tvalempty:unit->tvalis_empty:t->boolvalexists:(key->value->bool)->t->boolvalbindings:t->(key*value)listendmoduletypeS=sigincludePSincludeLattice.Swithtypet:=tvalwiden_with_fct:(value->value->value)->t->t->t(* Widen using a custom widening function for value rather than the default one for value *)valjoin_with_fct:(value->value->value)->t->t->t(* Join using a custom join function for value rather than the default one for value *)valleq_with_fct:(value->value->bool)->t->t->bool(* Leq test using a custom leq function for value rather than the default one provided for value *)end(** Subsignature of {!S}, which is sufficient for {!Print}. *)moduletypeBindings=sigtypettypekeytypevaluevalfold:(key->value->'a->'a)->t->'a->'avaliter:(key->value->unit)->t->unitend(** Reusable output definitions for maps. *)modulePrint(D:Printable.S)(R:Printable.S)(M:Bindingswithtypekey=D.tandtypevalue=R.t)=structletpretty()map=letdoc=M.fold(funkvacc->acc++dprintf"%a ->@?@[%a@]\n"D.prettykR.prettyv)mapnilinifdoc=Pretty.nilthentext"{}"elsedprintf"@[{\n @[%a@]}@]"Pretty.insertdocletshowmap=GobPretty.sprintprettymapletprintXmlfmap=BatPrintf.fprintff"<value>\n<map>\n";M.iter(funkv->BatPrintf.fprintff"<key>\n%s</key>\n%a"(XmlUtil.escape(D.showk))R.printXmlv)map;BatPrintf.fprintff"</map>\n</value>\n"letto_yojsonmap=letl=M.fold(funkvacc->(D.showk,R.to_yojsonv)::acc)map[]in`AssoclendmoduletypeGroupable=sigincludePrintable.Stypegroup(* use [@@deriving show { with_path = false }] *)valcompare_group:group->group->intvalshow_group:group->stringvalto_group:t->groupend(** Reusable output definitions for maps with key grouping. *)modulePrintGroupable(D:Groupable)(R:Printable.S)(M:Bindingswithtypekey=D.tandtypevalue=R.t)=structincludePrint(D)(R)(M)moduleGroup=structtypet=D.group[@@derivingord]endmoduleGroupMap=Map.Make(Group)letpretty()mapping=letgroups=M.fold(funkvacc->GroupMap.update(D.to_groupk)(fundoc->letdoc=Option.valuedoc~default:Pretty.nilinletdoc'=doc++dprintf"%a ->@? @[%a@]\n"D.prettykR.prettyvinSomedoc')acc)mappingGroupMap.emptyinletpretty_groups()=GroupMap.fold(fungroupdocacc->acc++dprintf"@[%s {\n @[%a@]}@]\n"(D.show_groupgroup)Pretty.insertdoc)groupsnilindprintf"@[{\n @[%t@]}@]"pretty_groupsletshowmap=GobPretty.sprintprettymap(* TODO: groups in XML, JSON? *)endmodulePMap(Domain:Printable.S)(Range:Lattice.S):PSwithtypekey=Domain.tandtypevalue=Range.t=structmoduleM=Map.Make(Domain)includePrintable.StdincludeMtypekey=Domain.ttypevalue=Range.ttypet=Range.tM.t(* key -> value mapping *)letname()="map"(* And one less brainy definition *)letfor_all2=M.equalletequalxy=x==y||for_all2Range.equalxyletcomparexy=ifequalxythen0elseM.compareRange.comparexylethashxs=fold(funkva->a+(Domain.hashk*Range.hashv))xs0letempty()=M.emptyletadd_listkeyvaluesm=List.fold_left(funacc(key,value)->addkeyvalueacc)mkeyvaluesletadd_list_setkeysvaluem=List.fold_left(funacckey->addkeyvalueacc)mkeysletadd_list_funkeysfm=List.fold_left(funacckey->addkey(fkey)acc)mkeysletlong_map2op=letfkv1v2=matchv1,v2with|Somev1,Somev2->Some(opv1v2)|Some_,_->v1|_,Some_->v2|_->NoneinM.mergefletmap2op=(* Similar to the previous, except we ignore elements that only occur in one
* of the mappings, so we start from an empty map *)letfkv1v2=matchv1,v2with|Somev1,Somev2->Some(opv1v2)|_->NoneinM.mergefincludePrint(Domain)(Range)(structtypenonrect=ttypenonreckey=keytypenonrecvalue=valueletfold=foldletiter=iterend)(* uncomment to easily check pretty's grouping during a normal run, e.g. ./regtest 01 01: *)(* let add k v m = let _ = Logs.debug "%a" pretty m in M.add k v m *)letarbitrary()=QCheck.alwaysM.empty(* S TODO: non-empty map *)letreliftm=M.fold(funkvacc->M.add(Domain.reliftk)(Range.reliftv)acc)mM.emptyend(* TODO: why is HashCached.hash significantly slower as a functor compared to being inlined into PMap? *)moduleHashCached(M:S):Swithtypekey=M.keyandtypevalue=M.value=structincludeLattice.HashCached(M)typekey=M.keytypevalue=M.valueletaddkv=lift_f'(M.addkv)letremovek=lift_f'(M.removek)letfindk=lift_f(M.findk)letfind_optk=lift_f(M.find_optk)letmemk=lift_f(M.memk)letiterf=lift_f(M.iterf)letmapf=lift_f'(M.mapf)letmapif=lift_f'(M.mapif)letfoldfxa=M.foldf(unliftx)aletfilterf=lift_f'(M.filterf)letmergef=lift_f2'(M.mergef)letfor_allf=lift_f(M.for_allf)letcardinal=lift_fM.cardinalletchoose=lift_fM.chooseletsingletonkv=lift@@M.singletonkvletempty()=lift@@M.empty()letis_empty=lift_fM.is_emptyletexistsp=lift_f(M.existsp)letbindings=lift_fM.bindingsletadd_listkeyvalues=lift_f'(M.add_listkeyvalues)letadd_list_setkeysvalue=lift_f'(M.add_list_setkeysvalue)letadd_list_funkeysf=lift_f'(M.add_list_funkeysf)letlong_map2op=lift_f2'(M.long_map2op)letmap2op=lift_f2'(M.map2op)letleq_with_fctf=lift_f2(M.leq_with_fctf)letjoin_with_fctf=lift_f2'(M.join_with_fctf)letwiden_with_fctf=lift_f2'(M.widen_with_fctf)letrelift=lift_f'M.reliftend(* TODO: this is very slow because every add/remove in a fold-loop relifts *)(* TODO: currently hardcoded to assume_idempotent *)moduleHConsed(M:S):Swithtypekey=M.keyandtypevalue=M.value=structincludeLattice.HConsed(structletassume_idempotent=falseend)(M)typekey=M.keytypevalue=M.valueletlift_f'fx=lift@@lift_ffxletlift_f2'fxy=lift@@lift_f2fxyletaddkv=lift_f'(M.addkv)letremovek=lift_f'(M.removek)letfindk=lift_f(M.findk)letfind_optk=lift_f(M.find_optk)letmemk=lift_f(M.memk)letiterf=lift_f(M.iterf)letmapf=lift_f'(M.mapf)letmapif=lift_f'(M.mapif)letfoldfxa=M.foldf(unliftx)aletfilterf=lift_f'(M.filterf)letmergef=lift_f2'(M.mergef)letfor_allf=lift_f(M.for_allf)letcardinal=lift_fM.cardinalletchoose=lift_fM.chooseletsingletonkv=lift@@M.singletonkvletempty()=lift@@M.empty()letis_empty=lift_fM.is_emptyletexistsp=lift_f(M.existsp)letbindings=lift_fM.bindingsletadd_listkeyvalues=lift_f'(M.add_listkeyvalues)letadd_list_setkeysvalue=lift_f'(M.add_list_setkeysvalue)letadd_list_funkeysf=lift_f'(M.add_list_funkeysf)letlong_map2op=lift_f2'(M.long_map2op)letmap2op=lift_f2'(M.map2op)letleq_with_fctf=lift_f2(M.leq_with_fctf)letjoin_with_fctf=lift_f2'(M.join_with_fctf)letwiden_with_fctf=lift_f2'(M.widen_with_fctf)endmoduleTimed(M:S):Swithtypekey=M.keyandtypevalue=M.value=structlettimestrfarg=Timing.wrap(M.name())(Timing.wrapstrf)arg(* Printable.S *)typet=M.tletequalxy=time"equal"(M.equalx)yletcomparexy=time"compare"(M.comparex)ylethashx=time"hash"M.hashxlettagx=time"tag"M.tagx(* TODO: time these also? *)letname=M.nameletto_yojson=M.to_yojsonletshow=M.showletpretty=M.prettyletpretty_diff=M.pretty_diffletprintXml=M.printXmlletarbitrary=M.arbitrary(* Lattice.S *)lettop()=time"top"M.top()letis_topx=time"is_top"M.is_topxletbot()=time"bot"M.bot()letis_botx=time"is_bot"M.is_botxletleqxy=time"leq"(M.leqx)yletjoinxy=time"join"(M.joinx)yletmeetxy=time"meet"(M.meetx)yletwidenxy=time"widen"(M.widenx)yletnarrowxy=time"narrow"(M.narrowx)y(* MapDomain.S *)typekey=M.keytypevalue=M.valueletaddkvx=time"add"(M.addkv)xletremovekx=time"remove"(M.removek)xletfindkx=time"find"(M.findk)xletfind_optkx=time"find_opt"(M.find_optk)xletmemkx=time"mem"(M.memk)xletiterfx=time"iter"(M.iterf)xletmapfx=time"map"(M.mapf)xletmapifx=time"mapi"(M.mapif)xletfoldfxa=time"fold"(M.foldfx)aletfilterfx=time"filter"(M.filterf)xletmergefxy=time"merge"(M.mergefx)yletfor_allfx=time"for_all"(M.for_allf)xletcardinalx=time"cardinal"M.cardinalxletchoosex=time"choose"M.choosexletsingletonkv=time"singleton"(M.singletonk)vletempty()=time"empty"M.empty()letis_emptyx=time"is_empty"M.is_emptyxletexistspx=time"exists"(M.existsp)xletbindingsx=time"bindings"M.bindingsxletadd_listxsx=time"add_list"(M.add_listxs)xletadd_list_setksvx=time"add_list_set"(M.add_list_setksv)xletadd_list_funksfx=time"add_list_fun"(M.add_list_funksf)xletlong_map2fxy=time"long_map2"(M.long_map2fx)yletmap2fxy=time"map2"(M.map2fx)yletleq_with_fctfxy=time"leq_with_fct"(M.leq_with_fctfx)yletjoin_with_fctfxy=time"join_with_fct"(M.join_with_fctfx)yletwiden_with_fctfxy=time"widen_with_fct"(M.widen_with_fctfx)yletreliftx=M.reliftxendmoduleMapBot(Domain:Printable.S)(Range:Lattice.S):Swithtypekey=Domain.tandtypevalue=Range.t=structincludePMap(Domain)(Range)letleq_with_fctfm1m2=(* For each key-value in m1, the same key must be in m2 with a geq value: *)letpkeyvalue=tryfvalue(findkeym2)withNot_found->falseinm1==m2||for_allpm1letleq=leq_with_fctRange.leqletfindxm=tryfindxmwith|Not_found->Range.bot()lettop()=raiseLattice.TopValueletbot()=empty()letis_top_=falseletis_bot=is_emptyletpretty_diff()((m1:t),(m2:t)):Pretty.doc=letdiff_keykvacc_opt=matchfindkm2with|v2whennot(Range.leqvv2)->letacc=BatOption.map_default(funacc->acc++line)Pretty.nilacc_optinSome(acc++dprintf"Map: %a =@?@[%a@]"Domain.prettykRange.pretty_diff(v,v2))|exceptionLattice.BotValue->letacc=BatOption.map_default(funacc->acc++line)Pretty.nilacc_optinSome(acc++dprintf"Map: %a =@?@[%a not leq bot@]"Domain.prettykRange.prettyv)|v2->acc_optinmatchfolddiff_keym1Nonewith|Somew->w|None->Pretty.dprintf"No binding grew."letmeetm1m2=ifm1==m2thenm1elsemap2Range.meetm1m2letjoin_with_fctfm1m2=ifm1==m2thenm1elselong_map2fm1m2letjoin=join_with_fctRange.joinletwiden_with_fctf=long_map2fletwiden=widen_with_fctRange.widenletnarrow=map2Range.narrowendmoduleMapTop(Domain:Printable.S)(Range:Lattice.S):Swithtypekey=Domain.tandtypevalue=Range.t=structincludePMap(Domain)(Range)letleq_with_fctfm1m2=(* TODO use merge or sth faster? *)(* For each key-value in m2, the same key must be in m1 with a leq value: *)letpkeyvalue=tryf(findkeym1)valuewithNot_found->falseinm1==m2||for_allpm2letleq=leq_with_fctRange.leqletfindxm=tryfindxmwith|Not_found->Range.top()lettop()=empty()letbot()=raiseLattice.BotValueletis_top=is_emptyletis_bot_=false(* let cleanup m = fold (fun k v m -> if Range.is_top v then remove k m else m) m m *)letmeetm1m2=ifm1==m2thenm1elselong_map2Range.meetm1m2letjoin_with_fctfm1m2=ifm1==m2thenm1elsemap2fm1m2letjoin=join_with_fctRange.joinletwiden_with_fctf=map2fletwiden=widen_with_fctRange.widenletnarrow=long_map2Range.narrowletpretty_diff()((m1:t),(m2:t)):Pretty.doc=letdiff_keykvacc_opt=matchfindkm1with|v1whennot(Range.leqv1v)->letacc=BatOption.map_default(funacc->acc++line)Pretty.nilacc_optinSome(acc++dprintf"Map: %a =@?@[%a@]"Domain.prettykRange.pretty_diff(v1,v))|exceptionLattice.TopValue->letacc=BatOption.map_default(funacc->acc++line)Pretty.nilacc_optinSome(acc++dprintf"Map: %a =@?@[top not leq %a@]"Domain.prettykRange.prettyv)|v1->acc_optinmatchfolddiff_keym2Nonewith|Somew->w|None->Pretty.dprintf"No binding grew."endexceptionFn_over_AllofstringmoduleLiftTop(Range:Lattice.S)(M:Swithtypevalue=Range.t):Swithtypekey=M.keyandtypevalue=Range.t=structincludeLattice.LiftTop(M)typekey=M.keytypevalue=M.valueletaddkv=function|`Top->`Top|`Liftedx->`Lifted(M.addkvx)letremovek=function|`Top->`Top|`Liftedx->`Lifted(M.removekx)letfindk=function|`Top->Range.top()|`Liftedx->M.findkxletfind_optk=function|`Top->Some(Range.top())|`Liftedx->M.find_optkxletmemk=function|`Top->true|`Liftedx->M.memkxletmapf=function|`Top->`Top|`Liftedx->`Lifted(M.mapfx)letadd_listxs=function|`Top->`Top|`Liftedx->`Lifted(M.add_listxsx)letadd_list_setksv=function|`Top->`Top|`Liftedx->`Lifted(M.add_list_setksvx)letadd_list_funksf=function|`Top->`Top|`Liftedx->`Lifted(M.add_list_funksfx)letmap2fxy=matchx,ywith|`Liftedx,`Liftedy->`Lifted(M.map2fxy)|_->raise(Fn_over_All"map2")letlong_map2fxy=matchx,ywith|`Liftedx,`Liftedy->`Lifted(M.long_map2fxy)|_->raise(Fn_over_All"long_map2")letfor_allf=function|`Top->raise(Fn_over_All"for_all")|`Liftedx->M.for_allfxletiterf=function|`Top->raise(Fn_over_All"iter")|`Liftedx->M.iterfxletfoldfxa=matchxwith|`Top->raise(Fn_over_All"fold")|`Liftedx->M.foldfxaletfilterfx=matchxwith|`Top->raise(Fn_over_All"filter")|`Liftedx->`Lifted(M.filterfx)letmergefxy=matchx,ywith|`Liftedx,`Liftedy->`Lifted(M.mergefxy)|_->raise(Fn_over_All"merge")letleq_with_fctfxy=match(x,y)with|(_,`Top)->true|(`Top,_)->false|(`Liftedx,`Liftedy)->M.leq_with_fctfxyletjoin_with_fctfxy=match(x,y)with|(`Top,x)->`Top|(x,`Top)->`Top|(`Liftedx,`Liftedy)->`Lifted(M.join_with_fctfxy)letwiden_with_fctfxy=match(x,y)with|(`Liftedx,`Liftedy)->`Lifted(M.widen_with_fctfxy)|_->yletcardinal=function|`Top->raise(Fn_over_All"cardinal")|`Liftedx->M.cardinalxletchoose=function|`Top->raise(Fn_over_All"choose")|`Liftedx->M.choosexletsingletonkv=`Lifted(M.singletonkv)letempty()=`Lifted(M.empty())letis_empty=function|`Top->false|`Liftedx->M.is_emptyxletexistsf=function|`Top->raise(Fn_over_All"exists")|`Liftedx->M.existsfxletbindings=function|`Top->raise(Fn_over_All"bindings")|`Liftedx->M.bindingsxletmapif=function|`Top->`Top|`Liftedx->`Lifted(M.mapifx)endmoduleMapBot_LiftTop(Domain:Printable.S)(Range:Lattice.S):Swithtypekey=Domain.tandtypevalue=Range.t=structmoduleM=MapBot(Domain)(Range)includeLiftTop(Range)(M)endmoduleLiftBot(Range:Lattice.S)(M:Swithtypevalue=Range.t):Swithtypekey=M.keyandtypevalue=Range.t=structincludeLattice.LiftBot(M)typekey=M.keytypevalue=M.valueletaddkv=function|`Bot->`Bot|`Liftedx->`Lifted(M.addkvx)letremovek=function|`Bot->`Bot|`Liftedx->`Lifted(M.removekx)letfindk=function|`Bot->Range.bot()|`Liftedx->M.findkxletfind_optk=function|`Bot->Some(Range.bot())|`Liftedx->M.find_optkxletmemk=function|`Bot->false|`Liftedx->M.memkxletmapf=function|`Bot->`Bot|`Liftedx->`Lifted(M.mapfx)letadd_listxs=function|`Bot->`Bot|`Liftedx->`Lifted(M.add_listxsx)letadd_list_setksv=function|`Bot->`Bot|`Liftedx->`Lifted(M.add_list_setksvx)letadd_list_funksf=function|`Bot->`Bot|`Liftedx->`Lifted(M.add_list_funksfx)letmap2fxy=matchx,ywith|`Liftedx,`Liftedy->`Lifted(M.map2fxy)|_->raise(Fn_over_All"map2")letlong_map2fxy=matchx,ywith|`Liftedx,`Liftedy->`Lifted(M.long_map2fxy)|_->raise(Fn_over_All"long_map2")letfor_allf=function|`Bot->raise(Fn_over_All"for_all")|`Liftedx->M.for_allfxletiterf=function|`Bot->raise(Fn_over_All"iter")|`Liftedx->M.iterfxletfoldfxa=matchxwith|`Bot->raise(Fn_over_All"fold")|`Liftedx->M.foldfxaletfilterfx=matchxwith|`Bot->raise(Fn_over_All"filter")|`Liftedx->`Lifted(M.filterfx)letmergefxy=matchx,ywith|`Liftedx,`Liftedy->`Lifted(M.mergefxy)|_->raise(Fn_over_All"merge")letjoin_with_fctfxy=match(x,y)with|(`Bot,x)->x|(x,`Bot)->x|(`Liftedx,`Liftedy)->`Lifted(M.join_with_fctfxy)letwiden_with_fctfxy=match(x,y)with|(`Liftedx,`Liftedy)->`Lifted(M.widen_with_fctfxy)|_->yletleq_with_fctfxy=match(x,y)with|(`Bot,_)->true|(_,`Bot)->false|(`Liftedx,`Liftedy)->M.leq_with_fctfxyletcardinal=function|`Bot->raise(Fn_over_All"cardinal")|`Liftedx->M.cardinalxletchoose=function|`Bot->raise(Fn_over_All"choose")|`Liftedx->M.choosexletsingletonkv=`Lifted(M.singletonkv)letempty()=`Lifted(M.empty())letis_empty=function|`Bot->false|`Liftedx->M.is_emptyxletexistsf=function|`Bot->raise(Fn_over_All"exists")|`Liftedx->M.existsfxletbindings=function|`Bot->raise(Fn_over_All"bindings")|`Liftedx->M.bindingsxletmapif=function|`Bot->`Bot|`Liftedx->`Lifted(M.mapifx)endmoduleMapTop_LiftBot(Domain:Printable.S)(Range:Lattice.S):Swithtypekey=Domain.tandtypevalue=Range.t=structmoduleM=MapTop(Domain)(Range)includeLiftBot(Range)(M)end(** Map abstracted by a single (joined) key. *)moduleJoined(E:Lattice.S)(R:Lattice.S):Swithtypekey=E.tandtypevalue=R.t=structtypekey=E.ttypevalue=R.tincludeLattice.Prod(E)(R)letsingletoner=(e,r)letexistsp(e,r)=perletfor_allp(e,r)=perletmeme(e',_)=E.leqee'letchooseer=erletbindingser=[er]letremovee((e',_)aser)=ifE.leqe'ethen(E.bot(),R.bot())elseerletmapf(e,r)=(e,fr)letmapif(e,r)=(e,fer)letmap2f(e,r)(e',r')=(E.meetee',frr')letlong_map2f(e,r)(e',r')=(E.joinee',frr')letmergefm1m2=failwith"MapDomain.Joined.merge"(* TODO: ? *)letfoldf(e,r)a=feraletempty()=(E.bot(),R.bot())letadder(e',r')=(E.joinee',R.joinrr')letis_empty(e,_)=E.is_boteletiterf(e,r)=ferletcardinaler=ifis_emptyerthen0else1letfinde(e',r)=ifE.leqee'thenrelseraiseNot_foundletfind_opte(e',r)=ifE.leqee'thenSomerelseNoneletfilterps=failwith"MapDomain.Joined.filter"letadd_listersm=List.fold_left(funacc(e,r)->adderacc)mersletadd_list_setesrm=List.fold_left(funacce->adderacc)mesletadd_list_funesfm=List.fold_left(funacce->adde(fe)acc)mesletleq_with_fct___=failwith"MapDomain.Joined.leq_with_fct"letjoin_with_fct___=failwith"MapDomain.Joined.join_with_fct"letwiden_with_fct___=failwith"MapDomain.Joined.widen_with_fct"end