123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230(**************************************************************************)(* 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). *)(* *)(**************************************************************************)exceptionError_TopexceptionError_BottomexceptionNot_less_thanexceptionCan_not_subdiv(* let msg_emitter = Lattice_messages.register "Abstract_interp" *)(* open Lattice_type *)typetruth=True|False|Unknownletinv_truth=function|Unknown->Unknown|True->False|False->TruemoduleComp=structtypet=Lt|Gt|Le|Ge|Eq|Netyperesult=truth=True|False|Unknownletinv=function|Gt->Le|Lt->Ge|Le->Gt|Ge->Lt|Eq->Ne|Ne->Eqletsym=function|Gt->Lt|Lt->Gt|Le->Ge|Ge->Le|Eq->Eq|Ne->Neletpretty_compfmt=function|Gt->Format.pp_print_stringfmt">"|Lt->Format.pp_print_stringfmt"<"|Le->Format.pp_print_stringfmt"<="|Ge->Format.pp_print_stringfmt">="|Eq->Format.pp_print_stringfmt"=="|Ne->Format.pp_print_stringfmt"!="letinv_result=function|Unknown->Unknown|True->False|False->TrueendmoduleInt=structinclude(Integer:moduletypeofIntegerwithtypet=Integer.t)moduleSet=Set.Make(Integer)(* include (Datatype.Integer: Datatype.S_with_collections with type t:=Integer.t) *)letten_thousands=Integer.of_int10000;;letminus_ten_thousands=Integer.of_int@@-10000;;letprettyfmtv=(* If we can print a 4-digit decimal number. *)ifInteger.gevten_thousands||Integer.levminus_ten_thousandsthenFormat.fprintffmt"%a"(Integer.pretty~hexa:true)velseFormat.fprintffmt"%s"@@Z.to_stringv(* let pretty fmt v =
* if not (Kernel.BigIntsHex.is_default ()) then
* let max = of_int (Kernel.BigIntsHex.get ()) in
* if gt (abs v) max then Integer.pretty ~hexa:true fmt v
* else Integer.pretty ~hexa:false fmt v
* else
* Integer.pretty ~hexa:false fmt v *)(** execute [f] on [inf], [inf + step], ... *)letfoldf~inf~sup~stepacc=(* Format.printf "Int.fold: inf:%a sup:%a step:%a@\n"
pretty inf pretty sup pretty step; *)letnb_loop=e_div(subsupinf)stepinletrecfold_incr~counter~infacc=ifequalcounteronethousandthenCodex_log.performance_warning"enumerating %a integers"prettynb_loop;ifleinfsupthenbegin(* Format.printf "Int.fold: %a@\n" pretty inf; *)fold_incr~counter:(succcounter)~inf:(addstepinf)(finfacc)endelseaccinletrecfold_decr~counter~supacc=ifequalcounteronethousandthenCodex_log.performance_warning"enumerating %a integers"prettynb_loop;ifleinfsupthenbegin(* Format.printf "Int.fold: %a@\n" pretty inf; *)fold_decr~counter:(succcounter)~sup:(addstepsup)(fsupacc)endelseacciniflezerostepthenfold_incr~counter:zero~infaccelsefold_decr~counter:zero~supaccend(* Typing constraints are enforced directly in the .mli *)moduleRel=structincludeIntletcheck~rem~modu=zero<=rem&&rem<moduletadd_abs=addletsub_abs=subendmoduleBool=structtypet=Top|True|False|Bottomlethash(b:t)=Hashtbl.hashbletequal(b1:t)(b2:t)=b1=b2letcompare(b1:t)(b2:t)=Stdlib.compareb1b2letprettyfmt=function|Top->Format.fprintffmt"Top"|True->Format.fprintffmt"True"|False->Format.fprintffmt"False"|Bottom->Format.fprintffmt"Bottom"letis_includedt1t2=matcht1,t2with|Bottom,_|_,Top|True,True|False,False->true|_->falseletbottom=Bottomlettop=Topletjoinb1b2=matchb1,b2with|Top,_|_,Top|True,False->Top|True,_|_,True->True|False,_|_,False->False|Bottom,Bottom->Bottomletnarrowb1b2=matchb1,b2with|Bottom,_|_,Bottom|True,False->Bottom|True,_|_,True->True|False,_|_,False->False|Top,Top->Topletlink=joinletmeet=narrowtypewiden_hint=unitletwiden()=joinletcardinal_zero_or_oneb=not(equalbtop)letintersectsb1b2=matchb1,b2with|Bottom,_|_,Bottom->false|_,Top|Top,_->true|False,False|True,True->true|False,True|True,False->falseletdiffb1b2=matchb1,b2with|b1,Bottom->b1|_,Top->Bottom|Bottom,_->Bottom|Top,True->False|Top,False->True|True,True->Bottom|True,False->True|False,True->False|False,False->Bottomletdiff_if_oneb1b2=matchb1,b2with|b1,Top->b1|_,_->diffb1b2letfold_enumfbinit=letelements=matchbwith|Top->[True;False]|True->[True]|False->[False]|Bottom->[]inList.fold_right(funbacc->fbacc)elementsinitletcardinal=function|Top->2|True|False->1|Bottom->0letcardinal_less_thanbi=letc=cardinalbinifc>ithenraiseNot_less_thanelsectypeblt=t(* include (Datatype.Make_with_collections *)(* (struct *)(* type t = blt *)(* let name = "Bool_lattice" *)(* let structural_descr = Structural_descr.t_abstract *)(* let reprs = [Top; True; False; Bottom] *)(* let equal = equal *)(* let compare = compare *)(* let hash = hash *)(* let rehash = Datatype.identity *)(* let copy = Datatype.identity *)(* let pretty = pretty *)(* let internal_pretty_code = Datatype.undefined *)(* let varname = Datatype.undefined *)(* let mem_project = Datatype.never_any_project *)(* end) : *)(* Datatype.S with type t := t) *)end