Advertisement

Unified Reasoning About Robustness Properties of Symbolic-Heap Separation Logic

Conference paper
Part of the Lecture Notes in Computer Science book series (LNCS, volume 10201)

Abstract

We introduce heap automata, a formalism for automatic reasoning about robustness properties of the symbolic heap fragment of separation logic with user-defined inductive predicates. Robustness properties, such as satisfiability, reachability, and acyclicity, are important for a wide range of reasoning tasks in automated program analysis and verification based on separation logic. Previously, such properties have appeared in many places in the separation logic literature, but have not been studied in a systematic manner. In this paper, we develop an algorithmic framework based on heap automata that allows us to derive asymptotically optimal decision procedures for a wide range of robustness properties in a uniform way.

We implemented a prototype of our framework and obtained promising results for all of the aforementioned robustness properties.

Further, we demonstrate the applicability of heap automata beyond robustness properties. We apply our algorithmic framework to the model checking and the entailment problem for symbolic-heap separation logic.

1 Introduction

Separation logic (SL) [38] is a popular formalism for Hoare-style verification of imperative, heap-manipulating programs. While its symbolic heap fragment originally emerged as an idiomatic form of assertions that occur naturally in hand-written proofs [4, 5, 34], a variety of program analyses based on symbolic-heap separation logic have been developed [2, 5, 9, 16, 22, 30, 35]. Consequently, it now serves as formal basis for a multitude of automated verification tools, such as [6, 8, 15, 17, 20, 28, 31, 37], capable of proving complex properties of a program’s heap, such as memory safety, for large code bases [15, 16]. These tools typically rely on systems of inductive predicate definitions (SID) to specify the shape of data structures employed by a program, such as trees and linked lists. Originally, separation logic tools implemented highly-specialized procedures for such fixed SIDs. As this limits their applicability, there is an ongoing trend to support custom SIDs that are either defined manually [17, 28] or even automatically generated. The latter may, for example, be obtained from the tool Caber [12].

Robustness Properties. Allowing for arbitrary SIDs, however, raises various questions about their robustness. A user-defined or auto-generated SID might, for example, be inconsistent, introduce unallocated logical variables, specify data structures that contain undesired cycles, or produce garbage, i.e., parts of the heap that are unreachable from any program variable. Accidentally introducing such properties into specifications can have a negative impact on performance, completeness, and even soundness of the employed verification algorithms:
  • Brotherston et al. [11] point out that tools might waste time on inconsistent scenarios due to unsatisfiability of specifications.

  • The absence of unallocated logical variables, also known as establishment, is required by the approach of Iosif et al. [26, 27] to obtain a decidable fragment of symbolic heaps.

  • Other verification approaches, such as the one by Habermehl et al. [23, 24], assume that no garbage is introduced by data structure specifications.

  • During program analysis and verification, questions such as reachability, acyclicity and garbage-freedom arise depending on the properties of interest. For example, as argued by Zanardini and Genaim [39], acyclicity of the heap is crucial in automated termination proofs.

Being able to check such robustness properties of custom SIDs is thus crucial (1) in debugging of separation-logic specifications prior to program analysis and (2) in the program analyses themselves. So far, however, all of the above properties have either been addressed individually or not systematically at all. For example, satisfiability is studied in detail by Brotherston et al. [11], whereas establishment is often addressed with ad-hoc solutions [23, 26].

Several reasoning tasks arise in the context of robustness properties. As a motivation, consider the problem of acyclicity. If our program analysis requires acyclicity, we would like to decide whether all interpretations of a symbolic heap are acyclic; if not, to find out how cycles can be introduced into the heap (counterexample generation); and, finally, to be able to generate a new SID that does guarantee acyclicity (called refinement below). A systematic treatment of robustness properties should cover these reasoning tasks in general, not just for the problem of acyclicity.

Problem Statement. We would like to develop a framework that enables:
  1. 1.

    Decision procedures for robustness properties. In program analysis, we generally deal with symbolic heaps that reference SIDs specifying unbounded data structures and thus usually have infinitely many interpretations. We need to be able to decide whether all, or some, of these infinitely many interpretations are guaranteed to satisfy a given robustness property.

     
  2. 2.

    Generation of counterexamples that violate a desired property.

     
  3. 3.

    Refinement of SIDs to automatically generate a new SID that respects a given robustness property.

     
  4. 4.

    Automatic combination of decision procedures to derive decision procedures for complex robustness properties from simpler ingredients.

     
Motivating Example: Inductive Reasoning About Robustness Properties. The key insight underlying our solution to the above problems is that many properties of symbolic heaps can be decided iteratively by inductive reasoning. To motivate our approach, we illustrate this reasoning process with a concrete example. Consider an SID for acyclic singly-linked list segments with head x and tail y:The two rules of the SID define a case distinction: A list is either empty or the first element has a successor u (specified by the points-to assertion \(x \mapsto u\)), which in turn is at the head of a (shorter) singly-linked list segment, \(\mathtt {sll}(u, y)\). The inequality in the second rule guarantees that there is no cyclic model. Now, consider the following symbolic heap with predicate calls to sll: Open image in new window , which might appear as an assertion during program analysis. Say our program analysis depends on the acyclicity of \(\varphi \), so we need to determine whether \(\varphi \) is acyclic. We can do so by inductive reasoning as follows.
  • We analyze the call \(\mathtt {sll}(x,z)\), the first list segment in the symbolic heap \(\varphi \). If it is interpreted by the right-hand side of the first rule of the SID from above, then there is no cycle in \(\mathtt {sll}(x,z)\) and z is reachable from x.

  • If we already know for a call \(\mathtt {sll}(u,z)\) that all of its models are acyclic structures and that z is reachable from u, then z is also reachable from x in the symbolic heap Open image in new window obtained by the second rule of the SID. Since our SID does not introduce dangling pointers, we also know that there is still no cycle.

  • By induction, \(\mathtt {sll}(x,z)\) is thus acyclic and z is reachable from x.

  • Likewise, \(\mathtt {sll}(y,x)\) is acyclic and x is reachable from y.

  • Now, based on the information we discovered for \(\mathtt {sll}(x,z)\) and \(\mathtt {sll}(y,x)\), we examine \(\varphi \) and conclude that it is cyclic, as z is reachable from x, y is reachable from z, and x is reachable from y. Crucially, we reason inductively and thus do not re-examine the list segments to arrive at our conclusion.

In summary, we examine a symbolic heap and corresponding SID bottom-up, starting from the non-recursive base case. Moreover, at each stage of this analysis, we remember a fixed amount of information—namely what we discover about reachability between parameters and acyclicity of every symbolic heap we examine. Similar inductive constructions are defined explicitly for various robustness properties throughout the separation logic literature [11, 13, 26]. Our aim is to generalize such manual constructions following an automata-theoretic approach: We introduce automata that operate on symbolic heaps and store the relevant information of each symbolic heap they examine in their state space. Whenever such an automaton comes across a predicate that it has already analyzed, it can simply replace the predicate with the information that is encoded in the corresponding state. In other words, our automata recognize robustness properties in a compositional way by exploiting the inductive structure inherent in the SIDs.

Systematic Reasoning About Robustness Properties. Our novel automaton model, heap automata, works directly on the structure of symbolic heaps as outlined in the example, and can be applied to all the problems introduced before. In particular, heap automata enable automatic refinement of SIDs and enjoy a variety of closure properties through which we can derive counterexample generation as well as decision procedures for various robustness properties—including satisfiability, establishment, reachability, garbage-freedom, and acyclicity.

Our approach can thus be seen as an algorithmic framework for deciding a wide range of robustness properties of symbolic heaps. Furthermore, we show asymptotically optimal complexity of our automata-based decision procedures in a uniform way. By enabling this systematic approach to reasoning about robustness, our framework generalizes prior work that studied single robustness properties in isolation, such as the work by Brotherston et al. [11, 13].

As a natural byproduct of our automata-based approach, we also derive decision procedures for the model-checking problem, which was recently studied, and proven to be ExpTime–complete in general, by Brotherston et al. [13]. This makes it possible to apply our framework to run-time verification—a setting in which robustness properties are of particular importance [13, 28, 33].

Entailment Checking with Heap Automata. Finally, we also address the entailment problem. In Hoare-style program analysis, decision procedures for the entailment problem become essential to discharge implications between assertions, as required, for example, by the rule of consequence [25]. Because of this central role in verification, there is an extensive body of research on decision procedures for entailment; see, for example [3, 10, 14, 21, 26, 27, 32, 36]. Antonopoulos et al. [1] study the complexity of the entailment problem and show that it is undecidable in general, and already ExpTime–hard for SIDs specifying sets of trees.

We use heap automata to check entailment between determined symbolic heaps. Intuitively, determinedness is a strong form of the establishment property guaranteeing that two variables are either equal or unequal in every model. Unlike other decision procedures [3, 26, 27], our approach does not impose syntactic restrictions on the symbolic heap under consideration but merely requires that suitable heap automata for the predicates on the right-hand side of the entailment are provided. In particular, we show how to obtain ExpTime decision procedures from such heap automata—which exist for highly non-trivial SIDs. If desired, additional syntactic restrictions can be integrated seamlessly into our approach to boost our algorithms’ performance.

Contributions. Our main contributions can be summarized as follows.

  • We introduce heap automata, a novel automaton model operating directly on symbolic heaps. We prove that heap automata enjoy various useful closure properties. Besides union, intersection and complement, they are closed under the conjunction with pure formulas, allowing the construction of complex heap automata from simple ones.

  • We develop a powerful algorithmic framework for automated reasoning about and debugging of symbolic heaps with inductive predicate definitions based on heap automata.

  • We show that key robustness properties, such as satisfiability, establishment, reachability, garbage freedom and acyclicity, can naturally be expressed as heap automata. Moreover, the upper bounds of decision procedures obtained from our framework are shown to be optimal—i.e., ExpTime–complete—in each of these cases. Further, they enable automated refinement of SIDs to filter out (or expose) symbolic heaps with undesired properties.

  • Additionally, we apply heap automata to tackle the entailment and the model checking problem for symbolic heaps. We show that if each predicate of an SID can be represented by a heap automaton, then the entailment problem for the corresponding fragment of symbolic heaps is decidable in 2-ExpTime in general and ExpTime-complete if the maximal arity of predicates and points-to assertions is bounded. For example, our framework yields an ExpTime decision procedure for a symbolic heap fragment capable of representing trees with linked leaves—a fragment that is out of scope of most ExpTime decision procedures known so far (cf. [3, 21, 27]).

  • We implemented a prototype of our framework that yields promising results for all robustness properties considered in the paper.

Organization of the Paper. The fragment of symbolic heaps with inductive predicate definitions is briefly introduced in Sect. 2. Heap automata and derived decision procedures are studied in Sect. 3. Section 4 demonstrates that a variety of robustness properties can be checked by heap automata. We report on a prototypical implementation of our framework in Sect. 5. Special attention to the entailment problem is paid in Sect. 6. Finally, Sect. 7 concludes. Due to lack of space, most proofs as well as detailed constructions are provided in a full version of this paper that is available online [29].

2 Symbolic Heaps

This section briefly introduces the symbolic heap fragment of separation logic equipped with inductive predicate definitions.

Basic Notation. \(\mathbb {N}\) is the set of natural numbers and \(2^{S}\) is the powerset of a set S. \((co) dom (f)\) is the (co)domain of a (partial) function f. We abbreviate tuples \((u_1, \ldots , u_n)\), \(n \ge 0\), by \(\mathbf {u}\) and write \(\mathbf {u}\!\left[ i\right] \), \(1 \le i \le \Vert \mathbf {u}\Vert = n\), to denote \(u_i\), the i-th element of \(\mathbf {u}\). By slight abuse of notation, the same symbol \(\mathbf {u}\) is used for the set of all elements occurring in tuple \(\mathbf {u}\). The empty tuple is \(\varepsilon \) and the set of all (non-empty) tuples [of length \(n \ge 0\)] over a finite set S is \(S^{*}\) (\(S^{+}\) [\(S^{n}\)]). The concatenation of tuples \(\mathbf {u}\) and \(\mathbf {v}\) is \(\mathbf {u}\,\mathbf {v}\).

Syntax. We usually denote variables taken from \(\textit{Var}\) (including a dedicated variable \( \mathbf null \)) by abcxyz, etc. Moreover, let \( Pred \) be a set of predicate symbols and \( ar : Pred \rightarrow \mathbb {N}\) be a function assigning each symbol its arity. Spatial formulas \(\varSigma ^{}\) and pure formulas \(\pi \) are given by the following grammar:where \(\mathbf {y}\) is a non-empty tuple of variables. Here, \( emp \) stands for the empty heap, \(x \mapsto \mathbf {y}\) is a points-to assertion and Open image in new window is the separating conjunction. Furthermore, for \(P\in Pred \) and a tuple of variables \(\mathbf {y}\) of length \( ar (P)\), \(P\mathbf {y}\) is a predicate call. A symbolic heap \(\varphi (\mathbf {x}_{0}^{})\) with variables \(\textit{Var}(\varphi )\) and free variables \(\mathbf {x}_{0}^{} \subseteq \textit{Var}(\varphi )\) is a formula of the form Open image in new window   where \(\varSigma ^{}\) is a spatial formula, \(\varGamma ^{}\) is a sequence of predicate calls and \(\varPi ^{}\) is a finite set of pure formulas, each with variables from \(\mathbf {x}_{0}^{}\) and \(\mathbf {z}^{}\). This normal form, in which predicate calls and points-to assertions are never mixed, is chosen to simplify formal constructions. If an element of a symbolic heap is empty, we usually omit it to improve readability. For the same reason, we fix the notation from above and write \(\mathbf {z}^{\varphi }\), \(\mathbf {x}_{i}^{\varphi }\), \(\varSigma ^{\varphi }\) etc. to denote the respective component of symbolic heap \(\varphi \) in formal constructions. Hence, \(\Vert \mathbf {x}_{0}^{\varphi }\Vert \) and \(\Vert \varGamma ^{\varphi }\Vert \) refer to the number of free variables and the number of predicate calls of \(\varphi \), respectively. We omit the superscript whenever the symbolic heap under consideration is clear from the context. If a symbolic heap \(\tau \) contains no predicate calls, i.e., \(\Vert \varGamma ^{\tau }\Vert = 0\), then \(\tau \) is called reduced. Moreover, to simplify the technical development, we tacitly assume that \( \mathbf null \) is a free variable that is passed to every predicate call. Thus, for each \(i \in \mathbb {N}\), we write \(\mathbf {x}_{i}^{}\!\left[ 0\right] \) as a shortcut for \( \mathbf null \) and treat \(\mathbf {x}_{i}^{}\!\left[ 0\right] \) as if \(\mathbf {x}_{i}^{}\!\left[ 0\right] \in \mathbf {x}_{i}^{}\).1

Systems of Inductive Definitions. Every predicate symbol is associated with one or more symbolic heaps by a system of inductive definitions (SID). Formally, an SID is a finite set of rules of the form \(P\mathbf {x}_{0}^{} \Leftarrow \varphi \), where \(\varphi \) is a symbolic heap with \( ar (P) = \Vert \mathbf {x}_{0}^{\varphi }\Vert \). The set of all predicate symbols occurring in SID \(\varPhi \) and their maximal arity are denoted by \( Pred (\varPhi )\) and \( ar (\varPhi )\), respectively.

Example 1

An SID specifying doubly-linked list segments is defined by:where \(x_1\) corresponds to the head of the list, \(x_2\) and \(x_3\) represent the previous and the next list element and \(x_4\) represents the tail of the list. Further, the following rules specify binary trees with root \(x_1\), leftmost leaf \(x_2\) and successor of the rightmost leaf \(x_3\) in which all leaves are connected by a singly-linked list from left to right.

Definition 1

We write \( SH ^{}_{}\) for the set of all symbolic heaps and \( SH ^{\varPhi }_{}\) for the set of symbolic heaps restricted to predicate symbols taken from SID \(\varPhi \). Moreover, given a computable function \(\mathcal {C}: SH ^{}_{} \rightarrow \{0, 1\}\), the set of symbolic heaps \( SH ^{}_{\mathcal {C}}\) is given by \( SH ^{}_{\mathcal {C}} \triangleq \{ \varphi \in SH ^{}_{} \mid \mathcal {C}(\varphi ) = 1 \}\). We collect all SIDs in which every right-hand side belongs to \( SH ^{}_{\mathcal {C}}\) in \( SID _{\mathcal {C}}\). To refer to the set of all reduced symbolic heaps (belonging to a set defined by \(\mathcal {C}\)), we write \( RSH ^{}_{}\) \(( RSH ^{}_{\mathcal {C}})\).

Example 2

Let \(\alpha \in \mathbb {N}\) and \(\text {FV}^{\le \alpha }(\varphi ) \triangleq {\left\{ \begin{array}{ll} 1, &{} \Vert \mathbf {x}_{0}^{\varphi }\Vert \le \alpha \\ 0, &{} \text {otherwise} \end{array}\right. }\).

Clearly, \(\text {FV}^{\le \alpha }\) is computable. Moreover, \( SH ^{}_{\text {FV}^{\le \alpha }}\) is the set of all symbolic heaps having at most \(\alpha \) free variables.

Semantics. As in a typical RAM model, we assume heaps to consist of records with a finite number of fields. Let \(\textit{Val}\) denote an infinite set of values and \(\textit{Loc}\subseteq \textit{Val}\) an infinite set of addressable locations. Moreover, we assume the existence of a special non-addressable value \( \mathbf null \in \textit{Val}\setminus \textit{Loc}\).

A heap is a finite partial function \(h: \textit{Loc}\rightharpoonup \textit{Val}^{+}\) mapping locations to non-empty tuples of values. We write \(h_1 \uplus h_2\) to denote the union of heaps \(h_1\) and \(h_2\) provided that \( dom (h_1) \cap dom (h_2) = \emptyset \). Otherwise, \(h_1 \uplus h_2\) is undefined. Variables are interpreted by a stack, i.e., a partial function \(s~:~\textit{Var}\rightharpoonup \textit{Val}\) with \(s( \mathbf null ) = \mathbf null \). Furthermore, stacks are canonically extended to tuples of variables by componentwise application. We call a stack–heap pair \((s,h)\) a state. The set of all states is \(\textit{States}\). The semantics of a symbolic heap with respect to an SID and a state is shown in Fig. 1. Note that the semantics of predicate calls is explained in detail next.
Fig. 1.

Semantics of the symbolic heap fragment of separation logic with respect to an SID \(\varPhi \) and a state \((s,h)\).

Unfoldings of Predicate Calls. The semantics of predicate calls is defined in terms of unfolding trees. Intuitively, an unfolding tree specifies how predicate calls are replaced by symbolic heaps according to a given SID. The resulting reduced symbolic heap obtained from an unfolding tree is consequently called an unfolding. Formally, let Open image in new window . Then a predicate call \(P_{i}^{}\mathbf {x}_{i}^{}\) may be replaced by a reduced symbolic heap \(\tau \) if \(\Vert \mathbf {x}_{i}^{}\Vert = \Vert \mathbf {x}_{0}^{\tau }\Vert \) and \(\textit{Var}(\varphi ) \cap \textit{Var}(\tau ) \subseteq \mathbf {x}_{0}^{\tau }\). The result of such a replacement iswhere \(\tau \left[ \mathbf {x}_{0}^{\tau } / \mathbf {x}_{i}^{}\right] \) denotes the substitution of each free variable of \(\tau \) by the corresponding parameter of \(P_i^{}\).

A tree over symbolic heaps \( SH ^{\varPhi }_{}\) is a finite partial function \(t : \mathbb {N}^{*} \rightharpoonup SH ^{\varPhi }_{}\) such that \(\emptyset \ne dom (t) \subseteq \mathbb {N}^{*}\) is prefix-closed and for all \(\mathbf {u} \in dom (t)\) with \(t(\mathbf {u}) = \varphi \), we have \(\{1,\ldots ,\Vert \varGamma ^{\varphi }\Vert \} = \{ i \in \mathbb {N}~|~ \mathbf {u}\,i \in dom (t) \}\). The element \(\varepsilon \in dom (t)\) is called the root of tree t. Furthermore, the subtree Open image in new window of t with root \(\mathbf {u}\) is Open image in new window with Open image in new window .

Definition 2

Let \(\varPhi \in SID _{}\) and \(\varphi \in SH ^{\varPhi }_{}\). Then the set of unfolding trees of \(\varphi \) w.r.t. \(\varPhi \), written \(\mathbb {T}_{\varPhi }(\varphi )\), is the least set that contains all trees t that satisfy (1) \(t(\varepsilon ) = \varphi \) and (2) Open image in new window for each \(1 \le i \le \Vert \varGamma ^{\varphi }\Vert \), where \(P_i^{\varphi } \Leftarrow \psi _i \in \varPhi \).

Note that for every reduced symbolic heap \(\tau \), we have \(\Vert \varGamma ^{\tau }\Vert = 0\). Thus, \(\mathbb {T}_{\varPhi }(\tau ) = \{ t \}\), where \(t : \{ \varepsilon \} \rightarrow \{ \tau \}: \varepsilon \mapsto \tau \), forms the base case in Definition 2. Every unfolding tree t specifies a reduced symbolic heap \(\llbracket t \rrbracket \), which is obtained by recursively replacing predicate calls by reduced symbolic heaps:

Definition 3

The unfolding of an unfolding tree \(t \in \mathbb {T}_{\varPhi }(\varphi )\) iswhere we tacitly assume that the variables \(\mathbf {z}^{t(\varepsilon )}\), i.e., the existentially quantified variables in \(t(\varepsilon )\), are substituted by fresh variables.

Example 3

Recall from Example 1 the two symbolic heaps \(\tau \) (upper) and \(\varphi \) (lower) occurring on the right-hand side of the dll predicate. Then \(t : \{\varepsilon ,1\} \rightarrow \{\varphi , \tau \}: \varepsilon \mapsto \varphi , 1 \mapsto \tau \) is an unfolding tree of \(\varphi \). The corresponding unfolding is

Definition 4

The set of all unfoldings of a predicate call \(P_{i}^{}\mathbf {x}_{i}^{}\) w.r.t. an SID \(\varPhi \) is denoted by \(\mathbb {U}_{\varPhi }(P_{i}^{}\mathbf {x}_{i}^{})\). Analogously, the unfoldings of a symbolic heap \(\varphi \) are \( \mathbb {U}_{\varPhi }(\varphi )~\triangleq ~\{ \llbracket t \rrbracket ~|~ t \in \mathbb {T}_{\varPhi }(\varphi ) \} \).

Then, as already depicted in Fig. 1, the semantics of predicate calls requires the existence of an unfolding satisfying a given state. This semantics corresponds to a particular iteration of the frequently used semantics of predicate calls based on least fixed points (cf. [11]). Further note that applying the SL semantics to a given symbolic heap coincides with applying them to a suitable unfolding.

Lemma 1

Let \(\varphi \in SH ^{\varPhi }_{}\). Then, for every \((s,h) \in \textit{States}\), we have
$$\begin{aligned} s,h\models _{\varPhi } \varphi ~\text {iff}~ \exists \tau \in \mathbb {U}_{\varPhi }(\varphi ) ~.~ s,h\models _{\emptyset } \tau . \end{aligned}$$

3 Heap Automata

In this section we develop a procedure to reason about robustness properties of symbolic heaps. This procedure relies on the notion of heap automata; a device that assigns one of finitely many states to any given symbolic heap.

Definition 5

A heap automaton over \( SH ^{}_{\mathcal {C}}\) is a tuple \(\mathfrak {A} = (Q, SH ^{}_{\mathcal {C}},\varDelta ,F)\), where Q is a finite set of states and \(F \subseteq Q\) is a set of final states, respectively. Moreover, \(\varDelta \subseteq Q^{*} \times SH ^{}_{\mathcal {C}}\times Q\) is a decidable transition relation such that \((\mathbf {q},\varphi ,p) \in \varDelta \) implies that \(\Vert \mathbf {q}\Vert = \Vert \varGamma ^{\varphi }\Vert \). We often write \(\mathbf {q} \xrightarrow {\varphi }_{\mathfrak {A}} p\) instead of \((\mathbf {q},\varphi ,p) \in \varDelta \).

A transition \(\mathbf {q} \xrightarrow {\varphi }_{\mathfrak {A}} p\) takes a symbolic heap \(\varphi \) and an input state \(q_i\) for every predicate call \(P_i\) of \(\varphi \)—collected in the tuple \(\mathbf {q}\)—and assigns an output state p to \(\varphi \). Thus, the intuition behind a transition is that \(\varphi \) has a property encoded by state p if every predicate call \(P_i\) of \(\varphi \) is replaced by a reduced symbolic heap \(\tau _i\) that has a property encoded by state \(\mathbf {q}\!\left[ i\right] \).

Note that every heap automaton \(\mathfrak {A}\) assigns a state p to a reduced symbolic heap \(\tau \) within a single transition of the form \(\varepsilon \xrightarrow {\tau }_{\mathfrak {A}} p\). Alternatively, \(\mathfrak {A}\) may process a corresponding unfolding tree t with \(\llbracket t \rrbracket = \tau \). In this case, \(\mathfrak {A}\) proceeds similarly to the compositional construction of unfoldings (see Definition 3). However, instead of replacing every predicate call \(P_i\) of the symbolic heap \(t(\varepsilon )\) at the root of t by an unfolding Open image in new window of a subtree of t, \(\mathfrak {A}\) uses states to keep track of the properties of these unfolded subtrees. Consequently, \(\mathfrak {A}\) assigns a state p to the symbolic heap \(t(\varepsilon )\) if \((q_1,\ldots ,q_m) \xrightarrow {t(\varepsilon )}_{\mathfrak {A}} p\) holds, where for each \(1 \le i \le m\), \(q_i\) is the state assigned to the unfolding of subtree Open image in new window , i.e., there is a transition Open image in new window . It is then natural to require that p should coincide with the state assigned directly to the unfolding \(\llbracket t \rrbracket \), i.e., \(\varepsilon \xrightarrow {\llbracket t \rrbracket }_{\mathfrak {A}} p\). Hence, we require all heap automata considered in this paper to satisfy a compositionality property.

Definition 6

A heap automaton \(\mathfrak {A} = (Q, SH ^{}_{\mathcal {C}},\varDelta ,F)\) is compositional if for every \(p \in Q\), every \(\varphi \in SH ^{}_{\mathcal {C}}\) with \(m \ge 0\) predicate calls Open image in new window , and all reduced symbolic heaps \(\tau _1,\ldots ,\tau _m \in RSH ^{}_{\mathcal {C}}\), we have:
$$ \begin{array}{c} \exists \mathbf {q} \in Q^m ~.~ (\mathbf {q},\varphi ,p) \in \varDelta ~\text {and}~ \bigwedge _{1 \le i \le m} (\varepsilon ,\tau _i,\mathbf {q}\!\left[ i\right] ) \in \varDelta \\ \text {if and only if} \\ (\varepsilon ,~ \varphi \left[ P_1/\tau _1,\ldots ,P_m/\tau _m\right] ,~p) ~\in ~ \varDelta . \end{array} $$

Due to the compositionality property, we can safely define the language \(L(\mathfrak {A})\) accepted by a heap automaton \(\mathfrak {A}\) as the set of all reduced symbolic heaps that are assigned a final state, i.e., \(L(\mathfrak {A}) \,\triangleq \, \{ \tau \in RSH ^{}_{\mathcal {C}}~|~ \exists q \in F \,.\, \varepsilon \xrightarrow {\tau }_{\mathfrak {A}} q \}\).

Example 4

Given a symbolic heap \(\varphi \), let \(|\varSigma ^{\varphi }|\) denote the number of points-to assertions in \(\varphi \). As a running example, we consider a heap automaton \(\mathfrak {A} = (\{0,1\}, SH ^{}_{},\varDelta ,\{1\})\), where \(\varDelta \) is given by
$$\begin{aligned} \mathbf {q} \xrightarrow {\varphi }_{\mathfrak {A}} p ~\text {iff}~ p = {\left\{ \begin{array}{ll} 1, &{} \text {if}~ |\varSigma ^{\varphi }| + \sum _{i=1}^{\Vert \mathbf {q}\Vert } \mathbf {q}\!\left[ i\right] > 0 \\ 0, &{} \text {otherwise}. \end{array}\right. } \end{aligned}$$
While \(\mathfrak {A}\) is a toy example, it illustrates the compositionality property: Consider the reduced symbolic heap Open image in new window . Since \(\tau \) contains no points-to assertions, \(\mathfrak {A}\) rejects \(\tau \) in a single step, i.e., \(\varepsilon \xrightarrow {\tau }_{\mathfrak {A}} 0 \notin \{1\}\). The compositionality property of \(\mathfrak {A}\) ensures that \(\mathfrak {A}\) yields the same result for every unfolding tree t whose unfolding \(\llbracket t \rrbracket \) is equal to \(\tau \). For instance, \(\tau \) is a possible unfolding of the symbolic heap Open image in new window , where \(\texttt {sll}\) is a predicate specifying singly-linked list segments as in Sect. 1. More precisely, if both predicate calls are replaced according to the rule \(\texttt {sll}(x,y) \Leftarrow emp : \{x = y\}\), we obtain \(\tau \) again (up to renaming of parameters as per Definition 3). In this case, \(\mathfrak {A}\) rejects as before: We have \(\varepsilon \xrightarrow { emp : \{x=y\}}_{\mathfrak {A}} 0\) for both base cases and \((0,0) \xrightarrow {\varphi }_{\mathfrak {A}} 0\) for the symbolic heap \(\varphi \). By the compositionality property, this is equivalent to \(\varepsilon \xrightarrow {\tau }_{\mathfrak {A}} 0\). Analogously, if a predicate call, say the first, is replaced according to the rule \(\texttt {sll}(x,y) \Leftarrow \psi \), where Open image in new window , \(1 \xrightarrow {\psi }_{\mathfrak {A}} 1\) and \((1,0) \xrightarrow {\varphi }_{\mathfrak {A}} 1\) holds, i.e., \(\mathfrak {A}\) accepts. In general, \(L(\mathfrak {A})\) is the set of all reduced symbolic heaps that contain at least one points-to assertion.
While heap automata can be applied to check whether a single reduced symbolic heap has a property of interest, i.e., belongs to the language of a heap automaton, our main application is directed towards reasoning about infinite sets of symbolic heaps, such as all unfoldings of a symbolic heap \(\varphi \). Thus, given a heap automaton \(\mathfrak {A}\), we would like to answer the following questions:
  1. 1.

    Does there exist an unfolding of \(\varphi \) that is accepted by \(\mathfrak {A}\)?

     
  2. 2.

    Are all unfoldings of \(\varphi \) accepted by \(\mathfrak {A}\)?

     

We start with a special case of the first question in which \(\varphi \) is a single predicate call. The key idea behind our corresponding decision procedure is to transform the SID \(\varPhi \) to filter out all unfoldings that are not accepted by \(\mathfrak {A}\). One of our main results is that such a refinement is always possible.

Theorem 1

(Refinement Theorem). Let \(\mathfrak {A}\) be a heap automaton over \( SH ^{}_{\mathcal {C}}\) and \(\varPhi \in SID _{\mathcal {C}}\). Then one can effectively construct a refined \(\varPsi \in SID _{\mathcal {C}}\) such that for each \(P\in Pred (\varPhi )\), we have \(\mathbb {U}_{\varPsi }(P\mathbf {x}_{0}^{}) = \mathbb {U}_{\varPhi }(P\mathbf {x}_{0}^{}) ~\cap ~ L(\mathfrak {A})\).

Proof

We construct \(\varPsi \in SID _{\mathcal {C}}\) over the predicate symbols \( Pred (\varPsi ) = ( Pred (\varPhi ) \times Q_{\mathfrak {A}}) \cup Pred (\varPhi )\) as follows: If \(P\mathbf {x}_{0}^{} \Leftarrow \varphi \in \varPhi \) with Open image in new window , \(m \ge 0\), and \((q_1, \ldots , q_m) \xrightarrow {\varphi }_{\mathfrak {A}} q_0\), we add a rule to \(\varPsi \) in which \(P\) is substituted by \(\langle P,q_0\rangle \) and each predicate call \(P_{i}^{}\mathbf {x}_{i}^{}\) is substituted by a call \(\langle P_i,q_i\rangle \mathbf {x}_{i}^{}\). Furthermore, for each \(q \in F_{\mathfrak {A}}\), we add a rule \(P\mathbf {x}_{0}^{} \Leftarrow \langle P,q\rangle \mathbf {x}_{0}^{}\) to \(\varPsi \). See [29]  for details.    \(\square \)

Example 5

Applying the refinement theorem to the heap automaton from Example 4 and the SID from Example 1 yields a refined SID given by the rules:Hence, the refined predicate \( \texttt {dll} \,\mathbf {x}_{0}^{}\) specifies all non-empty doubly-linked lists.

To answer question (1) we then check whether the set of unfoldings of a refined SID is non-empty. This boils down to a simple reachability analysis.

Lemma 2

Given an SID \(\varPhi \) and a predicate symbol \(P\in Pred (\varPhi )\), it is decidable in linear time whether the set of unfoldings of \(P\) is empty, i.e., Open image in new window .

Proof

(sketch). It suffices to check whether the predicate \(P\) lies in the least set R such that (1) \(I \in R\) if \(I\mathbf {x}_{0}^{} \Leftarrow \tau \in \varPhi \) for some \(\tau \in RSH ^{}_{}\), and (2) \(I \in R\) if \(I\mathbf {x}_{0}^{} \Leftarrow \varphi \in \varPhi \) and for each \(P_{i}^{\varphi }\mathbf {x}_{i}^{\varphi }\), \(1 \le i \le \Vert \varGamma ^{\varphi }\Vert \), \(P_i^{\varphi } \in R\). The set R is computable in linear time by a simple backward reachability analysis.

   \(\square \)

As outlined before, putting the Refinement Theorem and Lemma 2 together immediately yields a decision procedure for checking whether some unfolding of a predicate symbol P is accepted by a heap automaton: Construct the refined SID and subsequently check whether the set of unfoldings of P is non-empty.

To extend this result from unfoldings of single predicates to unfoldings of arbitrary symbolic heaps \(\varphi \), we just add a rule \(P \Leftarrow \varphi \), where \(P\) is a fresh predicate symbol, and proceed as before.

Corollary 1

Let \(\mathfrak {A}\) be a heap automaton over \( SH ^{}_{\mathcal {C}}\) and \(\varPhi \in SID _{\mathcal {C}}\). Then, for each \(\varphi \in SH ^{\varPhi }_{\mathcal {C}}\), it is decidable whether there exists Open image in new window such that \(\tau \in L(\mathfrak {A})\).

The refinement and emptiness check can also be integrated: Algorithm 1 displays a simple procedure that constructs the refined SID \(\varPsi \) from Theorem 1 on-the-fly while checking whether its set of unfoldings is empty for a given predicate symbol. Regarding complexity, the size of a refined SID2 obtained from an SID \(\varPhi \) and a heap automaton \(\mathfrak {A}\) is bounded by \(\Vert \varPhi \Vert \cdot \Vert Q_{\mathfrak {A}}\Vert ^{M+1}\), where M is the maximal number of predicate calls occurring in any rule of \(\varPhi \). Thus, the aforementioned algorithm runs in time \(\mathcal {O}\left( \Vert \varPhi \Vert \cdot \Vert Q_{\mathfrak {A}}\Vert ^{M+1} \cdot \Vert \varDelta _{\mathfrak {A}}\Vert \right) \), where \(\Vert \varDelta _{\mathfrak {A}}\Vert \) denotes the complexity of deciding whether the transition relation \(\varDelta _{\mathfrak {A}}\) holds for a given tuple of states and a symbolic heap occurring in a rule of \(\varPhi \).

Example 6

Resuming our toy example, we check whether some unfolding of the doubly-linked list predicate \(\texttt {dll}\,\mathbf {x}_{0}^{}\) (see Example 1) contains points-to assertions. Formally, we decide whether \(\mathbb {U}_{\varPhi }(\texttt {dll}\,\mathbf {x}_{0}^{}) \cap L(\mathfrak {A}) \ne \emptyset \), where \(\mathfrak {A}\) is the heap automaton introduced in Example 4. Algorithm 1 first picks the rule that maps dll to the empty list segment and consequently adds \(\langle \texttt {dll},0\rangle \) to the set R of reachable predicate–state pairs. In the next iteration, it picks the rule that maps to the non-empty list. Since \(\langle \mathtt {dll},0\rangle \in R\), s is set to 0 in the do-loop. Abbreviating the body of the rule to \(\varphi \), we have \((0,\varphi ,1) \in \varDelta \), so the algorithm adds \(\langle \texttt {dll},1\rangle \) to R. After that, no is returned, because 1 is a final state of \(\mathfrak {A}\). Hence, some unfolding of \(\texttt {dll}\) is accepted by \(\mathfrak {A}\) and thus contains points-to assertions.

We now revisit question (2) from above–are all unfoldings accepted by a heap automaton?–and observe that heap automata enjoy several closure properties.

Theorem 2

[29]. Let \(\mathfrak {A}\) and \(\mathfrak {B}\) be heap automata over \( SH ^{}_{\mathcal {C}}\). Then there exist heap automata \(\mathfrak {C}_1,\mathfrak {C}_2,\mathfrak {C}_3\) over \( SH ^{}_{\mathcal {C}}\) with \(L(\mathfrak {C}_1) = L(\mathfrak {A}) \cup L(\mathfrak {B})\), \(L(\mathfrak {C}_2) = L(\mathfrak {A}) \cap L(\mathfrak {B})\), and \(L(\mathfrak {C}_3) = RSH ^{}_{\mathcal {C}}\setminus L(\mathfrak {A})\), respectively.

Then, by the equivalence \(X \subseteq Y \Leftrightarrow X \,\cap \, \overline{Y} = \emptyset \) and Theorem 2, it is also decidable whether every unfolding of a symbolic heap is accepted by a heap automaton.

Corollary 2

Let \(\mathfrak {A}\) be a heap automaton over \( SH ^{}_{\mathcal {C}}\) and \(\varPhi \in SID _{\mathcal {C}}\). Then, for each \(\varphi \in SH ^{}_{\mathcal {C}}\), it is decidable whether \(\mathbb {U}_{\varPhi }(\varphi ) \subseteq L(\mathfrak {A})\) holds.

Note that complementation of heap automata in general leads to an exponentially larger state space and exponentially higher complexity of evaluating \(\varDelta \). Thus, \(\mathbb {U}_{\varPhi }(\varphi ) \subseteq L(\mathfrak {A})\) is decidable in \( \mathcal {O}\left( \left( \Vert \varphi \Vert + \Vert \varPhi \Vert \right) \cdot \Vert 2^{Q_{\mathfrak {A}}}\Vert ^{2(M+1)} \cdot \Vert \varDelta _{\mathfrak {A}}\Vert \right) \). In many cases it is, however, possibly to construct smaller automata for the complement directly to obtain more efficient decision procedures. For example, this is the case for most heap automata considered in Sect. 4.

Apart from decision procedures, Theorem 1 enables systematic refinement of SIDs according to heap automata in order to establish desired properties. For instance, as shown in Sect. 4, an SID in which every unfolding is satisfiable can be constructed from any given SID. Another application of Theorem 1 is counterexample generation for systematic debugging of SIDs that are manually written as data structure specifications or even automatically generated. Such counterexamples are obtained by constructing the refined SID w.r.t. the complement of a given heap automaton. Then an unfolding of the SID that is rejected by the original heap automaton, i.e., a counterexample, can be reconstructed from a (failed) emptiness check. Further applications are examined in the following.

Remark 1

While we focus on the well-established symbolic heap fragment of separation logic, we remark that the general reasoning principle underlying heap automata is also applicable to check robustness properties of richer fragments. For example, permissions [7] are easily integrated within our framework.

4 A Zoo of Robustness Properties

This section demonstrates the wide applicability of heap automata to decide and establish robustness properties of SIDs. In particular, the sets of symbolic heaps informally presented in the introduction can be accepted by heap automata over the set \( SH ^{}_{\text {FV}^{\le \alpha }}\) of symbolic heaps with at most \(\alpha \ge 0\) free variables (cf. Example 2). Furthermore, we analyze the complexity of related decision problems. Towards a formal presentation, some terminology is needed.

Definition 7

The set of tight models of a symbolic heap \(\varphi \in SH ^{\varPhi }_{}\) is defined as \(\textit{Models}({\varphi }) \triangleq \{ (s,h) \in \textit{States}\,|\, dom (s) = \mathbf {x}_{0}^{\varphi } ,\, s,h\models _{\varPhi } \varphi \}\).

We often consider relationships between variables that hold in every tight model of a reduced symbolic heap. Formally, let \(\tau \triangleq \exists \mathbf {z}^{} . \varSigma ^{} : \varPi ^{} \in RSH ^{}_{}\). Moreover, let \( \textit{strip} (\tau )\) be defined as \(\tau \) except that each of its variables is free, i.e., \( \textit{strip} (\tau ) \triangleq \varSigma ^{} : \varPi ^{}\). Then two variables \(x,y \in \textit{Var}(\tau )\) are definitely (un)equal in \(\tau \), written \(x =_{\tau } y\) (\(x \ne _{\tau } y\)), if \(s(x) = s(y)\) (\(s(x) \ne s(y)\)) holds for every \((s,h) \in \textit{Models}({ \textit{strip} (\tau )})\). Analogously, a variable is definitely allocated if it is definitely equal to a variable occurring on the left-hand side of a points-to assertion. Thus the set of definitely allocated variables in \(\tau \) is given by
$$\begin{aligned} \textit{alloc} (\tau ) ~=~ \{ x \in \textit{Var}(\tau ) ~|~ \forall (s,h) \in \textit{Models}({ \textit{strip} (\tau )}) ~.~ s(x) \in dom (h) \}. \end{aligned}$$
Finally, a variable x definitely points-to variable y in \(\tau \), written \(x \mapsto _{\tau } y\), if for every \((s,h) \in \textit{Models}({ \textit{strip} (\tau )})\), we have \(s(y) \in h(s(x))\).

Example 7

Recall from Example 1 the symbolic heap \(\tau \) in the first rule of \(\texttt {tll}\,\mathbf {x}_{0}^{}\). Then \( \textit{alloc} (\tau ) = \{ x_1, x_2 \}\) and neither \(x_1 =_{\tau } x_3\) nor \(x_1 \ne _{\tau } x_3\) holds. Further,
$$\begin{aligned}&x_1 =_{\tau } x_2 ~\text {is true,}~&x_1 =_{\tau } x_3 ~\text {is false,}~&x_1 \ne _{\tau } \mathbf null ~\text {is true,}~ \\&x_1 \ne _{\tau } x_3 ~\text {is false,}~&x_1 \mapsto _{\tau } x_3 ~\text {is true,}~&x_3 \mapsto _{\tau } x_1 ~\text {is false.}~ ~\, \end{aligned}$$

Remark 2

All definite relationships are decidable in polynomial time. In fact, each of these relationships boils down to first adding inequalities \(x \ne \mathbf null \) and \(x \ne y\) for every pair x, y of distinct variables occurring on the left-hand side of points-to assertions to the set of pure formulas and then computing its (reflexive), symmetric (and transitive) closure with respect to \(\ne \) (and \(=\)). Furthermore, if the closure contains a contradiction, e.g., \( \mathbf null \ne \mathbf null \), it is set to all pure formulas over the variables of a given reduced symbolic heap. After that, it is straightforward to decide in polynomial time whether variables are definitely allocated, (un)equal or pointing to each other.

4.1 Tracking Equalities and Allocation

Consider the symbolic heap Open image in new window . Clearly, \(\varphi \) is unsatisfiable if \(x = y\) holds for every unfolding of \(P_1(x,y)\) and \(y \ne z\) holds for every unfolding of \(P_2(y,z)\). Analogously, \(\varphi \) is unsatisfiable if x is allocated in every unfolding of \(P_1(x,y)\) and z is allocated in every unfolding of \(P_2(y,z)\), because Open image in new window implies \(x \ne z\). This illustrates that robustness properties, such as satisfiability, require detailed knowledge about the relationships between parameters of predicate calls. Consequently, we construct a heap automaton \(\mathfrak {A}_{ \texttt {TRACK} }\) that keeps track of this knowledge. More precisely, \(\mathfrak {A}_{ \texttt {TRACK} }\) should accept those unfoldings in which it is guaranteed that
  • given a set \(A \subseteq \mathbf {x}_{0}^{}\), exactly the variables in A are definitely allocated, and

  • exactly the (in)equalities in a given set of pure formulas \(\varPi ^{}\) hold.

Towards a formal construction, we formalize the desired set of symbolic heaps.

Definition 8

Let \(\alpha \in \mathbb {N}_{> 0}\) and \(\mathbf {x}_{0}^{}\) be a tuple of variables with \(\Vert \mathbf {x}_{0}^{}\Vert = \alpha \). Moreover, let \(A \subseteq \mathbf {x}_{0}^{}\) and \(\varPi ^{}\) be a finite set of pure formulas over \(\mathbf {x}_{0}^{}\). The tracking property \( \texttt {TRACK} (\alpha ,A,\varPi ^{})\) is the set
$$\begin{aligned}&\{ \tau (\mathbf {x}_{0}^{}) \in RSH ^{}_{\text {FV}^{\le \alpha }} ~|~ \forall i,j ~.~ \mathbf {x}_{0}^{}\!\left[ i\right] \in A ~\text {iff}~ \mathbf {x}_{0}^{}\!\left[ i\right] \in \textit{alloc} (\tau ) \\&\qquad \text {and}~ \mathbf {x}_{0}^{}\!\left[ i\right] \sim \mathbf {x}_{0}^{}\!\left[ j\right] \in \varPi ^{} ~~\text {iff}~~ \mathbf {x}_{0}^{\tau }\!\left[ i\right] \sim _{\tau } \mathbf {x}_{0}^{\tau }\!\left[ j\right] \}. \end{aligned}$$

Intuitively, our heap automaton \(\mathfrak {A}_{ \texttt {TRACK} }\) stores in its state space which free variables are definitely equal, unequal and allocated. Its transition relation then enforces that these stored information are correct, i.e., a transition \(\mathbf {q} \xrightarrow {\varphi }_{\mathfrak {\mathfrak {A}_{ \texttt {TRACK} }}} p\) is only possible if the information stored in p is consistent with \(\varphi \) and with the information stored in the states \(\mathbf {q}\) for the predicate calls of \(\varphi \).

Formally, let \(\mathbf {x}_{0}^{}\) be a tuple of variables with \(\Vert \mathbf {x}_{0}^{}\Vert = \alpha \) and \( Pure (\mathbf {x}_{0}^{}) \triangleq 2^{\{ \mathbf {x}_{0}^{}\!\left[ i\right] \sim \mathbf {x}_{0}^{}\!\left[ j\right] ~|~ 0 \le i,j \le \alpha , \sim \in \{\,=,\,\ne \,\} \}}\) be the powerset of all pure formulas over \(\mathbf {x}_{0}^{}\). The information stored by our automaton consists of a set of free variables \(B \subseteq \mathbf {x}_{0}^{}\) and a set of pure formulas \(\varLambda \in Pure (\mathbf {x}_{0}^{})\). Now, for some unfolding \(\tau \) of a symbolic heap \(\varphi \), assume that B is chosen as the set of all definitely allocated free variables of \(\tau \). Moreover, assume \(\varLambda \) is the set of all definite (in)equalities between free variables in \(\tau \). We can then construct a reduced symbolic heap \(\textit{kernel}(\varphi ,(B,\varLambda ))\) from B and \(\varLambda \) that precisely captures these relationships between free variables.

Definition 9

Let \(\varphi \mathbf {x}_{0}^{}\) be a symbolic heap, \(B \subseteq \mathbf {x}_{0}^{}\) and \(\varLambda \in Pure (\mathbf {x}_{0}^{})\). Furthermore, let \(\text {min}(B,\varLambda ) = \{ \mathbf {x}_{0}^{i} \in B ~|~ \lnot \exists \mathbf {x}_{0}^{j} \in B . j < i ~\text {and}~ \mathbf {x}_{0}^{i} =_{\varLambda } \mathbf {x}_{0}^{j} \}\) be the set of minimal (w.r.t. to occurrence in \(\mathbf {x}_{0}^{}\)) allocated free variables. Then
$$\begin{aligned} \textit{kernel}(\varphi ,(B,\varLambda )) ~\triangleq ~ \bigstar _{\mathbf {x}_{0}^{}\!\left[ i\right] \in \text {min}(B,\varLambda )} ~ \mathbf {x}_{0}^{\varphi }\!\left[ i\right] \mapsto \mathbf null ~:~ \varLambda , \end{aligned}$$
where we write Open image in new window for Open image in new window .

Consequently, the relationships between free variables remain unaffected if a predicate call of \(\varphi \) is replaced by \(\textit{kernel}(\varphi ,(B,\varLambda ))\) instead of \(\tau \). Thus, \(\mathfrak {A}_{ \texttt {TRACK} }\) has one state per pair \((B, \varLambda )\). In the transition relation of \(\mathfrak {A}_{ \texttt {TRACK} }\) it suffices to replace each predicate call \(P\mathbf {x}_{0}^{}\) by the corresponding symbolic heap \(\textit{kernel}(P\mathbf {x}_{0}^{},(B,\varLambda ))\). and check whether the current state is consistent with the resulting symbolic heap. Intuitively, a potentially large unfolding of a symbolic heap \(\varphi \) with m predicate calls is “compressed” into a small one that contains all necessary information about parameters of predicate calls. Here, \(\mathbf {q}\) is a sequence of pairs \((B,\varLambda )\) as explained above. Formally,

Definition 10

\(\mathfrak {A}_{ \texttt {TRACK} }= (Q, SH ^{}_{\text {FV}^{\le \alpha }},\varDelta ,F)\) is given by:
$$\begin{aligned} Q ~\triangleq ~&2^{{\mathbf {x}_{0}^{}}} ~\times ~ Pure (\mathbf {x}_{0}^{}), \qquad \quad F ~\triangleq ~ \{ (A,\varPi ^{}) \}, \\ \varDelta ~~:~~&\mathbf {q} \xrightarrow {\varphi }_{\mathfrak {\mathfrak {A}_{ \texttt {TRACK} }}} (A_0,\varPi ^{}_0) ~\text {iff}~ \forall x,y \in \mathbf {x}_{0}^{} ~.~ \\&\quad y \in A_0 \leftrightarrow y^{\varphi } \in \textit{alloc} ( \textit{compress} (\varphi ,\mathbf {q})) \\&\quad \text {and}~ x \sim y \in \varPi ^{}_0 ~\leftrightarrow ~ x^{\varphi } \sim _{ \textit{compress} (\varphi ,\mathbf {q})} y^{\varphi }, \\ \textit{compress} (\varphi ,\mathbf {q}) ~\triangleq ~&\varphi \left[ P_1 / \textit{kernel}(P_{1}^{}\mathbf {x}_{1}^{},\mathbf {q}[1]), \ldots , P_m / \textit{kernel}(P_{m}^{}\mathbf {x}_{m}^{},\mathbf {q}[m])\right] , \end{aligned}$$
where \(m = \Vert \varGamma ^{\varphi }\Vert = \Vert \mathbf {q}\Vert \) is the number of predicate calls in \(\varphi \) and \(y^{\varphi }\) denotes the free variable of \(\varphi \) corresponding to \(y \in \mathbf {x}_{0}^{}\), i.e., if \(y = \mathbf {x}_{0}^{}\!\left[ i\right] \) then \(y^{\varphi } = \mathbf {x}_{0}^{\varphi }\!\left[ i\right] \).

Since \( \textit{compress} (\tau ,\varepsilon ) = \tau \) holds for every reduced symbolic heap \(\tau \), it is straightforward to show that \(L(\mathfrak {A}_{ \texttt {TRACK} }) = \texttt {TRACK} (\alpha ,A,\varPi )\). Furthermore, \(\mathfrak {A}_{ \texttt {TRACK} }\) satisfies the compositionality property [29]. Hence,

Lemma 3

For all \(\alpha \in \mathbb {N}_{> 0}\) and all sets \(A \subseteq \mathbf {x}_{0}^{}\), \(\varPi ^{} \in Pure (\mathbf {x}_{0}^{})\), there is a heap automaton over \( SH ^{}_{\text {FV}^{\le \alpha }}\) accepting \( \texttt {TRACK} (\alpha ,A,\varPi ^{})\).

4.2 Satisfiability

Tracking relationships between free variables of symbolic heaps is a useful auxiliary construction that serves as a building block in automata for more natural properties. For instance, the heap automaton \(\mathfrak {A}_{ \texttt {TRACK} }\) constructed in Definition 10 can be reused to deal with the

Satisfiability Problem (SL-SAT): Given \(\varPhi \in SID _{}\), \(\varphi \in SH ^{\varPhi }_{}\), decide whether \(\varphi \) is satisfiable, i.e., there exists \((s,h) \in \textit{States}\) such that \(s,h \models _{\varPhi } \varphi \).

Theorem 3

For each \(\alpha \in \mathbb {N}_{> 0}\), there is a heap automaton over \( SH ^{}_{\text {FV}^{\le \alpha }}\) accepting the set \( \texttt {SAT} (\alpha ) \triangleq \{ \tau \in RSH ^{}_{\text {FV}^{\le \alpha }} ~|~ \tau ~\text {is satisfiable} \} \) of all satisfiable reduced symbolic heaps with at most \(\alpha \) free variables.

Proof

A heap automaton accepting \( \texttt {SAT} (\alpha )\) is constructed as in Definition 10 except for the set of final states \( F \triangleq \{ (A,\varPi ^{}) ~|~ \mathbf null \ne \mathbf null \,\notin \varPi ^{} \} \) (cf. [29]).    \(\square \)

A heap automaton accepting the complement of \( \texttt {SAT} (\alpha )\) is constructed analogously by choosing \(F \triangleq \{ (A,\varPi ^{}) ~|~ \mathbf null \ne \mathbf null \,\in \varPi ^{} \}\). Thus, together with Corollary 1, we obtain a decision procedure for the satisfiability problem similar to the one proposed in [11]. Regarding complexity, the heap automaton \(\mathfrak {A}_{ \texttt {SAT} }\) from Definition 10 has \(2^{2\alpha ^2 + \alpha }\) states. By Remark 2, membership in \(\varDelta _{\mathfrak {A}_{ \texttt {SAT} }}\) is decidable in polynomial time. Thus, by Corollary 1, our construction yields an exponential-time decision procedure for \({ \textsc {SL-SAT} }\). If the number of free variables \(\alpha \) is bounded, an algorithm in \(\textsc {NP}\) is easily obtained by guessing a suitable unfolding tree of height at most \(\Vert Q_{\mathfrak {A}_{ \texttt {SAT} }}\Vert \) and running \(\mathfrak {A}_{ \texttt {SAT} }\) on it to check whether its unfolding is decidable (cf. [29]). This is in line with the results of Brotherston et al. [11], where the satisfiability problem is shown to be \(\textsc {ExpTime}\)–complete in general and NP–complete if the number of free variables is bounded. These complexity bounds even hold for the following special case [13]:

Restricted Satisfiability Problem (SL-RSAT): Given an SID \(\varPhi \) that contains no points-to assertions, and a predicate symbol \(P\), decide whether \(P\mathbf {x}\) is satisfiable w.r.t. \(\varPhi \). The complement of this problem is denoted by \(\overline{{ \textsc {SL-RSAT} }}\).

4.3 Establishment

A symbolic heap \(\varphi \) is established if every existentially quantified variable of every unfolding of \(\varphi \) is definitely equal to a free variable or definitely allocated.3 This property is natural for symbolic heaps that specify the shape of data structures; for example, the SIDs in Example 1 define sets of established symbolic heaps. Further, establishment is often required to ensure decidability of the entailment problem [26, 27]. Establishment can also be checked by heap automata.

Theorem 4

For all \(\alpha \in \mathbb {N}_{> 0}\), there is a heap automaton over \( SH ^{}_{\text {FV}^{\le \alpha }}\) accepting the set of all established reduced symbolic heaps with at most \(\alpha \) free variables:
$$\begin{aligned} \texttt {EST} (\alpha ) ~\triangleq ~ \{ \tau \in RSH ^{}_{\text {FV}^{\le \alpha }} ~|~&\forall y \in \textit{Var}(\tau ) ~.~ y \in \textit{alloc} (\tau ) ~\text {or}~ \exists x \in \mathbf {x}_{0}^{\tau } ~.~ x =_{\tau } y \} \end{aligned}$$

Proof

The main idea in the construction of a heap automaton \(\mathfrak {A}_{ \texttt {EST} }\) for \( \texttt {EST} (\alpha )\) is to verify that every variable is definitely allocated or equal to a free variable while running \(\mathfrak {A}_{ \texttt {TRACK} }\) (see Definition 10) in parallel to keep track of the relationships between free variables. An additional flag \(q \in \{0,1\}\) is attached to each state of \(\mathfrak {A}_{ \texttt {TRACK} }\) to store whether the establishment condition is already violated (\(q=0\)) or holds so far (\(q=1\)). Formally, \(\mathfrak {A}_{ \texttt {EST} }= (Q, SH ^{}_{\text {FV}^{\le \alpha }},\varDelta ,F)\), where
$$\begin{aligned}&Q ~\triangleq ~ Q_{\mathfrak {A}_{ \texttt {TRACK} }} \times \{0,1\}, \qquad F ~\triangleq ~ Q_{\mathfrak {A}_{ \texttt {TRACK} }} \times \{1\}, \\&\varDelta ~~:~~ (p_1,q_1) \ldots (p_m,q_m) \xrightarrow {\varphi }_{\mathfrak {\mathfrak {A}_{ \texttt {EST} }}} (p_0,q_0) \\&~\text {iff}~ p_1\ldots p_m \xrightarrow {\varphi }_{\mathfrak {\mathfrak {A}_{ \texttt {TRACK} }}} p_0 ~\text {and}~ q_0 = \min \{q_1,\ldots ,q_m, \textit{check} (\varphi ,p_1 \ldots p_m)\}. \end{aligned}$$
Here, \( \textit{check} : SH ^{}_{\text {FV}^{\le \alpha }} \times Q_{\mathfrak {A}_{ \texttt {TRACK} }}^{*} \rightarrow \{0,1\}\) is a predicate given by
$$\begin{aligned} \textit{check} (\varphi ,\mathbf {p}) ~\triangleq ~ {\left\{ \begin{array}{ll} 1, &{} ~\text {if}~ \forall y \in \textit{Var}(\varphi ) ~.~ y \in \textit{alloc} ( \textit{compress} (\varphi ,\mathbf {p})) \\ &{} \qquad \text {or}~ \exists x \in \mathbf {x}_{0}^{\varphi } ~.~ x =_{ \textit{compress} (\varphi ,\mathbf {p})} y \\ 0, &{} ~\text {otherwise}, \end{array}\right. } \end{aligned}$$
where \( \textit{compress} (\varphi ,\mathbf {p})\) is the reduced symbolic heap obtained from the tracking property as in Definition 10. Moreover, unlike in the construction of \(\mathfrak {A}_{ \texttt {TRACK} }\), we are not interested in a specific set of relationships between the pure formulas, so any state of \(\mathfrak {A}_{ \texttt {TRACK} }\) is chosen as a final state provided that predicate \( \textit{check} \) could be evaluated to 1. See [29]  for a correctness proof.   \(\square \)

Again, it suffices to swap the final- and non-final states of \(\mathfrak {A}_{ \texttt {EST} }\) to obtain a heap automaton \(\mathfrak {A}_{\overline{ \texttt {EST} }}\) accepting the complement of \( \texttt {EST} (\alpha )\). Thus, by Corollary 1 and Remark 2, we obtain an ExpTime decision procedure for the

Establishment Problem (SL-EST): Given an SID \(\varPhi \) and \(\varphi \in SH ^{\varPhi }_{}\), decide whether every \(\tau \in \mathbb {U}_{\varPhi }(\varphi )\) is established.

Lemma 4

\(\overline{{ \textsc {SL-RSAT} }}\) is polynomial-time reducible to SL-EST. Hence, the establishment problem \({ \textsc {SL-EST} }\) is ExpTime–hard in general and coNP–hard if the maximal number of free variables is bounded.

Proof

Let \((\varPhi ,P)\) be an instance of \(\overline{{ \textsc {SL-RSAT} }}\). Moreover, let \(\varphi \mathbf {x}_{0}^{} \,\triangleq \, \exists \mathbf {z} y ~.~ P\mathbf {z} : \{ \mathbf {x}_{0}^{}\!\left[ 1\right] = \mathbf null , y \ne \mathbf null \}.\) As y is neither allocated nor occurs in \(P\mathbf {z}\), \(\varphi \) is established iff \(\mathbf {x}_{0}^{}\!\left[ 1\right] = y\) iff \( \mathbf null \ne \mathbf null \) iff \(P\mathbf {x}\) is unsatisfiable. Hence, \((\varPhi ,\varphi ) \in { \textsc {SL-EST} }\) iff \((\varPhi ,P) \in \overline{{ \textsc {SL-RSAT} }}\). A full proof is found in [29].    \(\square \)

Lemma 5

SL-EST is in coNP for a bounded number of free variables \(\alpha \).

Proof

Let \((\varPhi ,\varphi )\) be an instance of \({ \textsc {SL-EST} }\), \(N = \Vert \varPhi \Vert + \Vert \varphi \Vert \), and \(M \le N\) be the maximal number of predicate calls occurring in \(\varphi \) and any rule of \(\varPhi \). Moreover, let \(\mathfrak {A}_{\overline{ \texttt {EST} }}\) be a heap automaton accepting \(\overline{ \texttt {EST} (\alpha )}\)—the complement of \( \texttt {EST} (\alpha )\) (cf. Theorem 4). Since \(\alpha \) is bounded by a constant, so is the number of states of \(\mathfrak {A}_{\overline{ \texttt {EST} }}\), namely \(\Vert Q_{\mathfrak {A}_{\overline{ \texttt {EST} }}}\Vert \le k = 2^{2\alpha ^2 + \alpha + 1}\). Now, let \(\mathbb {T}_{\varPhi }(\varphi )^{\le k}\) denote the set of all unfolding trees \(t \in \mathbb {T}_{\varPhi }(\varphi )\) of height at most k. Clearly, each of these trees is of size \(\Vert t\Vert \le M^{k} \le N^{k}\), i.e., polynomial in N. Moreover, let \(\omega : dom (t) \rightarrow Q_{\mathfrak {A}_{\overline{ \texttt {EST} }}}\) be a function mapping each node of t to a state of \(\mathfrak {A}_{\overline{ \texttt {EST} }}\). Again, \(\omega \) is of size polynomial in N; as such \(\Vert \omega \Vert \le k \cdot N^{k}\). Let \(\varOmega _{t}\) denote the set of all of these functions \(\omega \) for a given unfolding tree t with \(\omega (\varepsilon ) \in F_{\mathfrak {A}_{\overline{ \texttt {EST} }}}\). Given an unfolding tree \(t \in \mathbb {T}_{\varPhi }(\varphi )^{\le k}\) and \(\omega \in \varOmega _{t}\), we can easily decide whether \(\varepsilon \xrightarrow {\llbracket t \rrbracket }_{\mathfrak {\mathfrak {A}_{\overline{ \texttt {EST} }}}} \omega (\varepsilon )\) holds: For each \(u,u1,\ldots ,un \in dom (t)\), \(u(n+1) \notin dom (t)\), \(n \ge 0\), it suffices to check whether \(\omega (u1) \ldots \omega (un) \xrightarrow {t(u)}_{\mathfrak {\mathfrak {A}_{\overline{ \texttt {EST} }}}} \omega (u)\). Since, by Remark 2, each of these checks can be performed in time polynomial in N the whole procedure is feasible in polynomial time. We now show that \((\varPhi ,\varphi ) \in { \textsc {SL-EST} }\) if and only if
$$\begin{aligned} \forall t \in \mathbb {T}_{\varPhi }(\varphi )^{\le k} ~.~ \forall \omega \in \varOmega _{t} ~.~ \text {not}~ \varepsilon \xrightarrow {\llbracket t \rrbracket }_{\mathfrak {\mathfrak {A}_{\overline{ \texttt {EST} }}}} \omega (\varepsilon ). \end{aligned}$$
Since each \(t \in \mathbb {T}_{\varPhi }(\varphi )\) and each \(\omega \in \varOmega _{t}\) is of size polynomial in N, this is equivalent to \({ \textsc {SL-EST} }\) being in \(\textsc {coNP}\). To complete the proof, note that \(\mathbb {U}_{\varPhi }(\varphi ) \subseteq \texttt {EST} (\alpha )\) holds iff \(\llbracket t \rrbracket \notin \overline{ \texttt {EST} (\alpha )}\) for each \(t \in \mathbb {T}_{\varPhi }(\varphi )\). Furthermore, by a standard pumping argument, it suffices to consider trees in \(\mathbb {T}_{\varPhi }(\varphi )^{\le k}\): If there exists a taller tree t with \(\llbracket t \rrbracket \in \overline{ \texttt {EST} (\alpha )}\) then there is some path of length greater k in t on which two nodes are assigned the same state by a function \(\omega \in \varOmega _{t}\) proving membership of t in \(\overline{ \texttt {EST} (\alpha )}\). This path can be shortened to obtain a tree of smaller height.    \(\square \)

Putting upper and lower bounds together, we conclude:

Theorem 5

\({ \textsc {SL-EST} }\) is \(\textsc {ExpTime}\)–complete in general and \(\textsc {coNP}\)–complete if the number of free variables \(\alpha \) is bounded.

4.4 Reachability

Another family of robustness properties is based on reachability questions, e.g., “is every location of every model of a symbolic heap reachable from the location of a program variable?” or “is every model of a symbolic heap acyclic?”. For established SIDs, heap automata accepting these properties are an extension of the tracking automaton introduced in Definition 10.

More precisely, a variable y is definitely reachable from x in \(\tau \in RSH ^{}_{}\), written \(x \rightsquigarrow _{\tau } y\), if and only if \(x \mapsto _{\tau } y\) or there exists a \(z \in \textit{Var}(\tau )\) such that \(x \mapsto _{\tau } z\) and \(z \rightsquigarrow _{\tau } y\).4 Note that we define reachability to be transitive, but not reflexive. As for the other definite relationships between variables, definite reachability is computable in polynomial time for reduced symbolic heaps, e.g., by performing a depth-first search on the definite points-to relation \(\mapsto _{\tau }\). Note that our notion of reachability does not take variables into account that are only reachable from one another in some models of a reduced symbolic heap. For example, consider the symbolic heap Open image in new window . Then \(x \rightsquigarrow _{\tau } z\) does not hold, but there exists a model \((s,h)\) with \(s(z) = s(y) \in h(s(x))\). Thus, reachability introduced by unallocated variables is not detected. However, the existence (or absence) of such variables can be checked first due to Theorem 4.

Theorem 6

Let \(\alpha \in \mathbb {N}_{> 0}\) and \(R \subseteq \mathbf {x}_{0}^{} \times \mathbf {x}_{0}^{}\) be a binary relation over the variables \(\mathbf {x}_{0}^{}\) with \(\Vert \mathbf {x}_{0}^{}\Vert = \alpha \). Then the reachability property \( \texttt {REACH} (\alpha ,R)\), given by the set \(\{ \tau \in RSH ^{}_{\text {FV}^{\le \alpha }} ~|~ \forall i,j ~.~ (\mathbf {x}_{0}^{}\!\left[ i\right] ,\mathbf {x}_{0}^{}\!\left[ j\right] ) \in R ~\text {iff}~ \mathbf {x}_{0}^{\tau }\!\left[ i\right] \rightsquigarrow _{\tau } \mathbf {x}_{0}^{\tau }\!\left[ j\right] \},\) can be accepted by a heap automaton over \( SH ^{}_{\text {FV}^{\le \alpha }}\).

Proof

(sketch). A heap automaton \(\mathfrak {A}_{ \texttt {REACH} }\) accepting \( \texttt {REACH} (\alpha ,R)\) is constructed similarly to the heap automaton \(\mathfrak {A}_{ \texttt {TRACK} }\) introduced in Definition 10. The main difference is that \(\mathfrak {A}_{ \texttt {REACH} }\) additionally stores a binary relation \(S \subseteq \mathbf {x}_{0}^{} \times \mathbf {x}_{0}^{}\) in its state space to remember which free variables are reachable from one another. Correspondingly, we adapt Definition 9 as follows:
$$\begin{aligned} \textit{kernel}(\varphi ,(B,\varLambda ,S)) ~\triangleq ~ \exists z ~.~ \bigstar _{\text {min}(B,\varLambda )} ~ \mathbf {x}_{0}^{\varphi }\!\left[ i\right] \mapsto (\mathbf {v}_i) ~:~ \varLambda , \end{aligned}$$
where z is a fresh variable and \(\mathbf {v}_i\!\left[ j\right] \triangleq \mathbf {x}_{0}^{\varphi }\!\left[ j\right] \) if \((i,j) \in S\) and \(\mathbf {v}_i\!\left[ j\right] \triangleq z\), otherwise. The other parameters \(\varphi ,B,\varLambda \) are the same as in Definition 10. Note that the additional variable z is needed to deal with allocated free variables that cannot reach any other free variable, including \( \mathbf null \). Moreover, the set of final states is \(F_{\mathfrak {A}_{ \texttt {REACH} }} = Q_{\mathfrak {A}_{ \texttt {TRACK} }} \times \{R\}\). Correctness of this encoding is verified in the transition relation. Hence, the transition relation of \(\mathfrak {A}_{ \texttt {REACH} }\) extends the transition relation of \(\mathfrak {A}_{ \texttt {TRACK} }\) by the requirement \( (x,y) \in S ~\text {iff}~ x^{\varphi } \rightsquigarrow _{ \textit{compress} (\varphi ,\mathbf {p})} y^{\varphi } \) for every pair of free variables \(x,y \in \mathbf {x}_{0}^{}\). Here, \( \textit{compress} (\varphi ,\mathbf {p})\) is defined as in Definition 10 except that the new encoding \(\textit{kernel}(P_i\mathbf {x}_{i}^{},\mathbf {q}[i])\) from above is used. Since \( \textit{compress} (\tau ,\varepsilon ) = \tau \) holds for every reduced symbolic heap \(\tau \), it is straightforward to verify that \(L(\mathfrak {A}_{ \texttt {REACH} }) = \texttt {REACH} (\alpha )\). Further details are found in [29].    \(\square \)

Furthermore, we consider the related

Reachability Problem (SL-REACH): Given an SID \(\varPhi \), \(\varphi \in SH ^{\varPhi }_{}\) with \(\alpha = \Vert \mathbf {x}_{0}^{\varphi }\Vert \) and variables \(x,y \in \mathbf {x}_{0}^{\varphi }\), decide whether \(x \rightsquigarrow _{\tau } y\) holds for all \(\tau \in \mathbb {U}_{\varPhi }(\varphi )\).

Theorem 7

The decision problem SL-REACH is ExpTime–complete in general and coNP–complete if the number of free variables is bounded.

Proof

Membership in ExpTime follows from our upper bound derived for Algorithm 1, the size of the state space of \(\mathfrak {A}_{ \texttt {REACH} }\), which is exponential in \(\alpha \), and Remark 2. If \(\alpha \) is bounded, membership in \(\textsc {coNP}\) is shown analogously to Lemma 5. Lower bounds are shown by reducing \(\overline{{ \textsc {SL-RSAT} }}\) to SL-REACH. Formally, let \((\varPhi ,P)\) be an instance of \(\overline{{ \textsc {SL-RSAT} }}\). Moreover, let Open image in new window As \(\mathbf {x}_{0}^{}\!\left[ 2\right] \) is neither allocated nor \( \mathbf null \), \(\mathbf {x}_{0}^{}\!\left[ 2\right] \) is not definitely reachable from \(\mathbf {x}_{0}^{}\!\left[ 1\right] \) in any model of \(\varphi \). Hence \((\varPhi ,\varphi ,\mathbf {x}_{0}^{}\!\left[ 1\right] ,\mathbf {x}_{0}^{}\!\left[ 2\right] ) \in { \textsc {SL-REACH} }\) iff \(P\) is unsatisfiable. A detailed proof is found in [29].    \(\square \)

4.5 Garbage-Freedom

Like the tracking automaton \(\mathfrak {A}_{ \texttt {TRACK} }\), the automaton \(\mathfrak {A}_{ \texttt {REACH} }\) is a useful ingredient in the construction of more complex heap automata.

For instance, such an automaton can easily be modified to check whether a symbolic heap is garbage-free, i.e., whether every existentially quantified variable in every unfolding is reachable from some program variable.5

Garbage-freedom is a natural requirement if SIDs represent data structure specifications. For example, the SIDs in Example 1 are garbage-free. Furthermore, this property is needed by the approach of Habermehl et al. [24].

Lemma 6

For each \(\alpha \in \mathbb {N}_{> 0}\), the set \( \texttt {GFREE} (\alpha )\), given by
$$\begin{aligned}&\{ \tau \in RSH ^{}_{\text {FV}^{\le \alpha }} ~|~ \forall y \in \textit{Var}(\tau ) ~.~ \exists x \in \mathbf {x}_{0}^{\tau } ~.~ x =_{\tau } y ~\text {or}~ x \rightsquigarrow _{\tau } y \}, \end{aligned}$$
of garbage-free symbolic heaps can be accepted by a heap automaton over \( SH ^{}_{\text {FV}^{\le \alpha }}\).

Proof

(sketch). A heap automaton \(\mathfrak {A}_{ \texttt {GFREE} }\) accepting \( \texttt {GFREE} (\alpha )\) is constructed similarly to the heap automaton \(\mathfrak {A}_{ \texttt {EST} }\) introduced in the proof of Theorem 4. The main difference is that heap automaton \(\mathfrak {A}_{ \texttt {REACH} }\) is used instead of \(\mathfrak {A}_{ \texttt {TRACK} }\). Furthermore, the predicate \( \textit{check} : SH ^{}_{\text {FV}^{\le \alpha }} \times Q_{\mathfrak {A}_{ \texttt {REACH} }}^{*} \rightarrow \{0,1\}\) is redefined to verify that every variable of a symbolic heap \(\varphi \) is established in \( \textit{compress} (\varphi ,\mathbf {p})\), where \( \textit{compress} (\varphi ,\mathbf {p})\) is the same as in the construction of \(\mathfrak {A}_{ \texttt {REACH} }\) (see Theorem 6):
$$\begin{aligned} \textit{check} (\varphi ,\mathbf {p}) ~\triangleq ~ {\left\{ \begin{array}{ll} 1, &{} ~\text {if}~ \forall y \in \textit{Var}(\varphi ) \,.\, \exists x \in \mathbf {x}_{0}^{\varphi }.~ \\ &{} \qquad x =_{ \textit{compress} (\varphi ,\mathbf {p})} y ~\text {or}~ x \rightsquigarrow _{ \textit{compress} (\varphi ,\mathbf {p})} y \\ 0, &{} ~\text {otherwise}, \end{array}\right. } \end{aligned}$$
Since \( \textit{compress} (\tau ,\varepsilon ) = \tau \) holds for every reduced symbolic heap \(\tau \), it is straightforward that \(L(\mathfrak {A}_{ \texttt {GFREE} }) = \texttt {GFREE} (\alpha )\). A proof is found in [29].    \(\square \)

To guarantee that symbolic heaps are garbage-free, we solve the

Garbage-Freedom Problem (SL-GF): Given an SID \(\varPhi \) and \(\varphi \in SH ^{\varPhi }_{}\), decide whether every \(\tau \in \mathbb {U}_{\varPhi }(\varphi )\) is garbage-free, i.e., \(\tau \in \texttt {GFREE} (\alpha )\) for some \(\alpha \in \mathbb {N}\).

Theorem 8

SL-GF is ExpTime–complete in general and \(\textsc {coNP}\)–complete if the number of free variables \(\alpha \) is bounded.

4.6 Acyclicity

Automatic termination proofs of programs frequently rely on the acyclicity of employed data structures, i.e., they assume that no variable is reachable from itself (cf. [39]). Hence, we are interested in verifying that an SID is acyclic.

Lemma 7

For each \(\alpha \in \mathbb {N}_{> 0}\), the set of all weakly acyclic symbolic heaps
$$\begin{aligned} \texttt {ACYCLIC} (\alpha ) ~\triangleq ~&\{ \tau \in RSH ^{}_{\text {FV}^{\le \alpha }} ~|~ \mathbf null \ne _{\tau } \mathbf null ~\text {or}~ \forall x \in \textit{Var}(\tau ) ~.~ \text {not}~ x \rightsquigarrow _{\tau } x \} \end{aligned}$$
can be accepted by a heap automaton over \( SH ^{}_{\text {FV}^{\le \alpha }}\).

Here, the condition \( \mathbf null \ne _{\tau } \mathbf null \) ensures that an unsatisfiable reduced symbolic heap is considered weakly acyclic. Further, note that our notion of acyclicity is weak in the sense that dangling pointers may introduce cyclic models that are not considered. For example, \(\exists z . x \mapsto z\) is weakly acyclic, but contains cyclic models if x and z are aliases. However, weak acyclicity coincides with the absence of cyclic models for established SIDs—a property considered in Sect. 4.3.

Proof

(sketch). A heap automaton \(\mathfrak {A}_{ \texttt {ACYCLIC} }\) for the set of all weakly acyclic reduced symbolic heaps is constructed analogously to the heap automaton \(\mathfrak {A}_{ \texttt {GFREE} }\) in the proof of Lemma 6. The main difference is the predicate \( \textit{check} : SH ^{}_{\text {FV}^{\le \alpha }} \,\times \, Q_{\mathfrak {A}_{ \texttt {REACH} }}^{*} \rightarrow \{0,1\}\), which now checks whether a symbolic heap is weakly acyclic:
$$\begin{aligned} \textit{check} (\varphi ,\mathbf {p}) ~\triangleq ~ {\left\{ \begin{array}{ll} 1, &{} ~\text {if}~ \forall y \in \textit{Var}(\varphi ) ~.~ \text {not}~x \rightsquigarrow _{ \textit{compress} (\varphi ,\mathbf {p})} x \\ 0, &{} ~\text {otherwise}. \end{array}\right. } \end{aligned}$$
Moreover, the set of final states \(F_{\mathfrak {A}_{ \texttt {ACYCLIC} }}\) is chosen such that accepted symbolic heaps are unsatisfiable or \( \textit{check} (\varphi ,\mathbf {p}) =1\). See [29]  for details.    \(\square \)

For example, the symbolic heap \(\texttt {sll}\,\mathbf {x}_{0}^{}\) is weakly acyclic, but \(\texttt {dll}\,\mathbf {x}_{0}^{}\) (cf. Example 1) is not. In general, we are interested in the

Acyclicity Problem (SL-AC): Given an SID \(\varPhi \) and \(\varphi \in SH ^{\varPhi }_{}\), decide whether every \(\tau \in \mathbb {U}_{\varPhi }(\varphi )\) is weakly acyclic, i.e., \(\tau \in \texttt {ACYCLIC} (\alpha )\) for some \(\alpha \in \mathbb {N}\).

Theorem 9

SL-AC is ExpTime–complete in general and \(\textsc {coNP}\)–complete if the number of free variables \(\alpha \) is bounded.

Proof

Similar to the proof of Theorem 5. For lower bounds, we show that \(\overline{{ \textsc {SL-RSAT} }}\) is reducible to SL-AC. Let \((\varPhi ,P)\) be an instance of \(\overline{{ \textsc {SL-RSAT} }}\). Moreover, let Open image in new window . Since \(\mathbf {x}_{0}^{}\!\left[ 1\right] \) is definitely reachable from itself, \(\varphi \mathbf {x}_{0}^{}\) is weakly acyclic iff \(P\mathbf {x}_{0}^{}\) is unsatisfiable. Thus, \((\varPhi ,\varphi ) \in { \textsc {SL-AC} }\) iff \((\varPhi ,P) \in \overline{{ \textsc {SL-RSAT} }}\). See [29]  for details.    \(\square \)

5 Implementation

We developed a prototype of our framework—called Harrsh 6—that implements Algorithm 1 as well as all heap automata constructed in the previous sections. In addition, our tool supports automatic refinement of SIDs. Algorithms for counterexample generation and automatic combination of decision procedures can be extracted from the (constructive) proof of Theorem 2, but have not yet been implemented. The code, the tool and our experiments are available online.7

For our experimental results, we first considered common SIDs from the literature, such as singly- and doubly-linked lists, trees, trees with linked-leaves etc. For each of these SIDs, we checked all robustness properties presented throughout this paper, i.e., the existence of points-to assertions (Example 4), the tracking property \( \texttt {TRACK} (B,\varLambda )\) (Sect. 4.1), satisfiability (Sect. 4.2), establishment (Sect. 4.3), the reachability property \( \texttt {REACH} (\alpha ,R)\) (Sect. 4.4), garbage-freedom (Sect. 4.5), and weak acyclicity (Sect. 4.6). All in all, our implementation of Algorithm 1 takes 300ms to successfully check these properties on all 45 problem instances. Since the SIDs under consideration are typically carefully handcrafted to be robust, the low runtime is to be expected. Moreover, we ran heap automata on benchmarks of the tool Cyclist [11]. In particular, our results for the satisfiability problem—the only robustness property checked by both tools—were within the same order of magnitude.

Further details are found in [29].

6 Entailment Checking with Heap Automata

So far, we have constructed heap automata for reasoning about robustness properties, such as satisfiability, establishment and acyclicity. This section demonstrates that our approach can also be applied to discharge entailments for certain fragments of separation logic. Formally, we are concerned with the

Entailment Problem (SL-\(\mathrm{{ENTAIL}}_{C}^{\varPhi }\) ): Given symbolic heaps \(\varphi ,\psi \in SH ^{\varPhi }_{\mathcal {C}}\), decide whether \(\varphi \models _{\varPhi } \psi \) holds, i.e., \(\forall (s,h) \in \textit{States}.~ s,h\models _{\varPhi } \varphi ~\text {implies}~ s,h\models _{\varPhi } \psi \).

Note that the symbolic heap fragment of separation logic is not closed under conjunction and negation. Thus, a decision procedure for satisfiability (cf. Theorem 3) does not yield a decision procedure for the entailment problem. It is, however, essential to have a decision procedure for entailment, because this problem underlies the important rule of consequence in Hoare logic [25]. In the words of Brotherston et al. [10], “effective procedures for establishing entailments are at the foundation of automatic verification based on separation logic”.

We show how our approach to decide robustness properties, is applicable to discharge entailments for certain fragments of symbolic heaps. This results in an algorithm deciding entailments between so-called determined symbolic heaps for SIDs whose predicates can be characterized by heap automata.

Definition 11

A reduced symbolic heap \(\tau \) is determined if all tight models of \(\tau \) are isomorphic.8 If \(\tau \) is also satisfiable then we call \(\tau \) well-determined. Moreover, for some SID \(\varPhi \), a symbolic heap \(\varphi \in SH ^{\varPhi }_{}\) is (well-)determined if all of its unfoldings \(\tau \in \mathbb {U}_{\varPhi }(\varphi )\) are (well-)determined. Consequently, an SID \(\varPhi \) is (well-)determined if \(P\mathbf {x}\) is (well-)determined for each predicate symbol \(P\) in \(\varPhi \).

We present two sufficient conditions for determinedness of symbolic heaps. First, a reduced symbolic heap \(\tau \) is determined if all equalities and inequalities between variables are explicit, i.e., \(\forall x,y \in \textit{Var}(\tau )\, .\, x = y \in \varPi ^{\tau }\) or \(x \ne y \in \varPi ^{\tau }\)  [29]. Furthermore, a reduced symbolic heap \(\tau \) is determined if every variable is definitely allocated or definitely equal to \( \mathbf null \), i.e., \(\forall x \in \textit{Var}(\tau )\, .\, x \in \textit{alloc} (\tau )\) or \(x =_{\tau } \mathbf null \). These two notions can also be combined: A symbolic heap is determined if every variable x is definitely allocated or definitely equal to \( \mathbf null \) or there is an explicit pure formula \(x \sim y\) between x and each other variable y.

Example 8

By the previous remark, the SID generating acyclic singly-linked lists from Sect. 1 is well-determined. Furthermore, although the predicate \(\texttt {dll}\,\mathbf {x}_{0}^{}\) from Example 1 is not determined, the following symbolic heap is well-determined: Open image in new window .

6.1 Entailment Between Predicate Calls

We start by considering entailments between predicate calls of well-determined SIDs. By definition, an entailment \(\varphi \models _{\varPhi } \psi \) holds if for every stack–heap pair \((s,h)\) that satisfies an unfolding of \(\varphi \), there exists an unfolding of \(\psi \) that is satisfied by \((s,h)\) as well. Our first observation is that, for well-determined unfoldings, two quantifiers can be switched: It suffices for each unfolding \(\sigma \) of \(\varphi \) to find one unfolding \(\tau \) of \(\psi \) such that every model of \(\sigma \) is also a model of \(\tau \).

Lemma 8

Let \(\varPhi \in SID _{}\) and \(P_1,P_2\) be predicate symbols with \( ar (P_1) = ar (P_2)\). Moreover, let \(\mathbb {U}_{\varPhi }(P_1\mathbf {x})\) be well-determined. Then

Note that, even if only well-determined predicate calls are taken into account, it is undecidable in general whether an entailment \(P_1\mathbf {x}_{0}^{} \models _{\varPhi } P_2\mathbf {x}_{0}^{}\) holds [1, Theorem 3]. To obtain decidability, we additionally require the set of reduced symbolic heaps entailing a given predicate call to be accepted by a heap automaton.

Definition 12

Let \(\varPhi \in SID _{\mathcal {C}}\) and \(\varphi \in SH ^{\varPhi }_{\mathcal {C}}\). Thenis the set of all reduced symbolic heaps in \( SH ^{}_{\mathcal {C}}\) over the same free variables as \(\varphi \) that entail an unfolding of \(\varphi \).

Example 9

Let \(\varphi (\mathbf {x}_{0}^{}) = \texttt {tll}\,\mathbf {x}_{0}^{} : \{ \mathbf {x}_{0}^{}\!\left[ 1\right] \ne \mathbf {x}_{0}^{}\!\left[ 2\right] \}\), where \(\texttt {tll}\) is a predicate of SID \(\varPhi \) introduced in Example 1. Then \(H_{\varphi ,\varPhi }^{\text {FV}^{\le 3}}\) consists of all reduced symbolic heaps with three free variables representing non-empty trees with linked leaves. In particular, note that these symbolic heaps do not have to be derived using the SID \(\varPhi \). For instance, they might contain additional pure formulas.

In particular, \(H_{P\mathbf {x},\varPhi }^{\mathcal {C}}\) can be accepted by a heap automaton for common predicates specifying data structures such as lists, trees, and trees with linked leaves.

We are now in a position to decide entailments between predicate calls.

Lemma 9

Let \(\varPhi \in SID _{\mathcal {C}}\) and \(P_1,P_2 \in Pred (\varPhi )\) be predicate symbols having the same arity. Moreover, let \(\mathbb {U}_{\varPhi }(P_1\mathbf {x})\) be well-determined and \(H_{P_2\mathbf {x},\varPhi }^{\mathcal {C}}\) be accepted by a heap automaton over \( SH ^{}_{\mathcal {C}}\). Then the entailment \(P_1\mathbf {x} \models _{\varPhi } P_2\mathbf {x}\) is decidable.

Proof

Let \(\mathfrak {A}_{ P_2\mathbf {x} }\) be a heap automaton over \( SH ^{}_{\mathcal {C}}\) accepting \(H_{P_2\mathbf {x},\varPhi }^{\mathcal {C}}\). Thenwhere the last inclusion is decidable by Corollary 2.    \(\square \)

6.2 Entailment Between Symbolic Heaps

Our next step is to generalize Lemma 9 to arbitrary determined symbolic heaps \(\varphi \) instead of single predicate calls. This requires the construction of heap automata \(\mathfrak {A}_{ \varphi }\) accepting \(H_{\varphi ,\varPhi }^{\mathcal {C}}\). W.l.o.g. we assume SIDs and symbolic heaps to be well-determined instead of determined only. Otherwise, we apply Theorem 1 with the heap automaton \(\mathfrak {A}_{ \texttt {SAT} }\) (cf. Theorem 3) to obtain a well-determined SID. Thus, we restrict our attention to the following set.

Definition 13

The set \( SH ^{}_{\langle \alpha \rangle }\) is given by \(\langle \alpha \rangle : SH ^{}_{} \rightarrow \{0,1\}\), where \(\langle \alpha \rangle (\varphi ) = 1\) iff \(\varphi \) is well-determined and every predicate call of \(\varphi \) has \(\le \alpha \in \mathbb {N}\) parameters.

Clearly, \(\langle \alpha \rangle \) is decidable, because satisfiability is decidable (cf. Theorem 3) and verifying that a symbolic heap has at most \(\alpha \) parameters amounts to a simple syntactic check. Note that, although the number of parameters in predicate calls is bounded by \(\alpha \), the number of free variables of a symbolic heap \(\varphi \in SH ^{}_{\langle \alpha \rangle }\) is not. We then construct heap automata for well-determined symbolic heaps.

Theorem 10

[29]. Let \(\alpha \in \mathbb {N}\) and \(\varPhi \in SID _{\text {FV}^{\le \alpha }}\) be established. Moreover, for each predicate symbol \(P\in Pred (\varPhi )\), let there be a heap automaton over \( SH ^{}_{\langle \alpha \rangle }\) accepting \(H_{P\mathbf {x},\varPhi }^{\langle \alpha \rangle }\). Then, for every well-determined symbolic heap \(\varphi \in SH ^{\varPhi }_{}\), there is a heap automaton over \( SH ^{}_{\langle \alpha \rangle }\) accepting \(H_{\varphi ,\varPhi }^{\langle \alpha \rangle }\).

Remark 3

Brotherston et al. [13] studied the model-checking problem for symbolic heaps, i.e., the question whether \(s,h\models _{\varPhi } \varphi \) holds for a given stack–heap pair \((s,h)\), an SID \(\varPhi \), and a symbolic heap \(\varphi \in SH ^{}_{\varPhi }\). They showed that this problem is ExpTime–complete in general and NP–complete if the number of free variables is bounded. We obtain these results for determined symbolic heaps in a natural way: Observe that every stack–heap pair \((s,h)\) is characterized by an established, well-determined, reduced symbolic heap, say \(\tau \), that has exactly \((s,h)\) as a tight model up to isomorphism. Then Theorem 10 yields a heap automaton \(\mathfrak {A}_{ \tau }\) accepting \(H_{\tau ,\varPhi }^{\langle \alpha \rangle }\), where \(\alpha \) is the maximal arity of any predicate in \(\varPhi \). Thus, \(s,h\models _{\varPhi } \varphi \) iff \(L(\mathfrak {A}_{ \tau }) \cap \mathbb {U}_{\varPhi }(\varphi ) \ne \emptyset \), which is decidable by Corollary 1. Further, note that the general model-checking problem is within the scope of heap automata. A suitable state space is the set of all subformulas of the symbolic heap \(\tau \).

Coming back to the entailment problem, it remains to put our results together. Algorithm 2 depicts a decision procedure for the entailment problem that, given an entailment \(\varphi \models _{\varPhi } \psi \), first removes all unsatisfiable unfoldings of \(\varphi \), i.e. \(\varphi \) becomes well-determined. After that, our previous reasoning techniques for heap automata and SIDs from Sect. 3 are applied to decide whether \(\varphi \models _{\varPhi } \psi \) holds.

Theorem 11

Let \(\alpha \in \mathbb {N}\) and \(\varPhi \in SID _{\text {FV}^{\le \alpha }}\) be established. Moreover, for every \(P\in Pred (\varPhi )\), let \(H_{P\mathbf {x},\varPhi }^{\langle \alpha \rangle }\) be accepted by a heap automaton over \( SH ^{}_{\langle \alpha \rangle }\). Then \(\varphi \models _{\varPhi } \psi \) is decidable for determined \(\varphi ,\psi \in SH ^{\varPhi }_{}\) with \(\mathbf {x}_{0}^{\varphi } = \mathbf {x}_{0}^{\psi }\).

Proof

We define a new SID \(\varOmega \triangleq \varPhi \cup \{ P\mathbf {x} \Leftarrow \varphi \}\), where \(P\) is a fresh predicate symbol of arity \(\Vert \mathbf {x}_{0}^{\varphi }\Vert \). Clearly, \(\varphi \models _{\varPhi } \psi \) iff \(P\mathbf {x} \models _{\varOmega } \psi \). Since \(\varphi \) and \(\varPhi \) are established, so is \(\varOmega \). Then applying Theorem 1 to \(\varOmega \) and \(\mathfrak {A}_{ \texttt {SAT} }\) (cf. Theorem 3), we obtain a well-determined SID \(\varPsi \in SID _{\langle \alpha \rangle }\) where none of the remaining unfoldings of \(\varOmega \) is changed, i.e., for each \(P\in Pred (\varOmega )\), we have \(\mathbb {U}_{\varPsi }(P\mathbf {x}) \subseteq \mathbb {U}_{\varOmega }(P\mathbf {x})\). By Theorem 10, the set \(H_{\psi ,\varPhi }^{\langle \alpha \rangle } = H_{\psi ,\varPsi }^{\langle \alpha \rangle }\) can be accepted by a heap automaton over \( SH ^{}_{\langle \alpha \rangle }\). Then, analogously to the proof of Lemma 9, \( \varphi \models _{\varPhi } \psi ~\text {iff}~ P\mathbf {x} \models _{\varPsi } \psi ~~\text {iff}~~ \mathbb {U}_{\varPsi }(P\mathbf {x}) \subseteq H_{\psi ,\varPsi }^{\langle \alpha \rangle },\) where the last inclusion is decidable by Corollary 2.    \(\square \)

6.3 Complexity

Algorithm 2 may be fed with arbitrarily large heap automata. For a meaningful complexity analysis, we thus consider heap automata of bounded size only.

Definition 14

An SID \(\varPhi \) is \(\alpha \)bounded if for each \(P\in Pred (\varPhi )\) there exists a heap automaton \(\mathfrak {A}_{P}\) over \( SH ^{}_{\langle \alpha \rangle }\) accepting \(H_{P\mathbf {x},\varPhi }^{\langle \alpha \rangle }\) such that \(\varDelta _{\mathfrak {A}_P}\) is decidable in \(\mathcal {O}\left( 2^{\text {poly}(\Vert \varPhi \Vert )}\right) \) and \(\Vert Q_{\mathfrak {A}_P}\Vert \le 2^{\text {poly}(\alpha )}\).

The bounds from above are natural for a large class of heap automata. In particular, all heap automata constructed in Sect. 4 stay within these bounds. Then a close analysis of Algorithm 2 for \(\alpha \)–bounded SIDs yields the following complexity results. A detailed analysis is provided in [29].

Theorem 12

\({ \textsc {SL-ENTAIL} }_{\langle \alpha \rangle }^{\varPhi }\) is decidable in 2-ExpTime for every \(\alpha \)–bounded SID \(\varPhi \). If \(\alpha \ge 1\) is a constant then \({ \textsc {SL-ENTAIL} }_{\langle \alpha \rangle }^{\varPhi }\) is ExpTime-complete.

Note that lower complexity bounds depend on the SIDs under consideration. Antonopoulos et al. [1, Theorem 6] showed that the entailment problem is already \(\varPi ^{P}_{2}\)–complete (the second level of the polynomial hierarchy) for the base fragment, i.e., \(\varPhi = \emptyset \). Thus, under common complexity assumptions, the exponential time upper bound derived in Theorem 12 is asymptotically optimal for a deterministic algorithm. Since the entailment problem is already ExpTime–hard for points-to assertions of arity 3 and SIDs specifying regular sets of trees (cf. [1, Theorem 5] and [29]), exponential time is actually needed for certain SIDs.

6.4 Expressiveness

Most common data structures specified by SIDs, such as lists, trees, trees with linked leaves and combinations thereof can be encoded by heap automata [29]. However, SIDs are more expressive than heap automata. For example, consider two concatenated lists of the same length that use different fields. While such lists are outside the scope of heap automata, a suitable SID is given by:In general, the close relationship between established SIDs and context-free graph languages studied by Dodds [19, Theorem 1] and Courcelle’s work on recognizable graph languages [18, Theorems 4.34 and 5.68], suggest that heap automata exist for every set of reduced symbolic heaps that can be specified in monadic second-order logic over graphs [18].

7 Conclusion

We developed an algorithmic framework for automatic reasoning about and debugging of the symbolic heap fragment of separation logic. Our approach is centered around a new automaton model, heap automata, that is specifically tailored to symbolic heaps. We show that many common robustness properties as well as certain types of entailments are naturally covered by our framework—often with optimal asymptotic complexity. There are several directions for future work including automated learning of heap automata accepting common data structures and applying heap automata to the abduction problem [16].

Footnotes

  1. 1.

    Since \(\mathbf {x}_{i}^{}\!\left[ 0\right] \) is just a shortcut and not a proper variable, \(\Vert \mathbf {x}_{i}^{}\Vert \) refers to the number of variables in \(\mathbf {x}_{i}^{}\) apart from \(\mathbf {x}_{i}^{}\!\left[ 0\right] \).

  2. 2.

    We assume a reasonable function \(\Vert .\Vert \) assigning a size to SIDs, symbolic heaps, unfolding trees, etc. For instance, the size \(\Vert \varPhi \Vert \) of an SID \(\varPhi \) is given by the product of its number of rules and the size of the largest symbolic heap contained in any rule.

  3. 3.

    Sometimes this property is also defined by requiring that each existentially quantified variable is “eventually allocated”  [26].

  4. 4.

    The definite points-to relation \(\mapsto _{\tau }\) was defined at the beginning of Sect. 4.

  5. 5.

    Note that a variable may be reachable from different program variables in different unfoldings as garbage-freedom is formally defined as a set of reduced symbolic heaps in which no form of disjunction exists (cf. Lemma 6).

  6. 6.

    Heap Automata for Reasoning about Robustness of Symbolic Heaps.

  7. 7.
  8. 8.

    Two states \((s_1,h_1), (s_2,h_2)\) are isomorphic iff \( dom (s_1) = dom (s_2)\) and there exists a bijective function \(g : dom (h_1) \rightarrow dom (h_2)\) such that for all \(x \in dom (s_1)\) and all \(\ell \in dom (h_1)\), we have \(g(s_1(x)) = s_2(x)\) and \(g(h_1(\ell )) = h_2(g(\ell ))\), where g is lifted to tuples by componentwise application.

Notes

Acknowledgements

We thank Tomer Kotek, Georg Weissenbacher and the anonymous reviewers for their helpful comments.

References

  1. 1.
    Antonopoulos, T., Gorogiannis, N., Haase, C., Kanovich, M., Ouaknine, J.: Foundations for decision problems in separation logic with general inductive predicates. In: Muscholl, A. (ed.) FoSSaCS 2014. LNCS, vol. 8412, pp. 411–425. Springer, Heidelberg (2014). doi: 10.1007/978-3-642-54830-7_27 CrossRefGoogle Scholar
  2. 2.
    Berdine, J., Calcagno, C., Cook, B., Distefano, D., O’Hearn, P.W., Wies, T., Yang, H.: Shape analysis for composite data structures. In: Damm, W., Hermanns, H. (eds.) CAV 2007. LNCS, vol. 4590, pp. 178–192. Springer, Heidelberg (2007). doi: 10.1007/978-3-540-73368-3_22 CrossRefGoogle Scholar
  3. 3.
    Berdine, J., Calcagno, C., O’Hearn, P.W.: A decidable fragment of separation logic. In: Lodaya, K., Mahajan, M. (eds.) FSTTCS 2004. LNCS, vol. 3328, pp. 97–109. Springer, Heidelberg (2004). doi: 10.1007/978-3-540-30538-5_9 CrossRefGoogle Scholar
  4. 4.
    Berdine, J., Calcagno, C., O’Hearn, P.W.: Smallfoot: modular automatic assertion checking with separation logic. In: de Boer, F.S., Bonsangue, M.M., Graf, S., de Roever, W.P. (eds.) FMCO 2005. LNCS, vol. 4111, pp. 115–137. Springer, Heidelberg (2006). doi: 10.1007/11804192_6 Google Scholar
  5. 5.
    Berdine, J., Calcagno, C., O’Hearn, P.W.: Symbolic execution with separation logic. In: Yi, K. (ed.) APLAS 2005. LNCS, vol. 3780, pp. 52–68. Springer, Heidelberg (2005). doi: 10.1007/11575467_5 CrossRefGoogle Scholar
  6. 6.
    Berdine, J., Cook, B., Ishtiaq, S.: SLAyer: memory safety for systems-level code. In: Gopalakrishnan, G., Qadeer, S. (eds.) CAV 2011. LNCS, vol. 6806, pp. 178–183. Springer, Heidelberg (2011). doi: 10.1007/978-3-642-22110-1_15 CrossRefGoogle Scholar
  7. 7.
    Bornat, R., Calcagno, C., O’Hearn, P.W., Parkinson, M.: Permission accounting in separation logic. In: ACM SIGPLAN Notices, vol. 40, pp. 259–270. ACM (2005)Google Scholar
  8. 8.
    Botincan, M., Distefano, D., Dodds, M., Grigore, R., Naudziuniene, D., Parkinson, M.J.: coreStar: the core of jStar. BOOGIE 2011, 65–77 (2011)Google Scholar
  9. 9.
    Brookes, S.: A semantics for concurrent separation logic. Theoret. Comput. Sci. 375(1), 227–270 (2007)MathSciNetCrossRefzbMATHGoogle Scholar
  10. 10.
    Brotherston, J., Distefano, D., Petersen, R.L.: Automated cyclic entailment proofs in separation logic. In: Bjørner, N., Sofronie-Stokkermans, V. (eds.) CADE 2011. LNCS (LNAI), vol. 6803, pp. 131–146. Springer, Heidelberg (2011). doi: 10.1007/978-3-642-22438-6_12 CrossRefGoogle Scholar
  11. 11.
    Brotherston, J., Fuhs, C., Pérez, J.A.N., Gorogiannis, N.: A decision procedure for satisfiability in separation logic with inductive predicates. In: CSL-LICS 2014, pp. 25:1–25:10. ACM (2014)Google Scholar
  12. 12.
    Brotherston, J., Gorogiannis, N.: Cyclic abduction of inductively defined safety and termination preconditions. In: Müller-Olm, M., Seidl, H. (eds.) SAS 2014. LNCS, vol. 8723, pp. 68–84. Springer, Heidelberg (2014). doi: 10.1007/978-3-319-10936-7_5 Google Scholar
  13. 13.
    Brotherston, J., Gorogiannis, N., Kanovich, M.I., Rowe, R.: Model checking for symbolic-heap separation logic with inductive predicates. In: POPL 2016, pp. 84–96. ACM (2016)Google Scholar
  14. 14.
    Brotherston, J., Gorogiannis, N., Petersen, R.L.: A generic cyclic theorem prover. In: Jhala, R., Igarashi, A. (eds.) APLAS 2012. LNCS, vol. 7705, pp. 350–367. Springer, Heidelberg (2012). doi: 10.1007/978-3-642-35182-2_25 CrossRefGoogle Scholar
  15. 15.
    Calcagno, C., Distefano, D.: Infer: an automatic program verifier for memory safety of C programs. In: Bobaru, M., Havelund, K., Holzmann, G.J., Joshi, R. (eds.) NFM 2011. LNCS, vol. 6617, pp. 459–465. Springer, Heidelberg (2011). doi: 10.1007/978-3-642-20398-5_33 CrossRefGoogle Scholar
  16. 16.
    Calcagno, C., Distefano, D., O’Hearn, P., Yang, H.: Compositional shape analysis by means of bi-abduction. In: POPL 2009, pp. 289–300. ACM (2009)Google Scholar
  17. 17.
    Chin, W., David, C., Nguyen, H.H., Qin, S.: Automated verification of shape, size and bag properties via user-defined predicates in separation logic. Sci. Comput. Program. 77(9), 1006–1036 (2012)CrossRefzbMATHGoogle Scholar
  18. 18.
    Courcelle, B., Engelfriet, J.: Graph Structure and Monadic Second-Order Logic: A Language-Theoretic Approach, vol. 138. Cambridge University Press, Cambridge (2012)CrossRefzbMATHGoogle Scholar
  19. 19.
    Dodds, M.: From separation logic to hyperedge replacement and back. In: Ehrig, H., Heckel, R., Rozenberg, G., Taentzer, G. (eds.) ICGT 2008. LNCS, vol. 5214, pp. 484–486. Springer, Heidelberg (2008). doi: 10.1007/978-3-540-87405-8_40 CrossRefGoogle Scholar
  20. 20.
    Dudka, K., Peringer, P., Vojnar, T.: Predator: a practical tool for checking manipulation of dynamic data structures using separation logic. In: Gopalakrishnan, G., Qadeer, S. (eds.) CAV 2011. LNCS, vol. 6806, pp. 372–378. Springer, Heidelberg (2011). doi: 10.1007/978-3-642-22110-1_29 CrossRefGoogle Scholar
  21. 21.
    Enea, C., Lengál, O., Sighireanu, M., Vojnar, T.: Compositional entailment checking for a fragment of separation logic. In: Garrigue, J. (ed.) APLAS 2014. LNCS, vol. 8858, pp. 314–333. Springer, Heidelberg (2014). doi: 10.1007/978-3-319-12736-1_17 Google Scholar
  22. 22.
    Gotsman, A., Berdine, J., Cook, B., Sagiv, M.: Thread-modular shape analysis. In: PLDI 2007, pp. 266–277. ACM (2007)Google Scholar
  23. 23.
    Habermehl, P., Holík, L., Rogalewicz, A., Šimáček, J., Vojnar, T.: Forest automata for verification of heap manipulation. In: Gopalakrishnan, G., Qadeer, S. (eds.) CAV 2011. LNCS, vol. 6806, pp. 424–440. Springer, Heidelberg (2011). doi: 10.1007/978-3-642-22110-1_34 CrossRefGoogle Scholar
  24. 24.
    Habermehl, P., Holík, L., Rogalewicz, A., Šimáček, J., Vojnar, T.: Forest automata for verification of heap manipulation. Formal Methods Syst. Des. 41(1), 83–106 (2012)CrossRefzbMATHGoogle Scholar
  25. 25.
    Hoare, C.A.R.: An axiomatic basis for computer programming. Commun. ACM 12(10), 576–580 (1969)CrossRefzbMATHGoogle Scholar
  26. 26.
    Iosif, R., Rogalewicz, A., Simacek, J.: The tree width of separation logic with recursive definitions. In: Bonacina, M.P. (ed.) CADE 2013. LNCS (LNAI), vol. 7898, pp. 21–38. Springer, Heidelberg (2013). doi: 10.1007/978-3-642-38574-2_2 CrossRefGoogle Scholar
  27. 27.
    Iosif, R., Rogalewicz, A., Vojnar, T.: Deciding entailments in inductive separation logic with tree automata. In: Cassez, F., Raskin, J.-F. (eds.) ATVA 2014. LNCS, vol. 8837, pp. 201–218. Springer, Heidelberg (2014). doi: 10.1007/978-3-319-11936-6_15 Google Scholar
  28. 28.
    Jacobs, B., Smans, J., Philippaerts, P., Vogels, F., Penninckx, W., Piessens, F.: VeriFast: a powerful, sound, predictable, fast verifier for C and Java. In: Bobaru, M., Havelund, K., Holzmann, G.J., Joshi, R. (eds.) NFM 2011. LNCS, vol. 6617, pp. 41–55. Springer, Heidelberg (2011). doi: 10.1007/978-3-642-20398-5_4 CrossRefGoogle Scholar
  29. 29.
    Jansen, C., Katelaan, J., Matheja, C., Noll, T., Zuleger, F.: Unified reasoning about robustness properties of symbolic-heap separation logic. CoRR abs/1610.07041 (2016). http://arxiv.org/abs/1610.07041
  30. 30.
    Le, Q.L., Gherghina, C., Qin, S., Chin, W.-N.: Shape analysis via second-order bi-abduction. In: Biere, A., Bloem, R. (eds.) CAV 2014. LNCS, vol. 8559, pp. 52–68. Springer, Heidelberg (2014). doi: 10.1007/978-3-319-08867-9_4 Google Scholar
  31. 31.
    Magill, S., Tsai, M.-H., Lee, P., Tsay, Y.-K.: THOR: a tool for reasoning about shape and arithmetic. In: Gupta, A., Malik, S. (eds.) CAV 2008. LNCS, vol. 5123, pp. 428–432. Springer, Heidelberg (2008). doi: 10.1007/978-3-540-70545-1_41 CrossRefGoogle Scholar
  32. 32.
    Navarro Pérez, J.A., Rybalchenko, A.: Separation logic modulo theories. In: Shan, C. (ed.) APLAS 2013. LNCS, vol. 8301, pp. 90–106. Springer, Heidelberg (2013). doi: 10.1007/978-3-319-03542-0_7 CrossRefGoogle Scholar
  33. 33.
    Nguyen, H.H., Kuncak, V., Chin, W.-N.: Runtime checking for separation logic. In: Logozzo, F., Peled, D.A., Zuck, L.D. (eds.) VMCAI 2008. LNCS, vol. 4905, pp. 203–217. Springer, Heidelberg (2008). doi: 10.1007/978-3-540-78163-9_19 CrossRefGoogle Scholar
  34. 34.
    O’Hearn, P., Reynolds, J., Yang, H.: Local reasoning about programs that alter data structures. In: Fribourg, L. (ed.) CSL 2001. LNCS, vol. 2142, pp. 1–19. Springer, Heidelberg (2001). doi: 10.1007/3-540-44802-0_1 CrossRefGoogle Scholar
  35. 35.
    O’Hearn, P.W.: Resources, concurrency, and local reasoning. Theor. Comput. Sci. 375(1–3), 271–307 (2007)MathSciNetCrossRefzbMATHGoogle Scholar
  36. 36.
    Piskac, R., Wies, T., Zufferey, D.: Automating separation logic with trees and data. In: Biere, A., Bloem, R. (eds.) CAV 2014. LNCS, vol. 8559, pp. 711–728. Springer, Heidelberg (2014). doi: 10.1007/978-3-319-08867-9_47 Google Scholar
  37. 37.
    Qiu, X., Garg, P., Ştefănescu, A., Madhusudan, P.: Natural proofs for structure, data, and separation. In: PLDI 2013, pp. 231–242. ACM (2013)Google Scholar
  38. 38.
    Reynolds, J.C.: Separation logic: a logic for shared mutable data structures. In: LICS 2002, pp. 55–74. IEEE (2002)Google Scholar
  39. 39.
    Zanardini, D., Genaim, S.: Inference of field-sensitive reachability and cyclicity. ACM Trans. Comput. Log. 15(4), 33:1–33:41 (2014)MathSciNetCrossRefzbMATHGoogle Scholar

Copyright information

© Springer-Verlag GmbH Germany 2017

Authors and Affiliations

  1. 1.Software Modeling and Verification GroupRWTH Aachen UniversityAachenGermany
  2. 2.TU WienViennaAustria

Personalised recommendations