123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231(**************************************************************************)(* 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). *)(* *)(**************************************************************************)(* TODO: produce of lattices should go in prod_lattice. Here, we have
only the produce of transfer functions. *)openSva_sig;;(* Default (non-reduced) product. We could apply a reduction function
(e.g. propagate the bottoms) *)moduleProd_Bitvector_Forward(A:WITH_BITVECTOR_FORWARDwithtypeboolean=Sva_quadrivalent.boolean)(B:WITH_BITVECTOR_FORWARDwithtypeboolean=A.boolean)(* :With_Bitvector_Forward *)=structmoduleBitvector_Forward=structmoduleABF=A.Bitvector_ForwardmoduleBBF=B.Bitvector_Forwardletbuext~size~oldsize(a,b)=(ABF.buext~size~oldsizea,BBF.buext~size~oldsizeb)letbsext~size~oldsize(a,b)=(ABF.bsext~size~oldsizea,BBF.bsext~size~oldsizeb)letbofbool~sizex=(ABF.bofbool~sizex,BBF.bofbool~sizex)letbextract~size~index~oldsize(a,b)=(ABF.bextract~size~index~oldsizea,BBF.bextract~size~index~oldsizeb)letbop2fafb=fun~size(a1,b1)(a2,b2)->(fa~sizea1a2,fb~sizeb1b2)letbop2_flagsfafb=fun~size~flags(a1,b1)(a2,b2)->(fa~size~flagsa1a2,fb~size~flagsb1b2)letbiadd=bop2_flagsABF.biaddBBF.biaddletbisub=bop2_flagsABF.bisubBBF.bisubletbimul=bop2_flagsABF.bimulBBF.bimulletbimul_add~size~prod~offset(l,r)=(ABF.bimul_add~size~prod~offsetl,BBF.bimul_add~size~prod~offsetr)letbisdiv=bop2ABF.bisdivBBF.bisdivletbismod=bop2ABF.bismodBBF.bismodletbiudiv=bop2ABF.biudivBBF.biudivletbiumod=bop2ABF.biumodBBF.biumodletband=bop2ABF.bandBBF.bandletbor=bop2ABF.borBBF.borletbxor=bop2ABF.bxorBBF.bxorletbshl=bop2_flagsABF.bshlBBF.bshlletbashr=bop2ABF.bashrBBF.bashrletblshr=bop2ABF.blshrBBF.blshrletbconcat~size1~size2(a1,b1)(a2,b2)=ABF.bconcat~size1~size2a1a2,BBF.bconcat~size1~size2b1b2letbpredfafb=fun(a1,b1)(a2,b2)->Sva_quadrivalent.Boolean_Lattice.inter(faa1a2)(fbb1b2)letbeq~size=bpred(ABF.beq~size)(BBF.beq~size)letbisle~size=bpred(ABF.bisle~size)(BBF.bisle~size)letbiule~size=bpred(ABF.biule~size)(BBF.biule~size)letbiconst~sizek=(ABF.biconst~sizek,BBF.biconst~sizek)endendmoduleProd_Bitvector_Backward(A:WITH_BITVECTOR_BACKWARDwithtypeboolean=Sva_quadrivalent.boolean)(B:WITH_BITVECTOR_BACKWARDwithtypeboolean=A.boolean)=structmoduleABB=A.Bitvector_Backward;;moduleBBB=B.Bitvector_Backward;;letcoalesce_nonesoldaoldbab=matcha,bwith|None,None->None|Somev,None->Some(v,oldb)|None,Somev->Some(olda,v)|Someva,Somevb->Some(va,vb)letbpred2op1op2(a1,a2)(b1,b2)res=let(newa1,newb1)=op1a1b1resinlet(newa2,newb2)=op2a2b2resin(coalesce_nonesa1a2newa1newa2,coalesce_nonesb1b2newb1newb2);;letbeq~size=bpred2(ABB.beq~size)(BBB.beq~size)letbiule~size=bpred2(ABB.biule~size)(BBB.biule~size)letbisle~size=bpred2(ABB.bisle~size)(BBB.bisle~size)letbop2op1op2(a1,a2)(b1,b2)(res1,res2)=let(newa1,newb1)=op1a1b1res1inlet(newa2,newb2)=op2a2b2res2in(coalesce_nonesa1a2newa1newa2,coalesce_nonesb1b2newb1newb2)letbop2_flags~size~flagsop1op2=bop2(op1~size~flags)(op2~size~flags)letbop2~sizeop1op2=bop2(op1~size)(op2~size)letbiadd=bop2_flagsABB.biaddBBB.biaddletbisub=bop2_flagsABB.bisubBBB.bisubletbimul=bop2_flagsABB.bimulBBB.bimulletbimul_add~size~prod~offset(l,r)(res_l,res_r)=coalesce_noneslr(ABB.bimul_add~size~prod~offsetlres_l)(BBB.bimul_add~size~prod~offsetrres_r)letband=bop2ABB.bandBBB.bandletbor=bop2ABB.borBBB.borletbxor=bop2ABB.bxorBBB.bxorletbisdiv=bop2ABB.bisdivBBB.bisdivletbismod=bop2ABB.bismodBBB.bismodletbiudiv=bop2ABB.biudivBBB.biudivletbiumod=bop2ABB.biumodBBB.biumodletbashr=bop2ABB.bashrBBB.bashrletblshr=bop2ABB.blshrBBB.blshrletbshl=bop2_flagsABB.bshlBBB.bshlletbconcat~size1~size2(xa,xb)(ya,yb)(resa,resb)=let(newxa,newya)=ABB.bconcat~size1~size2xayaresainlet(newxb,newyb)=BBB.bconcat~size1~size2xbybresbin(coalesce_nonesxaxbnewxanewxb,coalesce_nonesyaybnewyanewyb);;letbop1opaopb(xa,xb)(resa,resb)=letnewxa=opaxaresainletnewxb=opbxbresbincoalesce_nonesxaxbnewxanewxb;;letbsext~size~oldsizexres=bop1(ABB.bsext~size~oldsize)(BBB.bsext~size~oldsize)xresletbuext~size~oldsizexres=bop1(ABB.buext~size~oldsize)(BBB.buext~size~oldsize)xresletbofbool~sizeares=assertfalseletbextract~size~index~oldsizexres=bop1(ABB.bextract~size~index~oldsize)(BBB.bextract~size~index~oldsize)xresendmoduleProd_Bitvector(A:BITVECTORwithtypeboolean=Sva_quadrivalent.boolean)(B:BITVECTORwithtypeboolean=A.boolean)=structletname="Prod_Bitvector("^A.name^"*"^B.name^")";;moduleBoolean_Lattice=A.Boolean_LatticemoduleBitvector_Lattice=structtypet=A.Bitvector_Lattice.t*B.Bitvector_Lattice.tmoduleL=Lattices.Unimplemented.Bitvector_Lattice(structtypenonrect=tletloc=__LOC__end)include(L:moduletypeofLwithtypet:=t)letequal(a1,b1)(a2,b2)=A.Bitvector_Lattice.equala1a2&&B.Bitvector_Lattice.equalb1b2letcompare(a1,b1)(a2,b2)=letra=A.Bitvector_Lattice.comparea1a2inifra!=0thenraelseB.Bitvector_Lattice.compareb1b2lethash(a,b)=Hashing.hash2(A.Bitvector_Lattice.hasha)(B.Bitvector_Lattice.hashb)letpretty~sizefmt(a,b)=(* Used to test the product itself. *)(* if(not @@ A.Bitvector_Lattice.equal a (Obj.magic b)) then
* Codex_log.fatal "Error differnt %a %a" (A.Bitvector_Lattice.pretty ~size) a (B.Bitvector_Lattice.pretty ~size) b;
* Format.fprintf fmt "%a" (A.Bitvector_Lattice.pretty ~size) a *)Format.fprintffmt"(%a,%a)"(A.Bitvector_Lattice.pretty~size)a(B.Bitvector_Lattice.pretty~size)b;;letincludes~size(a1,a2)(b1,b2)=A.Bitvector_Lattice.includes~sizea1b1&&B.Bitvector_Lattice.includes~sizea2b2letwiden~size~previous:(a1,a2)(b1,b2)=(A.Bitvector_Lattice.widen~size~previous:a1b1),(B.Bitvector_Lattice.widen~size~previous:a2b2)letincludes_or_widen~size~previousnext=ifincludes~sizepreviousnextthen(true,next)else(false,widen~size~previousnext);;letjoin~size(a1,a2)(b1,b2)=(A.Bitvector_Lattice.join~sizea1b1,B.Bitvector_Lattice.join~sizea2b2)letbottom~size=A.Bitvector_Lattice.bottom~size,B.Bitvector_Lattice.bottom~sizelettop~size=A.Bitvector_Lattice.top~size,B.Bitvector_Lattice.top~sizeletis_bottom~size(a,b)=A.Bitvector_Lattice.is_bottom~sizea||B.Bitvector_Lattice.is_bottom~sizebletinter~size(a1,a2)(b1,b2)=(A.Bitvector_Lattice.inter~sizea1b1,B.Bitvector_Lattice.inter~sizea2b2)letsingleton~sizek=A.Bitvector_Lattice.singleton~sizek,B.Bitvector_Lattice.singleton~sizekletis_singleton~size(a,b)=matchA.Bitvector_Lattice.is_singleton~sizeawith|None->B.Bitvector_Lattice.is_singleton~sizeb|x->xletis_empty~size(a,b)=A.Bitvector_Lattice.is_empty~sizea||B.Bitvector_Lattice.is_empty~sizebletto_known_bits~size(a,b)=Lattices.Known_Bits.inter~size(A.Bitvector_Lattice.to_known_bits~sizea)(B.Bitvector_Lattice.to_known_bits~sizeb)endmoduleBoolean_Forward=A.Boolean_ForwardmoduleBoolean_Backward=A.Boolean_Backwardtypeboolean=A.booleantypebitvector=Bitvector_Lattice.tmoduleBitvector_Forward=structmoduleAB=Prod_Bitvector_Forward(A)(B)includeAB.Bitvector_ForwardendmoduleBitvector_Backward=structmoduleAB=Prod_Bitvector_Backward(A)(B)includeABendend