1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586openCommonopenOcollectionopenOsetopenOgraphopenOsetb(* graph2way prend en parametre le type de finitemap et set a prendre
* todo? add_arc doit ramer, car del la key, puis add =>
* better to have a ref to a set
* todo: efficient graph: with pointers and a tag: visited
* => need keep global value visited_counter
* check(that node is in, ...), display
*
* pourrait remettre val nods, a la place de les calculer. mais bon
* s'en sert pas vraiment car y'a pas de notion d'identifiant de noeud
* et de label.
*
* invariant: key in pred is also in succ (completness) and value in
* either table is a key also
*)class['a]ograph2wayasuccapred(*f1*)f2=object(o)inherit['a]ographvalsucc=asucc(* f1() ## new oassocb [] *)valpred=apred(* f1() ## new oassocb [] *)(* val nods = anodes ##f2() ## new osetb [] *)methodempty=raiseTodo(*{< succ = f1() ;(* new oassocb []; *)
pred = f1(); (* new oassocb []; *)
(* nods = f2(); ##new osetb []; *)
>}*)methodadd_nodee={<(* nods = nods#add e; *)pred=pred#add(e,f2());(* new osetb []); *)succ=succ#add(e,f2());(* new osetb []); *)>}methoddel_nodee={<(* nods = nods#del e; *)pred=pred#delkeye;succ=succ#delkeye;>}methodadd_arc(a,b)={<succ=succ#replkey(a,(succ#finda)#addb);pred=pred#replkey(b,(pred#findb)#adda);>}methoddel_arc(a,b)={<succ=succ#replkey(a,(succ#finda)#delb);pred=pred#replkey(b,(pred#findb)#dela);>}methodsuccessorse=succ#findemethodpredecessorse=pred#findemethodnodes=(* nods *)(* could take pred, same *)(* caml typing sux, arrive pas a faire: pred#fold (fun a (k,v) -> a#add k) (new osetb Set_.empty) *)leta=ref(newosetbSet_.empty)insucc#iter(fun(k,v)->a:=!a#addk);!amethodancestorsxs=letrecauxxsacc=matchxs#viewwith(* could be done with an iter *)|Empty->acc|Cons(x,xs)->(acc#addx)|>(funnewacc->aux(o#predecessorsx)newacc)|>(funnewacc->auxxsnewacc)inauxxs(f2())(* (new osetb []) *)methodchildrenxs=letrecauxxsacc=matchxs#viewwith(* could be done with an iter *)|Empty->acc|Cons(x,xs)->(acc#addx)|>(funnewacc->aux(o#successorsx)newacc)|>(funnewacc->auxxsnewacc)inauxxs(f2())(* (new osetb []) *)methodbrothersx=letparents=o#predecessorsxin(parents#fold(funacce->acc$++$o#successorse)(f2()))#delxend