Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file alias.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2021 Nomadic Labs, <contact@nomadic-labs.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)moduletypeS=sigtypemasstype'attype'astatevalcreate:('a*mass)array->'astatevalsampler:'astate->'atendmoduleMake(Mass:Basic_intf.Ring)(Mass_ord:Basic_intf.Infix_orderwithtype'am:='aandtypet=Mass.t)(M:Basic_intf.Monad)(Sampler:sigtype'at='aM.tvalmass:Mass.t->Mass.ttvalint:int->inttend):Swithtypemass=Mass.tandtype'at='aM.t=structtypemass=Mass.ttype'at='aM.ttype'astate={total:Mass.t;support:'aarray;p:Mass.tarray;alias:intarray}letrecinit_looptotalpaliassmalllarge=match(small,large)with|([],_)->List.iter(fun(_,i)->Array.setpitotal)large|(_,[])->(* This can only happen because of numerical inaccuracies when using
eg [Mass.t = float] *)List.iter(fun(_,i)->Array.setpitotal)small|((qi,i)::small',(qj,j)::large')->Array.setpiqi;Array.setaliasij;letqj'=Mass.sub(Mass.addqiqj)totalinifMass_ord.(qj'<total)theninit_looptotalpalias((qj',j)::small')large'elseinit_looptotalpaliassmall'((qj',j)::large')letsupport:fallback:'a->length:int->('a*Mass.t)list->'aArray.t=fun~fallback~lengthmeasure->leta=Array.makelengthfallbackinList.iteri(funi(elt,_)->Array.setaielt)measure;aletcheck_and_cleanupmeasure=let(total,measure)=Array.fold_left(fun((total,m)asacc)((_,p)aspoint)->ifMass_ord.(Mass.zero<p)then(Mass.addtotalp,point::m)elseifMass_ord.(p<Mass.zero)theninvalid_arg"create"else(* p = zero: drop point *)acc)(Mass.zero,[])measureinmatchmeasurewith|[]->invalid_arg"create"|(fallback,_)::_->(fallback,total,measure)(* NB: duplicate elements in the support are not merged;
the algorithm should still function correctly. *)letcreate(measure:('a*Mass.t)array)=let(fallback,total,measure)=check_and_cleanupmeasureinletlength=List.lengthmeasureinletn=Mass.of_intlengthinlet(_,small,large)=List.fold_left(fun(i,small,large)(_,p)->letq=Mass.mulpninifMass_ord.(q<total)then(i+1,(q,i)::small,large)else(i+1,small,(q,i)::large))(0,[],[])measureinletsupport=support~fallback~lengthmeasureinletp=Array.makelengthtotalinletalias=Array.makelength(-1)ininit_looptotalpaliassmalllarge;{total;support;p;alias}letsampler{total;support;p;alias}=letopenM.Infixinletn=Array.lengthsupportinSampler.intn>>=funi->letp=Array.getpiinSampler.masstotal>>=funelt->ifMass_ord.(elt<p)thenM.return(Array.getsupporti)elseletj=Array.getaliasiinassert(j>=0);M.return(Array.getsupportj)end