123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280(* 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=ref0typestack={stack:N.tStack.t;mutableset:NSet.t}letis_emptyst=Stack.is_emptyst.stackletpopst=letx=Stack.popst.stackinst.set<-NSet.removexst.set;xletpushxst=ifnot(NSet.memxst.set)then(Stack.pushxst.stack;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)elseiterategfvwletrectraversegvisitedstackx=ifnot(NSet.memxvisited)then(letvisited=NSet.addxvisitedinletvisited=g.fold_children(funyvisited->traversegvisitedstacky)xvisitedinStack.pushxstack;visited)elsevisitedlettraverse_allg=letstack=Stack.create()inletvisited=NSet.fold(funxvisited->traversegvisitedstackx)g.domainNSet.emptyinassert(NSet.equalg.domainvisited);stackletfgf=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;stack=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=ref0typestack={stack:N.tStack.t;mutableset:NSet.t}letis_emptyst=Stack.is_emptyst.stackletpopst=letx=Stack.popst.stackinNSet.addst.setx;xletpushxst=ifNSet.memst.setxthen(Stack.pushxst.stack;NSet.removest.setx)letreciterategfvw=ifis_emptywthenvelseletx=popwinleta=NTbl.getvxinincrm;letb=fvxinNTbl.setvxb;ifnot(D.equalab)then(g.iter_children(funy->pushyw)x;iterategfvw)elseiterategfvwletrectraversegto_visitstackx=ifNSet.memto_visitxthen(NSet.removeto_visitx;incrn;g.iter_children(funy->traversegto_visitstacky)x;Stack.pushxstack)lettraverse_allg=letstack=Stack.create()inletto_visit=NSet.copyg.domaininNSet.iter(funx->traversegto_visitstackx)g.domain;{stack;set=to_visit}letfsizegf=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
*)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);
*)resendend