Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file rSet.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110typet=Range.tlist(* retained in canonical form *)typerange=Range.tletempty=[]letsizet=List.fold_left~f:(funansv->ans+Range.sizev)~init:0tletis_emptyt=sizet=0(* A canonical interval list is one in which adjacent intervals have gap between them and intervals retained in ascending order according to their coordinates. *)letrecis_canonical(vl:Range.tlist):bool=matchvlwith|[]|_::[]->true|u::(v::_astail)->u.Range.hi<v.Range.lo&&is_canonicaltailletto_canonical(vl:Range.tlist):Range.tlist=(* Order relation such that subset and after are larger. *)letcompare_intervalsuv=matchRange.compare_containmentuvwith|Somex->-x|None->matchRange.compare_positionaluvwith|Somex->x|None->assertfalseinletvl=List.sort~compare:compare_intervalsvlinletreccanonizeansvl=matchvlwith|[]->ans|v::[]->v::ans|u::(v::vlastail)->ifPoly.equaluvthencanonizeanstailelseifRange.supersetuvthencanonizeans(u::vl)elseifRange.beforeuvthenmatchRange.unionuvwith|`Jointuv->canonizeans(uv::vl)|`Disjoint(u,_)->canonize(u::ans)tailelseinvalid_arg"impossible to get here"inletans=List.rev(canonize[]vl)inassert(is_canonicalans);ansletof_range_listl=letfacc(x,y)=ifx<=ythen(Range.make_unsafexy)::accelseaccinto_canonical(List.fold~f~init:[]l)letto_range_listt=List.map~f:(fun{Range.lo;hi}->lo,hi)tletto_listt=List.concat(List.map~f:Range.to_listt)letunionst=to_canonical(s@t)(* better implementation possible *)letinterst=letrecloopansst=match(s,t)with|(_,[])->ans|([],_)->ans|((u::sasul),(v::tasvl))->ifu.Range.lo>v.Range.hithenloopansultelseifu.Range.hi<v.Range.lothenloopanssvlelsematchRange.intersectuvwith|None->invalid_arg"impossible to get here"|Somew->matchStdlib.compareu.Range.hiv.Range.hiwith|-1->loop(w::ans)svl|0->loop(w::ans)st|1->loop(w::ans)ult|_->invalid_arg"impossible to get here"into_canonical(loop[]st)(* canoninicity could maybe be obtained simply by List.rev *)letdiffst=letrecloopansst=match(s,t)with|(_,[])->ans@(List.revs)|([],_)->ans|((u::sasul),(v::tasvl))->ifu.Range.lo>v.Range.hithenloopansultelseifu.Range.hi<v.Range.lothenloop(u::ans)svlelsematchRange.intersectuvwith|None->invalid_arg"impossible to get here"|Somew->letu_pre=Range.makeu.Range.lo(w.Range.lo-1)|>Result.okinletu_post=Range.make(w.Range.hi+1)u.Range.hi|>Result.okin(* v_pre = Range.make_opt v.Range.lo (w.Range.lo - 1)
** v_pre not needed, note also that u_pre and v_pre cannot both be None *)letv_post=Range.make(w.Range.hi+1)v.Range.hi|>Result.okinletans=matchu_prewithNone->ans|Somex->x::ansinlets=matchu_postwithNone->s|Somex->x::sinlett=matchv_postwithNone->t|Somex->x::tinloopansstinto_canonical(loop[]st)letsubsetst=is_empty(diffst)