Abstract
In this work, we present a semidecision procedure for a fragment of separation logic with userdefined predicates and Presburger arithmetic. To check the satisfiability of a formula, our procedure iteratively unfolds the formula and examines the derived disjuncts. In each iteration, it searches for a proof of either satisfiability or unsatisfiability. Our procedure is further enhanced with automatically inferred invariants as well as detection of cyclic proof. We also identify a syntactically restricted fragment of the logic for which our procedure is terminating and thus complete. This decidable fragment is relatively expressive as it can capture a range of sophisticated data structures with nontrivial pure properties, such as size, sortedness and nearbalanced. We have implemented the proposed solver and a new system for verifying heapbased programs. We have evaluated our system on benchmark programs from a software verification competition.
Keywords
 Decision procedures
 Satisfiability
 Separation logic
 Inductive predicates
 Cyclic proofs
Download conference paper PDF
1 Introduction
Satisfiability solvers, particularly those based on Satisfiability Modulo Theory (SMT) technology [3, 19], have made tremendous practical advances in the last decade to the point where they are now widely used in tools for applications as diverse as bug finding [27], program analyses [4] to automated verification [2]. However, current SMT solvers are based primarily on firstorder logic, and do not yet cater to the needs of resourceoriented logics, such as separation logic [26, 40]. Separation logic has recently established a solid reputation for reasoning about programs that manipulate heapbased data structures. One of its strengths is the ability to concisely and locally describe program states that hold in separate regions of heap memory. In particular, a spatial conjunction (i.e., \(\kappa _1 {*}\kappa _2\)) asserts that a given heap can be decomposed into two disjoint regions and the formulas, \(\kappa _1\) and \(\kappa _2\), hold respectively and separately in the two memory regions. In this work, we investigate the problem of verifying heapmanipulating programs in the framework of SMT. We reduce this problem to solving verification conditions representing precise program semantics [9, 10, 22, 44].
Developing an SMT solver supporting separation logic with inductive predicates and Presburger arithmetic is challenging as the satisfiability problem for this fragment is undecidable [30, 31]. We focus on an expressive fragment which consists of spatial predicates expressing empty heap assertion (\(\mathtt{emp}\)), pointsto assertion (\({x}{{\mapsto }}c(\bar{v})\)), and inductive predicate assertions (\({\small \mathtt{P}}(\bar{v})\)). Moreover, it may include pure constraints on data values and capture desired properties of structural heaps (such as size, height, sortedness and even nearbalanced tree properties). We thus face the challenge of handling recursive predicates with pure properties, that are inherently infinite. Furthermore, we would like to support both satisfiability (\(\mathtt {SAT}\)) and unsatisfiability (\(\mathtt {UNSAT}\)) checks.
There have been a number of preliminary attempts in this direction. For instance, early proposals fixed the set of shape predicates that may be used, for example, to linked lists (in SeLoger [17, 23], and SLL\(\mathbb {B}\) [34]) or trees (GRIT [36]). There are few approaches supporting userdefined predicates [14, 25, 39]. Brotherston et al. recently made an important contribution by introducing \(\mathtt {SLSAT}\), a decision procedure for a fragment of separation logic with arbitrary shapeonly inductive predicates [12]. However, \(\mathtt {SLSAT}\) is limited to the shape domain, whereas shape predicates extended with pure properties are often required for automated verification of functional correctness.
In this paper, we start by proposing a new procedure, called \(\mathtt {S2SAT}\), which combines underapproximation and overapproximation for simultaneously checking \(\mathtt {SAT}\) and \(\mathtt {UNSAT}\) properties for a sound and complete theory augmented with inductive predicates. \(\mathtt {S2SAT}\) takes a set of userdefined predicates and a logic formula as inputs. It iteratively constructs an unfolding tree by unfolding the formula in a breadthfirst, flow and contextsensitive manner until either a symbolic model, or a proof of unsatisfiability or a fixpoint (e.g., a cyclic proof) is identified. In each iteration, it searches over the leaves of the tree (the disjunction of which is equivalent to the input formula) to check whether there is a satisfiable leaf (which proves satisfiability) or whether all leaves are unsatisfiable. In particular, to prove \(\mathtt {SAT}\), it considers base disjuncts which are derived from basecase branches of the predicates. These disjuncts are underapproximations of the input formula and critical for satisfiability. Disjuncts which have no inductive predicates are precisely decided. To prove \(\mathtt {UNSAT}\), \(\mathtt {S2SAT}\) overapproximates the leaves prior to prove \(\mathtt {UNSAT}\). Our procedure systematically enumerates all disjuncts derived from a given inductive formula, so it is terminating for \(\mathtt {SAT}\). However, it may not be terminating for \(\mathtt {UNSAT}\) with those undecidable augmented logic. To facilitate termination, we propose an approach for fixpoint computation. This fixpoint computation is useful for domains with finite model semantics i.e., collecting semantics for a given formula of such domains is finite. In other words, the input formula is unsatisfiable when the unfolding goes on forever without uncovering any models. We have implemented one instantiation of the fixpoint detection for inductive proving based on cyclic proof [13] s.t. the soundness of the cyclic proof guarantees the wellfoundedness of all reasoning.
To explicitly handle heapmanipulating programs, we propose a separation logic instantiation of \(\mathtt {S2SAT}\), called \(\mathtt {S2SAT_{SL}}\). Our base theory is a combination of the aforementioned separation logic predicates except inductive predicates. We show that our decision procedure for this base theory is sound and complete. \(\mathtt {S2SAT_{SL}}\) overapproximates formulas with soundly inferred predicate invariants. In addition, we describe some syntax restrictions such that \(\mathtt {S2SAT_{SL}}\) is always able to construct a cyclic proof for a restricted formula so that our procedure is terminating and complete.
To summarize, we make the following technical contributions in this work.

We introduce cyclic proof into a satisfiability procedure for a base theory augmented with inductive predicates (refer to Sect. 3).

We propose a satisfiability procedure for separation logic with userdefined predicates and Presburger arithmetic (Sect. 4).

We prove that \(\mathtt {S2SAT_{SL}}\) is: (i) sound for \(\mathtt {SAT}\) and \(\mathtt {UNSAT}\); (ii) and terminating (i.e., proposing a new decision procedure) for restricted fragments (Sect. 5).

We present a mechanism to automatically derive sound (overapproximated) invariants for userdefined predicates (Sect. 6).

We have implemented the satisfiability solver \(\mathtt {S2SAT_{SL}}\) and the new verification system, called \(\mathtt {S2_{td}}\). We evaluated \(\mathtt {S2SAT_{SL}}\) and \(\mathtt {S2_{td}}\) with benchmarks from recent competitions. The experimental results show that our system is expressive, robust and efficient (Sect. 7).
Proofs of Lemmas and Theorems presented in this paper are available in the companion technical report [30].
2 Illustrative Example
We illustrate how our approach works with the example shown in Fig. 1. Our verification system proves that this program is memory safe and function \(\mathtt {ERROR()}\) (line 5) is never called. Our system uses symbolic execution in [6, 14] and largeblock encoding [8] to provide a semantic encoding of verification conditions. For safety, one of the generated verification conditions is: \(\varDelta _0~{\equiv }~ll(n{,}x)_0^0{*}test(x{,}r_1)_0^1{\wedge }n{\ge }0{\wedge }r_1{=}0\). If \(\varDelta _0\) is unsatisfiable, function \(\mathtt {ERROR()}\) is never called. In \(\varDelta _0\), \(\mathtt {ll}\) and \(\mathtt {test}\) are Interprocedural Control Flow Graph (ICFG) of the functions \(\mathtt {ll}\) and \(\mathtt {test}\). Our system eludes these ICFGs as inductive predicates. For each predicate, a parameter \(\mathtt{{res}}\) is appended at the end to model the return value of the function; for instance, the variables \(x\) (in \(\mathtt {ll}\)) and \(r_1\) (in \(\mathtt {test}\)) of \(\varDelta _0\) are the actual parameters corresponding to \(\mathtt{{res}}\). Each inductive predicate instance is also labeled with a subscript for the unfolding number and a superscript for the sequence number, which are used to control the unfolding in a breadthfirst and flowsensitive manner.
To discharge \(\varDelta _0\), \(\mathtt {S2SAT_{SL}}\) iteratively derives a series of unfolding trees \(\mathcal{T}_{i}\). An unfolding tree is a tree such that each node is labeled with an unfolded disjunct, corresponding to a path condition in the program. We say that a leaf of \(\mathcal{T}_{i}\) is closed if it is unsatisfiable; otherwise it is open. During each iteration, \(\mathtt {S2SAT_{SL}}\) either proves \(\mathtt {SAT}\) by identifying a satisfiable leaf of \(\mathcal{T}_{i}\) which contains no userdefined predicate instances or proves \(\mathtt {UNSAT}\) by showing that an overapproximation of all leaves is unsatisfiable. Initially, \(\mathcal{T}_{0}\) contains only one node \(\varDelta _0\). As \(\varDelta _0\) contains inductive predicates, it is not considered for proving \(\mathtt {SAT}\). \(\mathtt {S2SAT_{SL}}\) then overapproximates \(\varDelta _0\) to a firstorder logic formula by substituting each predicate instance with its corresponding sound invariants in order to prove \(\mathtt {UNSAT}\). We assume that \(\mathtt {ll}\) (resp. \(\mathtt {test}\)) is annotated with invariant \(i{\ge }0\) (resp. \(0{\le }\mathtt{{res}}{\le }1\)). Hence, the overapproximation of \(\varDelta _0\) is computed as: \(\pi _0{\equiv } n{\ge }0 {\wedge } 0{\le }r_1{\le }1 {\wedge } n {\ge }0 {\wedge }r_1{=}0\). Formula \(\pi _0\) is then passed to an SMT solver, such as Z3 [19], for unsatisfiable checking. As expected, \(\pi _0\) is not unsatisfiable.
Next, \(\mathtt {S2SAT_{SL}}\) selects an open leaf for unfolding to derive \(\mathcal{T}_{1}\). A leaf is selected in a breadthfirst manner; furthermore a predicate instance of the selected leaf is selected for unfolding if its sequence number is the smallest. With \(\varDelta _0\), the \(\mathtt {ll}\) instance is selected. As so, \(\mathcal{T}_{1}\) has two open leaves corresponding to two derived disjuncts:
Since \(\varDelta _{11}\) and \(\varDelta _{12}\) include predicate instances, they are not considered for \(\mathtt {SAT}\). To prove \(\mathtt {UNSAT}\), \(\mathtt {S2SAT_{SL}}\) computes their overapproximated invariants:
As neither \(\pi _{11}\) nor \(\pi _{12}\) is unsatisfiable, \(\mathtt {S2SAT_{SL}}\) selects \(\mathtt {test}\) of \(\varDelta _{11}\) for unfolding to construct \(\mathcal{T}_{2}\). For efficiency, unfolding is performed in a contextsensitive manner. A branch is infeasible (and pruned in advance) if its invariant is inconsistent with the (overapproximated) context. For instance, the invariant of the \(\mathtt {then}\) branch at line 12 of \(\mathtt {test}\) is \({\small \mathtt{inv}}_{test_o}{\equiv }p{=}{{\small \mathtt{{null}}}}{\wedge }\mathtt{{res}}{=}1\). As \({\small \mathtt{inv}}_{test_o}\) (after proper renaming) is inconsistent with \(\pi _{11}\), this branch is infeasible. Similarly, both \(\mathtt {else}\) branches of \(\mathtt {test}\) are infeasible. For \(\mathcal{T}_{3}\), the remaining leaf \(\varDelta _{12}\) is selected for unfolding. As the \(\mathtt {test}\)’s unfolding number is smaller than \(\mathtt {ll}\)’s, \(\mathtt {test}\) is selected. After the \(\mathtt {then}\) branch is identified as infeasible and pruned, \(\mathcal{T}_{3}\) is left with two open leaves as shown in Fig. 2, where infeasible leaves are dottedlined. \(\varDelta _{32}\) and \(\varDelta _{33}\) are as below.
As \(\varDelta _{32}\) and \(\varDelta _{33}\) include inductive predicate instances, \(\mathtt {SAT}\) checking is not applicable. For \(\mathtt {UNSAT}\) checking, \(\mathtt {S2SAT_{SL}}\) proves that \(\varDelta _{32}\) is unsatisfiable (its unsatisfiable cores are underlined as above); and shows that \(\varDelta _{33}\) can be linked back to \(\varDelta _0\) (i.e., subsumed by \(\varDelta _0\)). The latter is shown based on some weakening and substitution principles (see Sect. 4.2). In particular: (i) Substituting \(\varDelta _{33}\) with \(\theta {=}[n_2/n{,}x_1/x{,}n/n_1{,}x/r_2]\) such that predicate instances in the substituted formula, i.e., \(\varDelta _{{33}_a}\), and \(\varDelta _0\) are identical; as such, \(\varDelta _{{33}_a}\) is computed as below.
(ii) subtracting identical inductive predicates between \(\varDelta _{{33}_a}\) and \(\varDelta _0\); (iii) weakening the remainder of \(\varDelta _{{33}_a}\) (i.e., \(x_1{\mapsto }node({n_2}{,}{x})\) is eliminated); (iv) checking validity of the implication between pure of the remainder of \(\varDelta _{{33}_a}\) with the pure part of the remainder of \(\varDelta _0\), i.e., \(n_2{\ge }0{\wedge }r_1{=}0{\wedge }n_2{\ne }0{\wedge }n{=}n_2{}1{\wedge } x_1{\ne }{{\small \mathtt{{null}}}}{\wedge } {n_2}{\ge }0 {\implies } n{\ge }0{\wedge }r_1{=}0\). The backlink between \(\varDelta _{33}\) and \(\varDelta _{0}\) establishes a cyclic proof which then proves \(\varDelta _0\) is unsatisfiable.
3 \(\mathtt {S2SAT}\) Algorithm
In this section, we present \(\mathtt {S2SAT}\), a procedure for checking satisfiability of formula with inductive predicates. We start by defining our target formulas. Let \(\mathcal {L}\) be a base theory (logic) with the following properties: (i) \(\mathcal {L}\) is closed under propositional combination and supports boolean variables; (ii) there exists a complete decision procedure for \(\mathcal {L}\). Let \({\mathcal {L}}^{ind}\) be the extension of \(\mathcal {L}\) with inductive predicate instances defined in a system with a set of predicates \(\mathcal {P}{=} \{P_1, ..., P_k \}\). Each predicate may be annotated with a sound invariant. We use \({\lambda }\) to denote a formula in \(\mathcal {L}\) and \({\lambda ^{ind}}\) to denote a formula in the extended theory. Semantically, \({\lambda ^{ind}}{\equiv }\bigvee _{i{=}0}^n {\lambda }_i, ~ n{\ge }0\).
\(\mathtt {S2SAT}\) is presented in Algorithm 1. \(\mathtt {S2SAT}\) takes a formula \({\lambda ^{ind}}\) as input, systematically enumerates disjuncts \({\lambda }_i\) and can produce two possible outcomes if it terminates: \(\mathtt {SAT}\) with a satisfiable formula \({\lambda }_i\) or \(\mathtt {UNSAT}\) with a proof. We remark that nontermination is classified as \(\mathtt {UNKNOWN}\).
\(\mathtt {S2SAT}\) maintains a set of open leaves of the unfolding tree \(\mathcal{T}_{i}\) that is derived from \({\lambda ^{ind}}\). In each iteration, \(\mathtt {S2SAT}\) selects and unfolds an open leaf so as either to include more reachable base formulas (with the hope to produce a \(\mathtt {SAT}\) answer), or to refine inductive formulas (with the hope to produce an \(\mathtt {UNSAT}\) answer). Specially, in each iteration, \(\mathtt {S2SAT}\) checks whether the formula is \(\mathtt {SAT}\) at line 3; whether it is \(\mathtt {UNSAT}\) at line 6; whether a fixpoint can be established at line 7. Function \(\mathtt {\small \mathtt{{UA\_test}}}\) searches for a satisfiable base disjunct (i.e., \(\mathtt {is\_sat}\) is set to true). Simultaneously, it marks all unsatisfiable base disjuncts closed. Next, function \(\mathtt {\small \mathtt{{OA\_test}}}\) uses predicate invariants to overapproximate open leaves of \(\mathcal{T}_{i}\), and marks those with an unsatisfiable overapproximation closed. After that, function \(\mathtt {link\_back}\) attempts to link remaining open leaves back to interior nodes so as to form a fixpoint (i.e., a (partial) preproof for induction proving). The leaves which have been linked back are also marked as closed. Whenever all leaves are closed, \(\mathtt {S2SAT}\) decides \({\lambda ^{ind}}\) as \(\mathtt {UNSAT}\) (line 8). Otherwise, the \(\mathtt {choose\_bfs}\) (line 10) chooses an open leave in breadthfirst manner for unfolding.
Procedure \(\mathtt {link\_back}\) takes the unfolding tree \(\mathcal{T}_{i}\) as input and checks whether each open leaf \({\lambda ^{ind}}^{bud} {\in } \mathcal{T}_{i}\) matches with one interior node \({\lambda ^{ind}}^{comp}\) in \(\mathcal{T}_{i}\) via a matching function \(\mathtt {f_{fix}}\). \(\mathtt {f_{fix}}\) is based on weakening and substitution principles [13]. Intuitively, \(\mathtt {f_{fix}}\) detects the case of (i) the unfolding goes forever if we keep unfolding \({\lambda ^{ind}}^{bud}\); and (ii) \({\lambda ^{ind}}^{bud}\) has no model when \({\lambda ^{ind}}^{comp}\) has no model. If \(\mathtt {f_{fix}}\) \(({\lambda ^{ind}}^{bud},\varDelta ^{comp}){=}{\small \mathtt{{true}}}\,\), \(\varDelta ^{bud}\) is marked closed.
Our procedure systematically enumerates all disjuncts derived from a given inductive formula, so it is terminating for \(\mathtt {SAT}\). However, it may not be terminating for \(\mathtt {UNSAT}\) with those undecidable augmented logic. In the next paragraph, we discuss the soundness of the algorithm.
Soundness. When \(\mathtt {S2SAT}\) terminates, there are the following three cases.

(case A) \(\mathtt {S2SAT}\) produces \(\mathtt {SAT}\) with a base satisfiable \({\lambda ^{ind}}_i\);

(case B) \(\mathtt {S2SAT}\) produces \(\mathtt {UNSAT}\) with a proof that all leaves of \(\mathcal{T}_{i}\) are unsatisfiable;

(case C) \(\mathtt {S2SAT}\) produces \(\mathtt {UNSAT}\) with a fixpoint: a proof that some leaves of \(\mathcal{T}_{i}\) are unsatisfiable and the remaining leaves are linked back.
Under the assumption that \(\mathcal {L}\) is both sound and complete, case A can be shown to be sound straightforwardly. Soundness of case B immediately follows the soundness of \(\mathtt {\small \mathtt{{OA\_test}}}\). In the following, we describe the cyclic proof instantiation of \(\mathtt {link\_back}\) for fixpoint detection and prove the soundness of case C.
We use CYCLIC to denote the cyclic proof for entailment procedure adapted from [13]. The following definitions are adapted from their analogues of CYCLIC.
Definition 1
(PreProof). A preproof derived for a formula \({\lambda ^{ind}}\) is a pair (\(\mathcal{T}_{i}\), \(\mathcal L\)) where \(\mathcal{T}_{i}\) is an unfolding tree whose root labelled by \({\lambda ^{ind}}\) and \(\mathcal L\) is a backlink function assigning every open leaf \({\lambda ^{ind}}_{l}\) of \(\mathcal{T}_{i}\) to an interior node \({\lambda ^{ind}}_{c}= \mathcal{L}({{\lambda ^{ind}}_{l}})\) such that there exists some substitution \(\theta \) i.e., \({\lambda ^{ind}}_{c}={\lambda ^{ind}}_{l}[\theta ]\). \({\lambda ^{ind}}_{l}\) is referred as a bud and \({\lambda ^{ind}}_{c}\) is referred as its companion.
A path in a preproof is a sequence of nodes \(({\lambda ^{ind}}_{i})_{i{\ge }0}\).
Definition 2
(Trace).
Let \(({{\lambda ^{ind}}}_{i})_{i{\ge }0}\) be a path in a preproof \(\mathcal PP\). A trace following \(({\lambda ^{ind}}_{i})_{i{\ge }0}\) is a sequence \((\alpha _i)_{i{\ge }0}\) such that, for all \(i{\ge }0\), \(\alpha _i\) is a predicate instance \({\small \mathtt{P}}(\bar{t})\) in the formula \({\lambda ^{ind}}_{i}\), and either:

1.
\(\alpha _{i{+}1}\) is the subformula according to \({\small \mathtt{P}}(\bar{t})\) occurrence in \({\lambda ^{ind}}_{i{+}1}\), or

2.
\({\lambda ^{ind}}_{i}\)[\(\bar{t}\)/\(\bar{v}\)] where \({\lambda ^{ind}}_{i}\) is branches of inductive predicate \({\small \mathtt{P}}(\bar{v})\). i is a progressing point of the trace.
To ensure that preproofs correspond to sound proofs, a global soundness condition must be imposed on such preproofs as follows.
Definition 3
(Cyclic Proof). A preproof is a cyclic proof if, for every infinite path \(({\lambda ^{ind}}_{i})_{i{\ge }0}\), there is a tail of the path \(p{=}({\lambda ^{ind}}_{i})_{i{\ge }n}\) such that there is an infinitely progressing trace following p.
Theorem 1
(Soundness). If there is a cyclic proof of \({\lambda ^{ind}}_{0}\), \({\lambda ^{ind}}_{0}\) is \(\mathtt {UNSAT}\).
Proof
We reduce our cyclic proof problem for satisfiability to the cyclic proof problem for entailment check, i.e., \({\lambda ^{ind}}_{0} ~{{\vdash }}~{\small \mathtt{{false}}}\,\) of CYCLIC. Assume there is a cyclic proof \(\mathcal PP\) of \({\lambda ^{ind}}_{0}\). From \(\mathcal PP\) we construct the preproof \(\mathcal PP_{{\vdash }}\) for the sequent \({\lambda ^{ind}}_{0} ~{{\vdash }}~ {\small \mathtt{{false}}}\,\) as follows. For each node \(({\lambda ^{ind}}_{i})_{i{\ge }0}\) in \(\mathcal PP\), we replace the formula \({\lambda ^{ind}}_{i}\) by the sequent \({\lambda ^{ind}}_{i}~{{\vdash }}~{\small \mathtt{{false}}}\,\). Since \(\mathcal PP\) is a cyclic proof, it follows that for every infinite path \(({\lambda ^{ind}}_{i})_{i{\ge }0}\), there is a tail of the path, \(p{=}({\lambda ^{ind}}_{i})_{i{\ge }n}\), such that there is an infinitely progressing trace following p (Definition 3). Since formulas in [13] are only traced through the LHS of the sequent and not its RHS, it is implied that for every infinite path \(({\lambda ^{ind}}_{i} {{\vdash }}{\small \mathtt{{false}}}\,)_{i{\ge }0}\), there is a tail of the path, \(p{=}({\lambda ^{ind}}_{i}~{{\vdash }}~{\small \mathtt{{false}}}\,)_{i{\ge }n}\), such that there is an infinitely progressing trace following p. Thus, \(\mathcal PP_{{\vdash }}\) is a cyclic proof (Definition 3 of [13]). As such \({\lambda ^{ind}}_{0} ~{\models } {\small \mathtt{{false}}}\,\) (Theorem 6 of [13]). In other words, \({\lambda ^{ind}}_{0}\) is \(\mathtt {UNSAT}\). \(\square \)
To sum up, to implement a sound cyclic proof system besides the matching function, a global soundness condition must be established on preproofs to guarantee wellfoundedness of all reasoning.
4 Separation Logic Instantiation of \(\mathtt {S2SAT}\)
In this section, to explicitly handle heapmanipulating programs, we propose a separation logic instantiation of \(\mathtt {S2SAT}\), called \(\mathtt {S2SAT_{SL}}\). We start by presenting \({\small \mathtt{SLPA}}\), a fragment of separation logic with inductive predicates and arithmetic.
4.1 A Fragment of Separation Logic
Syntax. The syntax of \({\small \mathtt{SLPA}}\) formulas is presented in Fig. 3. We use \(\bar{x}\) to denote a sequence (e.g., \(\bar{v}\) for sequence of variables), and \({x_i}\) to denote the \(i^{th}\) element. Whenever possible, we discard \(f_i\) of the pointsto predicate and use its short form as \({x}{{\mapsto }}c(v_i)\). Note that \(v_1 {\ne } v_2\) and \(v {\ne } {{\small \mathtt{{null}}}}\) are short forms for \(\lnot (v_1{=}v_2)\) and \(\lnot (v{=}{{\small \mathtt{{null}}}})\), respectively. All free variables are implicitly universally quantified at the outermost level. To express different scenarios for shape predicates, the fragment supports disjunction \(\varPhi \) over formulas. Each predicate instance is of the form \({\small \mathtt{P}}(\bar{v})_u^o\) where \(o\) and \(u\) are labels used for context and flow sensitive unfolding. In particular, \(o\) captures the sequence number and \(u\) is the number of unfolding. For simplicity, we occasionally omit these two numbers if there is no ambiguity. A formula \(\varDelta \) is a base formula if it does not have any userdefined predicate instances. Otherwise, \(\varDelta \) is an inductive formula.
UserDefined Predicate. A userdefined predicate \(\mathtt P\) is of the following general form
where \(\mathtt P\) is predicate name; \(\bar{t}\) is a set of formal parameters; and \(\exists \bar{w_i}\cdot ~\varDelta _i\) (i \(\in \) 1...n) is a branch. Each branch is optionally annotated with a sound invariant \(\pi _i^b\) which is a pure formula that overapproximates the branch. \(\pi \) is an optionally sound predicate invariant. It must be a superset of all possible models of the predicate \(\mathtt P\) via a pure constraint on stack. The default invariant of each inductive predicate is \(\mathtt {true}\) . For efficiency, we infer more precise invariants automatically (see Sect. 6). Inductive branches may be recursive. We assume that the recursion is direct, i.e., a recursive branch of predicate \(\mathtt P\) includes at least one predicate instance \(\mathtt P\). In each branch, we require that variables which are not formal parameters must be existentially quantified i.e., \(\forall i\in 1...n {\cdot }\textit{FV}({\varDelta _i}){=} \bar{t}\) and \(\bar{w_i} {\cap } \bar{t}{=}\emptyset \) where \(\textit{FV}({\varDelta })\) are all free variables in the formula \(\varDelta \).
In the following, we apply \({\small \mathtt{SLPA}}\) to model two data structures: sorted lists (\(\mathtt {sortll}\)) without an annotated invariant and AVL trees (\(\mathtt {avl}\)) with annotatedinvariant.
Semantics. In the following, we discuss the semantics of \({\small \mathtt{SLPA}}\). Concrete heap models assume a fixed finite collection Node, a fixed finite collection Fields, a disjoint set Loc of locations (heap addresses), a set of nonaddress values Val, such that \({{\small \mathtt{{null}}}}~{\in }~ {\textit{Val}}\) and Val \(\cap \) Loc = \(\emptyset \). Further, we define:
The semantics is given by a forcing relation: \(s{,}h~{\models }~ \varPhi \) that forces the stack \(s\) and heap \(h\) to satisfy the constraint \(\varPhi \) where \(h\in {\textit{Heaps}} \), \(s\in {\textit{Stacks}}\), and \(\varPhi \) is a formula.
The semantics is presented in Fig. 4. \(dom(f)\) is the domain of function \(f\); \(h_1 {\#} h_2\) denotes that heaps \(h_1\) and \(h_2\) are disjoint, i.e., \(\text {dom}(h_1) ~{\cap }~ \text {dom}(h_2) ~{=}~ \emptyset \); and \(h_1 {\cdot } h_2\) denotes the union of two disjoint heaps. Inductive predicates are interpreted using the least model semantics [42]. Semantics of pure formulas depend on stack valuations; it is straightforward and omitted in Fig. 4, for simplicity.
4.2 Implementation of Separation Logic Instantiation
In the following, we describe how \(\mathtt {S2SAT_{SL}}\) is realized. In particular, we show how the functions \(\mathtt {\small \mathtt{{UA\_test}}}\), \(\mathtt {\small \mathtt{{OA\_test}}}\), \(\mathtt {unfold}\), and \(\mathtt {link\_back}\) are implemented.
Deciding Separation Logic Formula. Given an \({\small \mathtt{SLPA}}\) formula, the functions \(\mathtt {\small \mathtt{{UA\_test}}}\) and \(\mathtt {\small \mathtt{{OA\_test}}}\) in \(\mathtt {S2SAT_{SL}}\) work similarly, by reducing the formula to a firstorder formula systematically and deciding the firstorder formula. In the following, we define a function called , which transforms a separation logic formula into a firstorder formula. is defined over the symbolic heap as follows:
where the reduction at the first line (after \(\equiv \)) is for pointsto predicates, and the second line is for userdefined predicates. The auxiliary function \(\mathtt { inv}({\mathcal {P}},P,\bar{v})\) returns the invariant of the predicate \(\mathtt P\) with a proper renaming.
Next, the auxiliary procedure \(\mathtt {sat_p}\)(\(\exists \bar{w} {\cdot }~ \pi \)) takes a quantified firstorder formula as input. It preprocesses the formula and then invokes an SMT solver to solve it. The preprocessing consists of two steps. First, the existential quantifiers \(\bar{w}\) are eliminated through a projection \({\varPi }(\pi ,\bar{w})\). Second, remaining existential quantifiers are skolemized and \({{\small \mathtt{{null}}}}\) is substituted by special number (i.e., zero). The preprocessed formulas are of the form of linear arithmetic with free function symbols. These formulas may contain existential (\(\exists \)) and universal (\(\forall \)) quantifiers but no \(\exists \forall \) alternation. Hence, they are naively supported by SMT solvers.
Deriving Unfolding Tree. Next, we describe how function \(\mathtt {unfold}\) works in \(\mathtt {S2SAT_{SL}}\). Given a formula, \(\mathtt {unfold}\) selects one predicate instance for unfolding as follows.
Predicate instances in \(\kappa \) are sorted by a pair of unfolding number and ordering number where the former has higher priority. The instance \({\small \mathtt{P}}(\bar{v})_u^o\) is selected if \(\mathtt u\) is the smallest number of unfoldings and \(\mathtt o\) is the smallest number among instances which have the same unfolding number \(\mathtt u\). The procedure \(\mathtt{unfold}\) outputs a set of disjuncts which are combined from branches of the predicate \(\mathtt P\) with the remainder \(\kappa {\wedge }\pi \). At the middle, the predicate instance is unfolded by the procedure \(\mathtt {unfoldP}\). This auxiliary procedure \(\mathtt{unfoldP}({\small \mathtt{P}}(\bar{t})^o_u,\pi _{c})\) unfolds the userdefined predicate \(\mathtt P\) with actual parameter \(\bar{t}\) under the context \(\pi _{c}\). It outputs branches of the predicate \(\mathtt P\) that are not inconsistent with the context. It is formalized as follows.
In the first line, the procedure looks up the definition of \(\mathtt P\) and refreshes the existential quantifiers (using the function \(\textit{fresh}(...)\)). In the second line, formal parameters are substituted by the corresponding actual arguments. Finally, the substituted definition is combined and pruned as shown in the RHS of \(\leadsto \). Function \({\small \mathtt{freshEQ}}(\bar{v})\) above refreshes the sequence of variables \(\bar{v}\) and produces the equality constraints \(\pi _{eq}\) between the old and new ones, i.e. \(\pi _{eq}{\equiv }\bigwedge v_i{=}v'_i\). Let \({\small \mathtt{Q}}(\bar{t})^{o_l}_{\_}\) denote a predicate instance of the derived \(\kappa _i\), its unfolding number is set to \(\mathtt u{+}1\) if its corresponding branch \(\varDelta _i\) is recursive. Otherwise, it is \(\mathtt u\). Its sequence number is set to \(o_l{+}o\).
The branch invariant is used as a necessary condition to unfold a branch. The formalism underlying the pruning process is as follows: given a context \(\varDelta _c\) with its overapproximation \(\pi _c\) and a branch \(\varDelta _i\) with its overapproximation \(\pi ^b_i\), if \(\pi _c {\wedge } \pi ^b_i\) is unsatisfiable, so is \(\varDelta _c {*} \varDelta _i\). Similar to the specialization calculus [15], our unfolding mechanism also prunes infeasible disjuncts while unfolding userdefined predicates. However, the specialization calculus performs exhaustive pruning with multiple unfolding that may be highly costly and redundant compared with our onestep unfolding.
Detecting Cyclic Proof. In the following, we implement the matching function \(\mathtt {f_{cyclic}}\), an instantiation of \(\mathtt {f_{fix}}\), to form a cyclic proof for fixpoint detection. \(\mathtt {f_{cyclic}}\) checks whether there exists a wellfounded ordering relation \(R\) between \(\varDelta ^{comp}\) and \(\varDelta ^{bud}\) so as to form an infinite path following the path between these two nodes. If \(\varDelta ^{bud}\) matches with \(\varDelta ^{comp}\), \(\varDelta ^{bud}\) is marked as closed. For global infinitary soundness, \(\mathtt {f_{cyclic}}\) only considers those \(\varDelta ^{bud}\) and \(\varDelta ^{comp}\) of the restricted form as: \(\varDelta ^{comp}{\equiv }\varDelta _{b_1} {*} {\small \mathtt{P_1}}(\bar{t}_1)_m^0{*} ...{*}{\small \mathtt{P_i}}(\bar{t_i})_m^i\), and \(\varDelta ^{bud}{\equiv }\varDelta _{b_2} {*} {\small \mathtt{P_1}}(\bar{t}_1')_n^0{*} ...{*}{\small \mathtt{P_k}}(\bar{t_k'})_n^k\), where \(\mathtt k{\ge }i\), \(\mathtt n{>}m\), \(\varDelta _{b_1}\) and \(\varDelta _{b_2}\) are base formulas.
Like [13], \(\mathtt {f_{cyclic}}\) is implemented using the weakening and substitution principle. In particular, it looks for a substitution \(\theta \) s.t. \(\varDelta ^{bud}\theta ~{\implies }~ \varDelta ^{comp}\). \( {{\small \mathtt{{f_{cyclic}}}}}(\varDelta ^{bud}{,}\varDelta ^{comp})\) is formalized as the procedure \(\varDelta ^{bud}{~\vdash _{lb}~}\varDelta ^{comp}\) whose rules are presented in Fig. 5. These rules are applied as follows.

First, existential variables are refreshed (\([\underline{\mathbf{\scriptstyle EXL}}]\), \([\underline{\mathbf{\scriptstyle EXR}}]\) rules).

Second, inductive variables in \(\varDelta ^{bud}\) are substituted (\([\underline{\mathbf{\scriptstyle SUBST}}]\) rule). This substitution is based on wellordering relations \(R\). Let \({\small \mathtt{P}}({t})_m^k\) be a predicate instance in \(\varDelta ^{comp}\) and its corresponding subformula in \(\varDelta ^{bud}\) be \(R(s{,}{t})\), then \(s\), \(t\) are inductive variables. Two examples of wellfounded relations \(R\) are structural induction for pointer types where \(R(s{,}t)\) iff s is a subterm of t and natural number induction on integers where \(R(s{,}t)\) iff \(0{<}s{<}t\).

Third, heaps are exhaustively matched (\([\underline{\mathbf{\scriptstyle PREDMATCH}}]\) and \([\underline{\mathbf{\scriptstyle PTOMATCH}}]\) rules) and weakened (\([\underline{\mathbf{\scriptstyle PREDWEAKEN}}]\) and \([\underline{\mathbf{\scriptstyle PTOWEAKEN}}]\) rules). Soundness of these rules directly follows from the frame rule [26, 40].

Last, backlink is decided via the implication between pure formulas (\([\underline{\mathbf{\scriptstyle PURE}}]\) rule).
5 Soundness and Termination of \(\mathtt {S2SAT_{SL}}\)
In the following, we establish the correctness of \(\mathtt {S2SAT_{SL}}\).
5.1 Soundness
We show that (i) \(\mathtt {S2SAT_{SL}}\) is sound and complete for base formulas; and (ii) the functions \(\mathtt {\small \mathtt{{UA\_test}}}\), \(\mathtt {\small \mathtt{{OA\_test}}}\) and \(\mathtt {link\_back}\) in \(\mathtt {S2SAT_{SL}}\) are sound. These two tasks rely on soundness and completeness of the function \(\mathbf{{\scriptstyle eXPure}}\) over base formulas, soundness of \(\mathbf{{\scriptstyle eXPure}}\) over inductive formulas, and soundness of the function \(\mathtt {f_{cyclic}}\).
Lemma 1
(EquivSatisfiable Reduction). Let \(\varDelta {\equiv }\exists \bar{w}{\cdot }{x_1}{{\mapsto }}c_1(\bar{v}_1){*} ...{*} {x_n}{{\mapsto }}c_n(\bar{v}_n){\wedge }\alpha {\wedge } \phi \) be a base formula. \(\varDelta \) is satisfiable iff \({\mathbf{{\scriptstyle eXPure}}}({\varDelta })\) is satisfiable.
The proof is based on structural induction on \(\varDelta \).
Lemma 2
(OverApproximated Reduction). Given a formula \(\varDelta \) such that the invariants of userdefined predicates appearing in \(\varDelta \) are sound, then
In the following lemma, we consider the case \(\varGamma {=}\{ \}\) at line 8 of Algorithm 1.
Lemma 3
Given a formula \(\varDelta _0\) and the matching function \(\mathtt {f_{cyclic}}\) as presented in the previous section, \(\varDelta _0\) is \(\mathtt {UNSAT}\) if \(\varGamma {=}\{ \}\) (line 8).
To prove this Lemma, in [30] we show that there is a “trace manifold” which implies the global infinitary soundness (see [11], ch. 7) when a bud is linked back.
Theorem 2
(Soundness). Given a formula \(\varDelta \) and a set of userdefined predicates \(\mathcal {P}\),

\(\varDelta \) is satisfiable if \(\mathtt {S2SAT_{SL}}\) returns \(\mathtt {SAT}\).

if \(\mathtt {S2SAT_{SL}}\) terminates and returns \(\mathtt {UNSAT}\), \(\varDelta \) is unsatisfiable.
While the soundness of \(\mathtt {SAT}\) queries follows Lemma 1, the soundness of \(\mathtt {UNSAT}\) queries follows Lemmas 2 and 3. As satisfiability for \({\small \mathtt{SLPA}}\) is undecidable [30, 31], there is no guarantee that \(\mathtt {S2SAT_{SL}}\) terminates on all inputs. In the next subsection, we show that \(\mathtt {S2SAT_{SL}}\) terminates for satisfiable formulas in \({\small \mathtt{SLPA}}\) and with certain restrictions on the fragment, \(\mathtt {S2SAT_{SL}}\) always terminates.
5.2 Termination
Termination for SAT. In this paragraph, we show that \(\mathtt {S2SAT_{SL}}\) always terminates when it decides a satisfiable formula. Given a satisfiable formula
There exists a satisfiable base formula \(\varDelta _k\) such as:
where \(\varDelta ^P_k\) (\(k{\ge }0\)) denotes a base formula derived by unfolding the predicate \(\mathtt P\) \(k\) times and then substituting all predicate instances \(\mathtt P\) by \(\mathtt P\)’s base branch. Let \(k_m\) be the maximal number among \(k_0\),..,\(k_n\). The breadthfirst unfolding manner in the algorithm \(\mathtt {S2SAT}\) ensures that \(\mathtt {S2SAT_{SL}}\) identifies \(\varDelta _k\) before it encounters the following leaf:
We remark that the soundness of cyclic proof ensures that our \(\mathtt {link\_back}\) function only considers infinitely many unfolding traces. Thus, it never links finite many unfolding traces, i.e., traces connecting the root to satisfiable base leaves, like \(\varDelta _k\).
Decidable Fragment. In the following, we describe universal \({\small \mathtt{SLPA_{ind}}}\), a fragment of \({\small \mathtt{SLPA}}\), for which we prove that \(\mathtt {S2SAT_{SL}}\) always terminates. Compared to \({\small \mathtt{SLPA}}\), universal \({\small \mathtt{SLPA_{ind}}}\) restricts the set of inductive predicates \(\mathcal {P}\) as well as the inputs of \(\mathtt {S2SAT_{SL}}\).
Definition 4
( \({\small \mathtt{SLPA_{ind}}}\) ). An inductive predicate \(\mathtt{pred}~{\small \mathtt{P}}(\bar{t}){\equiv }\varPhi \) is wellfounded \({\small \mathtt{SLPA_{ind}}}\) if it has one induction case with \(N\) occurrences of \(\mathtt P\), and it has the shape as follows.
where \(\varPhi _0\) is disjunction of base formulas and the two following restrictions.

1.
\(\forall n{\in } 1...N ~ \bar{w}_n {\subseteq } \bar{w} {\cup } \{{{\small \mathtt{{null}}}}\}\) and \(\bar{w}_n\) do not appear in the equalities of \(\pi \),

2.
if \(t_i\) is a numerical parameter and there exists a wellordering relation \(R\) such that \(R(s{,}{t_i}{,}w_{1_i}{,}..{,}w_{m_i})\) (\(1{\le }m{\le }N\)) is a subformula of \(\pi \), the following conditions hold.

\(t_i\) is constrained separately (i.e., there does not exist \(j{\ne }i\) and a subformula \(\phi \) of \(\pi \) such that \(\{t_i,t_j\} {\subseteq } FV(\phi )\) or \(\{t_i,{w}_{n_j}\} {\subseteq } FV(\phi )\) or \(\{w_{m_i},{w}_{n_j}\} {\subseteq } FV(\phi )\) \(\forall m{,}n{\in } 1...N\), and

\(\forall n{\in } 1...N\), \(\pi \implies t_i{>}{w}_{n_i}\) or \(\pi \implies t_i{<}{w}_{n_i}\).

if \(t_i {\in } FV(\varPhi _0)\) then \(\varPhi _0 \implies t_i{=}k\), for some integer \(k\)
\(t_i\) is denoted as inductive parameters.

Restriction 1 guarantees that \(\mathtt {f_{cyclic}}\) can soundly weaken the heap by discarding irrelevant pointsto predicates and \(N{}1\) occurrences of \(\mathtt P\) (when \(N{\ge }2\)) while it links back. Restriction 2 implies that \(t_i{>}w_i{\ge }k_1\) or \(t_i{<}w_i{\le }k_2\) for some integer \(k_1\), \(k_2\). This ensures that leaf nodes of unfolding trees of an unsatisfiable input must be \(\mathtt {UNSAT}\) or linked back.
The above \({\small \mathtt{SLPA_{ind}}}\) fragment is expressive enough to describe a range of data structures, e.g. sorted lists \(\mathtt {sortll}\), lists/trees with size properties, or even AVL trees \(\mathtt {avl}\).
Definition 5
(Universal \({\small \mathtt{SLPA_{ind}}}\) ). Given a separation logic formula
\(\varDelta _0\) is universal \({\small \mathtt{SLPA_{ind}}}\) if all predicates \({\small \mathtt{P_1}}\),..,\({\small \mathtt{P_n}}\) are wellfounded \({\small \mathtt{SLPA_{ind}}}\), and if all \(\bar{x}\) of free, arithmetical, inductive variables, with \(\bar{x} {\subseteq } (\bar{t}_1 {\cup } ... {\cup }\bar{t}_n)\), \(\phi _0\) is a conjunction of \(\phi _{0,i}\) where \(\phi _{0,i}\) is either of the following form: (i) \({\small \mathtt{{true}}}\,\); or (ii) \(x_i{\ge }k_1\) for some integer \(k_1\); or (iii) \(x_i{\le }k_2\) for some integer \(k_2\).
Theorem 3
(Termination). \(\mathtt {S2SAT_{SL}}\) terminates for universal \({\small \mathtt{SLPA_{ind}}}\) formulas.
6 Sound Invariant Inference
In order to perform fully automatic verification without userprovided invariants, \(\mathtt {S2SAT_{SL}}\) supports automatic invariant inference. In this section, we describe invariant inference from userdefined predicates and predicate branches. While the former is used for overapproximation, the latter is used for contextsensitive predicate unfolding. To infer invariants for a set of userdefined predicates, we first build a dependency graph among the predicates. After that, we process each group of mutual dependent predicates following a bottomup manner. For simplicity, we present the inference for one directly recursive predicate. The inference for a group of mutual inductive predicates is similar.
Inferring Predicate Invariant. Our invariant inference is based on the principle of secondorder abduction [28, 45]. Given the predicate \(\mathtt P\) defined by m branches as \({\small \mathtt{P}}(\bar{t}) \equiv \bigvee ^m_{i=1} \varDelta _i\), we assume a sound invariant of \(\mathtt P\) as an unknown (secondorder) variable \({\small \mathtt{I}}({\bar{t}})\). After that we prove the lemma \({\small \mathtt{P}}(\bar{v}) {{\vdash }} {\small \mathtt{I}}({\bar{v}})\) via induction; and simultaneously generate a set of pure relational assumptions using secondorder abduction. The steps to prove the above lemma and generate a set of \(m\) relational assumptions over \(\mathtt I\) are as follows.

1.
Unfold LHS of the lemma to generate a set of \(m\) subgoals i.e. \(\varDelta _i[\bar{v}/\bar{t}] {{\vdash }} {\small \mathtt{I}}({\bar{v}})\) where \(i \in 1...m\). The original lemma is taken as the induction hypothesis.

2.
For each subgoal \(i\), overapproximate its LHS to a pure formula \(\pi _i\) and form an assumption relation \(\pi _i ~{\implies }~ {\small \mathtt{I}}({\bar{v}})\). There are two cases to compute \(\pi _i\).

if \(\varDelta _i\) is a base formula, then \(\pi _i{\equiv }\mathbf{{\scriptstyle eXPure}}({ \varDelta _{i}})\).

if \(\varDelta _i\) includes k instances \(\mathtt P\) such that \(\varDelta _i{\equiv }\varDelta _{rest_i}{*} {\small \mathtt{P}}({\bar{v_1}}){*}...{*} {\small \mathtt{P}}({\bar{v_k}})\), then we compute \(\pi _{i_0}{\equiv } \mathbf{{\scriptstyle eXPure}}({ \varDelta _{rest_i}})\), \(\pi _{i_j}{\equiv }{\small \mathtt{I}}({\bar{v_j}})\), for all \(j \in 1...k\), and \(\pi _i{\equiv } \bigwedge _{j{=}1}^k\pi _{i_k}\).


3.
Our system applies a least fixed point analysis to the set of gathered relational assumptions. We use the analyzer \(\mathtt LFP\) presented in [45] to compute these invariants.
We illustrate this procedure to infer an invariant for \(\mathtt {sortll}\). First, our system introduces an unknown relation \({\small \mathtt{I}}(\mathtt{root}{,}n{,}m)\). Second, it generates the below relational constraints.
Finally, it analyzes these two constraints and produces the following result:
Lemma 4
(Sound Invariant Inference). Given a predicate \({\small \mathtt{P}}(\bar{t}) ~{\equiv }~ \varPhi \), and \(\mathcal {R}\) be a set of relational assumptions generated by the steps above. If \(\mathcal {R}\) has a solution, i.e., \({\small \mathtt{I}}(\bar{v}){\equiv }\pi \), then we have \( \forall s, h\cdot s, h~{\models }~ {\small \mathtt{P}}(\bar{v})\), \(s~{\models } \pi \).
Proof Sketch: Soundness of Lemma 2 implies that for all \(i \in 1...m\), \(\pi _i\) is an overapproximated abstraction of \(\varDelta _i\). As such, the soundness of this lemma immediately follows from the soundness of secondorder abduction [28, 45]. \(\square \)
Inferring Branch Invariant. Given a predicate \(\mathtt P\) defined by m branches as \({\small \mathtt{P}}(\bar{t}) \equiv \bigvee ^m_{i=1} ({\exists } \bar{w_i}{\cdot }~ \varDelta _i) ~~{ \overline{inv}}{:}~ \pi \), we compute invariants for each branch of \(\mathtt P\) as \({\varPi }(\mathbf{{\scriptstyle eXPure}}(\varDelta _i),\bar{w_i})\) \({\forall }~i{=}1...m\). For example, with the invariant inferred for the predicate \(sortll\) as above, our system computes its branch invariants \(\pi ^b_1\) for the base branch and \(\pi ^b_2\) for the inductive branch as below.
Soundness of implies that the branch invariant overapproximates its branch.
7 Implementation and Evaluation
We have implemented the proposed solver \(\mathtt {S2SAT_{SL}}\) and a new interprocedural (topdown) program verification tool, called \(\mathtt {S2_{td}}\), which uses \(\mathtt {S2SAT_{SL}}\). We make use of Omega Calculator [38] to eliminate existential quantifiers, Z3 [19] as a backend SMT solver, and \(\mathtt {FixCalc}\) [37] to find closure form in inferring invariants for userdefined predicates.
In the following, we evaluate \(\mathtt {S2SAT_{SL}}\) and \(\mathtt {S2_{td}}\)’s robustness and efficiency on a set of benchmarks from the software verification competition SVCOMP [7]. We also present an evaluation of \(\mathtt {S2SAT_{SL}}\) in compositional (modular) program verification with the \(\mathtt {HIP/S2}\) system [14, 28] for a range of data structures.
7.1 Robustness and Efficiency
In [12], Brotherston et al. introduced a new and challenging set of satisfiability benchmarks discussed in Proposition 5.13 of [12]. In this Proposition, Brotherston et al. stated that there exists a family of predicates of size \(O\)(n) and that \(\mathtt {SLSAT}\) runs in \(\varOmega (2^n)\) time and space regardless of search strategies. Since \(\mathtt {SLSAT}\) relies on bottomup and contextinsensitive fixed point computation, it has to explore all possible models before answering a query. Their approach is designed for computing invariants of shape predicates rather than satisfiability checks. In contrast, \(\mathtt {S2SAT_{SL}}\) performs topdown and contextsensitive searches, as it is dedicated for satisfiability solving. Moreover, it prunes infeasible disjuncts, significantly reduces the search space, and provides better support for model discovery.
We conducted an experiment on comparing \(\mathtt {SLSAT}\)’s and \(\mathtt {S2SAT_{SL}}\)’s performance on this set of benchmarks. The results are shown in Table 1. The size \(\mathtt n\) of \(\mathtt {succ{}circuit*}\) (\(\mathtt {succ{}rec*}\)) benchmarks expresses the breadth (depth, resp.) of dependency. This set of benchmarks is a part of the UserDefined Predicate Satisfiability (UDB_sat) suite of SLCOMP 2014 [41]. The output is either a definite answer (sat, unsat) with running time (in milliseconds (ms), or seconds (s)), or an error. In particular, SO denotes stack overflow; TO denotes timeout (i.e., tools run longer than 1800 s); and X denotes a fatal error. The experimental results show that \(\mathtt {S2SAT_{SL}}\) is much more robust and also more efficient than \(\mathtt {SLSAT}\). While \(\mathtt {S2SAT_{SL}}\) successfully solved 24 (out of 40) benchmarks, \(\mathtt {SLSAT}\) was capable of handling 17 benchmarks. Furthermore, on 17 benchmarks that \(\mathtt {SLSAT}\) discharged successfully, \(\mathtt {S2SAT_{SL}}\) outperforms \(\mathtt {SLSAT}\), i.e., about 6.75 (3126 s/462 s) times faster. As shown in the table, \(\mathtt {S2SAT_{SL}}\) ran with neither stack overflow nor fatal errors over all these challenging benchmarks.
7.2 Modular Verification with \(\mathtt {S2SAT_{SL}}\)
In this subsection, we evaluate \(\mathtt {S2SAT_{SL}}\) in the context of modular program verification. \(\mathtt {S2SAT_{SL}}\) solver is integrated into the \(\mathtt {HIP/S2}\) [14, 28, 29] system to prune infeasible program paths in symbolic execution. Furthermore, \(\mathtt {S2SAT_{SL}}\) is also used by the entailment procedure \(\mathtt {SLEEK}\) to discharge verification conditions (VC) generated. In particular, when \(\mathtt {SLEEK}\) deduces a VC to the following form: \(\varDelta ~ {{\vdash }}~ \mathtt{emp}{\wedge }\pi _r\), the error calculus in \(\mathtt {SLEEK}\) [29] invokes \(\mathtt {S2SAT_{SL}}\) to discharge the following queries: \(\varDelta \) and \(\varDelta {\wedge }\lnot \pi _r\) for safety and \(\varDelta {\wedge }\pi _r\) for must errors. In experiments, we have extracted those VCs generated while \(\mathtt {HIP/S2}\) verified heapmanipulating programs.
We have evaluated \(\mathtt {S2SAT_{SL}}\) deciding the VCs discussed above. The experimental results are described in Table 2. Each line shows a test on one program. The first column lists data structures and their pure properties. are trees with nodes that are allowed to have a variable number of children, stored as doublylinked lists. TLL is a binary tree whose nodes point to their parents and all leaf nodes are linked as a singlylinked list. #Query is the number of satisfiability queries sent to \(\mathtt {S2SAT_{SL}}\) for each data structure. The next two columns report the outputs from \(\mathtt {S2SAT_{SL}}\). The last column shows the time (in seconds) taken by the \(\mathtt {{{\small \mathtt{{S2SAT_{SL}}}}}}\) solver. In this experiment, \(\mathtt {S2SAT_{SL}}\) terminated on all queries. Furthermore it exactly decided all \(\mathtt {SAT}\) and \(\mathtt {UNSAT}\) queries. These experimental results affirm the correctness of our algorithm \(\mathtt {S2SAT_{SL}}\). They also show that \(\mathtt {S2SAT_{SL}}\) is expressive, effective, and can be integrated into program verification systems for discharging satisfiability problems of separation logic formulas.
7.3 Recursive Program Verification with \(\mathtt {S2SAT_{SL}}\)
We have evaluated and compared our verification system \(\mathtt {S2_{td}}\) with stateoftheart verification tools on a set of SVCOMP benchmarks^{Footnote 1}. The results are presented in Table 3. There are 102 recursive/loop programs taken from Recursive and HeapReach subcategories in the benchmark; timeout is set to 180 s. In each program, there is at least one usersupplied assertion to model safety properties. The first column identities the subset of verification systems which competed in both the above subcategories. The next three columns count the instances of correct safe (s\(\surd \)), correct error (e\(\surd \)) and unknown (e.g., timeout). The next two columns capture the number of false positives (s✗) and false negatives (e✗). We rank these tools based on their points. Following the SVCOMP competition, we gave +2 for one s\(\surd \), +1 for one e\(\surd \), 0 for unk, \(16\) for one s✗, and \(32\) for one e✗. The last column expresses the total time in minutes. The results show that the proposed verification approach is promising; indeed, our system is effective and efficient: it produces the best correctness with zero false answers within the nearlyshortest time.
8 Related Work
Close to our work is the SeaHorn verification system [22]. While SeaHorn relies on Z3PDR to handle inductive predicates on nonheap domains, it is unclear (to us) how SeaHorn supports induction reasoning for heapbased programs (which is one contribution of our present work).
Our \(\mathtt {S2SAT}\) satisfiability procedure is based on unfolding which is similar to the algorithm in the Leon system [43, 44]. Leon, a verifier for functional programs, adds an unfolding mechanism for inductive predicates into complete theories. However, Leon only supports classic logic and not structural logic (i.e., separation logic). Neither does Leon support inductive reasoning. Furthermore, our system infers sound invariants for inductive predicates to facilitate overapproximation.
Our work is related to work on developing satisfiability solvers in separation logic. In the following, we summarize the development in this area. Smallfoot [5] has the first implemented decision procedure for a fragment of separation logic. This solver was originally customized to work with spatial formulas over list segments. Based on a fixed equality (disequality) constraint branches of the list segment, the proposals presented by [17, 32] further enhanced decision procedure for this fragment with equality reasoning. They provided normalization rules with a graph technique [17] and a superposition calculus [32] to infer (dis)equality constraints on pointers and used these constraints to prune infeasible branches of predicate instances during unfolding. Although these proposals can decide the formula of that fragment in polynomial time, it is not easy to extend them to a fragment with general inductive predicates (i.e., the fragment \({\small \mathtt{SLPA}}\)). Decision procedures in [33–36] support decidable fragments of separation logic with interreachable data structures using SMT. Our proposal extends these procedures to those fragments with general inductivelydefined predicates. Indeed, our decidable fragment can include more complex data structures, such as AVL trees.
\(\mathtt {S2SAT_{SL}}\) is closely related to the satisfiability solvers [12, 25] which are capable of handling separation logic formulas with general userdefined predicates. Decision procedures [12, 25] are able to handle predicates without pure properties. The former described a decidable fragment of userdefined predicates with bounded tree width. The problem of deciding separation logic formulas is then reduced to monadic secondorder logic over graphs. The latter, \(\mathtt {SLSAT}\), decides formulas with userdefined predicates via a equisatisfiable fixed point calculation. The main disadvantage of \(\mathtt {SLSAT}\) is that it is currently restricted to the domain of pointer equality and disequality, so that it cannot be used to support predicates with pure properties from infinite abstract domains.
Using overapproximation in decision procedures is not new. For example, D’Silva et al. have recently made use of abstract domains inside satisfiability solvers [20, 21]. In separation logic, satisfiability procedures in \(\mathtt {HIP/SLEEK}\) [14] and Dryad [39] decide formulas via a sound reduction that overapproximates predicate instances. \(\mathtt {HIP/SLEEK}\) and Dryad are capable of proving the validity of a wide range of expressive formulas with arbitrary predicates. However, expressivity comes with cost; as these procedures are incomplete, and they do not address the satisfiability problem. We believe that \(\mathtt {S2SAT}\) can be integrated into these systems to improve upon these two shortcomings.
9 Conclusion and Future Work
We have presented a satisfiability procedure for an expressive fragment of separation logic. Given a formula, our procedure examines both underapproximation (so as to prove \(\mathtt {SAT}\)) and overapproximation (so as to prove \(\mathtt {UNSAT}\)). Our procedure was strengthened with invariant generation and cyclic proof detection. We have also implemented a solver and a new verification system for heapmanipulating programs. We have evaluated them on a range of competition problems with either complex heap usage patterns or exponential complexity of time and space.
For future work, we might investigate \(\mathtt {S2SAT}\)based decision procedures for other complete theories (i.e., Presburger, string, bag/set) augmented with inductive predicates. We would also study a more general decidable fragment of separation logic by relaxing the restrictions for termination. Finally, we would like to improve \(\mathtt {S2_{td}}\) for array, string and pointer arithmetic reasoning as well as witness generation for erroneous programs.
Notes
References
Haran, A., Carter, M., Emmi, M., Lal, A., Qadeer, S., Rakamarić, Z.: SMACK+corral: a modular verifier. In: Baier, C., Tinelli, C. (eds.) TACAS 2015. LNCS, vol. 9035, pp. 451–454. Springer, Heidelberg (2015)
Barnett, M., Chang, B.Y.E., DeLine, R., Jacobs, B., M. Leino, K.R.: Boogie: a modular reusable verifier for objectoriented programs. In: de Boer, F.S., Bonsangue, M.M., Graf, S., de Roever, W.P. (eds.) FMCO 2005. LNCS, vol. 4111, pp. 364–387. Springer, Heidelberg (2006)
Barrett, C., Conway, C.L., Deters, M., Hadarean, L., Jovanović, D., King, T., Reynolds, A., Tinelli, C.: CVC4. In: Gopalakrishnan, G., Qadeer, S. (eds.) CAV 2011. LNCS, vol. 6806, pp. 171–177. Springer, Heidelberg (2011)
Beckman, N.E., Nori, A.V., Rajamani, S.K., Simmons, R.J.: Proofs from tests. In: ISSTA, pp. 3–14. ACM, New York (2008)
Berdine, J., Calcagno, C., W.O’Hearn, P.: A decidable fragment of separation logic. In: Lodaya, K., Mahajan, M. (eds.) FSTTCS 2004. LNCS, vol. 3328, pp. 97–109. Springer, Heidelberg (2004)
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)
Beyer, D.: Reliable and reproducible competition results with benchexec and witnesses (report on SVCOMP 2016). In: Chechik, M., Raskin, J.F. (eds.) TACAS 2016. LNCS, vol. 9636, pp. 887–904. Springer, Heidelberg (2016). doi:10.1007/9783662496749_55
Beyer, D., Cimatti, A., Griggio, A., Keremoglu, M.E., Sebastiani, R.: Software model checking via largeblock encoding. In: Proceedings of 9th International Conference on Formal Methods in ComputerAided Design, FMCAD 2009, pp. 25–32 (2009)
Bjørner, N., Gurfinkel, A., McMillan, K., Rybalchenko, A.: Horn clause solvers for program verification. In: Blass, A., Dershowitz, N., Finkbeiner, B., Schulte, W., Beklemishev, L.D., Beklemishev, L.D. (eds.) Gurevich Festschrift II 2015. LNCS, vol. 9300, pp. 24–51. Springer, Heidelberg (2015). doi:10.1007/9783319235349_2
Bjørner, N., McMillan, K.L., Rybalchenko, A.: Program verification as satisfiability modulo theories. In: SMT, pp. 3–11 (2012)
Brotherston. J.: Sequent calculus proof systems for inductive definitions. Ph.D. thesis, University of Edinburgh, November 2006
Brotherston, J., Fuhs, C., Pérez, J.A.N., Gorogiannis, N.: A decision procedure for satisfiability in separation logic with inductive predicates. In: CSLLICS 2014, pp. 25:1–25:10. ACM, New York (2014)
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)
Chin, W., David, C., Nguyen, H., Qin, S.: Automated verification of shape, size and bag properties via userdefined predicates in separation logic. SCP 77(9), 1006–1036 (2012)
Chin, W.N., Gherghina, C., Voicu, R., Le, Q.L., Craciun, F., Qin, S.: A specialization calculus for pruning disjunctive predicates to support verification. In: Gopalakrishnan, G., Qadeer, S. (eds.) CAV 2011. LNCS, vol. 6806, pp. 293–309. Springer, Heidelberg (2011)
Clarke, E., Kroning, D., Lerda, F.: A tool for checking ANSIC programs. In: Jensen, K., Podelski, A. (eds.) TACAS 2004. LNCS, vol. 2988, pp. 168–176. Springer, Heidelberg (2004)
Cook, B., Haase, C., Ouaknine, J., Parkinson, M., Worrell, J.: Tractable reasoning in a fragment of separation logic. In: Katoen, J.P., König, B. (eds.) CONCUR 2011. LNCS, vol. 6901, pp. 235–249. Springer, Heidelberg (2011)
Cordeiro, L., Fischer, B.: Verifying multithreaded software using smtbased contextbounded model checking. In: Proceedings of the 33rd International Conference on Software Engineering, ICSE 2011, pp. 331–340. ACM, New York (2011)
de Moura, L., Bjørner, N.S.: Z3: an efficient SMT solver. In: Ramakrishnan, C.R., Rehof, J. (eds.) TACAS 2008. LNCS, vol. 4963, pp. 337–340. Springer, Heidelberg (2008)
D’Silva, V., Haller, L., Kroening, D.: Satisfiability solvers are static analysers. In: Miné, A., Schmidt, D. (eds.) SAS 2012. LNCS, vol. 7460, pp. 317–333. Springer, Heidelberg (2012)
D’Silva, V., Haller, L., Kroening, D.: Abstract satisfaction. In: Proceedings of the 41st ACM SIGPLANSIGACT Symposium on Principles of Programming Languages, POPL 2014, pp. 139–150. ACM, New York (2014)
Gurfinkel, A., Kahsai, T., Komuravelli, A., Navas, J.A.: The seahorn verification framework. In: Kroening, D., Păsăreanu, C.S. (eds.) CAV 2015. LNCS, vol. 9206, pp. 343–361. Springer, Heidelberg (2015)
Haase, C., Ishtiaq, S., Ouaknine, J., Parkinson, M.J.: SeLoger: a tool for graphbased reasoning in separation logic. In: Sharygina, N., Veith, H. (eds.) CAV 2013. LNCS, vol. 8044, pp. 790–795. Springer, Heidelberg (2013)
Heizmann, M., Hoenicke, J., Podelski, A.: Software model checking for people who love automata. In: Sharygina, N., Veith, H. (eds.) CAV 2013. LNCS, vol. 8044, pp. 36–52. Springer, Heidelberg (2013)
Iosif, R., Rogalewicz, A., Simacek, J.: The tree width of separation logic with recursive definitions. In: Bonacina, M.P. (ed.) CADE 2013. LNCS, vol. 7898, pp. 21–38. Springer, Heidelberg (2013)
Ishtiaq, S., O’Hearn, P.: BI as an assertion language for mutable data structures. In: ACM POPL, pp. 14–26, London, January 2001
Jose, M., Majumdar, R.: Cause clue clauses: error localization using maximum satisfiability. In: PLDI, pp. 437–446. ACM, New York (2011)
Le, Q.L., Gherghina, C., Qin, S., Chin, W.N.: Shape analysis via secondorder biabduction. In: Biere, A., Bloem, R. (eds.) CAV 2014. LNCS, vol. 8559, pp. 52–68. Springer, Heidelberg (2014)
Le, Q.L., Sharma, A., Craciun, F., Chin, W.N.: Towards complete specifications with an error calculus. In: Brat, G., Rungta, N., Venet, A. (eds.) NFM 2013. LNCS, vol. 7871, pp. 291–306. Springer, Heidelberg (2013)
Le, Q.L., Sun, J., Chin, W.N.: Satisfiability modula heapbased programs. Technical report (2016). http://loc.bitbucket.org/papers/satslcav16.pdf
Makoto, T., Le, Q.L., Chin, W.N.: Presburger arithmetic and separation logic with inductive definitions. Technical report, May 2016
Navarro Pérez, J.A., Rybalchenko, A.: Separation logic + superposition calculus = heap theorem prover. In: Proceedings of the 32nd ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI), pp. 556–566 (2011)
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)
Piskac, R., Wies, T., Zufferey, D.: Automating separation logic using SMT. In: Sharygina, N., Veith, H. (eds.) CAV 2013. LNCS, vol. 8044, pp. 773–789. Springer, Heidelberg (2013)
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)
Piskac, R., Wies, T., Zufferey, D., 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)
Popeea, C., Chin, W.N.: Inferring disjunctive postconditions. In: Okada, M., Satoh, I. (eds.) ASIAN 2006. LNCS, vol. 4435, pp. 331–345. Springer, Heidelberg (2008)
Pugh, W.: The omega test: a fast practical integer programming algorithm for dependence analysis. Commun. ACM 8, 102–114 (1992)
Qiu, X., Garg, P., Ştefănescu, A., Madhusudan, P.: Natural proofs for structure, data, and separation. In: PLDI, pp. 231–242. ACM, New York (2013)
Reynolds, J., Logic, S.: A logic for shared mutable data structures. In: Proceedings of the 17th Annual IEEE Symposium on Logic in Computer Science, pp. 55–74 (2002)
Sighireanu, M., Cok, D.R.: Report on SLCOMP 2014. In: JSAT (2016)
Sims, É.J.: Extending separation logic with fixpoints and postponed substitution. Theor. Comput. Sci. 351(2), 258–275 (2006)
Suter, P., Dotta, M., Kuncak, V.: Decision procedures for algebraic data types with abstractions. In: Proceedings of the 37th Annual ACM SIGPLANSIGACT Symposium on Principles of Programming Languages, POPL 2010, pp. 199–210. ACM, New York (2010)
Suter, P., Köksal, A.S., Kuncak, V.: Satisfiability modulo recursive programs. In: Yahav, E. (ed.) Static Analysis. LNCS, vol. 6887, pp. 298–315. Springer, Heidelberg (2011)
Trinh, M.T., Le, Q.L., David, C., Chin, W.N.: Biabduction with pure properties for specification inference. In: Shan, C. (ed.) APLAS 2013. LNCS, vol. 8301, pp. 107–123. Springer, Heidelberg (2013)
Acknowledgements
We wish to thank Christopher M. Poskitt for his helpful comments on the manuscript. Quang Loc and Jun Sun are partially supported by NRF grant RGNRF1501 and WeiNgan by NRF grant NRF2014NCRNCR001040.
Author information
Authors and Affiliations
Corresponding author
Editor information
Editors and Affiliations
Rights and permissions
Copyright information
© 2016 Springer International Publishing Switzerland
About this paper
Cite this paper
Le, Q.L., Sun, J., Chin, WN. (2016). Satisfiability Modulo HeapBased Programs. In: Chaudhuri, S., Farzan, A. (eds) Computer Aided Verification. CAV 2016. Lecture Notes in Computer Science(), vol 9779. Springer, Cham. https://doi.org/10.1007/9783319415284_21
Download citation
DOI: https://doi.org/10.1007/9783319415284_21
Published:
Publisher Name: Springer, Cham
Print ISBN: 9783319415277
Online ISBN: 9783319415284
eBook Packages: Computer ScienceComputer Science (R0)