123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725(**************************************************************************)(* This file is part of the Codex semantics library. *)(* *)(* Copyright (C) 2013-2025 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* *)(* you can redistribute it and/or modify it under the terms of the GNU *)(* Lesser General Public License as published by the Free Software *)(* Foundation, version 2.1. *)(* *)(* It is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file LICENSE). *)(* *)(**************************************************************************)moduleLog=Tracelog.Make(structletcategory="Function_symbol"end);;moduleIn_bits=Units.In_bits(* We make the type concrete, so the type checker knows that they
cannot be equal. *)typeboolean=privateTypeBooleantypeinteger=privateTypeIntegertypeenum=privateTypeEnumtypebitvector=privateTypeBitvectortypebinary=bitvectortypememory=privateTypeMemorytypesize=In_bits.ttypecase=inttype'atyp=|Boolean:booleantyp|Integer:integertyp|Enum:enumtyp|Binary:size->binarytyp|Memory:memorytyptypez_t=Z.t(* We define these dummy types, used to represent knowledge about
arity in gadt. We need a definition and use constructors for this,
but they are never used. *)typear0=privateAr0type'aar1=privateAr1type('a,'b)ar2=privateAr2typeany_type=Any_type:'atyp->any_type[@@unboxed];;type('arg,'ret)function_symbol=|True:(ar0,boolean)function_symbol|False:(ar0,boolean)function_symbol|And:((boolean,boolean)ar2,boolean)function_symbol|Or:((boolean,boolean)ar2,boolean)function_symbol|Not:(booleanar1,boolean)function_symbol|BoolUnion:((boolean,boolean)ar2,boolean)function_symbol|Biconst:size*z_t->(ar0,binary)function_symbol|Biadd:{size:size;flags:Flags.Biadd.t}->((binary,binary)ar2,binary)function_symbol|Bisub:{size:size;flags:Flags.Bisub.t}->((binary,binary)ar2,binary)function_symbol|Bimul:{size:size;flags:Flags.Bimul.t}->((binary,binary)ar2,binary)function_symbol|Biudiv:size->((binary,binary)ar2,binary)function_symbol|Bisdiv:size->((binary,binary)ar2,binary)function_symbol|Biumod:size->((binary,binary)ar2,binary)function_symbol|Bismod:size->((binary,binary)ar2,binary)function_symbol|Bshl:{size:size;flags:Flags.Bshl.t}->((binary,binary)ar2,binary)function_symbol|Bashr:size->((binary,binary)ar2,binary)function_symbol|Blshr:size->((binary,binary)ar2,binary)function_symbol|Band:size->((binary,binary)ar2,binary)function_symbol|Bor:size->((binary,binary)ar2,binary)function_symbol|Bxor:size->((binary,binary)ar2,binary)function_symbol|Beq:size->((binary,binary)ar2,boolean)function_symbol|Bisle:size->((binary,binary)ar2,boolean)function_symbol|Biule:size->((binary,binary)ar2,boolean)function_symbol|Bconcat:size*size->((binary,binary)ar2,binary)function_symbol|Bextract:{size:size;index:In_bits.t;oldsize:size}->(binaryar1,binary)function_symbol|Bsext:size->(binaryar1,binary)function_symbol|Buext:size->(binaryar1,binary)function_symbol|Bofbool:size->(booleanar1,binary)function_symbol|Bunion:Operator_ids.Condition.t*size->((binary,binary)ar2,binary)function_symbol|Bchoose:Operator_ids.Choice.t*size->(binaryar1,binary)function_symbol|Iconst:z_t->(ar0,integer)function_symbol|Iadd:((integer,integer)ar2,integer)function_symbol|Isub:((integer,integer)ar2,integer)function_symbol|Imul:((integer,integer)ar2,integer)function_symbol|Idiv:((integer,integer)ar2,integer)function_symbol|Imod:((integer,integer)ar2,integer)function_symbol|Ishl:((integer,integer)ar2,integer)function_symbol|Ishr:((integer,integer)ar2,integer)function_symbol|Ior:((integer,integer)ar2,integer)function_symbol|Ixor:((integer,integer)ar2,integer)function_symbol|Iand:((integer,integer)ar2,integer)function_symbol|Ieq:((integer,integer)ar2,boolean)function_symbol|Ile:((integer,integer)ar2,boolean)function_symbol|Itimes:z_t->(integerar1,integer)function_symbol|EnumConst:case->(ar0,enum)function_symbol|CaseOf:case->(enumar1,boolean)function_symbol;;lettype_of:typeab.(a,b)function_symbol->btyp=function|True->Boolean|False->Boolean|And->Boolean|Or->Boolean|Not->Boolean|Biconst(size,_)->Binarysize|Biadd{size}->Binarysize|Bisub{size}->Binarysize|Bimul{size}->Binarysize|Biudiv(size)->Binarysize|Bisdiv(size)->Binarysize|Biumod(size)->Binarysize|Bismod(size)->Binarysize|Bshl{size}->Binarysize|Bashr(size)->Binarysize|Blshr(size)->Binarysize|Band(size)->Binarysize|Bor(size)->Binarysize|Bxor(size)->Binarysize|Beq(size)->Boolean|Bisle(size)->Boolean|Biule(size)->Boolean|Bconcat(s1,s2)->Binary(Units.In_bits.(s1+s2))|Bextract{size;index;oldsize}->Binarysize|Bsext(size)->Binarysize|Buext(size)->Binarysize|Bofbool(size)->Binarysize|Bunion(_,size)->Binarysize|Bchoose(_,size)->Binarysize|Iconst_->Integer|Iadd->Integer|Isub->Integer|Imul->Integer|Idiv->Integer|Imod->Integer|Ishl->Integer|Ishr->Integer|Ior->Integer|Ixor->Integer|Iand->Integer|Ieq->Boolean|Ile->Boolean|Itimes_->Integer|BoolUnion->Boolean|EnumConst_->Enum|CaseOf_->Boolean;;(* Used to identify a problem when we do not have a pretty printer. *)let_identify:typeab.(a,b)function_symbol->int=function|True->assertfalse|False->assertfalse|And->assertfalse|Or->assertfalse|Not->assertfalse|Biconst(_,_)->assertfalse|Biadd_->assertfalse|Bisub_->assertfalse|Bimul_->assertfalse|Biudiv_->assertfalse|Bisdiv_->assertfalse|Biumod_->assertfalse|Bismod_->assertfalse|Bshl_->assertfalse|Bashr_->assertfalse|Blshr_->assertfalse|Band_->assertfalse|Bor_->assertfalse|Bxor_->assertfalse|Beq_->assertfalse|Bisle_->assertfalse|Biule_->assertfalse|Bconcat(_,_)->assertfalse|Bextract_->assertfalse|Bsext_->assertfalse|Buext_->assertfalse|Bofbool_->assertfalse|Bunion(_,_)->assertfalse|Bchoose(_,_)->assertfalse|Iconst_->assertfalse|Iadd->assertfalse|Isub->assertfalse|Imul->assertfalse|Idiv->assertfalse|Imod->assertfalse|Ishl->assertfalse|Ishr->assertfalse|Ior->assertfalse|Ixor->assertfalse|Iand->assertfalse|Ieq->assertfalse|Ile->assertfalse|Itimes_->assertfalse|BoolUnion->assertfalse|EnumConst_->assertfalse|CaseOf_->assertfalse(* We use the last 6 bits (0..63) as the type. *)(* We use bit 7 and 8 for flags. *)(* We use 8 bits, from 9 to 15, for the size1 (0..255) *)(* We use 8 bits, from 16 to 24, for the size2 (0..255) *)(* If there are other large elements: we sdbm with this. *)(* MAYBE: Could be ppx generated. *)lethash:typeab.(a,b)function_symbol->int=function|True->1|False->2|And->3|Or->4|Not->5|Iadd->6|Isub->7|Imul->8|Idiv->9|Imod->10|Ishl->11|Ishr->12|Ior->13|Ixor->14|Iand->15|Ieq->16|Ile->17|Biadd{size;flags}->18lor((flags:>int)*64)lor((size:>int)lsl8)|Bisub{size;flags}->19lor((flags:>int)*64)lor((size:>int)lsl8)|Bimul{size;flags}->20lor((flags:>int)*64)lor((size:>int)lsl8)|Bshl{size;flags}->21lor((flags:>int)*64)lor((size:>int)lsl8)|Biudiv(size)->22lor((size:>int)lsl8)|Bisdiv(size)->23lor((size:>int)lsl8)|Biumod(size)->24lor((size:>int)lsl8)|Bismod(size)->25lor((size:>int)lsl8)|Bashr(size)->26lor((size:>int)lsl8)|Blshr(size)->27lor((size:>int)lsl8)|Band(size)->28lor((size:>int)lsl8)|Bor(size)->29lor((size:>int)lsl8)|Bxor(size)->30lor((size:>int)lsl8)|Beq(size)->31lor((size:>int)lsl8)|Bisle(size)->32lor((size:>int)lsl8)|Biule(size)->33lor((size:>int)lsl8)|Bconcat(s1,s2)->34lor((s1:>int)lsl8)lor((s2:>int)lsl16)|Bextract{size;index;oldsize}->35lor((size:>int)lsl8)lor((oldsize:>int)lsl16)lor((index:>int)lsl24)|Bsext(size)->36lor((size:>int)lsl8)|Buext(size)->37lor((size:>int)lsl8)|Bofbool(size)->38lor((size:>int)lsl8)|Bchoose(id,size)->Hashing.hash2(39lor((size:>int)lsl8))(id:>int)|Bunion(id,size)->Hashing.hash2(40lor((size:>int)lsl8))(id:>int)|Itimesk->Hashing.hash241(Z.hashk)|Iconstk->Hashing.hash242(Z.hashk)|Biconst(size,k)->Hashing.hash2(43lor((size:>int)lsl8))(Z.hashk)|BoolUnion->44|CaseOfcase->45lor(caselsl16)|EnumConstcase->46lor(caselsl16)(* TODO: Could be ppx generated. *)letequal:typeabcd.(a,b)function_symbol->(c,d)function_symbol->bool=funab->(Obj.magica)==(Obj.magicb)||(* Shortcut with small performance benefit. *)match(a,b)with|True,True->true|False,False->true|And,And->true|Or,Or->true|Not,Not->true|BoolUnion,BoolUnion->true|Iadd,Iadd->true|Isub,Isub->true|Imul,Imul->true|Idiv,Idiv->true|Imod,Imod->true|Ishl,Ishl->true|Ishr,Ishr->true|Ior,Ior->true|Ixor,Ixor->true|Iand,Iand->true|Ieq,Ieq->true|Ile,Ile->true|Biadd{size=s1;flags=flags1},Biadd{size=s2;flags=flags2}->s1=s2&&flags1=flags2|Bisub{size=s1;flags=flags1},Bisub{size=s2;flags=flags2}->s1=s2&&flags1=flags2|Bimul{size=s1;flags=flags1},Bimul{size=s2;flags=flags2}->s1=s2&&Int.equal(flags1:>int)(flags2:>int)|Bshl{size=s1;flags=flags1},Bshl{size=s2;flags=flags2}->s1=s2&&flags1=flags2|Biudiv(s1),Biudiv(s2)->s1==s2|Bisdiv(s1),Bisdiv(s2)->s1==s2|Biumod(s1),Biumod(s2)->s1==s2|Bismod(s1),Bismod(s2)->s1==s2|Bashr(s1),Bashr(s2)->s1==s2|Blshr(s1),Blshr(s2)->s1==s2|Band(s1),Band(s2)->s1==s2|Bor(s1),Bor(s2)->s1==s2|Bxor(s1),Bxor(s2)->s1==s2|Beq(s1),Beq(s2)->s1==s2|Bisle(s1),Bisle(s2)->s1==s2|Biule(s1),Biule(s2)->s1==s2|Bconcat(s1,s2),Bconcat(s3,s4)->s1==s3&&s2==s4|Bextract{size=s1;index=i1;oldsize=olds1},Bextract{size=s2;index=i2;oldsize=olds2}->i1==i2&&s1==s2&&olds1==olds2|Bsext(s1),Bsext(s2)->s1==s2|Buext(s1),Buext(s2)->s1==s2|Bofbool(s1),Bofbool(s2)->s1==s2|Bchoose(id1,s1),Bchoose(id2,s2)->id1==id2&&(assert(s1==s2);true)|Bunion(id1,s1),Bunion(id2,s2)->id1==id2&&(assert(s1==s2);true)|Itimesk1,Itimesk2->Z.equalk1k2|Iconstk1,Iconstk2->Z.equalk1k2|Biconst(s1,k1),Biconst(s2,k2)->s1==s2&&Z.equalk1k2|CaseOfc1,CaseOfc2->c1==c2|EnumConstc1,EnumConstc2->c1==c2|_,_->if(hasha)==(hashb)thenbeginLog.warning(funp->p"Bad hash collision or mistake");(* let _ = identify b in () *)end;false;;(**************** Builders ****************)moduleBuild=structmoduleArity=structtypenonrec'rar0=(ar0,'r)function_symboltypenonrec('a,'r)ar1=('aar1,'r)function_symboltypenonrec('a,'b,'r)ar2=(('a,'b)ar2,'r)function_symboltypenonrec('a,'b,'c,'r)ar3=unitendmoduleBinary=structletbiconst~sizek=Biconst(size,k)letbiadd~size~flags=Biadd{size;flags}letbisub~size~flags=Bisub{size;flags}letbimul~size~flags=Bimul{size;flags}letbor~size=Bor(size)letband~size=Band(size)letbxor~size=Bxor(size)letbisdiv~size=Bisdiv(size)letbismod~size=Bismod(size)letbiudiv~size=Biudiv(size)letbiumod~size=Biumod(size)letbshl~size~flags=Bshl{size;flags}letbashr~size=Bashr(size)letblshr~size=Blshr(size)letbisle~size=Bisle(size)letbiule~size=Biule(size)letbeq~size=Beq(size)letbconcat~size1~size2=Bconcat(size1,size2)letbextract~size~index~oldsize=Bextract{size;oldsize;index}letvalid~size=assertfalseletvalid_ptr_arith~size=assertfalseletbindex~size=assertfalseletbshift~size~offset~max=assertfalseletbuninit~size=assertfalseletbsext~size~oldsize=Bsext(size)letbuext~size~oldsize=Buext(size)letbofbool~size=Bofbool(size)letbchoose~sizechoice=Bchoose(choice,size)letbunion~sizecond=Bunion(cond,size)endend(**************** Generic pretty printers. ****************)(* This allows to print something (a type 'at) that contains a term. *)moduletypePRETTY_ARG=sigtype'at(* The term to print. *)type'apack(* Packing of the arguments. *)valpretty:Format.formatter->'at->unit(* Extraction of the subterms. *)valextract1:'aar1pack->'atvalextract2:('a,'b)ar2pack->'at*'btendmoduletypePRETTY_RESULT=sigtype'attype'apackvalpretty_destruct:Format.formatter->('arg,'a)function_symbol->'argpack->unitendmodulePretty(M:PRETTY_ARG):PRETTY_RESULTwithtype'at='aM.tandtype'apack='aM.pack=structtype'at='aM.ttype'apack='aM.packletpretty_destruct:typeaarg.Format.formatter->(arg,a)function_symbol->argM.pack->unit=funfmttermarg->letar1argstring=letx1=M.extract1arginFormat.fprintffmtstringM.prettyx1inletar2argstring=letx1,x2=M.extract2arginFormat.fprintffmtstringM.prettyx1M.prettyx2inletopenFormatinmatchtermwith|True->fprintffmt"true"|False->fprintffmt"false"|And->ar2arg"%a && %a"|Or->ar2arg"%a || %a"|Not->ar1arg"!(%a)"|BoolUnion->ar2arg"boolunion(%a,%a)"|Biconst(size,k)->fprintffmt"(bin%d "(size:>int);(ifZ.numbitsk<8then(fprintffmt"%s)"@@Z.to_stringk)elsefprintffmt"0x%s)"@@Z.format"x"k)|Biadd(size)->ar2arg"(%a +b %a)"|Bisub(size)->ar2arg"(%a -b %a)"|Bimul(size)->ar2arg"(%a * %a)"|Biudiv(size)->ar2arg"(%a /bu %a)"|Bisdiv(size)->ar2arg"(%a /bs %a)"|Biumod(size)->ar2arg"(%a %%bs %a)"|Bismod(size)->ar2arg"(%a %%bu %a)"|Bshl(size)->ar2arg"(%a << %a)"|Blshr(size)->ar2arg"(%a >>l %a)"|Bashr(size)->ar2arg"(%a >>r %a)"|Band(size)->ar2arg"(%a & %a)"|Bor(size)->ar2arg"(%a | %a)"|Bxor(size)->ar2arg"(%a ^ %a)"|Beq(size)->ar2arg"(%a =b= %a)"|Bisle(size)->ar2arg"(%a <=bs %a)"|Biule(size)->ar2arg"(%a <=bu %a)"|Bconcat(s1,s2)->ar2arg"(%a::%a)"|Bunion(id,size)->letx,y=M.extract2arginfprintffmt"bunion%d_%d(%a,%a)"(id:>int)(size:>int)M.prettyxM.prettyy|Bextract{size;index;oldsize}->(ar1arg"(%a)[%d:%d]")(index:>int)((index:>int)+(size:>int))|Buext(size)->letx=M.extract1arginfprintffmt"buext%d(%a)"(size:>int)M.prettyx|Bsext(size)->letx=M.extract1arginfprintffmt"bsext%d(%a)"(size:>int)M.prettyx|Bofbool(size)->letx=M.extract1arginfprintffmt"bofbool%d(%a)"(size:>int)M.prettyx|Bchoose(id,size)->letx=M.extract1arginfprintffmt"bchoose%d_%d(%a)"(id:>int)(size:>int)M.prettyx|Iconstk->(ifZ.numbitsk<8then(fprintffmt"%s"@@Z.to_stringk)elsefprintffmt"0x%s"@@Z.format"x"k)|Idiv->ar2arg"(%a / %a)"|Imod->ar2arg"(%a %% %a)"|Iadd->ar2arg"(%a + %a)"|Isub->ar2arg"(%a - %a)"|Ieq->ar2arg"(%a = %a)"|Ile->ar2arg"(%a <= %a)"|Imul->ar2arg"(%a * %a)"|Ishl->ar2arg"(%a << %a)"|Ishr->ar2arg"(%a >> %a)"|Iand->ar2arg"(%a & %a)"|Ior->ar2arg"(%a | %a)"|Ixor->ar2arg"(%a ^ %a)"|Itimesk->letx=M.extract1arginfprintffmt"(%s * %a)"(Z.to_stringk)M.prettyx|EnumConstcase->fprintffmt"(enum_const %d)"case|CaseOfcase->letx=M.extract1arginfprintffmt"case %d of %a"caseM.prettyxend(**************** Generic evaluation functions. ****************)(* (Currently not used) *)[@@@warning"-32"](* Generic evaluators; probably the genericity is not worth it (and,
for instance, we lack some additional arguments here). *)moduleUnused_Eval(T:sigtype('arg,'res)tvaltrue_:(ar0,boolean)tvalfalse_:(ar0,boolean)tval(&&):((boolean,boolean)ar2,boolean)tval(||):((boolean,boolean)ar2,boolean)tvalnot:(booleanar1,boolean)tvalbiconst:size:size->z_t->(ar0,binary)tvalbitimes:size:size->z_t->(binaryar1,binary)tvalbiadd:size:size->((binary,binary)ar2,binary)tvalbisub:size:size->((binary,binary)ar2,binary)tvalbimul:size:size->((binary,binary)ar2,binary)tvalbisdiv:size:In_bits.t->((binary,binary)ar2,binary)tvalbismod:size:In_bits.t->((binary,binary)ar2,binary)tvalbiudiv:size:In_bits.t->((binary,binary)ar2,binary)tvalbiumod:size:In_bits.t->((binary,binary)ar2,binary)tvalbshl:size:In_bits.t->((binary,binary)ar2,binary)tvalbashr:size:In_bits.t->((binary,binary)ar2,binary)tvalblshr:size:In_bits.t->((binary,binary)ar2,binary)tvalband:size:In_bits.t->((binary,binary)ar2,binary)tvalbor:size:In_bits.t->((binary,binary)ar2,binary)tvalbxor:size:In_bits.t->((binary,binary)ar2,binary)tvalbeq:size:size->((binary,binary)ar2,boolean)tvalbisle:size:size->((binary,binary)ar2,boolean)tvalbiule:size:size->((binary,binary)ar2,boolean)t(* First argument become most significant. *)valbconcat:size1:In_bits.t->size2:In_bits.t->((binary,binary)ar2,binary)tvalbextract:size:In_bits.t->index:In_bits.t->oldsize:In_bits.t->(binaryar1,binary)tvalbuext:size:In_bits.t->(binaryar1,binary)tvalbsext:size:In_bits.t->(binaryar1,binary)tvaliconst:z_t->(ar0,integer)tvalitimes:z_t->(integerar1,integer)tvaliadd:((integer,integer)ar2,integer)tvalimul:((integer,integer)ar2,integer)tvalidiv:((integer,integer)ar2,integer)tvalimod:((integer,integer)ar2,integer)tvalishl:((integer,integer)ar2,integer)tvalishr:((integer,integer)ar2,integer)tvaliand:((integer,integer)ar2,integer)tvalior:((integer,integer)ar2,integer)tvalixor:((integer,integer)ar2,integer)tvalisub:((integer,integer)ar2,integer)tvalieq:((integer,integer)ar2,boolean)tvalile:((integer,integer)ar2,boolean)tend)=structleteval:typeargres.(arg,res)function_symbol->(arg,res)T.t=function|True->T.true_|False->T.false_|And->T.(&&)|Or->T.(||)|Not->T.not|Biconst(size,k)->T.biconst~sizek|Biadd{size;flags}->(* T.biadd ~size ~nsw ~nuw *)assertfalse|Bisub{size;flags}->(* T.bisub ~size ~nsw ~nuw *)assertfalse|Bimul{size;flags}->(* T.bimul ~size ~nsw ~nuw *)assertfalse|Bisdiv(size)->T.bisdiv~size|Bismod(size)->T.bismod~size|Biudiv(size)->T.biudiv~size|Biumod(size)->T.biumod~size|Bshl{size;flags}->(* T.bshl ~size *)assertfalse|Bashr(size)->T.bashr~size|Blshr(size)->T.blshr~size|Band(size)->T.band~size|Bor(size)->T.bor~size|Bxor(size)->T.bxor~size|Beq(size)->T.beq~size|Bisle(size)->T.bisle~size|Biule(size)->T.biule~size|Buext(size)->T.buext~size|Bsext(size)->T.bsext~size|Bconcat(size1,size2)->T.bconcat~size1~size2|Bextract{size;index;oldsize}->T.bextract~size~index~oldsize|Bofbool_->assertfalse|Bchoose_->assertfalse|Bunion_->assertfalse|BoolUnion->assertfalse|Iconstk->T.iconstk|Itimesk->T.itimesk|Iadd->T.iadd|Imul->T.imul|Idiv->T.idiv|Imod->T.imod|Ishl->T.ishl|Ishr->T.ishr|Iand->T.iand|Ior->T.ior|Ixor->T.ixor|Isub->T.isub|Ieq->T.ieq|Ile->T.ile|EnumConstcase->assertfalse|CaseOfcase->assertfalse;;end(* Idem; it is probably better if eval matches the term together with
its argument, and directly known the type of the arguments. *)moduleUnused_Eval_Forward(T:sigtype'attype'apackvalextract2:('a,'b)ar2pack->'at*'btvalextract1:('a)ar1pack->'atvaltrue_:booleantvalfalse_:booleantval(&&):booleant->booleant->booleantval(||):booleant->booleant->booleantvalnot:booleant->booleantvalbiconst:size:size->z_t->binarytvalbitimes:size:size->z_t->binaryt->binarytvalbiadd:size:size->binaryt->binaryt->binarytvalbisub:size:size->binaryt->binaryt->binarytvalbimul:size:size->binaryt->binaryt->binarytvalbisdiv:size:In_bits.t->binaryt->binaryt->binarytvalbismod:size:In_bits.t->binaryt->binaryt->binarytvalbiudiv:size:In_bits.t->binaryt->binaryt->binarytvalbiumod:size:In_bits.t->binaryt->binaryt->binarytvalbshl:size:In_bits.t->binaryt->binaryt->binarytvalbashr:size:In_bits.t->binaryt->binaryt->binarytvalblshr:size:In_bits.t->binaryt->binaryt->binarytvalband:size:In_bits.t->binaryt->binaryt->binarytvalbor:size:In_bits.t->binaryt->binaryt->binarytvalbxor:size:In_bits.t->binaryt->binaryt->binarytvalbeq:size:size->binaryt->binaryt->booleantvalbisle:size:size->binaryt->binaryt->booleantvalbiule:size:size->binaryt->binaryt->booleantvalbconcat:size1:In_bits.t->size2:In_bits.t->binaryt->binaryt->binarytvalbextract:size:In_bits.t->index:In_bits.t->oldsize:In_bits.t->binaryt->binarytvalbuext:size:In_bits.t->binaryt->binarytvalbsext:size:In_bits.t->binaryt->binarytvaliconst:z_t->integertvalitimes:z_t->integert->integertvaliadd:integert->integert->integertvalimul:integert->integert->integertvalidiv:integert->integert->integertvalimod:integert->integert->integertvalishl:integert->integert->integertvalishr:integert->integert->integertvaliand:integert->integert->integertvalior:integert->integert->integertvalixor:integert->integert->integertvalisub:integert->integert->integertvalieq:integert->integert->booleantvalile:integert->integert->booleantend)=structleteval:typeargres.(arg,res)function_symbol->argT.pack->resT.t=function|True->fun_->T.true_|False->fun_->T.false_|And->funarg->let(b1,b2)=T.extract2arginT.(&&)b1b2|Or->funarg->let(b1,b2)=T.extract2arginT.(||)b1b2|Not->funarg->T.not@@T.extract1arg|Biconst(size,k)->fun_->T.biconst~sizek|Biadd{size;flags}->funarg->let(_b1,_b2)=T.extract2argin(* T.biadd ~size b1 b2 *)assertfalse|Bisub{size;flags}->funarg->let(_b1,_b2)=T.extract2argin(* T.bisub ~size b1 b2 *)assertfalse|Bimul{size;flags}->funarg->let(_b1,_b2)=T.extract2argin(* T.bimul ~size b1 b2 *)assertfalse|Bisdiv(size)->funarg->let(b1,b2)=T.extract2arginT.bisdiv~sizeb1b2|Bismod(size)->funarg->let(b1,b2)=T.extract2arginT.bismod~sizeb1b2|Biudiv(size)->funarg->let(b1,b2)=T.extract2arginT.biudiv~sizeb1b2|Biumod(size)->funarg->let(b1,b2)=T.extract2arginT.biumod~sizeb1b2|Bshl{size;flags}->funarg->let(_b1,_b2)=T.extract2argin(* T.bshl ~size b1 b2 *)assertfalse|Bashr(size)->funarg->let(b1,b2)=T.extract2arginT.bashr~sizeb1b2|Blshr(size)->funarg->let(b1,b2)=T.extract2arginT.blshr~sizeb1b2|Band(size)->funarg->let(b1,b2)=T.extract2arginT.band~sizeb1b2|Bor(size)->funarg->let(b1,b2)=T.extract2arginT.bor~sizeb1b2|Bxor(size)->funarg->let(b1,b2)=T.extract2arginT.bxor~sizeb1b2|Beq(size)->funarg->let(b1,b2)=T.extract2arginT.beq~sizeb1b2|Bisle(size)->funarg->let(b1,b2)=T.extract2arginT.bisle~sizeb1b2|Biule(size)->funarg->let(b1,b2)=T.extract2arginT.biule~sizeb1b2|Buext(size)->funarg->T.buext~size@@T.extract1arg|Bsext(size)->funarg->T.bsext~size@@T.extract1arg|Bconcat(size1,size2)->funarg->let(b1,b2)=T.extract2arginT.bconcat~size1~size2b1b2|Bextract{size;index;oldsize}->funarg->T.bextract~size~index~oldsize@@T.extract1arg|Bofbool(size)->assertfalse|Bchoose(id,size)->assertfalse|Bunion(id,size)->assertfalse|Iconstk->fun_->T.iconstk|Itimesk->funarg->T.itimesk@@T.extract1arg|Iadd->funarg->let(i1,i2)=T.extract2arginT.iaddi1i2|Imul->funarg->let(i1,i2)=T.extract2arginT.imuli1i2|Idiv->funarg->let(i1,i2)=T.extract2arginT.idivi1i2|Imod->funarg->let(i1,i2)=T.extract2arginT.imodi1i2|Ishl->funarg->let(i1,i2)=T.extract2arginT.ishli1i2|Ishr->funarg->let(i1,i2)=T.extract2arginT.ishri1i2|Iand->funarg->let(i1,i2)=T.extract2arginT.iandi1i2|Ior->funarg->let(i1,i2)=T.extract2arginT.iori1i2|Ixor->funarg->let(i1,i2)=T.extract2arginT.ixori1i2|Isub->funarg->let(i1,i2)=T.extract2arginT.isubi1i2|Ieq->funarg->let(i1,i2)=T.extract2arginT.ieqi1i2|Ile->funarg->let(i1,i2)=T.extract2arginT.ilei1i2|BoolUnion->assertfalse|EnumConst_->assertfalse|CaseOf(case)->funarg->let_b=T.extract1arginassertfalseend(* Smartcons could be the home to a generic implementation of Smart
constructors, independent from the data attached to type t.
One issue is how to handle conditions; e.g. 0 * (1/x) can be
rewritten to 0 only if x is non-zero. Maybe we should be combining
the "conditions" attached to each argument, if there are some. *)moduleUnused_SmartCons(M:sigtype'atvaldestruct:'bt->('a,'b)function_symbol*'atvalconstruct:('a,'b)function_symbol->'at->'btvalsplit_boolean_boolean:(boolean,boolean)ar2t->booleant*booleantvalcombine_boolean_boolean:booleant->booleant->(boolean,boolean)ar2tend)=structlet(&&):booleanM.t->booleanM.t->booleanM.t=funab->matchM.destructawith|(True,_)->b|_->matchM.destructbwith|(True,_)->a|_->M.constructAnd@@M.combine_boolean_booleanab;;end[@@@warning"+32"]