[sledge] Update exp

Reviewed By: mbouaziz, ngorogiannis

Differential Revision: D9846743

fbshipit-source-id: c293970c7
master
Josh Berdine 6 years ago committed by Facebook Github Bot
parent 742b181282
commit 392f596b02

File diff suppressed because it is too large Load Diff

@ -10,48 +10,34 @@
Pure (heap-independent) expressions are complex arithmetic, Pure (heap-independent) expressions are complex arithmetic,
bitwise-logical, etc. operations over literal values and registers. bitwise-logical, etc. operations over literal values and registers.
Expressions are represented in curried form, where the only recursive Expressions are represented in curried form, where the only recursive
constructor is [App], which is an application of a function symbol to an constructor is [App], which is an application of a function symbol to an
argument. This is done to simplify the definition of 'subexpression' and argument. This is done to simplify the definition of 'subexpression' and
make it explicit, which is a significant help for treating equality make it explicit, which is a significant help for treating equality
between expressions using congruence closure. The specific constructor between expressions using congruence closure. The specific constructor
functions indicate and check the expected arity and types of the functions indicate and check the expected arity of the function symbols.
function symbols. *)
[] [Struct_rec] is also a recursive constructor, but its values are
treated as atomic since, as they are recursive, doing otherwise would
require inductive reasoning. *)
type t = private type t = private
| Var of {name: string; typ: Typ.t; loc: Loc.t} | Var of {id: int; name: string} (** Local variable / virtual register *)
(** Local variable / virtual register *) | Nondet of {msg: string}
| Global of {name: string; init: t option; typ: Typ.t; loc: Loc.t}
(** Global variable, with initalizer *)
| Nondet of {typ: Typ.t; loc: Loc.t; msg: string}
(** Anonymous local variable with arbitrary value, representing (** Anonymous local variable with arbitrary value, representing
non-deterministic approximation of value described by [msg]. *) non-deterministic approximation of value described by [msg] *)
| Label of {parent: string; name: string; loc: Loc.t} | Label of {parent: string; name: string}
(** Address of named code block within parent function *) (** Address of named code block within parent function *)
| Null of {typ: Typ.t} | App of {op: t; arg: t}
(** Pointer value that never refers to an object *)
| App of {op: t; arg: t; loc: Loc.t}
(** Application of function symbol to argument, curried *) (** Application of function symbol to argument, curried *)
| AppN of {op: t; args: t vector; loc: Loc.t} | Null (** Pointer value that never refers to an object *)
(** Application of function symbol to arguments. NOTE: may be cyclic | Splat (** Iterated concatenation of a single byte *)
when [op] is [Struct]. *) | Memory (** Size-tagged byte-array *)
| PtrFld of {fld: int} (** Pointer to a field of a struct *) | Concat (** Byte-array concatenation *)
| PtrIdx (** Pointer to an index of an array *) | Integer of {data: Z.t} (** Integer constant *)
| PrjFld of {fld: int} (** Project a field from a constant struct *) | Float of {data: string} (** Floating-point constant *)
| PrjIdx (** Project an index from a constant array *)
| UpdFld of {fld: int} (** Constant struct with updated field *)
| UpdIdx (** Constant array with updated index *)
| Integer of {data: Z.t; typ: Typ.t} (** Integer constant *)
| Float of {data: string; typ: Typ.t} (** Floating-point constant *)
| Array of {typ: Typ.t} (** Array constant *)
| Struct of {typ: Typ.t} (** Struct constant *)
| Cast of {typ: Typ.t} (** Cast to specified type, invertible *)
| Conv of {signed: bool; typ: Typ.t}
(** Convert to specified type, possibly with loss of information *)
| Select (** Conditional *)
(* binary: comparison *)
| Eq (** Equal test *) | Eq (** Equal test *)
| Ne (** Not-equal test *) | Dq (** Disequal test *)
| Gt (** Greater-than test *) | Gt (** Greater-than test *)
| Ge (** Greater-than-or-equal test *) | Ge (** Greater-than-or-equal test *)
| Lt (** Less-than test *) | Lt (** Less-than test *)
@ -62,194 +48,151 @@ type t = private
| Ule (** Unordered or less-than-or-equal test *) | Ule (** Unordered or less-than-or-equal test *)
| Ord (** Ordered test (neither arg is nan) *) | Ord (** Ordered test (neither arg is nan) *)
| Uno (** Unordered test (some arg is nan) *) | Uno (** Unordered test (some arg is nan) *)
(* binary: boolean / bitwise *)
| And (** Conjunction *)
| Or (** Disjunction *)
| Xor (** Exclusive-or / Boolean disequality *)
| Shl (** Shift left *)
| LShr (** Logical shift right *)
| AShr (** Arithmetic shift right *)
(* binary: arithmetic *)
| Add (** Addition *) | Add (** Addition *)
| Sub (** Subtraction *) | Sub (** Subtraction *)
| Mul (** Multiplication *) | Mul (** Multiplication *)
| Div (** Division *) | Div (** Division *)
| UDiv (** Unsigned division *) | Udiv (** Unsigned division *)
| Rem (** Remainder of division *) | Rem (** Remainder of division *)
| URem (** Remainder of unsigned division *) | Urem (** Remainder of unsigned division *)
| And (** Conjunction *)
val compare : t -> t -> int | Or (** Disjunction *)
| Xor (** Exclusive-or / Boolean disequality *)
| Shl (** Shift left *)
| Lshr (** Logical shift right *)
| Ashr (** Arithmetic shift right *)
| Conditional (** If-then-else *)
| Record (** Record (array / struct) constant *)
| Select (** Select an index from a record *)
| Update (** Constant record with updated index *)
| Struct_rec of {elts: t vector}
(** Struct constant that may recursively refer to itself
(transitively) from [elts]. NOTE: represented by cyclic values. *)
| Convert of {signed: bool; dst: Typ.t; src: Typ.t}
(** Convert between specified types, possibly with loss of information *)
[@@deriving compare, hash, sexp]
type exp = t
include Comparator.S with type t := t
val equal : t -> t -> bool val equal : t -> t -> bool
val pp : t pp
val invariant : ?partial:bool -> t -> unit
val t_of_sexp : Sexp.t -> t (** Exp.Var is re-exported as Var *)
val sexp_of_t : t -> Sexp.t
val fmt : t fmt
(** Re-exported modules *)
module Var : sig module Var : sig
type nonrec t = private t type t = private exp [@@deriving compare, hash, sexp]
type var = t
include Comparator.S with type t := t include Comparator.S with type t := t
val compare : t -> t -> int module Set : sig
type t = (var, comparator_witness) Set.t [@@deriving compare, sexp]
val equal : t -> t -> bool
val t_of_sexp : Sexp.t -> t
val sexp_of_t : t -> Sexp.t
val fmt : t fmt
val mk : ?loc:Loc.t -> string -> Typ.t -> t
val name : t -> string
val typ : t -> Typ.t
val loc : t -> Loc.t
end
module Global : sig
type init = t
type nonrec t = private t val pp : t pp
val empty : t
include Comparator.S with type t := t val of_vector : var vector -> t
end
val compare : t -> t -> int
val equal : t -> t -> bool val equal : t -> t -> bool
val pp : t pp
val t_of_sexp : Sexp.t -> t include Invariant.S with type t := t
val sexp_of_t : t -> Sexp.t
val hash : t -> int
val fmt : t fmt
val fmt_defn : t fmt
val mk : ?init:init -> ?loc:Loc.t -> string -> Typ.t -> t
val of_exp : init -> t option
val of_exp : exp -> t option
val program : string -> t
val fresh : string -> wrt:Set.t -> t * Set.t
val id : t -> int
val name : t -> string val name : t -> string
val typ : t -> Typ.t module Subst : sig
type t [@@deriving compare, sexp]
val loc : t -> Loc.t
val pp : t pp
val empty : t
val freshen : Set.t -> wrt:Set.t -> t
val extend : t -> replace:var -> with_:var -> t
val invert : t -> t
val exclude : t -> Set.t -> t
val is_empty : t -> bool
val domain : t -> Set.t
val range : t -> Set.t
val apply_set : t -> Set.t -> Set.t
val close_set : t -> Set.t -> Set.t
end
end end
(** Constructors *) (** Construct *)
val mkVar : Var.t -> t val var : Var.t -> t
val nondet : string -> t
val mkGlobal : Global.t -> t val label : parent:string -> name:string -> t
val null : t
val mkNondet : Typ.t -> string -> t val splat : byt:t -> siz:t -> t
val memory : siz:t -> arr:t -> t
val mkLabel : parent:string -> name:string -> t val concat : t -> t -> t
val bool : bool -> t
val mkNull : Typ.t -> t val integer : Z.t -> t
val float : string -> t
val mkPtrFld : ptr:t -> fld:int -> t val eq : t -> t -> t
val dq : t -> t -> t
val mkPtrIdx : ptr:t -> idx:t -> t val gt : t -> t -> t
val ge : t -> t -> t
val mkPrjFld : agg:t -> fld:int -> t val lt : t -> t -> t
val le : t -> t -> t
val mkPrjIdx : arr:t -> idx:t -> t val ugt : t -> t -> t
val uge : t -> t -> t
val mkUpdFld : agg:t -> elt:t -> fld:int -> t val ult : t -> t -> t
val ule : t -> t -> t
val mkUpdIdx : arr:t -> elt:t -> idx:t -> t val ord : t -> t -> t
val uno : t -> t -> t
val mkBool : bool -> t val add : t -> t -> t
val sub : t -> t -> t
val mkInteger : Z.t -> Typ.t -> t val mul : t -> t -> t
val div : t -> t -> t
val mkFloat : string -> Typ.t -> t val udiv : t -> t -> t
val rem : t -> t -> t
val mkArray : t vector -> Typ.t -> t val urem : t -> t -> t
val and_ : t -> t -> t
val mkStruct : t vector -> Typ.t -> t val or_ : t -> t -> t
val xor : t -> t -> t
val mkStruct_rec : val shl : t -> t -> t
(module Hashtbl.Key_plain with type t = 'id) val lshr : t -> t -> t
-> (id:'id -> t lazy_t vector -> Typ.t -> t) Staged.t val ashr : t -> t -> t
(** [mkStruct_rec Id id element_thunks typ] constructs a possibly-cyclic val conditional : cnd:t -> thn:t -> els:t -> t
[Struct] value. Cycles are detected using [Id]. The caller of val record : t list -> t
[mkStruct_rec Id] must ensure that a single unstaging of [mkStruct_rec val select : rcd:t -> idx:t -> t
Id] is used for each complete cyclic value. Also, the caller must ensure val update : rcd:t -> elt:t -> idx:t -> t
that recursive calls to [mkStruct_rec Id] provide [id] values that
uniquely identify at least one point on each cycle. Failure to obey val struct_rec :
these requirements will lead to stack overflow. *) (module Hashtbl.Key with type t = 'id)
-> (id:'id -> t lazy_t vector -> t) Staged.t
val mkCast : t -> Typ.t -> t (** [struct_rec Id id element_thunks] constructs a possibly-cyclic [Struct]
value. Cycles are detected using [Id]. The caller of [struct_rec Id]
val mkConv : t -> ?signed:bool -> Typ.t -> t must ensure that a single unstaging of [struct_rec Id] is used for each
complete cyclic value. Also, the caller must ensure that recursive calls
val mkSelect : cnd:t -> thn:t -> els:t -> t to [struct_rec Id] provide [id] values that uniquely identify at least
one point on each cycle. Failure to obey these requirements will lead to
val mkEq : t -> t -> t stack overflow. *)
val mkNe : t -> t -> t val convert : ?signed:bool -> dst:Typ.t -> src:Typ.t -> t -> t
val mkGt : t -> t -> t (** Access *)
val mkGe : t -> t -> t val fold_vars : t -> init:'a -> f:('a -> Var.t -> 'a) -> 'a
val fold_exps : t -> init:'a -> f:('a -> t -> 'a) -> 'a
val mkLt : t -> t -> t val fold : t -> init:'a -> f:('a -> t -> 'a) -> 'a
val fold_map : t -> init:'a -> f:('a -> t -> 'a * t) -> 'a * t
val mkLe : t -> t -> t val map : t -> f:(t -> t) -> t
val mkUgt : t -> t -> t (** Update *)
val mkUge : t -> t -> t val rename : t -> Var.Subst.t -> t
val mkUlt : t -> t -> t (** Query *)
val mkUle : t -> t -> t val fv : t -> Var.Set.t
val is_true : t -> bool
val mkOrd : t -> t -> t val is_false : t -> bool
val is_constant : t -> bool
val mkUno : t -> t -> t
val mkAnd : t -> t -> t
val mkOr : t -> t -> t
val mkXor : t -> t -> t
val mkShl : t -> t -> t
val mkLShr : t -> t -> t
val mkAShr : t -> t -> t
val mkAdd : t -> t -> t
val mkSub : t -> t -> t
val mkMul : t -> t -> t
val mkDiv : t -> t -> t
val mkUDiv : t -> t -> t
val mkRem : t -> t -> t
val mkURem : t -> t -> t
val locate : Loc.t -> t -> t
(** Update the debug location *)
(** Queries *)
val typ : t -> Typ.t

Loading…
Cancel
Save