123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314(***********************************************************************)(* *)(* Objective Caml *)(* *)(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)(* *)(* Copyright 1996 Institut National de Recherche en Informatique et *)(* en Automatique. All rights reserved. This file is distributed *)(* under the terms of the Apache 2.0 license. See ../THIRD-PARTY.txt *)(* for details. *)(* *)(***********************************************************************)(* Sets over ordered types *)open!ImportincludeSet_intfletwith_return=With_return.with_returnmoduleTree0=structtype'at=|Empty(* (Leaf x) is the same as (Node (Empty, x, Empty, 1, 1)) but uses less space. *)|Leafof'a(* first int is height, second is sub-tree size *)|Nodeof'at*'a*'at*int*inttype'atree='at(* Sets are represented by balanced binary trees (the heights of the children differ by
at most 2. *)letheight=function|Empty->0|Leaf_->1|Node(_,_,_,h,_)->h;;letlength=function|Empty->0|Leaf_->1|Node(_,_,_,_,s)->s;;letinvariants=letin_rangeloweruppercompare_eltv=(matchlowerwith|None->true|Somelower->compare_eltlowerv<0)&&(matchupperwith|None->true|Someupper->compare_eltvupper<0)inletreclooploweruppercompare_eltt=matchtwith|Empty->true|Leafv->in_rangeloweruppercompare_eltv|Node(l,v,r,h,n)->lethl=heightlandhr=heightrinabs(hl-hr)<=2&&h=(maxhlhr)+1&&n=lengthl+lengthr+1&&in_rangeloweruppercompare_eltv&&looplower(Somev)compare_eltl&&loop(Somev)uppercompare_eltrinfunt~compare_elt->loopNoneNonecompare_eltt;;letis_empty=functionEmpty->true|Leaf_|Node_->false(* Creates a new node with left son l, value v and right son r.
We must have all elements of l < v < all elements of r.
l and r must be balanced and | height l - height r | <= 2.
Inline expansion of height for better speed. *)letcreatelvr=lethl=matchlwithEmpty->0|Leaf_->1|Node(_,_,_,h,_)->hinlethr=matchrwithEmpty->0|Leaf_->1|Node(_,_,_,h,_)->hinleth=ifhl>=hrthenhl+1elsehr+1inifh=1thenLeafvelsebeginletsl=matchlwithEmpty->0|Leaf_->1|Node(_,_,_,_,s)->sinletsr=matchrwithEmpty->0|Leaf_->1|Node(_,_,_,_,s)->sinNode(l,v,r,h,sl+sr+1)end(* We must call [f] with increasing indexes, because the bin_prot reader in
Core_kernel.Set needs it. *)letof_increasing_iterator_unchecked~len~f=letrecloopn~fi=matchnwith|0->Empty|1->letk=fiinLeafk|2->letkl=fiinletk=f(i+1)increate(Leafkl)k(Empty)|3->letkl=fiinletk=f(i+1)inletkr=f(i+2)increate(Leafkl)k(Leafkr)|n->letleft_length=nlsr1inletright_length=n-left_length-1inletleft=loopleft_length~fiinletk=f(i+left_length)inletright=loopright_length~f(i+left_length+1)increateleftkrightinlooplen~f0letof_sorted_array_uncheckedarray~compare_elt=letarray_length=Array.lengtharrayinletnext=(* We don't check if the array is sorted or keys are duplicated, because that
checking is slower than the whole [of_sorted_array] function *)ifarray_length<2||compare_eltarray.(0)array.(1)<0then(funi->array.(i))else(funi->array.(array_length-1-i))inof_increasing_iterator_unchecked~len:array_length~f:next;;letof_sorted_arrayarray~compare_elt=matcharraywith|[||]|[|_|]->Result.Ok(of_sorted_array_uncheckedarray~compare_elt)|_->with_return(funr->letincreasing=matchcompare_eltarray.(0)array.(1)with|0->r.return(Or_error.error_string"of_sorted_array: duplicated elements")|i->i<0infori=1toArray.lengtharray-2domatchcompare_eltarray.(i)array.(i+1)with|0->r.return(Or_error.error_string"of_sorted_array: duplicated elements")|i->ifPoly.(<>)(i<0)increasingthenr.return(Or_error.error_string"of_sorted_array: elements are not ordered")done;Result.Ok(of_sorted_array_uncheckedarray~compare_elt))(* Same as create, but performs one step of rebalancing if necessary.
Assumes l and r balanced and | height l - height r | <= 3.
Inline expansion of create for better speed in the most frequent case
where no rebalancing is required. *)letballvr=lethl=matchlwithEmpty->0|Leaf_->1|Node(_,_,_,h,_)->hinlethr=matchrwithEmpty->0|Leaf_->1|Node(_,_,_,h,_)->hinifhl>hr+2thenbeginmatchlwith|Empty->assertfalse|Leaf_->assertfalse(* because h(l)>h(r)+2 and h(leaf)=1 *)|Node(ll,lv,lr,_,_)->ifheightll>=heightlrthencreatelllv(createlrvr)elsebeginmatchlrwith|Empty->assertfalse|Leaflrv->assert(is_emptyll);create(createlllvEmpty)lrv(createEmptyvr)|Node(lrl,lrv,lrr,_,_)->create(createlllvlrl)lrv(createlrrvr)endendelseifhr>hl+2thenbeginmatchrwithEmpty->assertfalse|Leafrv->create(createlvEmpty)rvEmpty|Node(rl,rv,rr,_,_)->ifheightrr>=heightrlthencreate(createlvrl)rvrrelsebeginmatchrlwithEmpty->assertfalse|Leafrlv->assert(is_emptyrr);create(createlvEmpty)rlv(createEmptyrvrr)|Node(rll,rlv,rlr,_,_)->create(createlvrll)rlv(createrlrrvrr)endendelsebeginleth=ifhl>=hrthenhl+1elsehr+1inletsl=matchlwithEmpty->0|Leaf_->1|Node(_,_,_,_,s)->sinletsr=matchrwithEmpty->0|Leaf_->1|Node(_,_,_,_,s)->sinifh=1thenLeafvelseNode(l,v,r,h,sl+sr+1)end(* Insertion of one element *)exceptionSameletaddtx~compare_elt=letrecaux=function|Empty->Leafx|Leafv->letc=compare_eltxvinifc=0thenraiseSameelseifc<0thenbal(Leafx)vEmptyelsebalEmptyv(Leafx)|Node(l,v,r,_,_)->letc=compare_eltxvinifc=0thenraiseSameelseifc<0thenbal(auxl)vrelseballv(auxr)intryauxtwithSame->t;;(* Same as create and bal, but no assumptions are made on the relative heights of l and
r. *)letrecjoinlvr~compare_elt=match(l,r)with|(Empty,_)->addrv~compare_elt|(_,Empty)->addlv~compare_elt|(Leaflv,_)->add(addrv~compare_elt)lv~compare_elt|(_,Leafrv)->add(addlv~compare_elt)rv~compare_elt|(Node(ll,lv,lr,lh,_),Node(rl,rv,rr,rh,_))->iflh>rh+2thenballllv(joinlrvr~compare_elt)elseifrh>lh+2thenbal(joinlvrl~compare_elt)rvrrelsecreatelvr;;(* Smallest and greatest element of a set *)letrecmin_elt=function|Empty->None|Leafv|Node(Empty,v,_,_,_)->Somev|Node(l,_,_,_,_)->min_eltl;;exceptionSet_min_elt_exn_of_empty_set[@@deriving_inlinesexp]let()=Ppx_sexp_conv_lib.Conv.Exn_converter.add([%extension_constructorSet_min_elt_exn_of_empty_set])(function|Set_min_elt_exn_of_empty_set->Ppx_sexp_conv_lib.Sexp.Atom"src/set.ml.Tree0.Set_min_elt_exn_of_empty_set"|_->assertfalse)[@@@end]exceptionSet_max_elt_exn_of_empty_set[@@deriving_inlinesexp]let()=Ppx_sexp_conv_lib.Conv.Exn_converter.add([%extension_constructorSet_max_elt_exn_of_empty_set])(function|Set_max_elt_exn_of_empty_set->Ppx_sexp_conv_lib.Sexp.Atom"src/set.ml.Tree0.Set_max_elt_exn_of_empty_set"|_->assertfalse)[@@@end]letmin_elt_exnt=matchmin_elttwith|None->raiseSet_min_elt_exn_of_empty_set|Somev->v;;letfold_untilt~init~f~finish=letrecfold_until_helper~ftacc=matchtwith|Empty->Continue_or_stop.Continueacc|Leafvalue->faccvalue|Node(left,value,right,_,_)->matchfold_until_helper~fleftaccwith|Stop_aasx->x|Continueacc->matchfaccvaluewith|Stop_aasx->x|Continuea->fold_until_helper~frightainmatchfold_until_helper~ftinitwith|Continuex->finishx|Stopx->x;;letrecmax_elt=function|Empty->None|Leafv|Node(_,v,Empty,_,_)->Somev|Node(_,_,r,_,_)->max_eltr;;letmax_elt_exnt=matchmax_elttwith|None->raiseSet_max_elt_exn_of_empty_set|Somev->v;;(* Remove the smallest element of the given set *)letrecremove_min_elt=function|Empty->invalid_arg"Set.remove_min_elt"|Leaf_->Empty|Node(Empty,_,r,_,_)->r|Node(l,v,r,_,_)->bal(remove_min_eltl)vr;;(* Merge two trees l and r into one. All elements of l must precede the elements of r.
Assume | height l - height r | <= 2. *)letmerget1t2=match(t1,t2)with|(Empty,t)->t|(t,Empty)->t|(_,_)->balt1(min_elt_exnt2)(remove_min_eltt2);;(* Merge two trees l and r into one. All elements of l must precede the elements of r.
No assumption on the heights of l and r. *)letconcatt1t2~compare_elt=match(t1,t2)with|Empty,t|t,Empty->t|(_,_)->joint1(min_elt_exnt2)(remove_min_eltt2)~compare_elt;;letsplittx~compare_elt=letrecsplitt=matchtwith|Empty->(Empty,None,Empty)|Leafv->letc=compare_eltxvinifc=0then(Empty,Somev,Empty)elseifc<0then(Empty,None,Leafv)else(Leafv,None,Empty)|Node(l,v,r,_,_)->letc=compare_eltxvinifc=0then(l,Somev,r)elseifc<0thenlet(ll,maybe_elt,rl)=splitlin(ll,maybe_elt,joinrlvr~compare_elt)elselet(lr,maybe_elt,rr)=splitrin(joinlvlr~compare_elt,maybe_elt,rr)insplitt;;(* Implementation of the set operations *)letempty=Emptyletrecmemtx~compare_elt=matchtwith|Empty->false|Leafv->letc=compare_eltxvinc=0|Node(l,v,r,_,_)->letc=compare_eltxvinc=0||mem(ifc<0thenlelser)x~compare_elt;;letsingletonx=Leafxletremovetx~compare_elt=letrecauxt=matchtwith|Empty->raiseSame|Leafv->ifcompare_eltxv=0thenEmptyelseraiseSame|Node(l,v,r,_,_)->letc=compare_eltxvinifc=0thenmergelrelseifc<0thenbal(auxl)vrelseballv(auxr)intryauxtwithSame->t;;letremove_indexti~compare_elt:_=letrecauxti=matchtwith|Empty->raiseSame|Leaf_->ifi=0thenEmptyelseraiseSame|Node(l,v,r,_,_)->letl_size=lengthlinletc=Poly.compareil_sizeinifc=0thenmergelrelseifc<0thenbal(auxli)vrelseballv(auxr(i-l_size-1))intryauxtiwithSame->t;;letunions1s2~compare_elt=letrecunions1s2=matchs1,s2with|Empty,t|t,Empty->t|Leafv1,_->union(Node(Empty,v1,Empty,1,1))s2|_,Leafv2->unions1(Node(Empty,v2,Empty,1,1))|(Node(l1,v1,r1,h1,_),Node(l2,v2,r2,h2,_))->ifh1>=h2thenifh2=1thenadds1v2~compare_eltelsebeginlet(l2,_,r2)=splits2v1~compare_eltinjoin(unionl1l2)v1(unionr1r2)~compare_eltendelseifh1=1thenadds2v1~compare_eltelsebeginlet(l1,_,r1)=splits1v2~compare_eltinjoin(unionl1l2)v2(unionr1r2)~compare_eltendinunions1s2;;letunion_list~comparator~to_treexs=letcompare_elt=comparator.Comparator.compareinList.foldxs~init:empty~f:(funacx->unionac(to_treex)~compare_elt);;letinters1s2~compare_elt=letrecinters1s2=matchs1,s2with|Empty,_|_,Empty->Empty|((Leafeltassingleton),other_set)|(other_set,(Leafeltassingleton))->ifmemother_setelt~compare_eltthensingletonelseEmpty|(Node(l1,v1,r1,_,_),t2)->matchsplitt2v1~compare_eltwith|(l2,None,r2)->concat(interl1l2)(interr1r2)~compare_elt|(l2,Somev1,r2)->join(interl1l2)v1(interr1r2)~compare_eltininters1s2;;letdiffs1s2~compare_elt=letrecdiffs1s2=matchs1,s2with|(Empty,_)->Empty|(t1,Empty)->t1|(Leafv1,t2)->diff(Node(Empty,v1,Empty,1,1))t2|(Node(l1,v1,r1,_,_),t2)->matchsplitt2v1~compare_eltwith|(l2,None,r2)->join(diffl1l2)v1(diffr1r2)~compare_elt|(l2,Some_,r2)->concat(diffl1l2)(diffr1r2)~compare_eltindiffs1s2;;moduleEnum=structtypeincreasingtypedecreasingtype('a,'direction)t=End|Moreof'a*'atree*('a,'direction)tletrecconss(e:(_,increasing)t):(_,increasing)t=matchswith|Empty->e|Leafv->(More(v,Empty,e))|Node(l,v,r,_,_)->consl(More(v,r,e));;letreccons_rights(e:(_,decreasing)t):(_,decreasing)t=matchswith|Empty->e|Leafv->More(v,Empty,e)|Node(l,v,r,_,_)->cons_rightr(More(v,l,e));;letof_sets:(_,increasing)t=conssEndletof_set_rights:(_,decreasing)t=cons_rightsEndletstarting_at_increasingtkeycompare:(_,increasing)t=letrecloopte=matchtwith|Empty->e|Leafv->loop(Node(Empty,v,Empty,1,1))e|Node(_,v,r,_,_)whencomparevkey<0->loopre|Node(l,v,r,_,_)->loopl(More(v,r,e))inlooptEnd;;letstarting_at_decreasingtkeycompare:(_,decreasing)t=letrecloopte=matchtwith|Empty->e|Leafv->loop(Node(Empty,v,Empty,1,1))e|Node(l,v,_,_,_)whencomparevkey>0->loople|Node(l,v,r,_,_)->loopr(More(v,l,e))inlooptEnd;;letcomparecompare_elte1e2=letrecloope1e2=matche1,e2with|End,End->0|End,_->-1|_,End->1|More(v1,r1,e1),More(v2,r2,e2)->letc=compare_eltv1v2inifc<>0thencelseloop(consr1e1)(consr2e2)inloope1e2;;letreciter~f=function|End->()|More(a,tree,enum)->fa;iter(constreeenum)~f;;letiter2compare_eltt1t2~f=letrecloopt1t2=matcht1,t2with|End,End->()|End,_->itert2~f:(funa->f(`Righta))|_,End->itert1~f:(funa->f(`Lefta))|More(a1,tree1,enum1),More(a2,tree2,enum2)->letcompare_result=compare_elta1a2inifcompare_result=0thenbeginf(`Both(a1,a2));loop(constree1enum1)(constree2enum2)endelseifcompare_result<0thenbeginf(`Lefta1);loop(constree1enum1)t2endelsebeginf(`Righta2);loopt1(constree2enum2)endinloopt1t2letsymmetric_difft1t2~compare_elt=letstepstate:((_,_)Either.t,_)Sequence.Step.t=matchstatewith|End,End->Done|End,More(elt,tree,enum)->Yield(Secondelt,(End,constreeenum))|More(elt,tree,enum),End->Yield(Firstelt,(constreeenum,End))|(More(a1,tree1,enum1)asleft),(More(a2,tree2,enum2)asright)->letcompare_result=compare_elta1a2inifcompare_result=0thenbeginletnext_state=ifphys_equaltree1tree2then(enum1,enum2)else(constree1enum1,constree2enum2)inSkipnext_stateendelseifcompare_result<0thenbeginYield(Firsta1,(constree1enum1,right))endelsebeginYield(Seconda2,(left,constree2enum2))endinSequence.unfold_step~init:(of_sett1,of_sett2)~f:step;;endletto_sequence_increasingcomparator~from_eltt=letnextenum=matchenumwith|Enum.End->Sequence.Step.Done|Enum.More(k,t,e)->Sequence.Step.Yield(k,Enum.conste)inletinit=matchfrom_eltwith|None->Enum.of_sett|Somekey->Enum.starting_at_increasingtkeycomparator.Comparator.compareinSequence.unfold_step~init~f:next;;letto_sequence_decreasingcomparator~from_eltt=letnextenum=matchenumwith|Enum.End->Sequence.Step.Done|Enum.More(k,t,e)->Sequence.Step.Yield(k,Enum.cons_rightte)inletinit=matchfrom_eltwith|None->Enum.of_set_rightt|Somekey->Enum.starting_at_decreasingtkeycomparator.Comparator.compareinSequence.unfold_step~init~f:next;;letto_sequencecomparator?(order=`Increasing)?greater_or_equal_to?less_or_equal_tot=letinclusive_boundsidetbound=letcompare_elt=comparator.Comparator.compareinletl,maybe,r=splittbound~compare_eltinlett=side(l,r)inmatchmaybewith|None->t|Someelt->addtelt~compare_eltinmatchorderwith|`Increasing->lett=Option.foldless_or_equal_to~init:t~f:(inclusive_boundfst)into_sequence_increasingcomparator~from_elt:greater_or_equal_tot|`Decreasing->lett=Option.foldgreater_or_equal_to~init:t~f:(inclusive_boundsnd)into_sequence_decreasingcomparator~from_elt:less_or_equal_tot;;letmerge_to_sequencecomparator?(order=`Increasing)?greater_or_equal_to?less_or_equal_tott'=Sequence.merge_with_duplicates(to_sequencecomparator~order?greater_or_equal_to?less_or_equal_tot)(to_sequencecomparator~order?greater_or_equal_to?less_or_equal_tot')~compare:beginmatchorderwith|`Increasing->comparator.compare|`Decreasing->Fn.flipcomparator.compareend;;letcomparecompare_elts1s2=Enum.comparecompare_elt(Enum.of_sets1)(Enum.of_sets2);;letiter2s1s2~compare_elt=Enum.iter2compare_elt(Enum.of_sets1)(Enum.of_sets2)letequals1s2~compare_elt=comparecompare_elts1s2=0letis_subsets1~of_:s2~compare_elt=letrecis_subsets1~of_:s2=matchs1,s2with|Empty,_->true|_,Empty->false|Leafv1,t2->memt2v1~compare_elt|Node(l1,v1,r1,_,_),Leafv2->beginmatchl1,r1with|Empty,Empty->(* This case shouldn't occur in practice because we should have constructed
a Leaf rather than a Node with two Empty subtrees *)compare_eltv1v2=0|_,_->falseend|Node(l1,v1,r1,_,_),(Node(l2,v2,r2,_,_)ast2)->letc=compare_eltv1v2inifc=0thenis_subsetl1~of_:l2&&is_subsetr1~of_:r2(* Note that height and size don't matter here. *)elseifc<0thenis_subset(Node(l1,v1,Empty,0,0))~of_:l2&&is_subsetr1~of_:t2elseis_subset(Node(Empty,v1,r1,0,0))~of_:r2&&is_subsetl1~of_:t2inis_subsets1~of_:s2;;letitert~f=letreciter=function|Empty->()|Leafv->fv|Node(l,v,r,_,_)->iterl;fv;iterrinitert;;letsymmetric_diff=Enum.symmetric_diffletrecfolds~init:accu~f=matchswith|Empty->accu|Leafv->faccuv|Node(l,v,r,_,_)->fold~fr~init:(f(fold~fl~init:accu)v);;lethash_fold_t_ignoring_structurehash_fold_elemstatet=foldt~init:(hash_fold_intstate(lengtht))~f:hash_fold_elem;;letcountt~f=Container.count~foldt~fletsummt~f=Container.sum~foldmt~fletrecfold_rights~init:accu~f=matchswith|Empty->accu|Leafv->fvaccu|Node(l,v,r,_,_)->fold_right~fl~init:(fv(fold_right~fr~init:accu));;letrecfor_allt~f:p=matchtwith|Empty->true|Leafv->pv|Node(l,v,r,_,_)->pv&&for_all~f:pl&&for_all~f:pr;;letrecexistst~f:p=matchtwith|Empty->false|Leafv->pv|Node(l,v,r,_,_)->pv||exists~f:pl||exists~f:pr;;letfilters~f:p~compare_elt=letrecfiltaccu=function|Empty->accu|Leafv->ifpvthenaddaccuv~compare_eltelseaccu|Node(l,v,r,_,_)->filt(filt(ifpvthenaddaccuv~compare_eltelseaccu)l)rinfiltEmptys;;letfilter_maps~f:p~compare_elt=letrecfiltaccu=function|Empty->accu|Leafv->(matchpvwith|None->accu|Somev->addaccuv~compare_elt)|Node(l,v,r,_,_)->filt(filt(matchpvwith|None->accu|Somev->addaccuv~compare_elt)l)rinfiltEmptys;;letpartition_tfs~f:p~compare_elt=letrecpart((t,f)asaccu)=function|Empty->accu|Leafv->ifpvthen(addtv~compare_elt,f)else(t,addfv~compare_elt)|Node(l,v,r,_,_)->part(part(ifpvthen(addtv~compare_elt,f)else(t,addfv~compare_elt))l)rinpart(Empty,Empty)s;;letrecelements_auxaccu=function|Empty->accu|Leafv->v::accu|Node(l,v,r,_,_)->elements_aux(v::elements_auxaccur)l;;letelementss=elements_aux[]sletchooset=matchtwith|Empty->None|Leafv->Somev|Node(_,v,_,_,_)->Somev;;letchoose_exnt=matchchoosetwith|None->raiseCaml.Not_found|Somev->v;;letof_listlst~compare_elt=List.foldlst~init:empty~f:(funtx->addtx~compare_elt);;letto_lists=elementssletof_arraya~compare_elt=Array.folda~init:empty~f:(funtx->addtx~compare_elt);;(* faster but equivalent to [Array.of_list (to_list t)] *)letto_array=function|Empty->[||]|Leafv->[|v|]|Node(l,v,r,_,s)->letres=Array.create~len:svinletpos_ref=ref0inletrecloop=function(* Invariant: on entry and on exit to [loop], !pos_ref is the next
available cell in the array. *)|Empty->()|Leafv->res.(!pos_ref)<-v;incrpos_ref|Node(l,v,r,_,_)->loopl;res.(!pos_ref)<-v;incrpos_ref;looprinloopl;(* res.(!pos_ref) is already initialized (by Array.create ~len:above). *)incrpos_ref;loopr;res;;letmapt~f~compare_elt=foldt~init:empty~f:(funtx->addt(fx)~compare_elt)letgroup_byset~equiv~compare_elt=letrecloopsetequiv_classes=ifis_emptysetthenequiv_classeselseletx=choose_exnsetinletequiv_x,not_equiv_x=partition_tfset~f:(funelt->phys_equalxelt||equivxelt)~compare_eltinloopnot_equiv_x(equiv_x::equiv_classes)inloopset[];;letrecfindt~f=matchtwith|Empty->None|Leafv->iffvthenSomevelseNone|Node(l,v,r,_,_)->iffvthenSomevelsematchfindl~fwith|None->findr~f|Some_asr->r;;letrecfind_mapt~f=matchtwith|Empty->None|Leafv->fv|Node(l,v,r,_,_)->matchfvwith|Some_asr->r|None->matchfind_mapl~fwith|None->find_mapr~f|Some_asr->r;;letfind_exnt~f=matchfindt~fwith|None->failwith"Set.find_exn failed to find a matching element"|Somee->e;;letrecnthti=matchtwith|Empty->None|Leafv->ifi=0thenSomevelseNone|Node(l,v,r,_,s)->ifi>=sthenNoneelsebeginletl_size=lengthlinletc=Poly.compareil_sizeinifc<0thennthlielseifc=0thenSomevelsenthr(i-l_size-1)end;;letstable_dedup_listxs~compare_elt=letrecloopxsleftoversalready_seen=matchxswith|[]->List.revleftovers|hd::tl->ifmemalready_seenhd~compare_eltthenlooptlleftoversalready_seenelselooptl(hd::leftovers)(addalready_seenhd~compare_elt)inloopxs[]empty;;lett_of_sexp_directa_of_sexpsexp~compare_elt=matchsexpwith|Sexp.Listlst->letelt_lst=List.maplst~f:a_of_sexpinletset=of_listelt_lst~compare_eltiniflengthset=List.lengthlstthensetelseletcompare(_,e)(_,e')=compare_eltee'inbeginmatchList.find_a_dup(List.zip_exnlstelt_lst)~comparewith|None->assertfalse|Some(el_sexp,_)->of_sexp_error"Set.t_of_sexp: duplicate element in set"el_sexpend|sexp->of_sexp_error"Set.t_of_sexp: list needed"sexp;;letsexp_of_tsexp_of_at=Sexp.List(fold_rightt~init:[]~f:(funelacc->sexp_of_ael::acc));;moduleNamed=structtypenonrec('a,'cmp)t={tree:'at;name:string;}letis_subset(subset:_t)~of_:(superset:_t)~sexp_of_elt~compare_elt=letinvalid_elements=diffsubset.treesuperset.tree~compare_eltinifis_emptyinvalid_elementsthenOk()elsebeginletinvalid_elements_sexp=sexp_of_tsexp_of_eltinvalid_elementsinOr_error.error_s(Sexp.message(subset.name^" is not a subset of "^superset.name)["invalid_elements",invalid_elements_sexp])endletequals1s2~sexp_of_elt~compare_elt=Or_error.combine_errors_unit[is_subsets1~of_:s2~sexp_of_elt~compare_elt;is_subsets2~of_:s1~sexp_of_elt~compare_elt]endendtype('a,'comparator)t={(* [comparator] is the first field so that polymorphic equality fails on a map due
to the functional value in the comparator.
Note that this does not affect polymorphic [compare]: that still produces
nonsense. *)comparator:('a,'comparator)Comparator.t;tree:'aTree0.t;}type('a,'comparator)tree='aTree0.tletlike{tree=_;comparator}tree={tree;comparator}letcompare_eltt=t.comparator.Comparator.comparemoduleAccessors=structletcomparatort=t.comparatorletinvariantst=Tree0.invariantst.tree~compare_elt:(compare_eltt)letlengtht=Tree0.lengtht.treeletis_emptyt=Tree0.is_emptyt.treeletelementst=Tree0.elementst.treeletmin_eltt=Tree0.min_eltt.treeletmin_elt_exnt=Tree0.min_elt_exnt.treeletmax_eltt=Tree0.max_eltt.treeletmax_elt_exnt=Tree0.max_elt_exnt.treeletchooset=Tree0.chooset.treeletchoose_exnt=Tree0.choose_exnt.treeletto_listt=Tree0.to_listt.treeletto_arrayt=Tree0.to_arrayt.treeletfoldt~init~f=Tree0.foldt.tree~init~fletfold_untilt~init~f=Tree0.fold_untilt.tree~init~fletfold_rightt~init~f=Tree0.fold_rightt.tree~init~fletfold_resultt~init~f=Container.fold_result~fold~init~ftletitert~f=Tree0.itert.tree~fletiter2ab~f=Tree0.iter2a.treeb.tree~f~compare_elt:(compare_elta)letexistst~f=Tree0.existst.tree~fletfor_allt~f=Tree0.for_allt.tree~fletcountt~f=Tree0.countt.tree~fletsummt~f=Tree0.summt.tree~fletfindt~f=Tree0.findt.tree~fletfind_exnt~f=Tree0.find_exnt.tree~fletfind_mapt~f=Tree0.find_mapt.tree~fletmemta=Tree0.memt.treea~compare_elt:(compare_eltt)letfiltert~f=liket(Tree0.filtert.tree~f~compare_elt:(compare_eltt))letaddta=liket(Tree0.addt.treea~compare_elt:(compare_eltt))letremoveta=liket(Tree0.removet.treea~compare_elt:(compare_eltt))letuniont1t2=liket1(Tree0.uniont1.treet2.tree~compare_elt:(compare_eltt1))letintert1t2=liket1(Tree0.intert1.treet2.tree~compare_elt:(compare_eltt1))letdifft1t2=liket1(Tree0.difft1.treet2.tree~compare_elt:(compare_eltt1))letsymmetric_difft1t2=Tree0.symmetric_difft1.treet2.tree~compare_elt:(compare_eltt1)letcompare_directt1t2=Tree0.compare(compare_eltt1)t1.treet2.treeletequalt1t2=Tree0.equalt1.treet2.tree~compare_elt:(compare_eltt1)letis_subsett~of_=Tree0.is_subsett.tree~of_:of_.tree~compare_elt:(compare_eltt)moduleNamed=structtypenonrec('a,'cmp)t={set:('a,'cmp)t;name:string;}letto_named_tree{set;name}={Tree0.Named.tree=set.tree;name;}letis_subset(subset:(_,_)t)~of_:(superset:(_,_)t)=Tree0.Named.is_subset(to_named_treesubset)~of_:(to_named_treesuperset)~compare_elt:(compare_eltsubset.set)~sexp_of_elt:subset.set.comparator.sexp_of_tletequalt1t2=Or_error.combine_errors_unit[is_subsett1~of_:t2;is_subsett2~of_:t1]endletpartition_tft~f=let(tree_t,tree_f)=Tree0.partition_tft.tree~f~compare_elt:(compare_eltt)inlikettree_t,likettree_f;;letsplitta=let(tree1,b,tree2)=Tree0.splitt.treea~compare_elt:(compare_eltt)inlikettree1,b,likettree2;;letgroup_byt~equiv=List.map(Tree0.group_byt.tree~equiv~compare_elt:(compare_eltt))~f:(liket);;letnthti=Tree0.ntht.treeiletremove_indexti=liket(Tree0.remove_indext.treei~compare_elt:(compare_eltt))letsexp_of_tsexp_of_a_t=Tree0.sexp_of_tsexp_of_at.treeletto_sequence?order?greater_or_equal_to?less_or_equal_tot=Tree0.to_sequencet.comparator?order?greater_or_equal_to?less_or_equal_tot.treeletmerge_to_sequence?order?greater_or_equal_to?less_or_equal_tott'=Tree0.merge_to_sequencet.comparator?order?greater_or_equal_to?less_or_equal_tot.treet'.treelethash_fold_directhash_fold_keystatet=Tree0.hash_fold_t_ignoring_structurehash_fold_keystatet.treeendincludeAccessorsletcompare__t1t2=compare_directt1t2moduleTree=structtype('a,'comparator)t=('a,'comparator)treeletcecomparator=comparator.Comparator.comparelett_of_sexp_direct~comparatora_of_sexpsexp=Tree0.t_of_sexp_direct~compare_elt:(cecomparator)a_of_sexpsexpletempty_without_value_restriction=Tree0.emptyletempty~comparator:_=empty_without_value_restrictionletsingleton~comparator:_e=Tree0.singletoneletlengtht=Tree0.lengthtletinvariants~comparatort=Tree0.invariantst~compare_elt:(cecomparator)letis_emptyt=Tree0.is_emptytletelementst=Tree0.elementstletmin_eltt=Tree0.min_elttletmin_elt_exnt=Tree0.min_elt_exntletmax_eltt=Tree0.max_elttletmax_elt_exnt=Tree0.max_elt_exntletchooset=Tree0.choosetletchoose_exnt=Tree0.choose_exntletto_listt=Tree0.to_listtletto_arrayt=Tree0.to_arraytletitert~f=Tree0.itert~fletexistst~f=Tree0.existst~fletfor_allt~f=Tree0.for_allt~fletcountt~f=Tree0.countt~fletsummt~f=Tree0.summt~fletfindt~f=Tree0.findt~fletfind_exnt~f=Tree0.find_exnt~fletfind_mapt~f=Tree0.find_mapt~fletfoldt~init~f=Tree0.foldt~init~fletfold_untilt~init~f=Tree0.fold_untilt~init~fletfold_rightt~init~f=Tree0.fold_rightt~init~fletmap~comparatort~f=Tree0.mapt~f~compare_elt:(cecomparator)letfilter~comparatort~f=Tree0.filtert~f~compare_elt:(cecomparator)letfilter_map~comparatort~f=Tree0.filter_mapt~f~compare_elt:(cecomparator)letpartition_tf~comparatort~f=Tree0.partition_tft~f~compare_elt:(cecomparator)letiter2~comparatorab~f=Tree0.iter2ab~f~compare_elt:(cecomparator)letmem~comparatorta=Tree0.memta~compare_elt:(cecomparator)letadd~comparatorta=Tree0.addta~compare_elt:(cecomparator)letremove~comparatorta=Tree0.removeta~compare_elt:(cecomparator)letunion~comparatort1t2=Tree0.uniont1t2~compare_elt:(cecomparator)letinter~comparatort1t2=Tree0.intert1t2~compare_elt:(cecomparator)letdiff~comparatort1t2=Tree0.difft1t2~compare_elt:(cecomparator)letsymmetric_diff~comparatort1t2=Tree0.symmetric_difft1t2~compare_elt:(cecomparator)letcompare_direct~comparatort1t2=Tree0.compare(cecomparator)t1t2letequal~comparatort1t2=Tree0.equalt1t2~compare_elt:(cecomparator)letis_subset~comparatort~of_=Tree0.is_subsett~of_~compare_elt:(cecomparator)letof_list~comparatorl=Tree0.of_listl~compare_elt:(cecomparator)letof_array~comparatora=Tree0.of_arraya~compare_elt:(cecomparator)letof_sorted_array_unchecked~comparatora=Tree0.of_sorted_array_uncheckeda~compare_elt:(cecomparator)letof_increasing_iterator_unchecked~comparator:_~len~f=Tree0.of_increasing_iterator_unchecked~len~fletof_sorted_array~comparatora=Tree0.of_sorted_arraya~compare_elt:(cecomparator)letunion_list~comparatorl=Tree0.union_listl~to_tree:Fn.id~comparatorletstable_dedup_list~comparatorxs=Tree0.stable_dedup_listxs~compare_elt:(cecomparator);;letgroup_by~comparatort~equiv=Tree0.group_byt~equiv~compare_elt:(cecomparator)letsplit~comparatorta=Tree0.splitta~compare_elt:(cecomparator)letnthti=Tree0.nthtiletremove_index~comparatorti=Tree0.remove_indexti~compare_elt:(cecomparator)letsexp_of_tsexp_of_a_t=Tree0.sexp_of_tsexp_of_atletto_treet=tletof_tree~comparator:_t=tletto_sequence~comparator?order?greater_or_equal_to?less_or_equal_tot=Tree0.to_sequencecomparator?order?greater_or_equal_to?less_or_equal_totletmerge_to_sequence~comparator?order?greater_or_equal_to?less_or_equal_tott'=Tree0.merge_to_sequencecomparator?order?greater_or_equal_to?less_or_equal_tott'letfold_resultt~init~f=Container.fold_result~fold~init~ftmoduleNamed=structincludeTree0.Namedletis_subset~comparatort1~of_:t2=Tree0.Named.is_subsett1~of_:t2~compare_elt:(cecomparator)~sexp_of_elt:comparator.Comparator.sexp_of_tletequal~comparatort1t2=Tree0.Named.equalt1t2~compare_elt:(cecomparator)~sexp_of_elt:comparator.Comparator.sexp_of_tendendmoduleUsing_comparator=structtypenonrec('elt,'cmp)t=('elt,'cmp)tincludeAccessorsletto_treet=t.treeletof_tree~comparatortree={comparator;tree}lett_of_sexp_direct~comparatora_of_sexpsexp=of_tree~comparator(Tree0.t_of_sexp_direct~compare_elt:comparator.comparea_of_sexpsexp)letempty~comparator={comparator;tree=Tree0.empty}moduleEmpty_without_value_restriction(Elt:Comparator.S1)=structletempty={comparator=Elt.comparator;tree=Tree0.empty}endletsingleton~comparatore={comparator;tree=Tree0.singletone}letunion_list~comparatorl=of_tree~comparator(Tree0.union_list~comparator~to_treel);;letof_sorted_array_unchecked~comparatorarray=lettree=Tree0.of_sorted_array_uncheckedarray~compare_elt:comparator.Comparator.comparein{comparator;tree};;letof_increasing_iterator_unchecked~comparator~len~f=of_tree~comparator(Tree0.of_increasing_iterator_unchecked~len~f);;letof_sorted_array~comparatorarray=Or_error.Monad_infix.(Tree0.of_sorted_arrayarray~compare_elt:comparator.Comparator.compare>>|funtree->{comparator;tree});;letof_list~comparatorl={comparator;tree=Tree0.of_listl~compare_elt:comparator.Comparator.compare};;letof_array~comparatora={comparator;tree=Tree0.of_arraya~compare_elt:comparator.Comparator.compare};;letstable_dedup_list~comparatorxs=Tree0.stable_dedup_listxs~compare_elt:comparator.Comparator.compare;;;letmap~comparatort~f={comparator;tree=Tree0.mapt.tree~f~compare_elt:comparator.Comparator.compare};;letfilter_map~comparatort~f={comparator;tree=Tree0.filter_mapt.tree~f~compare_elt:comparator.Comparator.compare;};;moduleTree=Treeendtype('elt,'cmp)comparator=(moduleComparator.Swithtypet='eltandtypecomparator_witness='cmp)letcomparator_s(typekcmp)t:(k,cmp)comparator=(modulestructtypet=ktypecomparator_witness=cmpletcomparator=t.comparatorend)letto_comparator(typeeltcmp)((moduleM):(elt,cmp)comparator)=M.comparatorletemptym=Using_comparator.empty~comparator:(to_comparatorm)letsingletonma=Using_comparator.singleton~comparator:(to_comparatorm)aletunion_listma=Using_comparator.union_list~comparator:(to_comparatorm)aletof_sorted_array_uncheckedma=Using_comparator.of_sorted_array_unchecked~comparator:(to_comparatorm)aletof_increasing_iterator_uncheckedm~len~f=Using_comparator.of_increasing_iterator_unchecked~comparator:(to_comparatorm)~len~fletof_sorted_arrayma=Using_comparator.of_sorted_array~comparator:(to_comparatorm)aletof_listma=Using_comparator.of_list~comparator:(to_comparatorm)aletof_arrayma=Using_comparator.of_array~comparator:(to_comparatorm)aletstable_dedup_listma=Using_comparator.stable_dedup_list~comparator:(to_comparatorm)aletmapma~f=Using_comparator.map~comparator:(to_comparatorm)a~fletfilter_mapma~f=Using_comparator.filter_map~comparator:(to_comparatorm)a~fmoduleM(Elt:sigtypettypecomparator_witnessend)=structtypenonrect=(Elt.t,Elt.comparator_witness)tendmoduletypeSexp_of_m=sigtypet[@@deriving_inlinesexp_of]includesig[@@@ocaml.warning"-32"]valsexp_of_t:t->Ppx_sexp_conv_lib.Sexp.tend[@@ocaml.doc"@inline"][@@@end]endmoduletypeM_of_sexp=sigtypet[@@deriving_inlineof_sexp]includesig[@@@ocaml.warning"-32"]valt_of_sexp:Ppx_sexp_conv_lib.Sexp.t->tend[@@ocaml.doc"@inline"][@@@end]includeComparator.Swithtypet:=tendmoduletypeCompare_m=sigendmoduletypeHash_fold_m=Hasher.Sletsexp_of_m__t(typeelt)(moduleElt:Sexp_of_mwithtypet=elt)t=sexp_of_tElt.sexp_of_t(fun_->Sexp.Atom"_")tletm__t_of_sexp(typeeltcmp)(moduleElt:M_of_sexpwithtypet=eltandtypecomparator_witness=cmp)sexp=Using_comparator.t_of_sexp_direct~comparator:Elt.comparatorElt.t_of_sexpsexpletcompare_m__t(moduleElt:Compare_m)t1t2=compare_directt1t2lethash_fold_m__t(typeelt)(moduleElt:Hash_fold_mwithtypet=elt)state=hash_fold_directElt.hash_fold_tstatelethash_m__tfoldert=letstate=hash_fold_m__tfolder(Hash.create())tinHash.get_hash_valuestatemodulePoly=structtypecomparator_witness=Comparator.Poly.comparator_witnesstypenonrec('elt,'cmp)set=('elt,comparator_witness)ttypenonrec'eltt=('elt,comparator_witness)ttypenonrec'elttree=('elt,comparator_witness)treetypenonrec'eltnamed=('elt,comparator_witness)Named.tincludeAccessorsletcomparator=Comparator.Poly.comparatorincludeUsing_comparator.Empty_without_value_restriction(Comparator.Poly)letsingletona=Using_comparator.singleton~comparatoraletunion_lista=Using_comparator.union_list~comparatoraletof_sorted_array_uncheckeda=Using_comparator.of_sorted_array_unchecked~comparatoraletof_increasing_iterator_unchecked~len~f=Using_comparator.of_increasing_iterator_unchecked~comparator~len~fletof_sorted_arraya=Using_comparator.of_sorted_array~comparatoraletof_lista=Using_comparator.of_list~comparatoraletof_arraya=Using_comparator.of_array~comparatoraletstable_dedup_lista=Using_comparator.stable_dedup_list~comparatoraletmapa~f=Using_comparator.map~comparatora~fletfilter_mapa~f=Using_comparator.filter_map~comparatora~fletof_treetree={comparator;tree}letto_treet=t.treeend