123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123(**************************************************************************)(* *)(* OCaml *)(* *)(* 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 GNU Lesser General Public License version 2.1, with the *)(* special exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)type('k,'v)t=Empty|Nodeof('k,'v)t*'k*'v*('k,'v)t*intletempty=Emptyletheight=functionEmpty->0|Node(_,_,_,_,h)->hletcreatelxdr=lethl=heightlandhr=heightrinNode(l,x,d,r,(ifhl>=hrthenhl+1elsehr+1))letballxdr=lethl=heightlandhr=heightrinifhl>hr+1thenmatchlwith|Node(ll,lv,ld,lr,_)whenheightll>=heightlr->createlllvld(createlrxdr)|Node(ll,lv,ld,Node(lrl,lrv,lrd,lrr,_),_)->create(createlllvldlrl)lrvlrd(createlrrxdr)|_->assertfalseelseifhr>hl+1thenmatchrwith|Node(rl,rv,rd,rr,_)whenheightrr>=heightrl->create(createlxdrl)rvrdrr|Node(Node(rll,rlv,rld,rlr,_),rv,rd,rr,_)->create(createlxdrll)rlvrld(createrlrrvrdrr)|_->assertfalseelsecreatelxdrletrecaddxdata=functionEmpty->Node(Empty,x,data,Empty,1)|Node(l,v,d,r,h)->letc=comparexvinifc=0thenNode(l,x,data,r,h)elseifc<0thenbal(addxdatal)vdrelseballvd(addxdatar)letrecfindx=functionEmpty->raiseNot_found|Node(l,v,d,r,_)->letc=comparexvinifc=0thendelsefindx(ifc<0thenlelser)letrecfind_str(x:string)=functionEmpty->raiseNot_found|Node(l,v,d,r,_)->letc=comparexvinifc=0thendelsefind_strx(ifc<0thenlelser)letrecmemx=functionEmpty->false|Node(l,v,_d,r,_)->letc=comparexvinc=0||memx(ifc<0thenlelser)letrecmerget1t2=match(t1,t2)with(Empty,t)->t|(t,Empty)->t|(Node(l1,v1,d1,r1,_h1),Node(l2,v2,d2,r2,_h2))->ball1v1d1(bal(merger1l2)v2d2r2)letrecremovex=functionEmpty->Empty|Node(l,v,d,r,_h)->letc=comparexvinifc=0thenmergelrelseifc<0thenbal(removexl)vdrelseballvd(removexr)letreciterf=functionEmpty->()|Node(l,v,d,r,_)->iterfl;fvd;iterfrletrecmapf=functionEmpty->Empty|Node(l,v,d,r,h)->Node(mapfl,v,fvd,mapfr,h)letrecfoldfmaccu=matchmwith|Empty->accu|Node(l,v,d,r,_)->foldfr(fvd(foldflaccu))openFormatletprintprint_keyprint_datappftbl=letprint_tblppftbl=iter(funkd->fprintfppf"@[<2>%a ->@ %a;@]@ "print_keykprint_datad)tblinfprintfppf"@[<hv 2>[[%a]]@]"print_tbltbl