123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2020 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. *)(* *)(*****************************************************************************)(* Our favorite "ring" *)moduleR=FloatmoduletypeS=sigtypettypebasisvalis_empty:t->boolvalcompare:t->t->intvalequal:t->t->boolvalzero:tvaladd:t->t->tvalsmul:R.t->t->tvalneg:t->tvalfold:(basis->R.t->'b->'b)->t->'b->'bvaliter:(basis->R.t->unit)->t->unitvalfind_map:(basis->R.t->'resoption)->t->'resoptionvalset:t->basis->R.t->tvalget_exn:t->basis->R.tvalget_opt:t->basis->R.toptionvalget:t->basis->R.tvalswap:t->basis->basis->tvalof_list:(basis*R.t)list->tvalto_list:t->(basis*R.t)listvalpp:pp_basis:(Format.formatter->basis->unit)->pp_element:(Format.formatter->R.t->unit)->Format.formatter->t->unitmoduleOp:sigval(.%[]):t->basis->R.tval(.%[]<-):t->basis->R.t->tval(+):t->t->tval(*):R.t->t->tendendmoduleMake(M:Map.S):Swithtypet=R.tM.tandtypebasis=M.key=structtypet=R.tM.ttypebasis=M.keyletis_empty=M.is_emptyletcompare:t->t->int=M.compareR.compareletequal:t->t->bool=M.equalR.equalletzero=M.emptyletaddvec1vec2=M.union(fun_elti1i2->letres=R.addi1i2inifR.compareresR.zero=0thenNoneelseSomeres)vec1vec2letsmulcoeffvec=ifR.comparecoeffR.zero=0thenzeroelseM.map(funx->R.mulcoeffx)vecletnegvec=M.mapR.negvecletfold=M.foldletiter=M.iterletfind_mapfvec=Seq.find_map(fun(basis,elt)->fbasiselt)@@M.to_seqvecletsetvecie=ifR.compareeR.zero=0thenM.removeivecelseM.addievecletget_optveci=M.findivecletget_exnveci=WithExceptions.Option.get~loc:__LOC__@@M.findivecletgetveci=Option.value~default:R.zero@@M.findivecletswapvecij=match(M.find_optivec,M.find_optjvec)with|None,None->vec|Someelt,None->letvec=M.removeivecinsetvecjelt|None,Someelt->letvec=M.removejvecinsetvecielt|Somee1,Somee2->letvec=setvecie2insetvecje1letof_listl=M.of_seq@@List.to_seqlletto_list=M.bindingsletpp~pp_basis~pp_elementfmtrvec=matchM.bindingsvecwith|[]->Format.fprintffmtr"∅"|bindings->Format.pp_print_list~pp_sep:(funfmtr()->Format.fprintffmtr";@,")(funfmtr(k,v)->Format.fprintffmtr"%a ↦ %a"pp_basiskpp_elementv)fmtrbindingsmoduleOp=structlet(.%[])vecx=getvecxlet(.%[]<-)vecxv=setvecxvlet(+)=addlet(*)=smulendendmoduleString=Make(String.Map)