123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132(******************************************************************************)(* *)(* Feat *)(* *)(* François Pottier, Inria Paris *)(* *)(* Copyright Inria. All rights reserved. This file is distributed under the *)(* terms of the MIT license, as described in the file LICENSE. *)(******************************************************************************)openIFSeqSigmoduleMake(IFSeq:IFSEQ_EXTENDED)=structmoduleIFSeq=IFSeq(* Core combinators. *)type'aenum=int->'aIFSeq.seqletempty:'aenum=fun_s->IFSeq.emptyletzero=emptyletenum(xs:'aIFSeq.seq):'aenum=funs->ifs=0thenxselseIFSeq.emptyletjust(x:'a):'aenum=(* enum (IFSeq.singleton x) *)funs->ifs=0thenIFSeq.singletonxelseIFSeq.emptyletpay(enum:'aenum):'aenum=funs->ifs=0thenIFSeq.emptyelseenum(s-1)letsum(enum1:'aenum)(enum2:'aenum):'aenum=funs->IFSeq.sum(enum1s)(enum2s)let(++)=sumletexists(xs:'alist)(enum:'a->'benum):'benum=funs->IFSeq.existsxs(funx->enumxs)(* [up i j] is the list of the integers of [i] included up to [j] included. *)letrecupij=ifi<=jtheni::up(i+1)jelse[](* This definition of [product] may seem slightly inefficient, as it builds
intermediate lists, but this is essentially irrelevant when it is used
in the definition of a memoized function. The overhead is paid only once. *)letproduct(enum1:'aenum)(enum2:'benum):('a*'b)enum=funs->IFSeq.bigsum(List.map(funs1->lets2=s-s1inIFSeq.product(enum1s1)(enum2s2))(up0s))let(**)=productletbalanced_product(enum1:'aenum)(enum2:'benum):('a*'b)enum=funs->ifsmod2=0thenlets=s/2inIFSeq.product(enum1s)(enum2s)elselets=s/2inIFSeq.sum(IFSeq.product(enum1s)(enum2(s+1)))(IFSeq.product(enum1(s+1))(enum2s))let(*-*)=balanced_productletmap(phi:'a->'b)(enum:'aenum):'benum=funs->IFSeq.mapphi(enums)(* -------------------------------------------------------------------------- *)(* Convenience functions. *)letfinite(xs:'alist):'aenum=List.fold_left(++)zero(List.mapjustxs)letbool:boolenum=justfalse++justtrue(* also: [finite [false; true]] *)letlist(elem:'aenum):'alistenum=letcons(x,xs)=x::xsinFix.Memoize.Int.fix(funlist->just[]++pay(mapcons(elem**list)))letdlistfixelem=letconsxxs=x::xsinfix(fundlistenv->just[]++pay(exists(elemenv)(fun(x,env')->map(consx)(dlistenv'))))(* -------------------------------------------------------------------------- *)(* Sampling. *)letrecsamplemeijk=ifi<jthenIFSeq.samplem(ei)(fun()->sampleme(i+1)jk())elsekend