12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544(***********************************************************************)(* *)(* 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<0inletreclooploweruppercompare_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=function|Empty->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=matchlwith|Empty->0|Leaf_->1|Node(_,_,_,h,_)->hinlethr=matchrwith|Empty->0|Leaf_->1|Node(_,_,_,h,_)->hinleth=ifhl>=hrthenhl+1elsehr+1inifh=1thenLeafvelse(letsl=matchlwith|Empty->0|Leaf_->1|Node(_,_,_,_,s)->sinletsr=matchrwith|Empty->0|Leaf_->1|Node(_,_,_,_,s)->sinNode(l,v,r,h,sl+sr+1));;(* 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)kEmpty|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~f0;;letof_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)<0thenfuni->array.(i)elsefuni->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=matchlwith|Empty->0|Leaf_->1|Node(_,_,_,h,_)->hinlethr=matchrwith|Empty->0|Leaf_->1|Node(_,_,_,h,_)->hinifhl>hr+2then(matchlwith|Empty->assertfalse|Leaf_->assertfalse(* because h(l)>h(r)+2 and h(leaf)=1 *)|Node(ll,lv,lr,_,_)->ifheightll>=heightlrthencreatelllv(createlrvr)else(matchlrwith|Empty->assertfalse|Leaflrv->assert(is_emptyll);create(createlllvEmpty)lrv(createEmptyvr)|Node(lrl,lrv,lrr,_,_)->create(createlllvlrl)lrv(createlrrvr)))elseifhr>hl+2then(matchrwith|Empty->assertfalse|Leafrv->create(createlvEmpty)rvEmpty|Node(rl,rv,rr,_,_)->ifheightrr>=heightrlthencreate(createlvrl)rvrrelse(matchrlwith|Empty->assertfalse|Leafrlv->assert(is_emptyrr);create(createlvEmpty)rlv(createEmptyrvrr)|Node(rll,rlv,rlr,_,_)->create(createlvrll)rlv(createrlrrvrr)))else(leth=ifhl>=hrthenhl+1elsehr+1inletsl=matchlwith|Empty->0|Leaf_->1|Node(_,_,_,_,s)->sinletsr=matchrwith|Empty->0|Leaf_->1|Node(_,_,_,_,s)->sinifh=1thenLeafvelseNode(l,v,r,h,sl+sr+1));;(* 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)intryauxtwith|Same->t;;(* Same as create and bal, but no assumptions are made on the relative heights of l and
r. *)letrecjoinlvr~compare_elt=matchl,rwith|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"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"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~frighta))inmatchfold_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=matcht1,t2with|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=matcht1,t2with|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=0thenEmpty,Somev,Emptyelseifc<0thenEmpty,None,LeafvelseLeafv,None,Empty|Node(l,v,r,_,_)->letc=compare_eltxvinifc=0thenl,Somev,relseifc<0then(letll,maybe_elt,rl=splitlinll,maybe_elt,joinrlvr~compare_elt)else(letlr,maybe_elt,rr=splitrinjoinlvlr~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)intryauxtwith|Same->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))intryauxtiwith|Same->t;;letunions1s2~compare_elt=letrecunions1s2=ifphys_equals1s2thens1else(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_eltelse(letl2,_,r2=splits2v1~compare_eltinjoin(unionl1l2)v1(unionr1r2)~compare_elt)elseifh1=1thenadds2v1~compare_eltelse(letl1,_,r1=splits1v2~compare_eltinjoin(unionl1l2)v2(unionr1r2)~compare_elt))inunions1s2;;letunion_list~comparator~to_treexs=letcompare_elt=comparator.Comparator.compareinList.foldxs~init:empty~f:(funacx->unionac(to_treex)~compare_elt);;letinters1s2~compare_elt=letrecinters1s2=ifphys_equals1s2thens1else(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_elt))ininters1s2;;letdiffs1s2~compare_elt=letrecdiffs1s2=ifphys_equals1s2thenEmptyelse(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_elt))indiffs1s2;;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<>0thencelseifphys_equalr1r2thenloope1e2elseloop(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=0then(f(`Both(a1,a2));loop(constree1enum1)(constree2enum2))elseifcompare_result<0then(f(`Lefta1);loop(constree1enum1)t2)else(f(`Righta2);loopt1(constree2enum2))inloopt1t2;;letsymmetric_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=0then(letnext_state=ifphys_equaltree1tree2thenenum1,enum2elseconstree1enum1,constree2enum2inSkipnext_state)elseifcompare_result<0thenYield(Firsta1,(constree1enum1,right))elseYield(Seconda2,(left,constree2enum2))inSequence.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;;letrecfind_first_satisfyingt~f=matchtwith|Empty->None|Leafv->iffvthenSomevelseNone|Node(l,v,r,_,_)->iffvthen(matchfind_first_satisfyingl~fwith|None->Somev|Some_asx->x)elsefind_first_satisfyingr~f;;letrecfind_last_satisfyingt~f=matchtwith|Empty->None|Leafv->iffvthenSomevelseNone|Node(l,v,r,_,_)->iffvthen(matchfind_last_satisfyingr~fwith|None->Somev|Some_asx->x)elsefind_last_satisfyingl~f;;letbinary_searcht~comparehowv=matchhowwith|`Last_strictly_less_than->find_last_satisfyingt~f:(funx->comparexv<0)|`Last_less_than_or_equal_to->find_last_satisfyingt~f:(funx->comparexv<=0)|`First_equal_to->(matchfind_first_satisfyingt~f:(funx->comparexv>=0)with|Somexaseltwhencomparexv=0->elt|None|Some_->None)|`Last_equal_to->(matchfind_last_satisfyingt~f:(funx->comparexv<=0)with|Somexaseltwhencomparexv=0->elt|None|Some_->None)|`First_greater_than_or_equal_to->find_first_satisfyingt~f:(funx->comparexv>=0)|`First_strictly_greater_than->find_first_satisfyingt~f:(funx->comparexv>0);;letbinary_search_segmentedt~segment_ofhow=letis_leftx=matchsegment_ofxwith|`Left->true|`Right->falseinletis_rightx=not(is_leftx)inmatchhowwith|`Last_on_left->find_last_satisfyingt~f:is_left|`First_on_right->find_first_satisfyingt~f:is_right;;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:(matchorderwith|`Increasing->comparator.compare|`Decreasing->Fn.flipcomparator.compare);;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->(matchl1,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|_,_->false)|Node(l1,v1,r1,_,_),(Node(l2,v2,r2,_,_)ast2)->letc=compare_eltv1v2inifc=0thenphys_equals1s2||(is_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;;letrecare_disjoints1s2~compare_elt=matchs1,s2with|Empty,_|_,Empty->true|Leafelt,other_set|other_set,Leafelt->not(memother_setelt~compare_elt)|Node(l1,v1,r1,_,_),t2->ifphys_equals1s2thenfalseelse(matchsplitt2v1~compare_eltwith|l2,None,r2->are_disjointl1l2~compare_elt&&are_disjointr1r2~compare_elt|_,Some_,_->false);;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->ifpvthenaddtv~compare_elt,felset,addfv~compare_elt|Node(l,v,r,_,_)->part(part(ifpvthenaddtv~compare_elt,felset,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_exn=letnot_found=Not_found_s(Atom"Set.choose_exn: empty set")inletchoose_exnt=matchchoosetwith|None->raisenot_found|Somev->vin(* named to preserve symbol in compiled binary *)choose_exn;;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_classeselse(letx=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,_,_)->iffvthenSomevelse(matchfindl~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>=sthenNoneelse(letl_size=lengthlinletc=Poly.compareil_sizeinifc<0thennthlielseifc=0thenSomevelsenthr(i-l_size-1));;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.lengthlstthensetelse(letset=refemptyinList.iter2_exnlstelt_lst~f:(funel_sexpel->ifmem!setel~compare_eltthenof_sexp_error"Set.t_of_sexp: duplicate element in set"el_sexpelseset:=add!setel~compare_elt);assertfalse)|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()else(letinvalid_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]));;letequals1s2~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);;letare_disjointt1t2=Tree0.are_disjointt1.treet2.tree~compare_elt:(compare_eltt1);;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_t;;letequalt1t2=Or_error.combine_errors_unit[is_subsett1~of_:t2;is_subsett2~of_:t1];;endletpartition_tft~f=lettree_t,tree_f=Tree0.partition_tft.tree~f~compare_elt:(compare_eltt)inlikettree_t,likettree_f;;letsplitta=lettree1,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.tree;;letbinary_searcht~comparehowv=Tree0.binary_searcht.tree~comparehowvletbinary_search_segmentedt~segment_ofhow=Tree0.binary_search_segmentedt.tree~segment_ofhow;;letmerge_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'.tree;;lethash_fold_directhash_fold_keystatet=Tree0.hash_fold_t_ignoring_structurehash_fold_keystatet.tree;;endincludeAccessorsletcompare__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_sexpsexp;;letempty_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)letare_disjoint~comparatort1t2=Tree0.are_disjointt1t2~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~f;;letof_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_tot;;letbinary_search~comparator:_t~comparehowv=Tree0.binary_searcht~comparehowvletbinary_search_segmented~comparator:_t~segment_ofhow=Tree0.binary_search_segmentedt~segment_ofhow;;letmerge_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_t;;letequal~comparatort1t2=Tree0.Named.equalt1t2~compare_elt:(cecomparator)~sexp_of_elt:comparator.Comparator.sexp_of_t;;endendmoduleUsing_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)a;;letof_increasing_iterator_uncheckedm~len~f=Using_comparator.of_increasing_iterator_unchecked~comparator:(to_comparatorm)~len~f;;letof_sorted_arrayma=Using_comparator.of_sorted_array~comparator:(to_comparatorm)a;;letof_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)a;;letmapma~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]valsexp_of_t:t->Ppx_sexp_conv_lib.Sexp.t[@@@end]endmoduletypeM_of_sexp=sigtypet[@@deriving_inlineof_sexp]valt_of_sexp:Ppx_sexp_conv_lib.Sexp.t->t[@@@end]includeComparator.Swithtypet:=tendmoduletypeCompare_m=sigendmoduletypeEqual_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"_")t;;letm__t_of_sexp(typeeltcmp)(moduleElt:M_of_sexpwithtypet=eltandtypecomparator_witness=cmp)sexp=Using_comparator.t_of_sexp_direct~comparator:Elt.comparatorElt.t_of_sexpsexp;;letcompare_m__t(moduleElt:Compare_m)t1t2=compare_directt1t2letequal_m__t(moduleElt:Equal_m)t1t2=equalt1t2lethash_fold_m__t(typeelt)(moduleElt:Hash_fold_mwithtypet=elt)state=hash_fold_directElt.hash_fold_tstate;;lethash_m__tfoldert=letstate=hash_fold_m__tfolder(Hash.create())tinHash.get_hash_valuestate;;modulePoly=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~comparatora;;letof_increasing_iterator_unchecked~len~f=Using_comparator.of_increasing_iterator_unchecked~comparator~len~f;;letof_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