Operator.Function_symbolSourceFunction symbol: Reusable tags that allow a building a term, i.e. a tagged representation of an expressions that composes transfer functions.
Some aliases for legibility
The case number of an enum
These types are never instanciated as values. They are used as phantom parameters in GADTs to distinguish terms and function symboles based on the concrete value they represent.
A boolean value, e.g. true or false
An unbounded integer value, often represented by Z.t in the concrete
An enum value: can take a fixed number of values depending on the enum type being considered.
A bitvector of size size We generally do not store the size; instead, most operation have a ~size parameter specifying the number of bits of the underlying operation.
A term of arity 0 is just a constant
A term of arity 1 is a unary operation (ex: boolean not). The 'a parameter represents the type of the argument.
A term of arity 2 is a binary operation (ex: addition) The 'a parameter represents the type of the arguments.
A GADT regrouping all our phantom type parameters
The type of function symbols takes two parameters:
'arg is the arity, i.e. the type of arguments needed to build this term. The arity should be either ar0, 'a ar1 or ('a, 'b) ar2.'ret it the return type of the function symbol, i.e. the type of the term whose head is this function symbol.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 : (boolean ar1, boolean) function_symbol| BoolUnion : ((boolean, boolean) ar2, boolean) function_symbol| Biconst : Units.In_bits.t * Z.t -> (ar0, binary) function_symbolBitvector constant with the given size and value.
*)| Biadd : {size : Units.In_bits.t;flags : Flags.Biadd.t;} -> ((binary, binary) ar2, binary) function_symbolAddition on bitvectors of size size. See biadd for the flag meanings.
| Bisub : {size : Units.In_bits.t;flags : Flags.Biadd.t;} -> ((binary, binary) ar2, binary) function_symbolBitvector subtraction See biadd for the flag meanings.
| Bimul : {size : Units.In_bits.t;flags : Flags.Bimul.t;} -> ((binary, binary) ar2, binary) function_symbolBitvector multiplication, See biadd for the flag meanings.
| Biudiv : Units.In_bits.t -> ((binary, binary) ar2, binary) function_symbolBitvector unsigned division.
*)| Bisdiv : Units.In_bits.t -> ((binary, binary) ar2, binary) function_symbolBitvector signed division. This is truncated (C99-like) integer division.
*)| Biumod : Units.In_bits.t -> ((binary, binary) ar2, binary) function_symbolBitvector unsigned modulo.
*)| Bismod : Units.In_bits.t -> ((binary, binary) ar2, binary) function_symbolBitvector signed modulo.
*)| Bshl : {size : Units.In_bits.t;flags : Flags.Bshl.t;} -> ((binary, binary) ar2, binary) function_symbolBitvector left-shift
*)| Bashr : Units.In_bits.t -> ((binary, binary) ar2, binary) function_symbolBitvector arithmetic right shift (pad with top-bit)
*)| Blshr : Units.In_bits.t -> ((binary, binary) ar2, binary) function_symbolBitvector logical right shift (pad with zeros)
*)| Band : Units.In_bits.t -> ((binary, binary) ar2, binary) function_symbolBitvector bitwise and
*)| Bor : Units.In_bits.t -> ((binary, binary) ar2, binary) function_symbolBitvector bitwise or
*)| Bxor : Units.In_bits.t -> ((binary, binary) ar2, binary) function_symbolBitvector bitwise xor
*)| Beq : Units.In_bits.t -> ((binary, binary) ar2, boolean) function_symbolBitvector equality
*)| Bisle : Units.In_bits.t -> ((binary, binary) ar2, boolean) function_symbolSigned comparison between two bitvectors (using less-or-equal <=). Bitvectors are interpreted as integers in [-2^{size-1}..-2^{size-1}-1] using two's complement.
| Biule : Units.In_bits.t -> ((binary, binary) ar2, boolean) function_symbolUnsigned comparison between two bitvectors (using less-or-equal <=). Bitvectors are interpreted as positive integers in [0..-2^{size}-1].
| Bconcat : Units.In_bits.t
* Units.In_bits.t -> ((binary, binary) ar2, binary) function_symbolBitvector concatenation: the new bitvector's size is the sum of the sizes of the arguments. The first argument becomes the most significant bits.
*)| Bextract : {size : Units.In_bits.t;index : Units.In_bits.t;oldsize : Units.In_bits.t;} -> (binary ar1, binary) function_symbolExtract a size of a bitvector of total size oldsize, starting at index. Should satisfy index + size <= oldsize.
| Bsext : Units.In_bits.t -> (binary ar1, binary) function_symbolSign-extend (pad left with topbit) the argument bitvector until it reaches the specified size.
| Buext : Units.In_bits.t -> (binary ar1, binary) function_symbolUnsngned-extend (pad left with zero) the argument bitvector until it reaches the specified size.
| Bofbool : Units.In_bits.t -> (boolean ar1, binary) function_symbolTurn a boolean into a bitvector: false is 0 and true is 1.
| Bunion : int
* Units.In_bits.t -> ((binary, binary) ar2, binary) function_symbol| Bchoose : int * Units.In_bits.t -> (binary ar1, binary) function_symbol| Iconst : Z.t -> (ar0, integer) function_symbolInteger constant
*)| 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_symbolThis is truncated (C99-like) integer division
*)| 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_symbolBitwise or, where negative integers are seen as prefixed by infinite ones
*)| Ixor : ((integer, integer) ar2, integer) function_symbol| Iand : ((integer, integer) ar2, integer) function_symbolBitwise and, where negative integers are seen as prefixed by infinite ones
*)| Ieq : ((integer, integer) ar2, boolean) function_symbol| Ile : ((integer, integer) ar2, boolean) function_symbol| Itimes : Z.t -> (integer ar1, integer) function_symbolMultiply an integer by a constant
*)| EnumConst : case -> (ar0, enum) function_symbolAn enum case with the given value
*)| CaseOf : case -> (enum ar1, boolean) function_symboltrue if the argument matches the given case, false otherwise.
Builder for these terms. Note that we do not perform any hash-consing here.
Helper to build pretty-printers. We can pretty print a term if we have access to the tag (representing the operation) and we know how to pretty-print the arguments.
module Pretty
(M : PRETTY_ARG) :
PRETTY_RESULT with type 'a t = 'a M.t and type 'a pack = 'a M.pack