Challenges and Applications of Assembly-Level Software Model Checking

ion functions φ map states S = (S1, . . . , Sk) to patterns φ(S) = (φ(S1), . , φ(Sk)). Pattern databases [CS98] are hash tables for fully explored abstract state spaces, storing with each abstract state the shortest path distance in the abstract space to the abstract goal. They are constructed in a complete traversal of the inverse abstract search space graph. Each distance value stored in the hash table is a lower bound on the solution cost in original space and serves as a heuristic estimate. Different pattern databases can be combined either by adding or maximizing the individual entries for a state. Pattern databases work, if the abstraction function is a homomorphism, so that each path in the original state space has a corresponding one in the abstract state space. In difference to the search in original space, the entire abstract space has to be looked at. As pattern databases are themselves hash tables we apply incremental hashing, too. If we restrict the exploration in STRIPS planning to some certain subset of propositions R ⊆ AP , we generate a planning state space homomorphism φ and an abstract planning state space [Ede01] with states SA ⊆ R. Abstractions of operators o = (P,A, D) are defined as φ(o) = (P ∩ R, A ∩ R,D ∩ R). Multiple pattern databases are composed based on a partition AP = R1 ∪ . ∪ Rl and induce abstractions φ1, . , φl as well as lookup hash tables PDB1,. ,PDBl. Two pattern databases are additive, if the sum of the retrieved values is admissible. One sufficient criterion is the following. For every pair of non-trivial operators o1 and o2 in the abstract spaces according to φ1 and φ2, we have that preimage φ−1 1 (o1) differs from φ −1 2 (o2). For pattern database addressing we use a multivariate variable encoding, namely, SAS+ [Hel04]. 6.7 Hashing Dynamic State Vectors In the previous section, we devised an incremental hashing scheme for static state vectors. This is not directly applicable for program model checkers, as they operate on dynamic and structured states. Dynamic means, that the size of a vector may change. For example, a program can dynamically allocate new memory regions. Structured means, that the state is separated in several subvectors rather than a single big vector. In StEAM for example, the stacks, machines, variable sections and the lock/memory pools constitute subvectors which together form a global state vector. In the following, we extend the incremental hashing scheme from the last section to be applicable for dynamic and distributed states. For dynamic vectors, components may be inserted at arbitrary positions. We will regard dynamic vectors as the equivalent of strings over an alphabet Σ. In the following, for two vectors a and b, let a, b denote the concatenation of a and b. For 100 CHAPTER 6. HASHING example, for a = (0, 8) and b = (15), we define a, b = (0, 8, 15). We define four general lemmas for the hash function h as used in Rabin-Karp hashing (cf. Section 6.5.1). Lemmas 1 and 2 relate to the insertion-, lemmas 3 and 4 to the deletion of components. Afterwards, we apply the lemmas to different types of data structures, such as stacks and queues. We use |a| to denote the size of a vector a. Lemma 1. For all a, b, c ∈ Σ∗ we have h(a, b, c) = h(a, c)− h(c) · |Σ||a| + h(b) · |Σ||a| + h(c) · |Σ||a|+|b| mod q.