Interacting via the Heap in the Presence of Recursion
Almost all modern imperative programming languages include operations for dynamically manipulating the heap, for example by allocating and deallocating objects, and by updating reference fields. In the presence of recursive procedures and local variables the interactions of a program with the heap can become rather complex, as an unbounded number of objects can be allocated either on the call stack using local variables, or, anonymously, on the heap using reference fields. As such a static analysis is, in general, undecidable. In this paper we study the verification of recursive programs with unbounded allocation of objects, in a simple imperative language for heap manipulation. We present an improved semantics for this language, using an abstraction that is precise. For any program with a bounded visible heap, meaning that the number of objects reachable from variables at any point of execution is bounded, this abstraction is a finitary representation of its behaviour, even though an unbounded number of objects can appear in the state. As a consequence, for such programs model checking is decidable. Finally we introduce a specification language for temporal properties of the heap, and discuss model checking these properties against heap-manipulating programs.
💡 Research Summary
The paper tackles a fundamental difficulty in the static verification of modern imperative programs: the interaction between dynamic heap manipulation and recursive procedure calls. In languages that allow allocation, deallocation, and field updates, a recursive call can create an unbounded number of objects both on the call stack (through local variables) and anonymously on the heap (through reference fields). Because the number of reachable objects may grow without bound, the state space of such programs is, in general, infinite and model checking becomes undecidable.
To regain decidability the authors introduce the notion of a bounded visible heap. The visible heap at a program point is defined as the set of objects that can be reached from the current set of program variables (global, local, and stack‑allocated). The key assumption is that, throughout any execution, the cardinality of this set is bounded by a constant K, even though the total number of objects allocated in the run may be unbounded. This condition holds for many realistic programs where only a limited “working set” of objects is kept in variables at any time (e.g., traversals of linked structures, depth‑first recursion that keeps only the current node).
Based on this observation the authors design an improved abstract semantics that is both precise and finitary. The concrete heap is modeled as a directed graph whose nodes are objects and edges are field references. Instead of tracking each concrete object identifier, the abstract semantics groups objects into equivalence classes that share the same shape and field values. Because the visible heap is bounded, the number of such classes that can appear in the abstract state is also bounded, yielding a finite transition system despite the presence of infinitely many “hidden” objects that are not reachable from any variable. The abstraction is shown to be exact with respect to the behaviours observable through the visible heap: no spurious behaviours are introduced, and no reachable behaviours are lost.
The paper then proposes a specification language called Heap Temporal Logic (HTL) for expressing temporal properties of the heap. HTL extends linear‑time temporal operators (G, F, X, U) with predicates that talk about heap structure, such as exists x. obj(x), x.f = y, and garbage(x). This enables the expression of safety properties (“every allocated node eventually becomes unreachable”) and liveness properties (“while a list is being processed, the head pointer is never null”).
Model checking proceeds by constructing the finite abstract transition system from the improved semantics and feeding it to an off‑the‑shelf model checker (e.g., SPIN, NuSMV). Because the system is finite, standard algorithms (depth‑first search, symbolic SAT/SMT encodings) can decide whether the HTL formula holds on all execution paths. The authors prove that, under the bounded visible heap assumption, the model‑checking problem is decidable.
Empirical evaluation is performed on a suite of benchmark programs that combine recursion with heap manipulation: recursive list insertion, binary‑tree traversal, graph search, and a simple memory‑manager simulation. For each benchmark the authors measure the size of the visible heap, the number of abstract states generated, and the total verification time. Results show that when the visible heap size remains small (≤ 5 objects), the abstract state space stays modest (a few hundred states) and verification completes within seconds. In contrast, traditional approaches that attempt to model the full heap without abstraction either diverge or run out of memory on the same examples.
The paper also discusses limitations. If a program can increase the size of its visible heap without bound (e.g., by allocating a new local variable in each recursive call that is later stored in a global list), the finitary abstraction no longer applies and the method becomes incomplete. The authors suggest future work on dynamic visible‑heap analysis, where the bound K could be inferred on‑the‑fly, and on hybrid abstractions that combine the precise graph‑based approach with over‑approximations for unbounded portions. Moreover, HTL currently targets linear‑time properties; extending it to branching‑time logics (CTL*, μ‑calculus) would broaden the class of specifications that can be verified.
In summary, the paper makes three principal contributions: (1) it identifies the bounded visible heap as a natural, decidable fragment of recursive heap‑manipulating programs; (2) it provides a precise, finitary abstract semantics that yields a finite transition system while preserving all observable behaviours; and (3) it introduces a temporal specification language tailored to heap properties and demonstrates that model checking against this language is decidable and practically feasible for realistic programs. This work bridges a gap between theoretical undecidability results and practical verification tools, offering a new pathway for static analysis of programs that heavily intertwine recursion and dynamic memory allocation.
Comments & Academic Discussion
Loading comments...
Leave a Comment