123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2021 Trili Tech, <contact@trili.tech> *)(* *)(* 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. *)(* *)(*****************************************************************************)moduleNon_empty=structtype'at={head:'a;tail:'alist}exceptionEmpty_listletof_pair(x,y)={head=x;tail=[y]}letof_list_exnx=matchxwith[]->raiseEmpty_list|x::xs->{head=x;tail=xs}letlength:typea.at->int=fun{tail;_}->List.lengthtail+1letnth_exn{head;tail}m=matchmwith|0->head|n->(matchList.nth_opttail(n-1)with|Somex->x|None->raiseEmpty_list)endmoduleFunctor=structmoduletypeS=sigtype'atvalmap:('a->'b)->'at->'btendendmoduleApplicative=structmoduletypeS=sigincludeFunctor.Svalreturn:'a->'atvalmap2:('a->'b->'c)->'at->'bt->'ctvalproduct:'at->'bt->('a*'b)tendendmoduleMonad=structmoduletypeS=sigincludeApplicative.Svaljoin:'att->'atvalbind:'at->('a->'bt)->'btendmoduleSyntax(M:S)=structlet(let*)=M.bindlet(let+)xf=M.mapfxlet(and+)=M.productlet(and*)=M.productendendmoduleIdentity=structtype'at='aletreturnx=xletmapfx=fxletmap2fxy=fxyletjoinx=xletbindxf=fxletproductxy=(x,y)letrunx=xendmoduleStateful_gen=structmoduletypeS=sigtype'amincludeMonad.Svalbool:booltvalnat_less_than:int->inttvalsmall_int:inttvalreplicate:int->'at->'alisttvalreplicate_for_each:'alist->'bt->('a*'b)listtvaltraverse:('a->'bt)->'alist->'blisttvaloneof:'atNon_empty.t->'atvalsmall_list:'at->'alisttvalopt:'at->'aoptiontvalchar_readable:chartvalstring_readable:stringtvallift:'am->'atvalto_qcheck_gen:'at->'amQCheck.Gen.tendmoduleMake(F:Monad.S)=structtype'am='aF.ttype'at=Random_pure.t->'aF.tletliftf_=fletreturnx_=F.returnxletbindmfg=letg1,g2=Random_pure.splitginF.bind(mg1)(funa->fag2)let(let*)=bindletmapfx=let*a=xinreturn(fa)letmap2fxyg=letg1,g2=Random_pure.splitginF.map2f(xg1)(yg2)letjoinx=let*y=xinyletproductxy=map2(funxy->(x,y))xylet(and+)=productlet(let+)xf=mapfxletboolg=F.return@@Random_pure.boolgletnat_less_thanmg=F.return@@Random_pure.intgmletsmall_intg=F.return@@Random_pure.intg32letreplicatemf=letrecloopn=matchnwith|0->return[]|_->let+x=fand+xs=loop(n-1)inx::xsinloopmletrectraversefxs=matchxswith|[]->return[]|x::xs->map2(funxxs->x::xs)(fx)(traversefxs)letreplicate_for_eachxsf=traverse(funa->let+b=fin(a,b))xsletoneofxs=let*i=nat_less_than(Non_empty.lengthxs)inNon_empty.nth_exnxsiletsmall_listg=let*n=small_intinreplicatengletoptg=oneof(Non_empty.of_list_exn[returnNone;map(funx->Somex)g])letchar_readable=let+n=nat_less_than26inchar_of_int@@(65+n)letstring_readable=let+l=small_listchar_readableinString.of_seq(List.to_seql)letto_qcheck_gengstd_random_state=g(Random_pure.of_seed(Stdlib.Random.State.int64std_random_stateStdlib.Int64.max_int))endmoduleDefault=Make(Identity)end