123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389(******************************************************************************
* *
* A Tree Set implementation *
* *
* The tree will remain mostly unbalanced! *
* Target is to add some 'laziness' with some functions *
* *
* Harry K W *
* *
*******************************************************************************)moduletypeTSet=sigtypettype'asetvalempty:tsetvaladd:t->tset->tsetvalmem:t->tset->boolvalcardinal:tset->intvalof_list:tlist->tsetvalto_list:tset->tlistvalroot:tset->toptionvalchoose:tset->tvaltake_min_opt:tset->toption*tsetvaltake_min:tset->t*tsetvaltake_max_opt:tset->toption*tsetvalinvert:tset->tsetvalinorder:tlist->tset->tlistvaliter:(t->unit)->tset->unitvaltraverse:(t->'b->'b)->'b->tset->'bvalpreorder:tlist->tset->tlistvaliter_preorder:(t->unit)->tset->unitvalpostorder:tlist->tset->tlistvaliter_postorder:(t->unit)->tset->unitvalfold:(t->'b->'b)->tset->'b->'bvalremove:t->tset->tsetvalunion:tset->tset->tsetvalis_empty:tset->boolvalelements:tset->tlistvalfilter:(t->bool)->tset->tsetvalfor_all:(t->bool)->tset->boolvalsubset:tset->tset->boolvalsubset_seq:tset->tsetSeq.tvaldiff:tset->tset->tsetvalto_seq:tset->tSeq.tvalsingleton:t->tsetvalmin_elt_opt:tset->toptionvalmax_elt_opt:tset->toptionvalof_seq:tSeq.t->tsetvalinter:tset->tset->tsetvalexists:(t->bool)->tset->boolvalfind_first_opt:(t->bool)->tset->toptionvalfind_first:(t->bool)->tset->tvalsearch:(t->int)->tset->tendlet(let*)=Option.bindmoduleTreeSet(Ord:Set.OrderedType):TSetwithtypet:=Ord.t=structtype'aset=|Empty|Nodeof'aset*'a*'aset;;letempty=EmptyexceptionNot_found(** [add 'a 'a set] Adds a node 'a to a given set *)letrecaddaval=function|Empty->Node(Empty,aval,Empty)|Node(left,v,right)->letp=Ord.compareavalvinifp<0thenNode(addavalleft,v,right)elseifp>0thenNode(left,v,addavalright)elseNode(left,aval,right);;(** [member 'a 'a set] Checks whether 'a is a member of the set *)letrecmemaval=function|Empty->false|Node(left,v,right)->letp=Ord.compareavalvinp=0||(ifp>0then(mem[@tailcall])avalrightelse(mem[@tailcall])avalleft);;(** [take_min 'a set]
Returns a pair of some minimum element in the set and the remaining set
*)letrectake_min=function|Empty->raiseNot_found|Node(Empty,v,r)->(v,r)|Node(l,v,r)->let(el,rest)=take_minlin(el,Node(rest,v,r));;(** [take_min 'a set]
Returns a pair of some minimum element in the set and the remaining set
*)letrectake_min_opt=function|Empty->(None,Empty)|Node(Empty,v,r)->(Somev,r)|Node(l,v,r)->let(el,rest)=take_min_optlin(el,Node(rest,v,r));;(** [choose 'a set]
Returns a pair of some minimum element in the set
*)letrecchoose=function|Empty->raiseNot_found|Node(Empty,v,_r)->v|Node(l,_v,_r)->choosel;;(** [choose 'a set]
Returns a pair of some minimum element in the set and the remaining set
*)letrecchoose_rest=function|Empty->raiseNot_found|Node(Empty,v,r)->(v,r)|Node(l,v,r)->let(el,rest)=choose_restlin(el,Node(rest,v,r));;(** [take_max 'a set]
Returns a pair of some maximum element in the set and the remaining set
*)letrectake_max_opt=function|Empty->(None,Empty)|Node(l,v,Empty)->(Somev,l)|Node(l,v,r)->let(el,rest)=take_max_optrin(el,Node(l,v,rest));;(** [max_elt_opt 'a set]
Returns some maximum element in the set and the remaining set
*)letrecmax_elt_opt=function|Empty->None|Node(_l,v,Empty)->Somev|Node(_l,_v,r)->max_elt_optr;;(** [min_elt_opt 'a set]
Returns some maximum element in the set and the remaining set
*)letrecmin_elt_opt=function|Empty->None|Node(Empty,v,_r)->Somev|Node(l,_v,_r)->min_elt_optl;;(** [root 'a set] Root element of the Set *)letroot=function|Empty->None|Node(_,v,_)->Some(v);;(** [root 'a set] Root element of the Set *)lettake_root=function|Empty->(None,Empty)|Node(x,v,y)->letg=letmin,rest=take_min_optyinmatchminwith|Somenext->Node(x,next,rest)|None->xinSome(v),g;;(** [set_of_list 'a list] Build a Set from a list *)letof_list=function|[]->Empty|rst->List.fold_left(Fun.flipadd)Emptyrst;;letof_list=of_list(** [set_of_seq 'a Seq] Build a Set from a lazy sequence *)letof_seq=Seq.fold_left(Fun.flipadd)Empty;;(** [cardinality 'a set] number of elements in the set (recursive) *)letreccardinal=function|Empty->0|Node(x,_,y)->cardinalx+1+cardinaly;;(* Sum Left and Right subtrees *)letcardinal=cardinal(** [invert 'a set] Invert the BST holding the set *)letrecinvert=function|Node(x,a,y)->Node(inverty,a,invertx)|e->e;;letinvert=invert(** [inorder 'a set] Inorder walk on the set *)letrecinorderstack=function|Empty->stack|Node(Empty,a,Empty)->a::stack|Node(x,a,y)->inorder(a::(inorderstackx))y;;(* Inorder traversal - Left - Root - Right *)(** [to_list 'a list] Build a list from a set *)letto_listset=inorder[]set;;letreciterg=function|Empty->()|Node(Empty,a,Empty)->(ga)|Node(x,a,y)->let_=itergxinlet_=gainitergy;;(* Inorder traversal - Left - Root - Right *)(** [preorder 'a set] Preorder walk on the set *)letrecpreorderstack=function|Empty->stack|Node(Empty,a,Empty)->a::stack|Node(x,a,y)->preorder(preorder(a::stack)x)y;;(* Preorder traversal - Root - left - Right*)(** [preorder 'a set] Preorder walk on the set *)letreciter_preorderg=function|Empty->()|Node(Empty,a,Empty)->(ga)|Node(x,a,y)->let_=gainlet_=iter_preordergxiniter_preordergy;;(* Preorder traversal - Root - left - Right*)(** [postorder 'a set] Postorder walk on the set *)letrecpostorderstack=function|Empty->stack|Node(Empty,a,Empty)->a::stack|Node(x,a,y)->a::(postorder(postorderstackx)y);;(* Postorder traversal Left - Right - Root *)(** [postorder 'a set] Postorder walk on the set *)letreciter_postorderg=function|Empty->()|Node(Empty,a,Empty)->(ga)|Node(x,a,y)->let_=iter_postordergxinlet_=iter_postordergyinga;;(* Postorder traversal Left - Right - Root *)(*if the set is empty as in only contains `Empty*)letis_empty=function|Empty->true|_->false;;(** ... f set'' (fold f set' (fold f set acc)) ... *)letrecfoldfsetacc=matchsetwith|Empty->acc|Node(Empty,a,Empty)->faacc|Node(x,a,y)->fa(foldfy(foldfxacc));;(** ... Remove an element from the set ... *)letrecremoveel=function|Empty->Empty|Node(x,a,y)->letp=Ord.compareelainifp=0thenletmin,rest=take_min_optyinmatchminwith|Somev->Node(x,v,rest)|None->xelseifp>0thenNode(x,a,removeely)elseNode(removeelx,a,y);;(** [travers 'a set] Inorder traversal on the set *)letrectraversefacc=function|Empty->acc|Node(Empty,a,Empty)->(faacc)|Node(x,a,y)->traversef(traversef(faacc)x)y;;(* Inorder traversal - Left - Root - Right *)(** ... set union of 2 sets ... *)letunionother=function|Empty->other|self->traverse(add)otherself;;(** ... list of elements in a set ... *)letelements=function|Empty->[]|self->fold(funeltacc->(elt::acc))self[];;(** ... sequence of elements in a set ... *)letto_seq=function|self->letrecauxl()=matchtake_rootlwith|(None,_)->Seq.Nil|(Somex,tail)->Seq.Cons(x,(auxtail))in(auxself);;(** ... test whether f is true for_all members of this set ... *)letrecfor_allf=function|Empty->true|self->let(max,rest)=take_min_optselfinmatchmaxwith|Somev->iffvthenfor_allfrestelsefalse|_->true;;(** Subset other self -> other is subset of self *)letsubsetother=function|Empty->is_emptyother|self->for_all(Fun.flipmemself)other;;(** Added: generate a sequence of subsets *)letrecsubset_seq=function|Empty->Seq.returnEmpty|rem->let(x,rest)=take_minreminletrest'=subset_seqrestinletrem=Seq.map(funy->addxy)rest'inSeq.appendrest'rem;;(** Filter the elements of a set *)letfilterf=function|Empty->Empty|self->fold(funeltacc->iffeltthenaddeltaccelseacc)selfempty;;(** set difference - filter all elements of other not in self *)letdiffother=function|Empty->other|self->filter(funx->not(memxself))other;;(** singleton *)letsingletonv=Node(Empty,v,Empty);;(** set intersection *)letinterother=function|Empty->Empty|self->filter(funx->memxself)other;;(** elt in set by function *)letrecexistsf=function|Empty->false|Node(l,v,r)->(fv)||(existsfl)||(existsfr);;(** find first element matching predicate f *)letrecfind_first_optf=function|Empty->None|nodes->let(sel,rest)=take_min_optnodesinlet*el=seliniffelthenSomeelelsefind_first_optfrest;;(** find first element matching predicate f *)letrecfind_firstf=function|Empty->raiseNot_found|nodes->let(el,rest)=choose_restnodesiniffelthenelelsefind_firstfrest;;(* TODO: use search in place of find_first if applicable *)letrecsearchc=function|Empty->raiseNot_found|Node(left,v,right)->letp=cvinifp=0thenvelseifp>0then(searchcright)else(searchcleft);;end