123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389(* Js_of_ocaml compiler
* http://www.ocsigen.org/js_of_ocaml/
* Copyright (C) 2010 Jérôme Vouillon
* Laboratoire PPS - CNRS Université Paris Diderot
*
* 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, with linking exception;
* either version 2.1 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*)open!StdlibmoduleMake(N:sigtypetend)(NSet:Set.Swithtypeelt=N.t)(NMap:Map.Swithtypekey=N.t)=structtypet={domain:NSet.t;fold_children:'a.(N.t->'a->'a)->N.t->'a->'a}letsuccessorsgx=tryNMap.findxgwithNot_found->NSet.emptyletadd_edgegxy=letl=successorsgxinNMap.addx(NSet.addyl)gletinvertg=leth=NSet.fold(funxh->g.fold_children(funyh->add_edgehyx)xh)g.domainNMap.emptyin{domain=g.domain;fold_children=(funfxa->NSet.foldf(successorshx)a)}moduletypeDOMAIN=sigtypetvalequal:t->t->boolvalbot:tendmoduleSolver(D:DOMAIN)=structletn=ref0letm=ref0typequeue={queue:N.tQueue.t;mutableset:NSet.t}letis_emptyst=Queue.is_emptyst.queueletpopst=letx=Queue.popst.queueinst.set<-NSet.removexst.set;xletpushxst=ifnot(NSet.memxst.set)then(Queue.pushxst.queue;st.set<-NSet.addxst.set)letreciterategfvw=ifis_emptywthenvelseletx=popwinleta=NMap.findxvinincrm;letb=fvxinletv=NMap.addxbvinifnot(D.equalab)then(g.fold_children(funy()->pushyw)x();iterategfvw)elseiterategfvwletrectraversegvisitedlstx=ifnot(NSet.memxvisited)then(letvisited=NSet.addxvisitedinletvisited=g.fold_children(funyvisited->traversegvisitedlsty)xvisitedinlst:=x::!lst;visited)elsevisitedlettraverse_allg=letlst=ref[]inletvisited=NSet.fold(funxvisited->traversegvisitedlstx)g.domainNSet.emptyinassert(NSet.equalg.domainvisited);letqueue=Queue.create()inList.iter~f:(funx->Queue.pushxqueue)!lst;queueletfgf=n:=0;m:=0;(*
let t1 = Timer.make () in
*)letv=NSet.fold(funxv->incrn;NMap.addxD.botv)g.domainNMap.emptyin(*
let t1 = Timer.get t1 in
let t2 = Timer.make () in
*)letw={set=g.domain;queue=traverse_allg}in(*
let t2 = Timer.get t2 in
let t3 = Timer.make () in
*)letres=iterategfvwin(*
let t3 = Timer.get t3 in
Format.eprintf "YYY %.2f %.2f %.2f@." t1 t2 t3;
Format.eprintf "YYY %d %d (%f)@." !m !n (float !m /. float !n);
*)resendendmoduletypeISet=sigtypettypeeltvaliter:(elt->unit)->t->unitvalmem:t->elt->boolvaladd:t->elt->unitvalremove:t->elt->unitvalcopy:t->tendmoduletypeTbl=sigtype'attypekeytypesizevalget:'at->key->'avalset:'at->key->'a->unitvalmake:size->'a->'atendmoduleMake_Imperative(N:sigtypetend)(NSet:ISetwithtypeelt=N.t)(NTbl:Tblwithtypekey=N.t)=structtypet={domain:NSet.t;iter_children:(N.t->unit)->N.t->unit}letsuccessorsgx=NTbl.getgxletadd_edgegxy=NTbl.setgx(y::successorsgx)letinvertsizeg=leth=NTbl.makesize[]inNSet.iter(funx->g.iter_children(funy->add_edgehyx)x)g.domain;{domain=g.domain;iter_children=(funfx->List.iter~f(successorshx))}moduletypeDOMAIN=sigtypetvalequal:t->t->boolvalbot:tendmoduleSolver(D:DOMAIN)=structletn=ref0letm=ref0typequeue={queue:N.tQueue.t;set:NSet.t}letis_emptyst=Queue.is_emptyst.queueletpopst=letx=Queue.popst.queueinNSet.addst.setx;xletpushxst=ifNSet.memst.setxthen(Queue.pushxst.queue;NSet.removest.setx)letreciterateg~updatefvw=ifis_emptywthenvelseletx=popwinleta=NTbl.getvxinincrm;letb=f~updatevxinifnot(D.equalab)then(NTbl.setvxb;g.iter_children(funy->pushyw)x);iterateg~updatefvwletrectraversegto_visitlstx=ifNSet.memto_visitxthen(NSet.removeto_visitx;incrn;g.iter_children(funy->traversegto_visitlsty)x;lst:=x::!lst)lettraverse_allg=letlst=ref[]inletto_visit=NSet.copyg.domaininNSet.iter(funx->traversegto_visitlstx)g.domain;letqueue=Queue.create()inList.iter~f:(funx->Queue.pushxqueue)!lst;{queue;set=to_visit}letcheckgvfreport=letupdate~children:__=()inNSet.iter(funx->leta=NTbl.getvxinletb=f~updatevxinifnot(D.equalab)then(NTbl.setvxb;reportxab))g.domainletf'sizegf=n:=0;m:=0;(*
let t1 = Timer.make () in
*)letv=NTbl.makesizeD.botin(*
let t1 = Timer.get t1 in
let t2 = Timer.make () in
*)letw=traverse_allgin(*
let t2 = Timer.get t2 in
let t3 = Timer.make () in
*)letupdate~childrenx=ifchildrentheng.iter_children(funy->pushyw)xelsepushxwinletres=iterateg~updatefvwin(*
let t3 = Timer.get t3 in
Format.eprintf "YYY %.2f %.2f %.2f@." t1 t2 t3;
Format.eprintf "YYY %d %d (%f)@." !m !n (float !m /. float !n);
*)resletfsizegf=f'sizeg(fun~update:_vx->fvx)endendmoduletypeACTION=sigtypetendmoduletypeDOMAIN=sigtypetvalequal:t->t->boolvalbot:tvaltop:tvaljoin:t->t->tendmoduleSolver(N:sigtypetend)(NSet:ISetwithtypeelt=N.t)(NTbl:Tblwithtypekey=N.t)(A:ACTION)(D:DOMAIN)=structtypet={domain:NSet.t;iter_children:(N.t->A.t->unit)->N.t->unit}typequeue={queue:N.tQueue.t;set:NSet.t}letis_emptyst=Queue.is_emptyst.queueletpopst=letx=Queue.popst.queueinNSet.addst.setx;xletpushxst=ifNSet.memst.setxthen(Queue.pushxst.queue;NSet.removest.setx)letreciterategf~statew=ifnot(is_emptyw)then(letdep=popwinifnot(D.equal(NTbl.getstatedep)D.bot)theng.iter_children(funtargetaction->leta=NTbl.getstatetargetinifnot(D.equalaD.top)thenletb=D.joina(f~state~dep~target~action)inifnot(D.equalab)then(NTbl.setstatetargetb;pushtargetw))dep;iterategf~statew)letrectraversegto_visitlstx=ifNSet.memto_visitxthen(NSet.removeto_visitx;g.iter_children(funy_->traversegto_visitlsty)x;lst:=x::!lst)lettraverse_allg=letlst=ref[]inletto_visit=NSet.copyg.domaininNSet.iter(funx->traversegto_visitlstx)g.domain;letqueue=Queue.create()inList.iter~f:(funx->Queue.pushxqueue)!lst;{queue;set=to_visit}letf~stategf=letw=traverse_allginiterategf~statewend