123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943(* This file is free software, part of dolmen. See file "LICENSE" for more information *)(* Type definitions *)(* ************************************************************************* *)(* private aliases *)typehash=inttypeindex=inttype'atag='aTag.t(* Extensible variant type for builtin operations *)typebuiltin=..(* Type for first order types *)typettype=Type(* Identifiers, parametrized by the kind of the type of the variable and
the lengths of the expected arguments lists *)type'tyid={ty:'ty;name:string;index:index;(** unique *)builtin:builtin;mutabletags:Tag.map;}(* The type of functions *)type('ttype,'ty)function_type={fun_vars:'ttypeidlist;(* prenex forall *)fun_args:'tylist;fun_ret:'ty;}(* Representation of types *)typety_var=ttypeidandty_const=(unit,ttype)function_typeidandty_descr=|Varofty_var|Appofty_const*tylistandty={as_:ty_varoption;mutabledescr:ty_descr;mutablehash:hash;(* lazy hash *)mutabletags:Tag.map;}(* Terms and formulas *)typeterm_var=tyidandterm_const=(ttype,ty)function_typeidandpattern=termandterm_descr=|Varofterm_var|Appofterm_const*tylist*termlist|Binderofbinder*term|Matchofterm*(pattern*term)listandbinder=|Existsofty_varlist*term_varlist|Forallofty_varlist*term_varlist|Letinof(term_var*term)listandterm={ty:ty;descr:term_descr;mutablehash:hash;mutabletags:Tag.map;}(* Alias for dolmen_loop and others who allow to have different types
for terms and formulas. *)typeformula=term(* Builtins *)(* ************************************************************************* *)typebuiltin+=Base|Wildcardtypebuiltin+=Prop|Unit|Univtypebuiltin+=Coerciontypebuiltin+=|True|False|Equal|Distinct|Neg|And|Or|Nand|Nor|Xor|Imply|Equivtypebuiltin+=Itetypebuiltin+=|Testerof{cstr:term_const;}|Constructorof{adt:ty_const;case:int;}|Destructorof{adt:ty_const;cstr:term_const;case:int;field:int;}(* arithmetic *)typebuiltin+=|Int|Integerofstring|Rat|Rationalofstring|Real|Decimalofstring|Lt|Leq|Gt|Geq|Minus|Add|Sub|Mul|Div|Div_e|Modulo_e|Div_t|Modulo_t|Div_f|Modulo_f|Abs|Divisible|Is_int|Is_rat|Floor|Ceiling|Truncate|Round(* arrays *)typebuiltin+=|Array|Store|Select(* Bitvectors *)typebuiltin+=|Bitvofint|Bitvecofstring|Bitv_concat|Bitv_extractofint*int|Bitv_repeat|Bitv_zero_extend|Bitv_sign_extend|Bitv_rotate_rightofint|Bitv_rotate_leftofint|Bitv_not|Bitv_and|Bitv_or|Bitv_nand|Bitv_nor|Bitv_xor|Bitv_xnor|Bitv_comp|Bitv_neg|Bitv_add|Bitv_sub|Bitv_mul|Bitv_udiv|Bitv_urem|Bitv_sdiv|Bitv_srem|Bitv_smod|Bitv_shl|Bitv_lshr|Bitv_ashr|Bitv_ult|Bitv_ule|Bitv_ugt|Bitv_uge|Bitv_slt|Bitv_sle|Bitv_sgt|Bitv_sge(* Floats *)typebuiltin+=|Floatofint*int|RoundingMode|Fpofint*int|RoundNearestTiesToEven|RoundNearestTiesToAway|RoundTowardPositive|RoundTowardNegative|RoundTowardZero|Plus_infinityofint*int|Minus_infinityofint*int|Plus_zeroofint*int|Minus_zeroofint*int|NaNofint*int|Fp_absofint*int|Fp_negofint*int|Fp_addofint*int|Fp_subofint*int|Fp_mulofint*int|Fp_divofint*int|Fp_fmaofint*int|Fp_sqrtofint*int|Fp_remofint*int|Fp_roundToIntegralofint*int|Fp_minofint*int|Fp_maxofint*int|Fp_leqofint*int|Fp_ltofint*int|Fp_geqofint*int|Fp_gtofint*int|Fp_eqofint*int|Fp_isNormalofint*int|Fp_isSubnormalofint*int|Fp_isZeroofint*int|Fp_isInfiniteofint*int|Fp_isNaNofint*int|Fp_isNegativeofint*int|Fp_isPositiveofint*int|Ieee_format_to_fpofint*int|Fp_to_fpofint*int*int*int|Real_to_fpofint*int|Sbv_to_fpofint*int*int|Ubv_to_fpofint*int*int|To_ubvofint*int*int|To_sbvofint*int*int|To_realofint*int(* Strings *)typebuiltin+=|String|Strofstring|Str_length|Str_at|Str_to_code|Str_of_code|Str_is_digit|Str_to_int|Str_of_int|Str_concat|Str_sub|Str_index_of|Str_replace|Str_replace_all|Str_replace_re|Str_replace_re_all|Str_is_prefix|Str_is_suffix|Str_contains|Str_lexicographic_strict|Str_lexicographic_large|Str_in_re(* String Regular languages *)typebuiltin+=|String_RegLan|Re_empty|Re_all|Re_allchar|Re_of_string|Re_range|Re_concat|Re_union|Re_inter|Re_star|Re_cross|Re_complement|Re_diff|Re_option|Re_powerofint|Re_loopofint*int(* Exceptions *)(* ************************************************************************* *)exceptionBad_ty_arityofty_const*tylistexceptionBad_term_arityofterm_const*tylist*termlistexceptionFilter_failed_tyofstring*ty*stringexceptionFilter_failed_termofstring*term*stringexceptionType_already_definedofty_constexceptionRecord_type_expectedofty_const(* Tags *)(* ************************************************************************* *)moduleTags=structtype'at='atagtypepos=Pretty.postypename=Pretty.nameletpos=Tag.create()letname=Tag.create()letrwrt=Tag.create()letexacts=Pretty.Exactsletinfix=Pretty.Infixletprefix=Pretty.Prefixletnamed=Tag.create()lettriggers=Tag.create()letbound=Tag.create()end(* Printing *)(* ************************************************************************* *)modulePrint=structtype'at=Format.formatter->'a->unitletprint_index=reffalseletpos:Pretty.postag=Tags.posletname:Pretty.nametag=Tags.nameletreturnfmt_strout()=Format.fprintfout"%(%)"fmt_strletttypefmtType=Format.fprintffmt"Type"letpp_indexfmt(v:_id)=Format.fprintffmt"/%d"v.indexletidfmt(v:_id)=matchTag.lastv.tagsnamewith|Some(Pretty.Exacts|Pretty.Renameds)->Format.fprintffmt"%s"s|None->if!print_indexthenFormat.fprintffmt"%s%a"v.name(Fmt.styled(`Fg(`Hi`Black))pp_index)velseFormat.fprintffmt"%s"v.nameletrecty_descrfmt(descr:ty_descr)=matchdescrwith|Varv->idfmtv|App(f,[])->idfmtf|App(f,l)->beginmatchTag.lastf.tagsposwith|SomePretty.Prefix->Format.fprintffmt"@[<hov 2>%a %a@]"idf(Format.pp_print_list~pp_sep:(return"")ty)l|SomePretty.InfixwhenList.lengthl>=2->letpp_sepfmt()=Format.fprintffmt" %a@ "idfinFormat.fprintffmt"@[<hov 2>%a@]"(Format.pp_print_list~pp_septy)l|None|SomePretty.Infix->Format.fprintffmt"@[<hov 2>%a(%a)@]"idf(Format.pp_print_list~pp_sep:(return",@ ")ty)lendandtyfmt(t:ty)=matcht.as_with|None->ty_descrfmtt.descr|Somev->Format.fprintffmt"(%a@ as@ %a)"ty_descrt.descridvletparamsfmt=function|[]->()|l->Format.fprintffmt"∀ @[<hov>%a@].@ "(Format.pp_print_list~pp_sep:(return",@ ")id)lletsignatureprintfmtf=matchf.fun_argswith|[]->Format.fprintffmt"@[<hov 2>%a%a@]"paramsf.fun_varsprintf.fun_ret|l->Format.fprintffmt"@[<hov 2>%a%a ->@ %a@]"paramsf.fun_vars(Format.pp_print_list~pp_sep:(return" ->@ ")print)lprintf.fun_retletfun_ty=signaturetyletfun_ttype=signaturettypeletid_prettyfmt(v:_id)=matchTag.lastv.tagsposwith|None->()|SomePretty.Infix->Format.fprintffmt"(%a)"idv|SomePretty.Prefix->Format.fprintffmt"[%a]"idvletid_typeprintfmt(v:_id)=Format.fprintffmt"@[<hov 2>%a%a :@ %a@]"idvid_prettyvprintv.tyletty_varfmtid=id_typettypefmtidletterm_varfmtid=id_typetyfmtidletty_constfmtid=id_typefun_ttypefmtidletterm_constfmtid=id_typefun_tyfmtidletbinder_namefmt=function|Exists_->Format.fprintffmt"∃"|Forall_->Format.fprintffmt"∀"|Letin_->Format.fprintffmt"let"letbinder_sepfmt=function|Exists_|Forall_->Format.fprintffmt"."|Letin_->Format.fprintffmt"in"letrectermfmtt=matcht.descrwith|Varv->idfmtv|App(f,[],[])->idfmtf|App(f,tys,args)->term_appfmtftysargs|Binder(b,body)->Format.fprintffmt"@[<hv 2>%a%a@ %a@]"binderbbinder_sepbtermbody|Match(scrutinee,branches)->Format.fprintffmt"@[<hv 2>match %a with@ %a@]"termscrutinee(Format.pp_print_list~pp_sep:(return"@ ")branch)branchesandterm_appfmt(f:_id)tysargs=matchTag.lastf.tagsposwith|SomePretty.Prefix->beginmatchargswith|[]->idfmtf|_->Format.fprintffmt"@[<hov>%a(%a)@]"idf(Format.pp_print_list~pp_sep:(return",@ ")term)argsend|SomePretty.InfixwhenList.lengthargs>=2->letpp_sepfmt()=Format.fprintffmt" %a@ "idfinFormat.fprintffmt"(@[<hov>%a@])"(Format.pp_print_list~pp_septerm)args|None|SomePretty.Infix->beginmatchtys,argswith|_,[]->Format.fprintffmt"%a(@[<hov>%a@])"idf(Format.pp_print_list~pp_sep:(return",@ ")ty)tys|[],_->Format.fprintffmt"%a(@[<hov>%a@])"idf(Format.pp_print_list~pp_sep:(return",@ ")term)args|_->Format.fprintffmt"%a(@[<hov>%a%a%a@])"idf(Format.pp_print_list~pp_sep:(return",@ ")ty)tys(return";@ ")()(Format.pp_print_list~pp_sep:(return",@ ")term)argsendandbinderfmtb=matchbwith|Exists(l,[])|Forall(l,[])->Format.fprintffmt"%a @[<hov>%a@]"binder_nameb(Format.pp_print_list~pp_sep:(return",@ ")ty_var)l|Exists([],l)|Forall([],l)->Format.fprintffmt"%a @[<hov>%a@]"binder_nameb(Format.pp_print_list~pp_sep:(return",@ ")term_var)l|Exists(tys,ts)|Forall(tys,ts)->Format.fprintffmt"%a @[<hov>%a,@ %a@]"binder_nameb(Format.pp_print_list~pp_sep:(return",@ ")ty_var)tys(Format.pp_print_list~pp_sep:(return",@ ")term_var)ts|Letinl->Format.fprintffmt"%a @[<hv>%a@]"binder_nameb(Format.pp_print_list~pp_sep:(return",@ ")binding)landbindingfmt(v,t)=Format.fprintffmt"@[<hov 2>%a =@ %a@]"idvtermtandbranchfmt(pattern,body)=Format.fprintffmt"@[<hov 2>| %a@ ->@ %a"termpatterntermbodyletiter~sepppfmtk=letfirst=reftrueink(funx->if!firstthenfirst:=falseelsesepfmt();ppfmtx)end(* Views *)(* ************************************************************************* *)moduleView=structmoduleTy=structtypet=[|`Int|`Rat|`Real|`Arrayofty*ty|`Bitvofint|`Floatofint*int|`String|`String_reg_lang(* Generic cases *)|`Varofty_var|`Appof[|`Genericofty_const|`Builtinofbuiltin]*tylist]letview(ty:ty):t=matchty.descrwith|Varv->`Varv|App(({builtin;_}asc),l)->beginmatchbuiltinwith|Int->`Int|Rat->`Rat|Real->`Real|Bitvi->`Bitvi|Float(e,s)->`Float(e,s)|Array->beginmatchlwith|[src;dst]->`Array(src,dst)|_->assertfalse(* not possible *)end|String->`String|String_RegLan->`String_reg_lang|Base->`App(`Genericc,l)|_->`App(`Builtinbuiltin,l)endendend(* Flags and filters *)(* ************************************************************************* *)moduleFilter=structtypestatus=[|`Pass|`Warn|`Errorofstring]typety_filter=string*boolref*(ty_const->tylist->status)typeterm_filter=string*boolref*(term_const->tylist->termlist->status)letty:ty_filtertag=Tag.create()letterm:term_filtertag=Tag.create()moduletypeS=sigvalname:stringvalactive:boolrefvalreset:unit->unitendend(* Helpers *)(* ************************************************************************* *)(* Useful shorthand for chaining comparisons *)let(<?>)i(cmp,x,y)=matchiwith|0->cmpxy|_->i(* hash helpers *)lethash2xy=Hashtbl.seeded_hashxylethash3xyz=hash2x(hash2yz)lethash4xyzt=hash2x(hash3yzt)(* option iter *)letoption_iterf=function|None->()|Somex->fx(* list hash *)lethash_listfl=letrecauxacc=function|[]->acc|x::r->aux(Hashtbl.seeded_hashacc(fx))rinaux0l(* lexicographic comparison *)letlexicographiccmpll'=letrecauxll'=matchl,l'with|[],[]->0|_::_,[]->1|[],_::_->-1|x::r,x'::r'->beginmatchcmpxx'with|0->auxrr'|res->resendinauxll'(* List creation *)letinit_listnf=letrecauxacci=ifi>nthenList.revaccelseaux(fi::acc)(i+1)inaux[]1(* constant list with the same elements *)letreplicatenx=letrecauxxaccn=ifn<=0thenaccelseauxx(x::acc)(n-1)inauxx[]n(* automatic cache *)letwith_cache~cachefx=matchHashtbl.findcachexwith|res->res|exceptionNot_found->letres=fxinHashtbl.addcachexres;res(* Ids *)(* ************************************************************************* *)moduleId=structtype'at='aid(* Usual functions *)lethash(v:_t)=v.indexletcomparevv'=comparev.indexv'.indexletequalvv'=comparevv'=0letprintfmtid=Format.pp_print_stringfmtid.name(* Tags *)lettag(id:_id)kv=id.tags<-Tag.addid.tagskvletget_tag(id:_id)k=Tag.getid.tagskletget_tag_last(id:_id)k=Tag.lastid.tagsk(* Creating ids *)letid_counter=ref0letmk?(builtin=Base)?(tags=Tag.empty)namety=incrid_counter;{name;ty;builtin;tags;index=!id_counter;}letconst?pos?name?builtin?tags?(ty_filters=[])?(term_filters=[])cnamefun_varsfun_argsfun_ret=letres=mk?builtin?tagscname{fun_vars;fun_args;fun_ret;}in(* Add filter tags *)List.iter(tagresFilter.ty)ty_filters;List.iter(tagresFilter.term)term_filters;(* Add pretty printing tags *)option_iter(tagresPrint.pos)pos;option_iter(funs->tagresPrint.name(Pretty.Exacts))name;(* Return the id *)resletindexed?pos?name?builtin?tagscnamefun_varsfun_argfun_ret=leth=Hashtbl.create13in(funi->matchHashtbl.findhiwith|res->res|exceptionNot_found->letfun_args=replicateifun_arginletc=const?pos?name?builtin?tagscnamefun_varsfun_argsfun_retinHashtbl.addhic;c)end(* Maps from pairs of integers *)(* ************************************************************************* *)moduleMi=Map.Make(structtypet=indexletcompare(a:int)b=compareabend)(* Sets of ids *)(* ************************************************************************* *)moduleFV=structtypeelt=|Tyofty_var|Termofterm_vartypet=eltMi.tlettokv=v.indexlettoken=function|Tyv->tokv|Termv->tokv(* let mem v s = Mi.mem (tok v) s *)(* let get v s = Mi.find (tok v) s *)letaddx(s:t)=Mi.add(tokenx)xsletdelx(s:t)=Mi.remove(tokx)sletempty=Mi.emptyletremovesl=List.fold_left(funaccv->delvacc)slletdiffss'=Mi.merge(fun_oo'->matcho,o'with|None,None->None|None,Some_->None|(Some_asres),None->res|Some_,Some_->None)ss'letmergess'=Mi.merge(fun_oo'->matcho,o'with|None,None->None|_,((Some_)asres)|((Some_)asres),_->res)ss'letto_lists=letaux_elt(tys,ts)=matcheltwith|Tyv->(v::tys,ts)|Termv->(tys,v::ts)inMi.foldauxs([],[])end(* Substitutions *)(* ************************************************************************* *)moduleSubst=structtype('a,'b)t=('a*'b)Mi.t(* Usual functions *)letempty=Mi.emptyletis_empty=Mi.is_emptyletwrapkey=function|None->None|Somex->Some(key,x)letmergef=Mi.merge(fun_opt1opt2->matchopt1,opt2with|None,None->assertfalse|Some(key,value),None->wrapkey@@fkey(Somevalue)None|None,Some(key,value)->wrapkey@@fkeyNone(Somevalue)|Some(key,value1),Some(_key,value2)->wrapkey@@fkey(Somevalue1)(Somevalue2))letiterf=Mi.iter(fun_(key,value)->fkeyvalue)letmapf=Mi.map(fun(key,value)->(key,fvalue))letfoldf=Mi.fold(fun_(key,value)acc->fkeyvalueacc)letbindingss=Mi.fold(fun_(key,value)acc->(key,value)::acc)s[]letfilterp=Mi.filter(fun_(key,value)->pkeyvalue)(* Comparisons *)letequalf=Mi.equal(fun(_,value1)(_,value2)->fvalue1value2)letcomparef=Mi.compare(fun(_,value1)(_,value2)->fvalue1value2)lethashhs=Mi.fold(funi(_,value)acc->Hashtbl.hash(acc,i,hvalue))s1letchoosem=snd(Mi.choosem)(* Iterators *)letexistspreds=tryiter(funms->ifpredmsthenraiseExit)s;falsewithExit->trueletfor_allpreds=tryiter(funms->ifnot(predms)thenraiseExit)s;truewithExit->falseletprintprint_keyprint_valuefmtmap=letauxfmt(_,(key,value))=Format.fprintffmt"@[<hov 2>%a ↦@ %a@]"print_keykeyprint_valuevalueinFormat.fprintffmt"@[<hv>%a@]"Print.(iter~sep:(return";@ ")aux)(funk->Mi.iter(funxy->k(x,y))map)letdebugprint_keyprint_valuefmtmap=letauxfmt(i,(key,value))=Format.fprintffmt"@[<hov 2>%d: %a ↦@ %a@]"iprint_keykeyprint_valuevalueinFormat.fprintffmt"@[<hv>%a@]"Print.(iter~sep:(return";@ ")aux)(funk->Mi.iter(funxy->k(x,y))map)(* Specific substitutions signature *)moduletypeS=sigtype'akeyvalget:'akey->('akey,'b)t->'bvalmem:'akey->('akey,'b)t->boolvalbind:('akey,'b)t->'akey->'b->('akey,'b)tvalremove:'akey->('akey,'b)t->('akey,'b)tend(* Variable substitutions *)moduleVar=structtype'akey='aidlettokv=v.indexletgetvs=snd(Mi.find(tokv)s)letmemvs=Mi.mem(tokv)sletbindsvt=Mi.add(tokv)(v,t)sletremovevs=Mi.remove(tokv)sendend(* Types *)(* ************************************************************************* *)moduleTy=struct(* Std type aliase *)typet=tytypeview=View.Ty.ttypesubst=(ty_var,ty)Subst.ttype'atag='aTag.t(* printing *)letprint=Print.ty(* hash function *)letrechash_aux(t:t)=matcht.descrwith|Varv->hash23(Id.hashv)|App(f,args)->hash35(Id.hashf)(hash_listhashargs)andhash(t:t)=ift.hash<0thent.hash<-hash_auxt;t.hash(* comparison *)letdiscr(t:t)=matcht.descrwith|Var_->1|App_->2letreccompare(u:t)(v:t)=ifu==v||u.descr==v.descrthen0elsebeginlethu=hashuandhv=hashvinifhu<>hvthenhu-hv(* safe since both are positive *)elsematchu.descr,v.descrwith|Varv,Varv'->Id.comparevv'|App(f,args),App(f',args')->Id.compareff'<?>(lexicographiccompare,args,args')|_,_->Stdlib.compare(discru)(discrv)endletequaluv=compareuv=0(* Set a wildcard/hole to a concrete type
Wildcard can be set to point to another type by mutating the
descr field of types (this is the only operation that mutates
this field).
In order to be correct, when we set a wildcard v to point at
another wildcard w, we must remember that, so that when we set
w to something, we also need to update v. *)letwildcard_tbl=refSubst.emptyletwildcard_getv=matchSubst.Var.getv!wildcard_tblwith|l->l|exceptionNot_found->[]letwildcard_addvl=letl'=wildcard_getvinwildcard_tbl:=Subst.Var.bind!wildcard_tblv(List.rev_appendll')letset_wildcardv(t:t)=letset_descr(t:t)(s:t)=s.descr<-t.descrinletl=wildcard_getvinList.iter(set_descrt)l;matcht.descrwith|Var({builtin=Wildcard;_}asw)->wildcard_addwl;|_->()(* Types definitions *)typeadt_case={cstr:term_const;tester:term_const;dstrs:term_constoptionarray;}typedef=|Abstract|Adtof{ty:ty_const;record:bool;cases:adt_casearray;}letdefinition_tag:defTag.t=Tag.create()letdefinitionc=Id.get_tag_lastcdefinition_tagletis_recordc=matchdefinitioncwith|SomeAdt{record;_}->record|_->falseletdefinecd=matchdefinitioncwith|None->Id.tagcdefinition_tagd|Some_->raise(Type_already_definedc)(* view *)letview=View.Ty.view(* Tags *)lettag(t:t)kv=t.tags<-Tag.addt.tagskvletget_tag(t:t)k=Tag.gett.tagskletget_tag_last(t:t)k=Tag.lastt.tagsk(* Module for namespacing *)moduleVar=structtypet=ty_varlettag=Id.taglethash=Id.hashletequal=Id.equalletcompare=Id.compareletget_tag=Id.get_tagletget_tag_last=Id.get_tag_lastletmkname=Id.mknameTypeendmoduleConst=structtypet=ty_constlettag=Id.taglethash=Id.hashletequal=Id.equalletcompare=Id.compareletget_tag=Id.get_tagletget_tag_last=Id.get_tag_lastletmknamen=Id.constname[](replicatenType)Typeletarity(c:t)=List.lengthc.ty.fun_argsletprop=Id.const~builtin:Prop"Prop"[][]Typeletunit=Id.const~builtin:Unit"unit"[][]Typeletbase=Id.const~builtin:Univ"$i"[][]Typeletint=Id.const~builtin:Int"int"[][]Typeletrat=Id.const~builtin:Rat"rat"[][]Typeletreal=Id.const~builtin:Real"real"[][]Typeletstring=Id.const~builtin:String"string"[][]Typeletstring_reg_lang=Id.const~builtin:String_RegLan"string_reglang"[][]Typeletarray=Id.const~builtin:Array"array"[][Type;Type]Typeletbitv=with_cache~cache:(Hashtbl.create13)(funi->Id.const~builtin:(Bitvi)(Format.asprintf"Bitv_%d"i)[][]Type)letfloat=with_cache~cache:(Hashtbl.create13)(fun(e,s)->Id.const~builtin:(Float(e,s))(Format.asprintf"FloatingPoint_%d_%d"es)[][]Type)letroundingMode=Id.const~builtin:RoundingMode"RoundingMode"[][]Typeendletmkdescr={as_=None;descr;hash=-1;tags=Tag.empty;}letas_tv={twithas_=Somev;}letof_varv=mk(Varv)letwildcard()=letv=Id.mk~builtin:Wildcard"_"Typeinlett=of_varvinwildcard_addv[t];tletreccheck_filtersresfargs=function|[]->res|(name,active,check)::r->if!activethenmatch(checkfargs)with|`Pass->check_filtersresfargsr|`Warn->check_filtersresfargsr|`Errormsg->raise(Filter_failed_ty(name,res,msg))elsecheck_filtersresfargsrletapply(f:Const.t)(args:tylist)=assert(f.ty.fun_vars=[]);ifList.lengthargs<>List.lengthf.ty.fun_argsthenraise(Bad_ty_arity(f,args))elsebeginletres=mk(App(f,args))incheck_filtersresfargs(Const.get_tagfFilter.ty)end(* Builtin types *)letprop=applyConst.prop[]letunit=applyConst.unit[]letbase=applyConst.base[]letint=applyConst.int[]letrat=applyConst.rat[]letreal=applyConst.real[]letstring=applyConst.string[]letstring_reg_lang=applyConst.string_reg_lang[]letarraysrcdst=applyConst.array[src;dst]letbitvi=apply(Const.bitvi)[]letfloat'es=apply(Const.floates)[]letfloates=float'(e,s)letroundingMode=applyConst.roundingMode[](* alias for alt-ergo *)letbool=prop(* Matching *)exceptionImpossible_matchingofty*tyletrecpmatchsubst(pat:ty)(t:ty)=matchpat,twith|{descr=Varv;_},_->beginmatchSubst.Var.getvsubstwith|t'->ifequaltt'thensubstelseraise(Impossible_matching(pat,t))|exceptionNot_found->Subst.Var.bindsubstvtend|{descr=App(f,f_args);_},{descr=App(g,g_args);_}->ifId.equalfgthenList.fold_left2pmatchsubstf_argsg_argselseraise(Impossible_matching(pat,t))|_->raise(Impossible_matching(pat,t))(* Unification *)exceptionImpossible_unificationoft*tletrecfollowsubst(t:t)=matchtwith|{descr=Varv;_}->beginmatchSubst.Var.getvsubstwith|t'->followsubstt'|exceptionNot_found->tend|t->tletrecoccurssubstl(t:t)=matchtwith|{descr=Varv;_}->List.exists(Id.equalv)l||beginmatchSubst.Var.getvsubstwith|exceptionNot_found->false|e->occurssubst(v::l)eend|{descr=App(_,tys);_}->List.exists(occurssubstl)tysletrobinson_bindsubstmvu=ifoccurssubst[v]uthenraise(Impossible_unification(m,u))elseSubst.Var.bindsubstvuletrobinson_assubstst=matchs.as_with|None->subst|Somev->robinson_bindsubstsvtletrecrobinsonsubstst=letsubst=robinson_as(robinson_assubstst)tsinlets=followsubstsinlett=followsubsttinmatchs,twith|({descr=Var({builtin=Wildcard;_}asv);_}asm),u|u,({descr=Var({builtin=Wildcard;_}asv);_}asm)->ifequalmuthensubstelserobinson_bindsubstmvu|({descr=Varv;_},{descr=Varv';_})->ifId.equalvv'thensubstelseraise(Impossible_unification(s,t))|{descr=App(f,f_args);_},{descr=App(g,g_args);_}->ifId.equalfgthenList.fold_left2robinsonsubstf_argsg_argselseraise(Impossible_unification(s,t))|_,_->raise(Impossible_unification(s,t))(* Substitutions *)letrecsubst_aux~fixvar_map(t:t)=matcht.descrwith|Varv->beginmatchSubst.Var.getvvar_mapwith|exceptionNot_found->t|ty->iffixthensubst_aux~fixvar_maptyelsetyend|App(f,args)->letnew_args=List.map(subst_aux~fixvar_map)argsinifList.for_all2(==)argsnew_argsthentelseapplyfnew_argsletsubst?(fix=true)var_mapt=ifSubst.is_emptyvar_mapthentelsesubst_aux~fixvar_mapt(* free variables *)letrecfree_varsacc(t:t)=matcht.descrwith|Varv->FV.add(FV.Tyv)acc|App(_,l)->List.fold_leftfree_varsacclend(* Terms *)(* ************************************************************************* *)moduleTerm=structtypet=termtypety=Ty.ttypety_var=Ty.Var.ttypety_const=Ty.Const.ttypesubst=(term_var,term)Subst.ttype'atag='aTag.texceptionWrong_typeoft*tyexceptionWrong_sum_typeofterm_const*tyexceptionWrong_record_typeofterm_const*ty_constexceptionField_repeatedofterm_constexceptionField_missingofterm_constexceptionField_expectedofterm_constexceptionConstructor_expectedofterm_constletprint=Print.term(* Tags *)lettag(t:t)kv=t.tags<-Tag.addt.tagskvletget_tag(t:t)k=Tag.gett.tagskletget_tag_last(t:t)k=Tag.lastt.tagsk(* Hash *)letrechash_auxt=matcht.descrwith|Varv->hash23(Id.hashv)|App(f,tys,args)->hash45(Id.hashf)(hash_listTy.hashtys)(hash_listhashargs)|Binder(b,body)->hash37(hash_binderb)(hashbody)|Match(scrutinee,branches)->hash311(hashscrutinee)(hash_branchesbranches)andhasht=ift.hash<=0thent.hash<-hash_auxt;t.hashandhash_binder=function|Exists(tys,ts)->hash33(hash_listId.hashtys)(hash_listId.hashts)|Forall(tys,ts)->hash35(hash_listId.hashtys)(hash_listId.hashts)|Letinl->letaux(v,t)=hash2(Id.hashv)(hasht)inhash27(hash_listauxl)andhash_branch(pattern,body)=hash2(hashpattern)(hashbody)andhash_branchesl=hash_listhash_branchl(* Comparison *)letdiscrt=matcht.descrwith|Var_->1|App_->2|Binder_->3|Match_->4letbinder_discr=function|Exists_->1|Forall_->2|Letin_->3letreccompareuv=ifu==vthen0elsebeginlethu=hashuandhv=hashvinifhu<>hvthenhu-hvelsematchu.descr,v.descrwith|Varv1,Varv2->Id.comparev1v2|App(f1,tys1,args1),App(f2,tys2,args2)->Id.comparef1f2<?>(lexicographicTy.compare,tys1,tys2)<?>(lexicographiccompare,args1,args2)|Binder(b,body),Binder(b',body')->compare_binderbb'<?>(compare,body,body')|Match(s,l),Match(s',l')->comparess'<?>(lexicographiccompare_branch,l,l')|_,_->(discru)-(discrv)endandcompare_binderbb'=matchb,b'with|Exists(tys,ts),Exists(tys',ts')->lexicographicId.comparetystys'<?>(lexicographicId.compare,ts,ts')|Forall(tys,ts),Forall(tys',ts')->lexicographicId.comparetystys'<?>(lexicographicId.compare,ts,ts')|Letinl,Letinl'->letaux(v,t)(v',t')=Id.comparevv'<?>(compare,t,t')inlexicographicauxll'|_,_->(binder_discrb)-(binder_discrb')andcompare_branch(p,b)(p',b')=comparepp'<?>(compare,b,b')letequaluv=compareuv=0(* Inspection *)letty{ty;_}=ty(* free variables *)letrecfree_varsacc(t:t)=matcht.descrwith|Varv->FV.add(FV.Termv)(Ty.free_varsaccv.ty)|App(_,tys,ts)->List.fold_leftfree_vars(List.fold_leftTy.free_varsacctys)ts|Binder((Exists(tys,ts)|Forall(tys,ts)),body)->letfv=free_varsFV.emptybodyinletfv=FV.removefvtysinletfv=FV.removefvtsinFV.mergefvacc|Binder(Letinl,body)->letfv=free_varsFV.emptybodyinletfv=List.fold_right(fun(v,t)acc->letacc=free_varsacctinletacc=FV.delvaccinletacc=Ty.free_varsaccv.tyinacc)lfvinFV.mergefvacc|Match(scrutinee,branches)->letacc=free_varsaccscrutineeinList.fold_left(funfv(pat,body)->letfree=free_varsFV.emptybodyinletbound=free_varsFV.emptypatinFV.mergefv(FV.difffreebound))accbranchesletfvt=lets=free_varsFV.emptytinFV.to_lists(* Helpers for adt definition *)letmk_cstrty_cnameivarsargsret=Id.constnamevarsargsret~builtin:(Constructor{adt=ty_c;case=i;})letmk_cstr_testercstr=letname=Format.asprintf"is:%a"Print.idcstrinId.const~builtin:(Tester{cstr})namecstr.ty.fun_vars[cstr.ty.fun_ret]Ty.prop(* ADT definition *)letdefine_adt_aux~recordty_constvarsl=letty=Ty.applyty_const(List.mapTy.of_varvars)inletcases=ref[]inletl'=List.mapi(funi(cstr_name,args)->letargs_ty=List.mapfstargsinletcstr=mk_cstrty_constcstr_nameivarsargs_tytyinlettester=mk_cstr_testercstrinletdstrs=Array.make(List.lengthargs)Noneinletl'=List.mapi(funj->function|(arg_ty,None)->(arg_ty,None)|(arg_ty,Somename)->letdstr=Id.constnamevars[ty]arg_ty~builtin:(Destructor{adt=ty_const;cstr;case=i;field=j;})indstrs.(j)<-Somedstr;(arg_ty,Somedstr))argsincases:={Ty.cstr;tester;dstrs;}::!cases;cstr,l')linassert(notrecord||List.length!cases=1);Ty.definety_const(Adt{ty=ty_const;record;cases=Array.of_list@@List.rev!cases;});l'letdefine_adt=define_adt_aux~record:falseletdefine_recordty_constvarsl=letname=ty_const.nameinletcstr_args=List.map(fun(field_name,ty)->ty,Somefield_name)linletl'=define_adt_aux~record:truety_constvars[name,cstr_args]inmatchl'with|[_,l'']->List.map(function|_,Somedstr->dstr|_,None->assertfalse)l''|_->assertfalse(* Exhaustivity check
TODO: implement this *)letcheck_exhaustivity_ty_pats=()(* Variables *)moduleVar=structtypet=term_varlettag=Id.taglethash=Id.hashletequal=Id.equalletcompare=Id.compareletget_tag=Id.get_tagletget_tag_last=Id.get_tag_lastletty({ty;_}:t)=tyletmknamety=Id.mknametyend(* Constants *)moduleConst=structtypet=term_constlettag=Id.taglethash=Id.hashletequal=Id.equalletcompare=Id.compareletget_tag=Id.get_tagletget_tag_last=Id.get_tag_lastletmknamevarsargsret=letr=refretinletb=reftrueinletargs=List.map(funty->if!b||not(Ty.equaltyret)thentyelsebeginletv=Ty.Var.mk"'ret"inr:=Ty.of_varv;b:=true;Ty.as_tyvend)argsinId.constnamevarsargs!rletarity(c:t)=List.lengthc.ty.fun_vars,List.lengthc.ty.fun_args(* Some constants *)let_true=Id.const~name:"⊤"~builtin:True"True"[][]Ty.proplet_false=Id.const~name:"⊥"~builtin:False"False"[][]Ty.propleteq=leta=Ty.Var.mk"alpha"inleta_ty=Ty.of_varainId.const~pos:Pretty.Infix~name:"="~builtin:Equal"Equal"[a][a_ty;a_ty]Ty.propleteqs=leta=Ty.Var.mk"alpha"inleta_ty=Ty.of_varainId.indexed~pos:Pretty.Infix~name:"="~builtin:Equal"Equals"[a]a_tyTy.propletdistinct=leta=Ty.Var.mk"alpha"inleta_ty=Ty.of_varainId.indexed~builtin:Distinct"Distinct"[a]a_tyTy.propletneg=Id.const~pos:Pretty.Prefix~name:"¬"~builtin:Neg"Neg"[][Ty.prop]Ty.proplet_and=Id.indexed~pos:Pretty.Infix~name:"∧"~builtin:And"And"[]Ty.propTy.proplet_or=Id.indexed~pos:Pretty.Infix~name:"∨"~builtin:Or"Or"[]Ty.propTy.propletnand=Id.const~pos:Pretty.Infix~name:"⊼"~builtin:Nand"Nand"[][Ty.prop;Ty.prop]Ty.propletnor=Id.const~pos:Pretty.Infix~name:"V"~builtin:Nor"or"[][Ty.prop;Ty.prop]Ty.propletxor=Id.const~pos:Pretty.Infix~name:"⊻"~builtin:Xor"Xor"[][Ty.prop;Ty.prop]Ty.propletimply=Id.const~pos:Pretty.Infix~name:"⇒"~builtin:Imply"Imply"[][Ty.prop;Ty.prop]Ty.propletequiv=Id.const~pos:Pretty.Infix~name:"⇔"~builtin:Equiv"Equiv"[][Ty.prop;Ty.prop]Ty.propletite=leta=Ty.Var.mk"alpha"inleta_ty=Ty.of_varainId.const~name:"ite"~builtin:Ite"Ite"[a][Ty.prop;a_ty;a_ty]a_tyletselect=leta=Ty.Var.mk"alpha"inleta_ty=Ty.of_varainletb=Ty.Var.mk"beta"inletb_ty=Ty.of_varbinId.const~name:"select"~builtin:Select"Select"[a;b][Ty.arraya_tyb_ty;a_ty]b_tyletstore=leta=Ty.Var.mk"alpha"inleta_ty=Ty.of_varainletb=Ty.Var.mk"beta"inletb_ty=Ty.of_varbinletarr=Ty.arraya_tyb_tyinId.const~name:"store"~builtin:Store"Store"[a;b][arr;a_ty;b_ty]arrletcoerce=leta=Ty.Var.mk"alpha"inletb=Ty.Var.mk"beta"inId.const~builtin:Coercion"coerce"[a;b][Ty.of_vara](Ty.of_varb)moduleInt=structletint=with_cache~cache:(Hashtbl.create113)(funs->Id.const~builtin:(Integers)s[][]Ty.int)letminus=Id.const~pos:Pretty.Prefix~name:"-"~builtin:Minus"Minus"[][Ty.int]Ty.intletadd=Id.const~pos:Pretty.Infix~name:"+"~builtin:Add"Add"[][Ty.int;Ty.int]Ty.intletsub=Id.const~pos:Pretty.Infix~name:"-"~builtin:Sub"Sub"[][Ty.int;Ty.int]Ty.intletmul=Id.const~pos:Pretty.Infix~name:"*"~builtin:Mul"Mul"[][Ty.int;Ty.int]Ty.intletdiv_e=Id.const~pos:Pretty.Infix~name:"/"~builtin:Div_e"Div_e"[][Ty.int;Ty.int]Ty.intletdiv_t=Id.const~pos:Pretty.Infix~name:"/t"~builtin:Div_t"Div_t"[][Ty.int;Ty.int]Ty.intletdiv_f=Id.const~pos:Pretty.Infix~name:"/f"~builtin:Div_f"Div_f"[][Ty.int;Ty.int]Ty.intletrem_e=Id.const~pos:Pretty.Infix~name:"%"~builtin:Modulo_e"Modulo"[][Ty.int;Ty.int]Ty.intletrem_t=Id.const~pos:Pretty.Infix~name:"%e"~builtin:Modulo_t"Modulo"[][Ty.int;Ty.int]Ty.intletrem_f=Id.const~pos:Pretty.Infix~name:"%f"~builtin:Modulo_f"Modulo"[][Ty.int;Ty.int]Ty.intletabs=Id.const~name:"abs"~builtin:Abs"Abs"[][Ty.int]Ty.intletlt=Id.const~pos:Pretty.Infix~name:"<"~builtin:Lt"LessThan"[][Ty.int;Ty.int]Ty.propletle=Id.const~pos:Pretty.Infix~name:"<="~builtin:Leq"LessOrEqual"[][Ty.int;Ty.int]Ty.propletgt=Id.const~pos:Pretty.Infix~name:">"~builtin:Gt"GreaterThan"[][Ty.int;Ty.int]Ty.propletge=Id.const~pos:Pretty.Infix~name:">="~builtin:Geq"GreaterOrEqual"[][Ty.int;Ty.int]Ty.propletfloor=Id.const~name:"floor"~builtin:Floor"Floor"[][Ty.int]Ty.intletceiling=Id.const~name:"ceiling"~builtin:Ceiling"Ceiling"[][Ty.int]Ty.intlettruncate=Id.const~name:"truncate"~builtin:Truncate"Truncate"[][Ty.int]Ty.intletround=Id.const~name:"round"~builtin:Round"Round"[][Ty.int]Ty.intletis_int=Id.const~name:"is_int"~builtin:Is_int"Is_int"[][Ty.int]Ty.propletis_rat=Id.const~name:"is_rat"~builtin:Is_rat"Is_rat"[][Ty.int]Ty.propletdivisible=Id.const~builtin:Divisible"Divisible"[][Ty.int;Ty.int]Ty.propendmoduleRat=structletrat=with_cache~cache:(Hashtbl.create113)(funs->Id.const~builtin:(Rationals)s[][]Ty.rat)letminus=Id.const~pos:Pretty.Prefix~name:"-"~builtin:Minus"Minus"[][Ty.rat]Ty.ratletadd=Id.const~pos:Pretty.Infix~name:"+"~builtin:Add"Add"[][Ty.rat;Ty.rat]Ty.ratletsub=Id.const~pos:Pretty.Infix~name:"-"~builtin:Sub"Sub"[][Ty.rat;Ty.rat]Ty.ratletmul=Id.const~pos:Pretty.Infix~name:"*"~builtin:Mul"Mul"[][Ty.rat;Ty.rat]Ty.ratletdiv=Id.const~pos:Pretty.Infix~name:"/"~builtin:Div"Div"[][Ty.rat;Ty.rat]Ty.ratletdiv_e=Id.const~pos:Pretty.Infix~name:"/e"~builtin:Div_e"Div_e"[][Ty.rat;Ty.rat]Ty.ratletdiv_t=Id.const~pos:Pretty.Infix~name:"/t"~builtin:Div_t"Div_t"[][Ty.rat;Ty.rat]Ty.ratletdiv_f=Id.const~pos:Pretty.Infix~name:"/f"~builtin:Div_f"Div_f"[][Ty.rat;Ty.rat]Ty.ratletrem_e=Id.const~pos:Pretty.Infix~name:"%"~builtin:Modulo_e"Modulo"[][Ty.rat;Ty.rat]Ty.ratletrem_t=Id.const~pos:Pretty.Infix~name:"%"~builtin:Modulo_t"Modulo"[][Ty.rat;Ty.rat]Ty.ratletrem_f=Id.const~pos:Pretty.Infix~name:"%"~builtin:Modulo_f"Modulo"[][Ty.rat;Ty.rat]Ty.ratletlt=Id.const~pos:Pretty.Infix~name:"<"~builtin:Lt"LessThan"[][Ty.rat;Ty.rat]Ty.propletle=Id.const~pos:Pretty.Infix~name:"<="~builtin:Leq"LessOrEqual"[][Ty.rat;Ty.rat]Ty.propletgt=Id.const~pos:Pretty.Infix~name:">"~builtin:Gt"GreaterThan"[][Ty.rat;Ty.rat]Ty.propletge=Id.const~pos:Pretty.Infix~name:">="~builtin:Geq"GreaterOrEqual"[][Ty.rat;Ty.rat]Ty.propletfloor=Id.const~name:"floor"~builtin:Floor"Floor"[][Ty.rat]Ty.ratletceiling=Id.const~name:"ceiling"~builtin:Ceiling"Ceiling"[][Ty.rat]Ty.ratlettruncate=Id.const~name:"truncate"~builtin:Truncate"Truncate"[][Ty.rat]Ty.ratletround=Id.const~name:"round"~builtin:Round"Round"[][Ty.rat]Ty.ratletis_int=Id.const~name:"is_int"~builtin:Is_int"Is_int"[][Ty.rat]Ty.propletis_rat=Id.const~name:"is_rat"~builtin:Is_rat"Is_rat"[][Ty.rat]Ty.propendmoduleReal=structletreal=with_cache~cache:(Hashtbl.create113)(funs->Id.const~builtin:(Decimals)s[][]Ty.real)letminus=Id.const~pos:Pretty.Prefix~name:"-"~builtin:Minus"Minus"[][Ty.real]Ty.realletadd=Id.const~pos:Pretty.Infix~name:"+"~builtin:Add"Add"[][Ty.real;Ty.real]Ty.realletsub=Id.const~pos:Pretty.Infix~name:"-"~builtin:Sub"Sub"[][Ty.real;Ty.real]Ty.realletmul=Id.const~pos:Pretty.Infix~name:"*"~builtin:Mul"Mul"[][Ty.real;Ty.real]Ty.realletdiv=Id.const~pos:Pretty.Infix~name:"/"~builtin:Div"Div"[][Ty.real;Ty.real]Ty.realletdiv_e=Id.const~pos:Pretty.Infix~name:"/"~builtin:Div_e"Div_e"[][Ty.real;Ty.real]Ty.realletdiv_t=Id.const~pos:Pretty.Infix~name:"/t"~builtin:Div_t"Div_t"[][Ty.real;Ty.real]Ty.realletdiv_f=Id.const~pos:Pretty.Infix~name:"/f"~builtin:Div_f"Div_f"[][Ty.real;Ty.real]Ty.realletrem_e=Id.const~pos:Pretty.Infix~name:"%"~builtin:Modulo_e"Modulo"[][Ty.real;Ty.real]Ty.realletrem_t=Id.const~pos:Pretty.Infix~name:"%"~builtin:Modulo_t"Modulo"[][Ty.real;Ty.real]Ty.realletrem_f=Id.const~pos:Pretty.Infix~name:"%"~builtin:Modulo_f"Modulo"[][Ty.real;Ty.real]Ty.realletlt=Id.const~pos:Pretty.Infix~name:"<"~builtin:Lt"LessThan"[][Ty.real;Ty.real]Ty.propletle=Id.const~pos:Pretty.Infix~name:"<="~builtin:Leq"LessOrEqual"[][Ty.real;Ty.real]Ty.propletgt=Id.const~pos:Pretty.Infix~name:">"~builtin:Gt"GreaterThan"[][Ty.real;Ty.real]Ty.propletge=Id.const~pos:Pretty.Infix~name:">="~builtin:Geq"GreaterOrEqual"[][Ty.real;Ty.real]Ty.propletfloor=Id.const~name:"floor"~builtin:Floor"Floor"[][Ty.real]Ty.realletceiling=Id.const~name:"ceiling"~builtin:Ceiling"Ceiling"[][Ty.real]Ty.reallettruncate=Id.const~name:"truncate"~builtin:Truncate"Truncate"[][Ty.real]Ty.realletround=Id.const~name:"round"~builtin:Round"Round"[][Ty.real]Ty.realletis_int=Id.const~name:"is_int"~builtin:Is_int"Is_int"[][Ty.real]Ty.propletis_rat=Id.const~name:"is_rat"~builtin:Is_rat"Is_rat"[][Ty.real]Ty.propendmoduleBitv=structletbitvs=Id.const~builtin:(Bitvecs)(Format.asprintf"bv#%s#"s)[][](Ty.bitv(String.lengths))letconcat=with_cache~cache:(Hashtbl.create13)(fun(i,j)->Id.const~builtin:Bitv_concat"bitv_concat"[][Ty.bitvi;Ty.bitvj](Ty.bitv(i+j)))letextract=with_cache~cache:(Hashtbl.create13)(fun(i,j,n)->Id.const~builtin:(Bitv_extract(i,j))(Format.asprintf"bitv_extract_%d_%d"ij)[][Ty.bitvn](Ty.bitv(i-j+1)))letrepeat=with_cache~cache:(Hashtbl.create13)(fun(k,n)->Id.const~builtin:Bitv_repeat(Format.asprintf"bitv_repeat_%d"k)[][Ty.bitvn](Ty.bitv(n*k)))letzero_extend=with_cache~cache:(Hashtbl.create13)(fun(k,n)->Id.const~builtin:Bitv_zero_extend(Format.asprintf"zero_extend_%d"k)[][Ty.bitvn](Ty.bitv(n+k)))letsign_extend=with_cache~cache:(Hashtbl.create13)(fun(k,n)->Id.const~builtin:Bitv_sign_extend(Format.asprintf"sign_extend_%d"k)[][Ty.bitvn](Ty.bitv(n+k)))letrotate_right=with_cache~cache:(Hashtbl.create13)(fun(k,n)->Id.const~builtin:(Bitv_rotate_rightk)(Format.asprintf"rotate_right_%d"k)[][Ty.bitvn](Ty.bitvn))letrotate_left=with_cache~cache:(Hashtbl.create13)(fun(k,n)->Id.const~builtin:(Bitv_rotate_leftk)(Format.asprintf"rotate_left_%d"k)[][Ty.bitvn](Ty.bitvn))letnot=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_not"bvnot"[][Ty.bitvn](Ty.bitvn))letand_=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_and"bvand"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letor_=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_or"bvor"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letnand=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_nand"bvnand"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letnor=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_nor"bvnor"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letxor=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_xor"bvxor"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letxnor=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_xnor"bvxnor"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letcomp=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_comp"bvcomp"[][Ty.bitvn;Ty.bitvn](Ty.bitv1))letneg=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_neg"bvneg"[][Ty.bitvn](Ty.bitvn))letadd=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_add"bvadd"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letsub=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_sub"bvsub"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letmul=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_mul"bvmul"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letudiv=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_udiv"bvudiv"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))leturem=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_urem"bvurem"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letsdiv=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_sdiv"bvsdiv"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letsrem=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_srem"bvsrem"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letsmod=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_smod"bvsmod"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letshl=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_shl"bvshl"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letlshr=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_lshr"bvlshr"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letashr=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_ashr"bvashr"[][Ty.bitvn;Ty.bitvn](Ty.bitvn))letult=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_ult"bvult"[][Ty.bitvn;Ty.bitvn]Ty.prop)letule=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_ule"bvule"[][Ty.bitvn;Ty.bitvn]Ty.prop)letugt=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_ugt"bvugt"[][Ty.bitvn;Ty.bitvn]Ty.prop)letuge=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_uge"bvsge"[][Ty.bitvn;Ty.bitvn]Ty.prop)letslt=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_slt"bvslt"[][Ty.bitvn;Ty.bitvn]Ty.prop)letsle=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_sle"bvsle"[][Ty.bitvn;Ty.bitvn]Ty.prop)letsgt=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_sgt"bvsgt"[][Ty.bitvn;Ty.bitvn]Ty.prop)letsge=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:Bitv_sge"bvsge"[][Ty.bitvn;Ty.bitvn]Ty.prop)endmoduleFloat=structletfp=with_cache~cache:(Hashtbl.create13)(fun(e,s)->Id.const~builtin:(Fp(e,s))"fp"[][Ty.bitv1;Ty.bitve;Ty.bitv(s-1)](Ty.floates))letroundNearestTiesToEven=Id.const~builtin:RoundNearestTiesToEven"RoundNearestTiesToEven"[][]Ty.roundingModeletroundNearestTiesToAway=Id.const~builtin:RoundNearestTiesToAway"RoundNearestTiesToAway"[][]Ty.roundingModeletroundTowardPositive=Id.const~builtin:RoundTowardPositive"RoundTowardPositive"[][]Ty.roundingModeletroundTowardNegative=Id.const~builtin:RoundTowardNegative"RoundTowardNegative"[][]Ty.roundingModeletroundTowardZero=Id.const~builtin:RoundTowardZero"RoundTowardZero"[][]Ty.roundingMode(** Generic function for creating functions primarily on the same floating
point format with optionally a rounding mode and a particular result
type *)letfp_gen_fun~args?rm?resnamebuiltin=with_cache~cache:(Hashtbl.create13)(funes->letfp=Ty.float'esinletargs=List.initargs(fun_->fp)inletargs=matchrmwithNone->args|Some()->Ty.roundingMode::argsinletres=matchreswith|Someres->res|None->fpinId.const~builtin:(builtines)name[]argsres)letplus_infinity=fp_gen_fun~args:0"plus_infinity"(fun(e,s)->Plus_infinity(e,s))letminus_infinity=fp_gen_fun~args:0"minus_infinity"(fun(e,s)->Minus_infinity(e,s))letplus_zero=fp_gen_fun~args:0"plus_zero"(fun(e,s)->Plus_zero(e,s))letminus_zero=fp_gen_fun~args:0"minus_zero"(fun(e,s)->Minus_zero(e,s))letnan=fp_gen_fun~args:0"nan"(fun(e,s)->NaN(e,s))letabs=fp_gen_fun~args:1"fp.abs"(fun(e,s)->Fp_abs(e,s))letneg=fp_gen_fun~args:1"fp.neg"(fun(e,s)->Fp_neg(e,s))letadd=fp_gen_fun~args:2~rm:()"fp.add"(fun(e,s)->Fp_add(e,s))letsub=fp_gen_fun~args:2~rm:()"fp.sub"(fun(e,s)->Fp_sub(e,s))letmul=fp_gen_fun~args:2~rm:()"fp.mul"(fun(e,s)->Fp_mul(e,s))letdiv=fp_gen_fun~args:2~rm:()"fp.div"(fun(e,s)->Fp_div(e,s))letfma=fp_gen_fun~args:3~rm:()"fp.fma"(fun(e,s)->Fp_fma(e,s))letsqrt=fp_gen_fun~args:1~rm:()"fp.sqrt"(fun(e,s)->Fp_sqrt(e,s))letrem=fp_gen_fun~args:2"fp.rem"(fun(e,s)->Fp_rem(e,s))letroundToIntegral=fp_gen_fun~args:1~rm:()"fp.roundToIntegral"(fun(e,s)->Fp_roundToIntegral(e,s))letmin=fp_gen_fun~args:2"fp.min"(fun(e,s)->Fp_min(e,s))letmax=fp_gen_fun~args:2"fp.max"(fun(e,s)->Fp_max(e,s))letleq=fp_gen_fun~args:2~res:Ty.prop"fp.leq"(fun(e,s)->Fp_leq(e,s))letlt=fp_gen_fun~args:2~res:Ty.prop"fp.lt"(fun(e,s)->Fp_lt(e,s))letgeq=fp_gen_fun~args:2~res:Ty.prop"fp.geq"(fun(e,s)->Fp_geq(e,s))letgt=fp_gen_fun~args:2~res:Ty.prop"fp.gt"(fun(e,s)->Fp_gt(e,s))leteq=fp_gen_fun~args:2~res:Ty.prop"fp.eq"(fun(e,s)->Fp_eq(e,s))letisNormal=fp_gen_fun~args:1~res:Ty.prop"fp.isnormal"(fun(e,s)->Fp_isNormal(e,s))letisSubnormal=fp_gen_fun~args:1~res:Ty.prop"fp.issubnormal"(fun(e,s)->Fp_isSubnormal(e,s))letisZero=fp_gen_fun~args:1~res:Ty.prop"fp.iszero"(fun(e,s)->Fp_isZero(e,s))letisInfinite=fp_gen_fun~args:1~res:Ty.prop"fp.isinfinite"(fun(e,s)->Fp_isInfinite(e,s))letisNaN=fp_gen_fun~args:1~res:Ty.prop"fp.isnan"(fun(e,s)->Fp_isNaN(e,s))letisNegative=fp_gen_fun~args:1~res:Ty.prop"fp.isnegative"(fun(e,s)->Fp_isNegative(e,s))letisPositive=fp_gen_fun~args:1~res:Ty.prop"fp.ispositive"(fun(e,s)->Fp_isPositive(e,s))letto_real=fp_gen_fun~args:1~res:Ty.real"fp.to_real"(fun(e,s)->To_real(e,s))letieee_format_to_fp=with_cache~cache:(Hashtbl.create13)(fun((e,s)ases)->Id.const~builtin:(Ieee_format_to_fp(e,s))"to_fp"[][Ty.bitv(e+s)](Ty.float'es))letto_fp=with_cache~cache:(Hashtbl.create13)(fun(e1,s1,e2,s2)->Id.const~builtin:(Fp_to_fp(e1,s1,e2,s2))"to_fp"[][Ty.roundingMode;Ty.floate1s1](Ty.floate2s2))letreal_to_fp=with_cache~cache:(Hashtbl.create13)(fun((e,s)ases)->Id.const~builtin:(Real_to_fp(e,s))"to_fp"[][Ty.roundingMode;Ty.real](Ty.float'es))letsbv_to_fp=with_cache~cache:(Hashtbl.create13)(fun(bv,e,s)->Id.const~builtin:(Sbv_to_fp(bv,e,s))"to_fp"[][Ty.roundingMode;Ty.bitvbv](Ty.floates))letubv_to_fp=with_cache~cache:(Hashtbl.create13)(fun(bv,e,s)->Id.const~builtin:(Ubv_to_fp(bv,e,s))"to_fp"[][Ty.roundingMode;Ty.bitvbv](Ty.floates))letto_ubv=with_cache~cache:(Hashtbl.create13)(fun(e,s,bv)->Id.const~builtin:(To_ubv(bv,e,s))"fp.to_ubv"[][Ty.roundingMode;Ty.floates](Ty.bitvbv))letto_sbv=with_cache~cache:(Hashtbl.create13)(fun(e,s,bv)->Id.const~builtin:(To_sbv(bv,e,s))"fp.to_sbv"[][Ty.roundingMode;Ty.floates](Ty.bitvbv))endmoduleString=structletstring=with_cache~cache:(Hashtbl.create13)(funs->Id.const~builtin:(Strs)(Format.asprintf{|"%s"|}s)[][]Ty.string)letlength=Id.const~builtin:Str_length"length"[][Ty.string]Ty.intletat=Id.const~builtin:Str_at"at"[][Ty.string;Ty.int]Ty.stringletto_code=Id.const~builtin:Str_to_code"to_code"[][Ty.string]Ty.intletof_code=Id.const~builtin:Str_of_code"of_code"[][Ty.int]Ty.stringletis_digit=Id.const~builtin:Str_is_digit"is_digit"[][Ty.string]Ty.propletto_int=Id.const~builtin:Str_to_int"to_int"[][Ty.string]Ty.intletof_int=Id.const~builtin:Str_of_int"of_int"[][Ty.int]Ty.stringletconcat=Id.const~builtin:Str_concat~pos:Pretty.Infix"++"[][Ty.string;Ty.string]Ty.stringletsub=Id.const~builtin:Str_sub"sub"[][Ty.string;Ty.int;Ty.int]Ty.stringletindex_of=Id.const~builtin:Str_index_of"index_of"[][Ty.string;Ty.string;Ty.int]Ty.intletreplace=Id.const~builtin:Str_replace"replace"[][Ty.string;Ty.string;Ty.string]Ty.stringletreplace_all=Id.const~builtin:Str_replace_all"replace_all"[][Ty.string;Ty.string;Ty.string]Ty.stringletreplace_re=Id.const~builtin:Str_replace_re"replace_re"[][Ty.string;Ty.string_reg_lang;Ty.string]Ty.stringletreplace_re_all=Id.const~builtin:Str_replace_re_all"replace_re_all"[][Ty.string;Ty.string_reg_lang;Ty.string]Ty.stringletis_prefix=Id.const~builtin:Str_is_prefix"is_prefix"[][Ty.string;Ty.string]Ty.propletis_suffix=Id.const~builtin:Str_is_suffix"is_suffix"[][Ty.string;Ty.string]Ty.propletcontains=Id.const~builtin:Str_contains"contains"[][Ty.string;Ty.string]Ty.propletlt=Id.const~builtin:Str_lexicographic_strict~pos:Pretty.Infix"lt"[][Ty.string;Ty.string]Ty.propletleq=Id.const~builtin:Str_lexicographic_large~pos:Pretty.Infix"leq"[][Ty.string;Ty.string]Ty.propletin_re=Id.const~builtin:Str_in_re"in_re"[][Ty.string;Ty.string_reg_lang]Ty.propmoduleReg_Lang=structletempty=Id.const~builtin:Re_empty"empty"[][]Ty.string_reg_langletall=Id.const~builtin:Re_all"all"[][]Ty.string_reg_langletallchar=Id.const~builtin:Re_allchar"allchar"[][]Ty.string_reg_langletof_string=Id.const~builtin:Re_of_string"of_string"[][Ty.string]Ty.string_reg_langletrange=Id.const~builtin:Re_range"range"[][Ty.string;Ty.string]Ty.string_reg_langletconcat=Id.const~builtin:Re_concat~pos:Pretty.Infix"++"[][Ty.string_reg_lang;Ty.string_reg_lang]Ty.string_reg_langletunion=Id.const~builtin:Re_union~pos:Pretty.Infix"∪"[][Ty.string_reg_lang;Ty.string_reg_lang]Ty.string_reg_langletinter=Id.const~builtin:Re_inter~pos:Pretty.Infix"∩"[][Ty.string_reg_lang;Ty.string_reg_lang]Ty.string_reg_langletdiff=Id.const~builtin:Re_diff~pos:Pretty.Infix"-"[][Ty.string_reg_lang;Ty.string_reg_lang]Ty.string_reg_langletstar=Id.const~builtin:Re_star~pos:Pretty.Prefix"*"[][Ty.string_reg_lang]Ty.string_reg_langletcross=Id.const~builtin:Re_cross~pos:Pretty.Prefix"+"[][Ty.string_reg_lang]Ty.string_reg_langletcomplement=Id.const~builtin:Re_complement"complement"[][Ty.string_reg_lang]Ty.string_reg_langletoption=Id.const~builtin:Re_option"option"[][Ty.string_reg_lang]Ty.string_reg_langletpower=with_cache~cache:(Hashtbl.create13)(funn->Id.const~builtin:(Re_powern)(Format.asprintf"power_%d"n)[][Ty.string_reg_lang]Ty.string_reg_lang)letloop=with_cache~cache:(Hashtbl.create13)(fun(n1,n2)->Id.const~builtin:(Re_loop(n1,n2))(Format.asprintf"loop_%d_%d"n1n2)[][Ty.string_reg_lang]Ty.string_reg_lang)endendend(* Constructors are simply constants *)moduleCstr=structtypet=term_constlettag=Id.taglethash=Id.hashletequal=Id.equalletcompare=Id.compareletget_tag=Id.get_tagletget_tag_last=Id.get_tag_lastletarity(c:t)=List.lengthc.ty.fun_vars,List.lengthc.ty.fun_argslettesterc=matchc.builtinwith|Constructor{adt;case;}->beginmatchTy.definitionadtwith|SomeAdt{cases;_}->cases.(case).tester|_->assertfalseend|_->raise(Constructor_expectedc)letvoid=matchdefine_adtTy.Const.unit[]["void",[]]with|[void,_]->void|_->assertfalseletpattern_arity(c:t)rettys=trylets=List.fold_left2Subst.Var.bindSubst.emptyc.ty.fun_varstysinlets=Ty.robinsonsc.ty.fun_retretinList.map(Ty.substs)c.ty.fun_argswith|Ty.Impossible_unification_->raise(Wrong_sum_type(c,ret))|Invalid_argument_->raise(Bad_term_arity(c,tys,[]))end(* Record fields are represented as their destructors, i.e. constants *)moduleField=structtypet=term_constlethash=Id.hashletequal=Id.equalletcompare=Id.compare(* Record field getter *)letfindty_ci=matchTy.definitionty_cwith|SomeAdt{record=true;cases=[|{dstrs;_}|];_}->beginmatchdstrs.(i)with|Somec->c|None->assertfalseend|_->raise(Record_type_expectedty_c)(* Record creation *)letindexty_cf=matchf.builtinwith|Destructor{adt=ty_d;case=i;field=j;_}->ifId.equalty_cty_dthenbeginassert(i=0);jendelseraise(Wrong_record_type(f,ty_c))|_->raise(Field_expectedf)end(* Filter check *)letreccheck_filtersresftysargs=function|[]->res|(name,active,check)::r->if!activethenmatch(checkftysargs)with|`Pass->check_filtersresftysargsr|`Warn->check_filtersresftysargsr|`Errormsg->raise(Filter_failed_term(name,res,msg))elsecheck_filtersresftysargsr(* Term creation *)letmk?(tags=Tag.empty)descrty={descr;ty;hash=-1;tags;}letof_varv=mk(Varv)v.ty(* This function does not check types enough, do not export outside the module *)letmk_bindbbody=mk(Binder(b,body))(tybody)(* Substitutions *)letrecty_var_list_substty_var_map=function|[]->ty_var_map|(v::r:ty_varlist)->ty_var_list_subst(Subst.Var.removevty_var_map)rletrecterm_var_list_substty_var_mapt_var_mapacc=function|[]->List.revacc,t_var_map|(v::r:term_varlist)->letty=Ty.substty_var_mapv.tyinifnot(Ty.equaltyv.ty)thenletnv=Var.mkv.nametyinterm_var_list_substty_var_map(Subst.Var.bindt_var_mapv(of_varnv))(nv::acc)relseterm_var_list_substty_var_map(Subst.Var.removevt_var_map)(v::acc)rletrecsubst_aux~fixty_var_mapt_var_map(t:t)=matcht.descrwith|Varv->beginmatchSubst.Var.getvt_var_mapwith|exceptionNot_found->t|term->iffixthensubst_aux~fixty_var_mapt_var_maptermelsetermend|App(f,tys,args)->letnew_tys=List.map(Ty.subst~fixty_var_map)tysinletnew_args=List.map(subst_aux~fixty_var_mapt_var_map)argsinifList.for_all2(==)new_tystys&&List.for_all2(==)new_argsargsthentelseapplyfnew_tysnew_args|Binder(b,body)->letb',ty_var_map,t_var_map=binder_subst~fixty_var_mapt_var_mapbinmk_bindb'(subst_aux~fixty_var_mapt_var_mapbody)|Match(scrutinee,branches)->letscrutinee=subst_aux~fixty_var_mapt_var_mapscrutineeinletbranches=List.map(branch_subst~fixty_var_mapt_var_map)branchesinpattern_matchscrutineebranchesandbinder_subst~fixty_var_mapt_var_map=function|Exists(tys,ts)->(* term variables in ts may have their types changed by the subst *)letty_var_map=ty_var_list_substty_var_maptysinletts,t_var_map=term_var_list_substty_var_mapt_var_map[]tsinExists(tys,ts),ty_var_map,t_var_map|Forall(tys,ts)->(* term variables in ts may have their types changed by the subst *)letty_var_map=ty_var_list_substty_var_maptysinletts,t_var_map=term_var_list_substty_var_mapt_var_map[]tsinForall(tys,ts),ty_var_map,t_var_map|Letinl->letl,t_var_map=binding_list_subst~fixty_var_mapt_var_map[]linLetinl,ty_var_map,t_var_mapandbinding_list_subst~fixty_var_mapt_var_mapacc=function|[]->List.revacc,t_var_map|((v,t)::r:(term_var*term)list)->lett=subst_aux~fixty_var_mapt_var_maptinifTy.equal(tyt)v.tythenbeginlett_var_map=Subst.Var.removevt_var_mapinletacc=(v,t)::accinbinding_list_subst~fixty_var_mapt_var_mapaccrendelsebeginletnv=Var.mkv.name(tyt)inlett_var_map=Subst.Var.bindt_var_mapv(of_varnv)inletacc=(nv,t)::accinbinding_list_subst~fixty_var_mapt_var_mapaccrendandbranch_subst~fixty_var_mapt_var_map(pattern,body)=let_,l=fvpatterninlet_,t_var_map=term_var_list_substty_var_mapt_var_map[]lin(subst_aux~fixty_var_mapt_var_mappattern,subst_aux~fixty_var_mapt_var_mapbody)andsubst?(fix=true)ty_var_mapt_var_mapt=ifSubst.is_emptyty_var_map&&Subst.is_emptyt_var_mapthentelsesubst_aux~fixty_var_mapt_var_mapt(* Application typechecking *)andinstantiate(f:term_const)tysargs=ifList.lengthf.ty.fun_vars<>List.lengthtys||List.lengthf.ty.fun_args<>List.lengthargsthenbeginraise(Bad_term_arity(f,tys,args))endelsebeginletmap=List.fold_left2Subst.Var.bindSubst.emptyf.ty.fun_varstysinlets=List.fold_left2(funsexpectedterm->tryTy.robinsonsexpected(tyterm)withTy.Impossible_unification_->raise(Wrong_type(term,Ty.substsexpected)))mapf.ty.fun_argsargsinSubst.iterTy.set_wildcards;Ty.substsf.ty.fun_retend(* Application *)andapplyftysargs=letret=instantiateftysargsinletres=mk(App(f,tys,args))retincheck_filtersresftysargs(Const.get_tagfFilter.term)(* Pattern matching *)andpattern_matchscrutineebranches=letscrutinee_ty=tyscrutineein(* first,
unify the type of the scrutinee and all patterns,
and unify the type of all bodies *)letbody_ty=Ty.wildcard()inlets=List.fold_left(funacc(pattern,body)->letacc=tryTy.robinsonaccscrutinee_ty(typattern)withTy.Impossible_unification_->raise(Wrong_type(pattern,scrutinee_ty))inletacc=tryTy.robinsonaccbody_ty(tybody)withTy.Impossible_unification_->raise(Wrong_type(body,body_ty))inacc)Subst.emptybranchesin(* Apply the substitution to the scrutinee, patterns and bodies *)let()=Subst.iterTy.set_wildcardsinletscrutinee=substsSubst.emptyscrutineeinletbranches=List.map(fun(pat,body)->(substsSubst.emptypat,substsSubst.emptybody))branchesin(* Check exhaustivity *)let()=check_exhaustivity(tyscrutinee)(List.mapfstbranches)in(* Build the pattern matching *)mk(Match(scrutinee,branches))body_ty(* Wrappers around application *)letapply_cstr=applyletapply_field(f:term_const)t=lettys=init_list(List.lengthf.ty.fun_vars)(fun_->Ty.wildcard())inapplyftys[t](* ADT constructor tester *)letcstr_testerct=lettester=Cstr.testercinletty_args=init_list(List.lengthtester.ty.fun_vars)(fun_->Ty.wildcard())inapplytesterty_args[t](* Recor creation *)letbuild_record_fieldsty_cl=letn=matchTy.definitionty_cwith|SomeAdt{record=true;cases=[|{dstrs;_}|];_}->Array.lengthdstrs|_->raise(Record_type_expectedty_c)inletfields=Array.makenNoneinList.iter(fun(field,value)->leti=Field.indexty_cfieldinmatchfields.(i)with|Some_->raise(Field_repeatedfield)|None->fields.(i)<-Somevalue)l;fieldsletmk_recordmissing=function|[]->raise(Invalid_argument"Dolmen.Expr.record")|((f,_)::_)asl->beginmatchf.builtinwith|Destructor{adt=ty_c;cstr=c;_}whenTy.is_recordty_c->letfields=build_record_fieldsty_clin(* Check that all fields are indeed present, and create the list
of term arguments *)lett_args=Array.to_list@@Array.mapi(funio->matchowith|None->missingty_ci|Somev->v)fieldsin(* Create type wildcard to be unified during application. *)letty_args=init_list(List.lengthc.ty.fun_vars)(fun_->Ty.wildcard())inapplycty_argst_args|_->raise(Field_expectedf)endletrecordl=mk_record(funty_ci->raise(Field_missing(Field.findty_ci)))lletrecord_witht=function|[]->t|l->letauxty_ci=letf=Field.findty_ciinapply_fieldftinmk_recordauxl(* typing annotations *)letensuretty=matchTy.robinsonSubst.emptytyt.tywith|s->substsSubst.emptyt|exceptionTy.Impossible_unification_->raise(Wrong_type(t,ty))(* coercion *)letcoercedst_tyt=letsrc_ty=tytinapplyConst.coerce[src_ty;dst_ty][t](* Common constructions *)letvoid=applyCstr.void[][]let_true=applyConst._true[][]let_false=applyConst._false[][]leteqab=applyConst.eq[tya][a;b]leteqs=function|[]->apply(Const.eqs0)[][]|(h::_)asl->apply(Const.eqs(List.lengthl))[tyh]lletdistinct=function|[]->apply(Const.distinct0)[][]|(h::_)asl->apply(Const.distinct(List.lengthl))[tyh]lletnegx=applyConst.neg[][x]let_andl=apply(Const._and(List.lengthl))[]llet_orl=apply(Const._or(List.lengthl))[]lletnandpq=applyConst.nand[][p;q]letnorpq=applyConst.nor[][p;q]letxorpq=applyConst.xor[][p;q]letimplypq=applyConst.imply[][p;q]letequivpq=applyConst.equiv[][p;q]letints=apply(Const.Int.ints)[][]letrats=apply(Const.Rat.rats)[][]letreals=apply(Const.Real.reals)[][](* arithmetic *)moduleInt=structletmk=intletminust=applyConst.Int.minus[][t]letaddab=applyConst.Int.add[][a;b]letsubab=applyConst.Int.sub[][a;b]letmulab=applyConst.Int.mul[][a;b]letdivab=applyConst.Int.div_e[][a;b]letremab=applyConst.Int.rem_e[][a;b]letdiv_eab=applyConst.Int.div_e[][a;b]letdiv_tab=applyConst.Int.div_t[][a;b]letdiv_fab=applyConst.Int.div_f[][a;b]letrem_eab=applyConst.Int.rem_e[][a;b]letrem_tab=applyConst.Int.rem_t[][a;b]letrem_fab=applyConst.Int.rem_f[][a;b]letabsa=applyConst.Int.abs[][a]letltab=applyConst.Int.lt[][a;b]letleab=applyConst.Int.le[][a;b]letgtab=applyConst.Int.gt[][a;b]letgeab=applyConst.Int.ge[][a;b]letfloora=applyConst.Int.floor[][a]letceilinga=applyConst.Int.ceiling[][a]lettruncatea=applyConst.Int.truncate[][a]letrounda=applyConst.Int.round[][a]letis_inta=applyConst.Int.is_int[][a]letis_rata=applyConst.Int.is_rat[][a]letto_intt=coerceTy.inttletto_ratt=coerceTy.rattletto_realt=coerceTy.realtletdivisiblest=applyConst.Int.divisible[][ints;t]endmoduleRat=struct(* let mk = rat *)letminust=applyConst.Rat.minus[][t]letaddab=applyConst.Rat.add[][a;b]letsubab=applyConst.Rat.sub[][a;b]letmulab=applyConst.Rat.mul[][a;b]letdivab=applyConst.Rat.div[][a;b]letdiv_eab=applyConst.Rat.div_e[][a;b]letdiv_tab=applyConst.Rat.div_t[][a;b]letdiv_fab=applyConst.Rat.div_f[][a;b]letrem_eab=applyConst.Rat.rem_e[][a;b]letrem_tab=applyConst.Rat.rem_t[][a;b]letrem_fab=applyConst.Rat.rem_f[][a;b]letltab=applyConst.Rat.lt[][a;b]letleab=applyConst.Rat.le[][a;b]letgtab=applyConst.Rat.gt[][a;b]letgeab=applyConst.Rat.ge[][a;b]letfloora=applyConst.Rat.floor[][a]letceilinga=applyConst.Rat.ceiling[][a]lettruncatea=applyConst.Rat.truncate[][a]letrounda=applyConst.Rat.round[][a]letis_inta=applyConst.Rat.is_int[][a]letis_rata=applyConst.Rat.is_rat[][a]letto_intt=coerceTy.inttletto_ratt=coerceTy.rattletto_realt=coerceTy.realtendmoduleReal=structletmk=realletminust=applyConst.Real.minus[][t]letaddab=applyConst.Real.add[][a;b]letsubab=applyConst.Real.sub[][a;b]letmulab=applyConst.Real.mul[][a;b]letdivab=applyConst.Real.div[][a;b]letdiv_eab=applyConst.Real.div_e[][a;b]letdiv_tab=applyConst.Real.div_t[][a;b]letdiv_fab=applyConst.Real.div_f[][a;b]letrem_eab=applyConst.Real.rem_e[][a;b]letrem_tab=applyConst.Real.rem_t[][a;b]letrem_fab=applyConst.Real.rem_f[][a;b]letltab=applyConst.Real.lt[][a;b]letleab=applyConst.Real.le[][a;b]letgtab=applyConst.Real.gt[][a;b]letgeab=applyConst.Real.ge[][a;b]letfloora=applyConst.Real.floor[][a]letceilinga=applyConst.Real.ceiling[][a]lettruncatea=applyConst.Real.truncate[][a]letrounda=applyConst.Real.round[][a]letis_inta=applyConst.Real.is_int[][a]letis_rata=applyConst.Real.is_rat[][a]letto_intt=coerceTy.inttletto_ratt=coerceTy.rattletto_realt=coerceTy.realtend(* Arrays *)letmatch_array_type=letsrc=Ty.Var.mk"_"inletdst=Ty.Var.mk"_"inletpat=Ty.array(Ty.of_varsrc)(Ty.of_vardst)in(funt->matchTy.pmatchSubst.emptypat(tyt)with|exceptionTy.Impossible_matching_->raise(Wrong_type(t,pat))|s->beginmatchSubst.Var.getsrcs,Subst.Var.getdstswith|res->res|exceptionNot_found->assertfalse(* internal error *)end)letselecttidx=letsrc,dst=match_array_typetinapplyConst.select[src;dst][t;idx]letstoretidxvalue=letsrc,dst=match_array_typetinapplyConst.store[src;dst][t;idx;value](* Bitvectors *)moduleBitv=structletmatch_bitv_typet=matchtytwith|{descr=App({builtin=Bitvi;_},_);_}->i|_->raise(Wrong_type(t,Ty.bitv0))letmks=apply(Const.Bitv.bitvs)[][]letconcatuv=leti=match_bitv_typeuinletj=match_bitv_typevinapply(Const.Bitv.concat(i,j))[][u;v]letextractijt=letn=match_bitv_typetin(* TODO: check that i and j are correct index for a bitv(n) *)apply(Const.Bitv.extract(i,j,n))[][t]letrepeatkt=letn=match_bitv_typetinapply(Const.Bitv.repeat(k,n))[][t]letzero_extendkt=letn=match_bitv_typetinapply(Const.Bitv.zero_extend(k,n))[][t]letsign_extendkt=letn=match_bitv_typetinapply(Const.Bitv.sign_extend(k,n))[][t]letrotate_rightkt=letn=match_bitv_typetinapply(Const.Bitv.rotate_right(k,n))[][t]letrotate_leftkt=letn=match_bitv_typetinapply(Const.Bitv.rotate_left(k,n))[][t]letnott=letn=match_bitv_typetinapply(Const.Bitv.notn)[][t]letand_uv=letn=match_bitv_typeuinapply(Const.Bitv.and_n)[][u;v]letor_uv=letn=match_bitv_typeuinapply(Const.Bitv.or_n)[][u;v]letnanduv=letn=match_bitv_typeuinapply(Const.Bitv.nandn)[][u;v]letnoruv=letn=match_bitv_typeuinapply(Const.Bitv.norn)[][u;v]letxoruv=letn=match_bitv_typeuinapply(Const.Bitv.xorn)[][u;v]letxnoruv=letn=match_bitv_typeuinapply(Const.Bitv.xnorn)[][u;v]letcompuv=letn=match_bitv_typeuinapply(Const.Bitv.compn)[][u;v]letnegt=letn=match_bitv_typetinapply(Const.Bitv.negn)[][t]letadduv=letn=match_bitv_typeuinapply(Const.Bitv.addn)[][u;v]letsubuv=letn=match_bitv_typeuinapply(Const.Bitv.subn)[][u;v]letmuluv=letn=match_bitv_typeuinapply(Const.Bitv.muln)[][u;v]letudivuv=letn=match_bitv_typeuinapply(Const.Bitv.udivn)[][u;v]leturemuv=letn=match_bitv_typeuinapply(Const.Bitv.uremn)[][u;v]letsdivuv=letn=match_bitv_typeuinapply(Const.Bitv.sdivn)[][u;v]letsremuv=letn=match_bitv_typeuinapply(Const.Bitv.sremn)[][u;v]letsmoduv=letn=match_bitv_typeuinapply(Const.Bitv.smodn)[][u;v]letshluv=letn=match_bitv_typeuinapply(Const.Bitv.shln)[][u;v]letlshruv=letn=match_bitv_typeuinapply(Const.Bitv.lshrn)[][u;v]letashruv=letn=match_bitv_typeuinapply(Const.Bitv.ashrn)[][u;v]letultuv=letn=match_bitv_typeuinapply(Const.Bitv.ultn)[][u;v]letuleuv=letn=match_bitv_typeuinapply(Const.Bitv.ulen)[][u;v]letugtuv=letn=match_bitv_typeuinapply(Const.Bitv.ugtn)[][u;v]letugeuv=letn=match_bitv_typeuinapply(Const.Bitv.ugen)[][u;v]letsltuv=letn=match_bitv_typeuinapply(Const.Bitv.sltn)[][u;v]letsleuv=letn=match_bitv_typeuinapply(Const.Bitv.slen)[][u;v]letsgtuv=letn=match_bitv_typeuinapply(Const.Bitv.sgtn)[][u;v]letsgeuv=letn=match_bitv_typeuinapply(Const.Bitv.sgen)[][u;v]endmoduleFloat=struct(* Floats *)letmatch_float_typet=matchtytwith|{descr=App({builtin=Float(e,s);_},_);_}->(e,s)|_->raise(Wrong_type(t,Ty.float00))letfpsignexpsignificand=lete=Bitv.match_bitv_typeexpinlets=Bitv.match_bitv_typesignificandinapply(Const.Float.fp(e,s+1))[][sign;exp;significand]letroundNearestTiesToEven=applyConst.Float.roundNearestTiesToEven[][]letroundNearestTiesToAway=applyConst.Float.roundNearestTiesToAway[][]letroundTowardPositive=applyConst.Float.roundTowardPositive[][]letroundTowardNegative=applyConst.Float.roundTowardNegative[][]letroundTowardZero=applyConst.Float.roundTowardZero[][]letplus_infinityes=apply(Const.Float.plus_infinity(e,s))[][]letminus_infinityes=apply(Const.Float.minus_infinity(e,s))[][]letplus_zeroes=apply(Const.Float.plus_zero(e,s))[][]letminus_zeroes=apply(Const.Float.minus_zero(e,s))[][]letnanes=apply(Const.Float.nan(e,s))[][]letabsx=letes=match_float_typexinapply(Const.Float.abses)[][x]letnegx=letes=match_float_typexinapply(Const.Float.neges)[][x]letaddrmxy=letes=match_float_typexinapply(Const.Float.addes)[][rm;x;y]letsubrmxy=letes=match_float_typexinapply(Const.Float.subes)[][rm;x;y]letmulrmxy=letes=match_float_typexinapply(Const.Float.mules)[][rm;x;y]letdivrmxy=letes=match_float_typexinapply(Const.Float.dives)[][rm;x;y]letfmarmxyz=letes=match_float_typexinapply(Const.Float.fmaes)[][rm;x;y;z]letsqrtrmx=letes=match_float_typexinapply(Const.Float.sqrtes)[][rm;x]letremxy=letes=match_float_typexinapply(Const.Float.remes)[][x;y]letroundToIntegralrmx=letes=match_float_typexinapply(Const.Float.roundToIntegrales)[][rm;x]letminxy=letes=match_float_typexinapply(Const.Float.mines)[][x;y]letmaxxy=letes=match_float_typexinapply(Const.Float.maxes)[][x;y]letleqxy=letes=match_float_typexinapply(Const.Float.leqes)[][x;y]letltxy=letes=match_float_typexinapply(Const.Float.ltes)[][x;y]letgeqxy=letes=match_float_typexinapply(Const.Float.geqes)[][x;y]letgtxy=letes=match_float_typexinapply(Const.Float.gtes)[][x;y]leteqxy=letes=match_float_typexinapply(Const.Float.eqes)[][x;y]letisNormalx=letes=match_float_typexinapply(Const.Float.isNormales)[][x]letisSubnormalx=letes=match_float_typexinapply(Const.Float.isSubnormales)[][x]letisZerox=letes=match_float_typexinapply(Const.Float.isZeroes)[][x]letisInfinitex=letes=match_float_typexinapply(Const.Float.isInfinitees)[][x]letisNaNx=letes=match_float_typexinapply(Const.Float.isNaNes)[][x]letisNegativex=letes=match_float_typexinapply(Const.Float.isNegativees)[][x]letisPositivex=letes=match_float_typexinapply(Const.Float.isPositivees)[][x]letto_realx=letes=match_float_typexinapply(Const.Float.to_reales)[][x]letieee_format_to_fpesbv=apply(Const.Float.ieee_format_to_fp(e,s))[][bv]letto_fpe2s2rmx=let(e1,s1)=match_float_typexinapply(Const.Float.to_fp(e1,s1,e2,s2))[][rm;x]letreal_to_fpesrmr=apply(Const.Float.real_to_fp(e,s))[][rm;r]letsbv_to_fpesrmbv=letn=Bitv.match_bitv_typebvinapply(Const.Float.sbv_to_fp(n,e,s))[][rm;bv]letubv_to_fpesrmbv=letn=Bitv.match_bitv_typebvinapply(Const.Float.ubv_to_fp(n,e,s))[][rm;bv]letto_ubvmrmx=let(e,s)=match_float_typexinapply(Const.Float.to_ubv(e,s,m))[][rm;x]letto_sbvmrmx=let(e,s)=match_float_typexinapply(Const.Float.to_sbv(e,s,m))[][rm;x]endmoduleString=structletof_ustrings=apply(Const.String.strings)[][]letlengths=applyConst.String.length[][s]letatsi=applyConst.String.at[][s;i]letis_digits=applyConst.String.is_digit[][s]letto_codes=applyConst.String.to_code[][s]letof_codei=applyConst.String.of_code[][i]letto_ints=applyConst.String.to_int[][s]letof_inti=applyConst.String.of_int[][i]letconcatss'=applyConst.String.concat[][s;s']letsubsin=applyConst.String.sub[][s;i;n]letindex_ofss'i=applyConst.String.index_of[][s;s';i]letreplacespatby=applyConst.String.replace[][s;pat;by]letreplace_allspatby=applyConst.String.replace_all[][s;pat;by]letreplace_respatby=applyConst.String.replace_re[][s;pat;by]letreplace_re_allspatby=applyConst.String.replace_re_all[][s;pat;by]letis_prefixss'=applyConst.String.is_prefix[][s;s']letis_suffixss'=applyConst.String.is_suffix[][s;s']letcontainsss'=applyConst.String.contains[][s;s']letltss'=applyConst.String.lt[][s;s']letleqss'=applyConst.String.leq[][s;s']letin_resre=applyConst.String.in_re[][s;re]moduleRegLan=structletempty=applyConst.String.Reg_Lang.empty[][]letall=applyConst.String.Reg_Lang.all[][]letallchar=applyConst.String.Reg_Lang.allchar[][]letof_strings=applyConst.String.Reg_Lang.of_string[][s]letrangess'=applyConst.String.Reg_Lang.range[][s;s']letconcatrere'=applyConst.String.Reg_Lang.concat[][re;re']letunionrere'=applyConst.String.Reg_Lang.union[][re;re']letinterrere'=applyConst.String.Reg_Lang.inter[][re;re']letdiffrere'=applyConst.String.Reg_Lang.diff[][re;re']letstarre=applyConst.String.Reg_Lang.star[][re]letcrossre=applyConst.String.Reg_Lang.cross[][re]letcomplementre=applyConst.String.Reg_Lang.complement[][re]letoptionre=applyConst.String.Reg_Lang.option[][re]letpowernre=apply(Const.String.Reg_Lang.powern)[][re]letloopn1n2re=apply(Const.String.Reg_Lang.loop(n1,n2))[][re]endend(* Wrappers for the tff typechecker *)letall_(tys,ts)body=ifTy.(equalprop)(tybody)thenmk_bind(Forall(tys,ts))bodyelseraise(Wrong_type(body,Ty.prop))letex_(tys,ts)body=ifTy.(equalprop)(tybody)thenmk_bind(Exists(tys,ts))bodyelseraise(Wrong_type(body,Ty.prop))letitecondt_thent_else=letty=tyt_theninapplyConst.ite[ty][cond;t_then;t_else](* let-bindings *)letbindvt=let()=Id.tagvTags.boundtinof_varvletletinlbody=List.iter(fun((v:Var.t),t)->ifnot(Ty.equalv.ty(tyt))thenraise(Wrong_type(t,v.ty)))l;mk_bind(Letinl)bodyend