package codex
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
The Codex library for building static analysers based on abstract interpretation
Install
dune-project
Dependency
Authors
Maintainers
Sources
1.0-rc4.tar.gz
md5=bc7266a140c6886add673ede90e335d3
sha512=8da42c0ff2c1098c5f9cb2b5b43b306faf7ac93b8f5ae00c176918cee761f249ff45b29309f31a05bbcf6312304f86a0d5a000eb3f1094d3d3c2b9b4c7f5c386
doc/src/codex.lattices/integer_standard.ml.html
Source file integer_standard.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180(**************************************************************************) (* 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). *) (* *) (**************************************************************************) (**************** Standard abstractions for integers. ****************) (* All these abstractions rely on pairs of Z. *) module ZPair = struct type t = Z.t * Z.t let compare (a1,b1) (a2,b2) = let res = Z.compare a1 a2 in if res == 0 then Z.compare b1 b2 else res ;; let equal (a1,b1) (a2,b2) = Z.equal a1 a2 && Z.equal b1 b2 let hash (a,b) = Hashing.hash2 (Z.hash a) (Z.hash b);; end module Interval = struct (* Min, max pair. Note that we can only represent finite sets. *) include ZPair;; let join (min1,max1) (min2,max2) = (Z.min min1 min2, Z.max max1 max2);; let inter (min1,max1) (min2,max2) = (Z.max min1 min2, Z.min max1 max2);; (* Any element where max is smaller than min is bottom, and this is the canonical one. *) let bottom () = Z.one, Z.zero let includes (min1,max1) (min2,max2) = Z.leq min1 min2 && Z.geq max1 max2;; let pretty fmt (a,b) = Format.fprintf fmt "[%s..%s]" (Z.to_string a) (Z.to_string b) end module Known_Bits = struct (* First bitvector = 0 where the bits must be 0, 1 otherwise. Second bitvector = 1 where the bits must be 1, 0 otherwise. *) include ZPair let bottom () = (Z.zero, Z.minus_one);; let is_bottom (x0,x1) = let open Z in not @@ Z.equal Z.zero @@ ~!x0 land x1 ;; let top () = (Z.minus_one, Z.zero);; type bitvalue = One | Zero | Unknown (* Note: 0 is the least significant bit. *) let testbit (x0,x1) index = if Z.testbit x0 index then if Z.testbit x1 index (* First bit is 1. *) then One else Unknown else Zero ;; let pretty fmt (x0,x1) = if is_bottom (x0,x1) then Format.fprintf fmt "<bottom>" else let size = Z.numbits x0 in for i = (size - 1) downto 0 do match testbit (x0,x1) i with | Zero -> Format.fprintf fmt "0" | One -> Format.fprintf fmt "1" | Unknown -> Format.fprintf fmt "?" done ;; let read s = let n = (String.length s) - 1 in let rec loop n bit (x0,x1) = if n < 0 then (x0,x1) else match s.[n] with | '0' -> loop (n-1) (Z.(lsl) bit 1) (x0,x1) | '1' -> loop (n-1) (Z.(lsl) bit 1) (Z.(lor) x0 bit, Z.(lor) x1 bit) | '?' -> loop (n-1) (Z.(lsl) bit 1) (Z.(lor) x0 bit, x1) | _ -> failwith "Wrong input" in loop n Z.one (Z.zero,Z.zero) ;; let singleton x = (x,x);; (* Intersection: keep the bits known by one side. *) let inter0 = Z.(land) let inter1 = Z.(lor) let inter (x0,x1) (y0,y1) = (inter0 x0 y0, inter1 x1 y1);; let join0 = Z.(lor) let join1 = Z.(land) let join (x0,x1) (y0,y1) = (join0 x0 y0, join1 x1 y1) let equal (x0,x1) (y0,y1) = Z.equal x0 y0 && Z.equal x1 y1;; let is_included x y = equal y (join x y);; let includes x y = is_included y x (* A widening operator from a paper by Antoine Miné. *) let widen ~size ~previous:(prev0,prev1) (new0,new1) = let res0 = let t = join0 prev0 new0 in if Z.equal prev0 t then prev0 else Z.minus_one in let res1 = let t = join1 prev1 new1 in if Z.equal prev1 t then prev1 else Z.zero in (res0,res1) ;; let includes_or_widen ~size ~previous _ = assert false end module Congruence = struct (* Represents a set q * Z + r, where q is the first element, and r the second. - If q is negative, this represents bottom. - If q is 0, this represents a singleton. - If q is >0, then 0 <= r < q. *) (* Note: we could have another abstraction representing truncated division. *) include ZPair let bottom () = (Z.minus_one, Z.minus_one) let top () = Z.one, Z.zero (* 1 * Z + 0 = R *) let singleton x = Z.zero, x end module Integer_Set = struct module ZSet = Set.Make(Z) let equal = ZSet.equal let compare = ZSet.compare let hash _ = assert false let pretty fmt x = Format.fprintf fmt "@[<hv>"; x |> ZSet.iter (fun x -> Format.fprintf fmt "%s@ " (Z.to_string x)); Format.fprintf fmt "@]" ;; type t = ZSet.t let bottom () = ZSet.empty (* let top = assert false *) let join = ZSet.union let inter = ZSet.inter let singleton = ZSet.singleton end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>