Model Checking as Program Verification by Abstract Interpretation
Abstract
Abstract interpretation offers a powerful toolset for static analysis, tackling precision, complexity and state-explosion issues. In the literature, state partitioning abstractions based on (bi)simulation and property-preserving state relations have been successfully applied to abstract model checking. Here, we pursue a different track in which model checking is seen as an instance of program verification. To this purpose, we introduce a suitable language – called (for del checking as abstract interpretation of leene lgebras) – which is used to encode temporal formulae as programs. In particular, we show that (universal fragments of) temporal logics, such as ACTL or, more generally, universal -calculus can be transformed into programs. Such programs return all and only the initial states which violate the formula. By applying abstract interpretation to programs, we pave the way for reusing more general abstractions than partitions as well as for tuning the precision of the abstraction to remove or avoid false alarms. We show how to perform model checking via a program logic that combines under-approximation and abstract interpretation analysis to avoid false alarms. The notion of locally complete abstraction is used to dynamically improve the analysis precision via counterexample-guided domain refinement.
Keywords and phrases:
ACTL, -calculus, model checking, abstract interpretation, program analysis, local completeness, abstract interpretation repair, domain refinement, Kleene algebra with testsCopyright and License:
2012 ACM Subject Classification:
Theory of computation Modal and temporal logics ; Theory of computation Verification by model checking ; Theory of computation Program verification ; Theory of computation Programming logic ; Theory of computation AbstractionFunding:
This research was partially funded by the Italian MUR, under the PRIN 2022 PNRR project no. P2022HXNSC on “Resource Awareness in Programming: Algebra, Rewriting, and Analysis”, and the PNRR project SEcurity and RIghts In the CyberSpace (SERICS, PE00000014 – CUP H73C2200089001), by the INdAM-GNCS Projects RISICO (CUP E53C22001930001) and MARQ (CUP E53C24001950001), by a WhatsApp Research Award and by an Amazon Research Award for AWS Automated Reasoning.Editors:
Patricia Bouyer and Jaco van de PolSeries and Publisher:
Leibniz International Proceedings in Informatics, Schloss Dagstuhl – Leibniz-Zentrum für Informatik
1 Introduction
Abstraction is a fundamental craft for mastering complexity. In model checking, abstraction-guided space reduction allows to mitigate the well-known state explosion problem [15]. Abstract interpretation [16, 17] is the de facto standard framework for designing sound analyses. The idea of applying abstract interpretation to model checking has been widely investigated, e.g., [3, 23, 50, 33, 30, 28, 14, 10, 4, 46, 21, 11, 12, 49, 25, 26, 44, 22, 19, 38, 45, 20, 29, 2, 37, 47, 35, 5, 40, 55] (§ 7 accounts for more closely related work). These approaches often rely on over-approximations that preserve some logical properties, like state partitioning abstractions or simulation-preserving relations.
Objective.
In this work, we pursue a different approach, which consists in recasting model checking of temporal formulae directly in terms of program verification, for which the whole tool-suite of abstract interpretation is readily available. To this aim, we exploit an instance of a Kleene algebra with tests and fixpoints () [36], whose primitives allow to map each temporal formula to a program that can single out all and only the counterexamples to the formula. This program can then be analysed through a sound abstract interpretation that over-approximates the concrete behaviour, so that all possible counterexamples are exposed. However, this over-approximation might not faithfully model the program behaviour in the abstract domain, thus possibly mixing true and false alarms. This lack of precision cannot happen when the abstract interpretation is complete [18]. However, completeness happens quite seldom, and even if, in principle, it can be achieved by refining the abstract domain [27], the most abstract domain refinement ensuring completeness is often way too concrete (it might well coincide with the concrete domain itself).
To remove false alarms, the validity of temporal formulae can be analysed by deriving certain judgements for the corresponding program in a suitable program logic. This enables the use of techniques borrowed from locally complete abstract interpretation [9, 7], where the over-approximation provided by the abstract domain is paired with an under-approximating specification, in the style of O’Hearn’s incorrectness logic [43]. This way, any alarm raised by an incorrectness logic proof corresponds to a true counterexample and local completeness guarantees that derivable judgements either exposes some true counterexamples (if any) or proves that there are none. Moreover, the failure of a proof obligation during inference can point out how to dynamically refine the underlying abstraction to enhance the precision and expressiveness of the analysis, a technique called abstract interpretation repair [8].
Methodology (and a toy example).
Our main insight is to design a meta-programming language, called (del checking as abstract interpretation of leene lgebras), where suitable temporal formulae can be mapped to. We show how this can be done for ACTL or, more generally, for the single variable -calculus without the existential diamond modality. is a language of regular commands, based on Kleene algebra with tests () [34] augmented with fixpoint operators () [36]. leverages a small set of primitives to extend and filter computation paths. They can be combined with the usual operators of sequential composition, join (i.e., nondeterministic choice), Kleene iteration, and least fixpoint computation. The corresponding programs are then analysed by abstract interpretation.
The language operates on computation paths , where represents the current system state, and represents the set of traversed states. In the following, we informally overload the symbol to denote . Several computation paths can be stacked and unstacked through the primitives and for dealing with nested temporal formulae. A generic stack is denoted and we call its current state. Each temporal formula is mapped to a program that intuitively computes counterexamples to , whence the bar over in the application of the encoding . Letting denote the usual (collecting) denotational semantics, a key result is, therefore, that a state satisfies the formula iff the execution of on returns the empty set. Of course, the results can be generalised additively to sets of stacks, for which filters out exactly those stacks whose current state satisfies . We can thus summarise the semantic correspondence between formulae satisfaction and execution of their programs by . As a special case, it follows that iff . For example, for an atomic proposition , we let , where is a primitive that filters out those states where is valid. As a further example, the program for the formula (stating that along every possible path always holds) is .
The intuition is quite simple: generates all the successors by iterating the operation, and they are filtered by , to expose those which fail to satisfy . The operations and manage the stack structure. In the example, to attain the semantic correspondence above, whenever a state such that is reachable from some initial state , we want to return and not : the operation serves to stash when looking for , and the operation to discard and unstash , to conclude . To make the next introductory examples easier to follow, we suggest that the reader ignore the and symbols, hence their faded rendering in programs.
To get a flavour of the proposed approach, we sketch an easy example, which is a variation of [12, Examples 3.4, 3.7]. Consider the transition system in Figure 1(a), which models the behaviour of cars at a US traffic light. State names consist of two letters, denoting, respectively, the traffic light status, i.e. red, yellow, green, and the car behaviour, i.e. stop, drive. We model check the validity in the initial state of the safety property , stating that it will never happen that the light is red and the car is driving. This is obviously true for the system, since is an unreachable state. We therefore consider the program , and compute its semantics , which turns out to be the empty set, thus allowing us to conclude that . In fact, after a few concrete steps of iteration, .
How the abstraction works.
We show how any sound abstraction of state properties in of the original system can be lifted to a range of sound abstractions on stacks with varying degrees of precision, in a way that programs can be analysed by an abstract interpreter, denoted by . The analysis output is always sound, meaning that the set of counterexamples is over-approximated. In particular, letting denote the abstraction map to an abstract lattice, and the bottom element of the corresponding abstract computational domain, if , then holds. Vice versa, if , then the abstract analysis might raise a false alarm because, in general, abstractions are not complete.
Back to the previous example, let us consider the (non-partitioning) abstract domain in Figure 1(c), induced by the abstract properties , and , whose concretizations are represented as dotted boxes in Figure 1(b). The abstract interpreter computes , thus allowing us to conclude that . Since has a transition to , we have . It is worth remarking that in the abstract domain , computing requires two iterations instead of four, as it happens in the concrete computation. Consider now the formula , namely, “whenever the semaphore is green, then at the next state the car is driving”. Spelling out the encoding, we have: . Again, holds for the concrete system in Figure 1(a), but here the abstract interpretation is imprecise, because and , so that , thus raising a false alarm. As explained above, we exploit / operators to manage the stack structure of domain elements and to recover the (abstract) states from which the computation started when property violations are found. For instance, in the case illustrated above, once the stack is obtained, representing an abstract trace where the property fails, its initial abstract state, , is recovered by applying two successive operations.
To eliminate false alarms, we leverage the concept of local completeness in abstract interpretation. Roughly, the idea consists in focusing on the (abstract) computation path produced by some input of interest, and then refining the abstraction only when needed to make it complete locally to such computation. More precisely, we apply a variation of local completeness logic (LCL) [9, 7], which is here extended to deal with fixpoint operators. The LCL proof system, parametrised by a generic state abstraction , works with O’Hearn-like judgements , where is a program and denote state properties or, equivalently, the underlying sets of states satisfying those properties. The triple is valid when is an under-approximation of the states reachable by from while the abstraction of over-approximates such reachable states, and the abstract computation of on the precondition is locally complete. Roughly, this can be expressed as . In our setting, where the program associated with a formula “returns” all the counterexamples to the validity of , an inference of shows that , thus bounding the set of counterexamples to in . Hence, if then does not hold for each , while holds for all states . If, instead, , then , and holds in the whole . As LCL derivations cannot succeed with locally incomplete abstractions, if some proof obligation fails, the abstract domain needs to be “fixed” to achieve local completeness. This can be accomplished, e.g., by applying the abstraction repair techniques defined in [8].
For the toy traffic light example, we can derive in LCL the program triple , that confirms the validity of the formula . Vice versa, an attempt to derive the triple fails because of local incompleteness. Roughly, we can successfully derive , but then the execution of on is not locally complete, because , while . The abstraction repair procedure of [8] would then lead to refine the abstract domain by adding a new abstract element to represent the concrete set . Since abstract domains must be closed under meets, the addition of will also entail the addition of such that . Letting , we can still derive , then , and finally , which can be composed together to conclude . In fact, in we just have .
Original contribution.
We set up a theoretical framework for the systematic reduction of model checking of temporal logics to program verification, thereby enabling the re-use of abstract interpretation techniques and verifiers either directly or with minimal effort. This framework consists of:
-
, a meta-programming language in which different temporal logics can be encoded so that the code for a formula computes exactly the counterexamples to ;
-
a systematic technique for lifting abstractions over state properties to abstractions suitable for the static analysis of programs;
-
an extension of the LCL program logic to handle least fixpoints, introducing a form of “false alarm-guided” abstraction refinement loop in the analysis of programs.
Synopsis.
In § 2 we provide some basics about abstract interpretation and the (fragments) of temporal logics considered in the paper. In § 3 we introduce the language , and then prove in § 4 the key results that relate formula satisfaction with program execution. In § 5 we define a general technique for deriving abstract domains for the static analysis of programs. In § 6 we showcase how local completeness logic reasoning can be exploited in our framework. In § 7 we discuss related work. Finally, in § 8 we draw some conclusions and sketch future avenues of research. Full proofs of our results and additional material are available in the extended version of this paper [1].
2 Background
A complete lattice is a poset where every subset has both least upper bound (lub) and greatest lower bound (glb), denoted by and , respectively, with and . When no ambiguities can arise, a lattice will be denoted as and subscripts will be omitted.
Given two complete lattices and , a function , is monotone if implies , and additive (resp., co-additive) if it preserves arbitrary lub (resp., glb). Any monotone function on a complete lattice has both a least and a greatest fixpoint, denoted by and , respectively. The set of functions from a set to a complete lattice , denoted , forms a complete lattice when endowed with the pointwise order s.t. if for all , . If are complete lattices, then is their product lattice endowed with the componentwise order s.t. if and . We write for the -ary product of with itself and for the complete lattice of non-empty finite sequences in , ordered by if and for all , with top and bottom .
2.1 Abstract Interpretation
Given two complete lattices and , called the concrete and the abstract domain, respectively, a Galois connection (GC) is a pair of functions and s.t. for any and .
The function is referred to as abstraction map and turns out to be additive, while is the concretization map which is always co-additive. Intuitively, any abstract element such that is a sound over-approximation for the concrete value , while the abstraction is the most precise over-approximation of in the abstract domain , i.e., holds. The notation denotes an abstract domain endowed with its underlying GC, and we will omit subscripts when and are clear from the context.
Example 2.1 (Image adjunction).
Given any function , let and denote the direct and inverse image of , respectively. The pair is a GC that we refer to as the image adjunction (this is an instance of [24, Exercise 7.18]).
The class of abstract domains on , denoted by , can be preordered by the domain refinement relation: when .
Example 2.2 (Control flow graphs and predicate abstraction).
Any program can be represented by its control flow graph (CFG). Let be a set of variables valued in and denote by the set of environments. A CFG is a graph , where is a finite set of nodes, representing program points, are the start and end nodes, respectively, and is a set of edges, labelled over a set of transfer (additive) functions . For example, the program c in Figure 2(a) is decorated with program points , has variables , and values ranging in the finite domain of integers modulo a given . The CFG of c is depicted in Figure 2(b).
Predicate abstraction allows to approximate program invariants [32]. Given a set of predicates (where any has a representation ), the predicate abstraction domain is defined by adding to the complement predicates , and then by closing under logical conjunction. We define a function that associates to each set of environments the strongest predicate it satisfies. For example, given the two predicates and , the predicate abstraction domain induced by the set is depicted in Figure 2(c). Correspondingly, the product abstraction allows us to represent the abstract state of the program as a function that associates to each program point the strongest predicate in that holds at . Hence, for instance, the set of all possible initial states of c, which is , is represented by the function , often written , omitting the program points which are mapped to .
An abstract interpreter computes in the underlying abstract domain through correct (and effective) abstract approximations of concrete functions. Given and a function , an abstract function is a correct approximation of if , and it is a complete approximation of when . The best correct approximation (bca) of in , is defined as , and turns out to be the most precise correct abstraction, i.e., for any other correct approximation of . When is complete, then , thus making completeness an abstract domain property defined by the equation . In program analysis, abstract domains are commonly endowed with correct but incomplete abstract transfer functions. When completeness holds, the abstract interpreter is as precise as possible for the given abstract domain and cannot raise false alarms when verifying properties that are expressible in the abstract domain [27].
2.2 Transition Systems and Logics
Temporal logics are typically interpreted over unlabeled, finite, directed graphs, whose nodes and edges model states and transitions between them (i.e., state changes), respectively.
A transition system is a tuple , where is a finite set of states ranged over by , is the set of initial states, is the transition relation, is a (finite) set of atomic propositions, ranged over by , and is the satisfaction relation.
We write instead of and let denote the set of direct successors of . As common in model checking [13], we consider systems whose transition relation is total, i.e., for all there exists such that .
A path is an infinite denumerable state sequence such that for all .
Example 2.3 (Control flow graphs as transition systems).
A CFG can be viewed as a transition system with states and transition relation defined by if there is an edge such that . Additionally, in order to make the transition relation total we add self-loops to all the states involving the end node . For instance, by using the shorthand for the states in Example 2.2, the transition is induced by the edge in Figure 2(b), while by in Figure 2(b).
Let us point out that the predicate abstraction in Example 2.2 naturally lifts to the powerset of states with codomain , with the abstraction map for . Given , we define .
ACTL.
ACTL is the fragment of CTL whose temporal formulae are universally quantified over all paths leaving the current state. Thus, given a set of atomic propositions :
Definition 2.4 (ACTL semantics).
Given a transition system , the semantics of ACTL formulae over is as follows:
Universal fragment of single variable -calculus.
The modal -calculus is a well known extension of propositional modal logic with least and greatest fixed point operators. We will focus on its universal fragment only allowing the modal operator that quantifies over all transitions. Moreover, for the sake of simplicity, we restrict to the single variable fragment where, roughly speaking, nested fixpoints cannot have mutual dependencies.
Given a set of atomic propositions , the -calculus is defined as follows:
Definition 2.5 (-calculus semantics).
Given , and a valuation , the semantics of -calculus formulae over is as follows:
where is the usual notation for function update.
We write instead of when the valuation is inessential, and when .
3 The Language
We define a meta-language, called (for del checking as abstract interpretation of leene lgebras), as a (generalised) Kleene Algebra with a set of basic expressions suited for identifying counterexamples to the validity of temporal formulae.
.
We rely on Kozen’s Kleene Algebra with tests [34] with a Fixpoint operator [36], for short. Given a set of basic expressions , is defined below:
The term represents the identity, i.e. no action, represents divergence, represents sequential composition, represents non-deterministic choice, represents the Kleene iteration of , i.e. performed zero or any finite number of times, is a variable ranging in a set , and represents the least fixpoint operator with respect to variable .
Commands are interpreted as functions over a complete lattice . Given a semantics for basic expressions, the semantics of regular expressions is inductively defined as follows, where is an environment:
It can be seen that the Kleene star can be encoded as a fixpoint , and, when the semantics of basic expressions is additive, also as . Although redundant, the inclusion of the Kleene star in our syntax is very convenient, as it enables significant simplifications in some encodings, particularly when the full expressiveness of least fixpoint calculations is not necessary (see the remark at the end of Section 4). The same applies to the proof logic studied in Section 6: while basic LCL suffices for the fragment without least fixpoint operator, its extension LCL is otherwise needed. For closed terms the environment is inessential and we write just instead of .
The Language .
Given a transition system , is an instance of interpreted over stacks of frames, each frame representing a computation path.
Definition 3.1 (Frame, stack).
A frame is a pair . We denote by the set of frames. A stack is a finite non-empty sequence of frames, i.e. an element of , denoted by , where is a stack or the empty sequence .
A frame represents a computation in where is the current state and is the set of traversed states, used for loop-detection. The order of the traversed states and their possible multiple occurrences are abstracted away as they are irrelevant when checking the satisfaction of a formula. Frames are stacked to deal with formulae with nested operators.
The language is defined as instance of with basic expressions for extending and filtering frames, for (de)constructing stacks, and to keep track of fixed-point equations.
Definition 3.2 ( language).
The language is an instance of with the following basic expressions, where ranges over atomic propositions:
The (concrete) semantics of is given over the powerset of the set of stacks, , ordered by subset inclusion. Although we could focus on stacks of uniform length, we use a larger domain to simplify the notation.
The semantics of commands follows from the general definition for , once we specify the semantics of its basic expressions.
Definition 3.3 (Basic expression semantics).
Given , the semantics of basic expressions is the additive extension of the functions below, where :
The basic expressions , , , , , operate on the top frame. The filter (resp. ) checks the validity of the proposition (resp. ), checks if the current state loops back to some state in the trace, extends the trace by one step in all possible ways, adds the current state to the trace and empties the trace. Instead, and change the stack length: extends the stack to start a new trace, while restores the previous trace from the stack. Given a set of states , we write as a shorthand for .
4 Formulae as programs
We show that ACTL and -calculus formulae can be transformed into programs so that for any transition system , the semantics of over consists exactly of the counterexamples to the validity of , that is, the states which do not satisfy .
Theorem 4.1 (Model checking as program verification).
Given , for any ACTL or formula and set of stacks , it holds
It follows that and that iff . It is also worth noting that the semantics of programs encoding formulae is a lower closure on sets of states, being monotone, reductive and idempotent (and it preserves arbitrary unions) [39, Section 3.2.3]. In this respect, it behaves analogously to the collecting semantics of Boolean tests which filter out memory states, keeping only those that satisfy the condition. As a consequence, similarly to what happens when abstracting Boolean tests, in any abstract domain approximating sets of states the identity , is a correct (over-)approximation of .
ACTL as .
To each ACTL formula we assign the program as follows:
The intuition is that programs act as (negative) filters: applied to a set of frames , each representing a computation that reached state , they filter out states where is satisfied, keeping only candidate counterexamples to the validity of . In general, when the check requires exploring the future of the current state, a new frame is started with ; if the search is successful, a closing recovers the starting state violating the formula. We explain the main clauses defining (see [1, Theorem B.1] for the proof of the correctness of this transform). It turns out that is a counterexample for
-
if is violated in at least one successor state of (as computed by ).
-
if there is an infinite trace where never holds. This is encoded by saying that does not hold in the current state, i.e. , and after that, there is an infinite trace traversing only states (collected through the command ) that do not satisfy . Since we deal with finite state systems, infinite traces can be identified with looping traces (whence the check ); for this to work, after the we the past.
-
if we can reach, by repeatedly applying , a counterexample to .
-
if does not hold in the current state, i.e. , and progressing through states that do not satisfy with , either we detect a maximal (looping) trace or a state where does not hold.
Example 4.2 (Control flow graphs and ACTL encoding).
In our running example (see Examples 2.2 and 2.3), we check the property stating that if the program c terminates then the variable is zero, which in the CFG means “when the exit node is reached, ” holds. This is expressed by the ACTL formula , where we use as syntactic sugar for . The corresponding program is: .
-calculus as .
To each -formula we assign the program as follows:
The second component of a frame is still used to identify looping computations. This intervenes in the encoding of least fixpoints : when checking the formula, the current state first logged to the current frame ( branch); a counterexample is found when we try to verify the fixpoint property in a state where the check has already been tried (filtered by ). The encoding of greatest fixpoints instead is simpler: searching for counterexamples naturally translates to a least fixpoint, which is offered natively by .
The correctness of this transform (see [1, Theorem B.2 and Corollary B.3]) leverages a small variation of the tableau construction in [53], with judgements roughly of the form , meaning that the formula holds in a state assuming that all the states in have been visited while checking the current fixpoint subformula. Then, it can be shown that given a formula and a stack , if there is no successful tableau for then holds, while otherwise.
Example 4.3 (Control flow graphs and -calculus encoding).
Consider again Examples 2.2 and 2.3. We now check the property “if after three steps we end up in program point then we will loop forever, every steps, on this program point 3.” It is known that regular properties of this kind cannot be expressed in ACTL (see, e.g., [54]). This property can be expressed in the -calculus as , where is a shortand for repeated times. Letting as a shorthand for a times composition of a program , the program encoding is , with .
It is well known that all ACTL formulae can be expressed as -calculus formulae. For example, , , and . Hence one could obtain programs generating counterexamples for ACTL by encoding ACTL in the -calculus and then generating the corresponding program. However, this in general produces programs which are (unnecessarily) more complex than those produced for ACTL formulae. For instance, the program for obtained through the -calculus encoding above would be .
5 Abstract Interpretation of
We show how to lift an abstraction over the states of a transition system to an abstraction over the domain of stacks. This is achieved stepwise by first considering an abstraction applied to each single stack, and then by merging classes of stacks through a suitable equivalence. The resulting stack abstraction will induce the abstract interpretation of programs.
Lifting the abstraction.
Let be a fixed transition system and let be an abstraction of state properties. We consider the lattice , with componentwise order, whose elements are called abstract frames, and, in turn, whose elements are called abstract stacks. As in the concrete case, we abbreviate as .
The abstraction map on state properties can be extended to a frame abstraction, that by abusing the notation, we still denote by , and is defined by . In turn, the abstraction is inductively defined on stacks as .
Now, a set of stacks is abstracted to a set of abstract stacks by first applying pointwise using the image adjunction (see Example 2.1) and then joining classes of abstract stacks in a way which is parameterised by a suitable equivalence. Given an equivalence , we let denote the equivalence class of w.r.t. . Given we let .
Definition 5.1 (Equivalence adjunction).
Given a complete lattice
, a compatible equivalence is an equivalence
such that for all , it holds that
is closed by joins of non-empty subsets. Let
, ordered as follows: if for all there is such that and .
Then, the pair
defined, for , , by
is a Galois connection, called equivalence adjunction.
In words, consists of the subsets of containing at most one representative for each equivalence class, and abstracts in the subset (in ) consisting of the least upper bounds of -equivalent elements in .
We can now define the stack abstraction parameterised by an equivalence on the lattice of abstract frames. Given an equivalence on any set , denotes the equivalence on induced by as follows: for all , if and for all .
Definition 5.2 (Stack abstraction).
Let be a compatible equivalence on the abstract domain and let us extend it to the lattice of abstract frames by if . The -stack abstraction is the domain along with the Galois connection defined by and .
In words, given a set of stacks, its abstraction first applies pointwise the underlying to each stack in , and then joins equivalent abstract stacks. As corner cases we can have the identity relation , which joins abstract frames with identical first component, and , the trivial relation, which joins all abstract stacks into one.
An abstract interpreter for counterexamples.
Given an abstraction for state properties and a compatible equivalence on , following the standard approach in abstract interpretation [16], we consider an abstract semantics , defined inductively as explained in § 3 and using as abstract semantics for basic expressions their BCAs on , denoted by . We write instead of when the abstract environment is inessential. Notably, the BCAs of basic expressions independent from the underlying system can be effectively defined, and some of them result to be complete.
Theorem 5.3 (Basic abstract operations).
Let be a compatible equivalence on the abstract domain . The BCAs of the basic expressions , , , for the -stack abstraction are as follows: for all
and the operations , , are globally complete. Moreover
where is the abstraction of the set of concrete states satisfying (and similarly for ).
For one can get under additional conditions on (cf. [1, Definition C.6]).
The soundness-by-design of this abstract semantics entails a sound program verification.
Proposition 5.4 (Program verification for satisfaction).
Given a transition system , for all ACTL or -calculus formulae , abstract domain , and a compatible equivalence on A, if then, for all , we have .
As in the concrete case, the abstract semantics of programs encoding formulae is a lower closure. This, together with the observation that the semantics only depends on the top frame of a stack, is relevant for the concrete implementation.
Remark 5.5.
We recalled in § 4 that for any Boolean test and abstract domain , the identity function is a correct approximation of the filtering semantics of . This function can be enhanced to , which is also a correct approximation of [39, Section 4.1]. If is a partitioning abstraction then one can show that is indeed the best correct approximation of . However, this property does not hold in general, even assuming that is a disjunctive abstraction, i.e., the additivity of (this is substantiated in [1, Example C.10]).
Example 5.6 (Control flow graphs and abstract frames).
In our running example, abstract frames are of the shape . The abstraction of singletons is with for all . With the aim of joining past states when they correspond to the same program point, we consider the equivalence on abstract frames defined by when . The property from Example 4.3 holds in the system, and we can prove it with this abstraction. Let we can compute , implying that the formula holds from any initial states (convergence is after a single full iteration). Instead, the abstract computation for from Example 4.2 yields a false positive.
6 Locally Complete Analyses
If the abstract interpretation of a program returns an alarm, i.e., , then any initial state in the concretisation of is a candidate counterexample to the validity of . However, due to over-approximation, we cannot distinguish spurious counterexamples from true ones. Here, we discuss how to combine under- and over-approximation for the analysis of programs to overcome this problem. In particular we leverage Local Completeness Logic (LCL) [9, 7] possibly paired with Abstract Interpretation Repair (AIR) strategies [8], to improve the analysis precision.
LCL.
Most abstract domains are not globally complete for program analysis, so that the corresponding analyses may well yield false alarms. Accordingly, [9, 7] studies how completeness can be locally weakened to an analysis of interest: given a function , an abstract domain is locally complete on a value , denoted by , when (hence global completeness amounts to for all ). Intuitively, the absence of false alarms in an abstract computation comes as a consequence of the local completeness of the abstract transfer functions on the traversed concrete states.
Moreover, local completeness is a convex property, and this allows to check local completeness on suitable under-approximations such that , as implies . The work [9, 7] implements this idea through LCL, an under-approximating program logic (in the style of incorrectness logic [43]), parameterised by the abstract domain which provides an over-approximation. The LCL proof rules for programs are recalled in Table 1. A provable LCL triple ensures that each state satisfying is reachable from some state satisfying , and also guarantees that and have the same abstraction in . This means that the LCL program logic is sound w.r.t. the following notion of validity.
Definition 6.1 (Valid LCL triples).
Let and be a program. A program triple is valid if .
The condition states that is locally complete for on , while that under-approximates and that over-approximates .
LCL for .
The LCL proof system has been defined for programs only, hence it is enough for programs induced by ACTL formulae. For analysing general and thus programs, we extend it to LCL including the inference rules in Table 2, where denotes the capture-avoiding substitution of the free occurrences of for in and the term represents the -th fixpoint approximant with the expected semantics ( and ). The syntax is used only in LCL derivations. Intuitively, since behaves as , the unique valid judgement is . The rule serves just to unfold as many times as needed. The key rule is (fix) which can be used whenever the -th approximant provides enough information: in case the premise holds, by local completeness we will have . Since it is always the case that , if the side condition holds, then local completeness for the fixpoint term can be inferred. These novel rules are sound, in the sense of preserving validity (Definition 6.1).
Remark 6.2.
When a least fixpoint appears in , we can exploit the following heuristic for choosing the value of : if the abstract domain satisfies the Ascending Chain Condition (ACC) then, for every there is such that . Then, by taking any such that is provable, the condition is readily satisfied, so that is valid. More precisely, the rule below is sound:
The following result relating LCL proofs with validity of formulae follows as an easy consequence of [9, Corollary 5.6] and Theorem 4.1.
Corollary 6.3 (Precision).
Let be a transition system. For all ACTL or -calculus formulae , abstract domain and compatible equivalence on A, if the triple is derivable, then and
-
if and only if for all we have ;
-
if then for all we have .
Example 6.4 (Control flow graphs and LCL derivations).
As pointed out in Example 5.6 the computation of the program , which encodes in the property (see Example 4.2), yields a false alarm when we use the abstract domain depicted in Figure 2(c). Consider as set of initial states , whose abstraction covers the set of possible initial states , because . Since the property holds, trying to derive a triple leads to the failure of some local completeness assumption, which can drive the refinement of . The imprecision is found in the fourth iteration of the operator, in which the set is abstracted to , losing the relation between and being either both valid or both invalid. Several domain repairs are possible. Following [8] we can repair the domain by adding the abstract point (a more abstract repair than adding the element , as proposed in [4]). Here we can also exploit a different route, by refining the equivalence so that when . This intuitively corresponds to abstract separately the states at program point . In both cases, it holds in the refined abstract domain .
Example 6.5 (Traffic light example, LCL derivation and repair, -calculus version).
Consider the toy traffic light example from Figure 1(a) and the property , briefly discussed in the introduction. We give some additional details in the light of the results presented. We first translate the formula in -calculus as whose encoding is , where . Then we try to derive the triple in the abstract domain (see Figure 1(c)) by applying the rule (afix) with (the number of iterations needed for convergence of the abstract fixpoint in ). By definition, ; then the first approximant is , but we can omit the branch that contains , so ; and the second approximant is . The attempt to derive the triple is sketched below, where the mid row gives an indication of the triples labelling the leaves of the derivation, reporting for each basic command involved, the pre-condition and post-condition of the triple, while the top row reports their abstractions.
While we can derive , the source of local incompleteness is found in the second branch, at the ! position, where the proof obligation for fails, since , while . We can thus repair the abstract domain . Following the procedure in [8], we add the new abstract point :
The repaired domain is , where is also added because the domain must be closed under meets. Now, in , the proof obligation for holds true: . In fact, in we just have (we omit the details for the first branch that are as above):
7 Related Work
Abstract interpretation and model checking have been applied to and combined with each other in several ways [50, 33, 30, 28, 14, 10, 4, 46, 21, 11, 12, 49, 25, 26, 44, 22, 19, 38, 45, 20, 29, 2, 37, 47, 35, 5] (see the survey [23] for further references). Abstract model checking broadly refers to checking a (temporal) specification in an abstract rather than a concrete model. On the one hand, in state partition-based approaches, the abstract model is itself a transition system, possibly induced by a behavioural state equivalence such as (bi)simulation, so that the verification method for the abstract model remains unaltered, e.g., [11, 12, 14, 37, 10]. On the other hand, if the abstract model derives from any, possibly nonpartitioning, state abstraction then the verification on this abstract model relies on abstract interpretation, e.g., [25, 5, 45, 46, 21, 38]. Hybrid abstraction techniques, in between these two approaches, have also been studied, e.g., predicate abstraction [33, 28], and the mixed transition systems with several universal and/or existential abstract transition relations in [22, 3]. Moreover, several works investigated the role of complete/exact/strongly preserving abstractions in model checking, e.g., [37, 20, 26, 44], and how to refine abstract models, e.g., [30, 29, 11, 12, 19, 21, 25, 45, 47, 50]. Let us also mention that [2] develops a theory of approximation for systems of fixpoint equations in the style of abstract interpretation, showing that up-to techniques can be interpreted as abstractions.
Our refinement technique somehow resembles CounterExample-Guided Abstraction Refinement (CEGAR) [12], a popular method for automatising the abstraction generation in model checking. CEGAR deals with state partition abstractions, thus merging sets of equivalent states: one starts from a rough abstraction which is iteratively refined on the basis of spurious counterexample traces arising due to over-approximation. The approach is sound for safety properties, i.e., no false positives can be found, and complete for a significant fragment of ACTL∗. It turns out that state partition abstractions are a specific instance in our approach. The attempt of proving the absence of counterexamples in LCL using an initial coarse abstraction will yield a computation by some means similar to CEGAR: failing LCL proof obligations lead to abstraction refinements which can be more general than partitions.
The general idea that model checking can be expressed as static analysis has been first investigated in [40]. This work shows that model checking of ACTL can be reduced to a logic-based static analysis formulated within the flow logic approach [42], which is then computed through a solver for the alternation-free least fixed point logic designed in [41]. This reduction technique has been later extended to the -calculus in [55]. One major goal of [40] was to show the close relationship and interplay between model checking and static analysis, coupled with early work in [51] and, later, in [48, 49, 52], proving that static program analysis can be reduced to model checking of modal formulae. Let us remark that the reduction of [40, 55] to a flow logic-based static analysis is given for concrete model checking only and does not encompass the chance of dealing with abstract model checking and related abstraction refinement techniques such as CEGAR, that can be instead achieved by-design in our approach.
8 Conclusion and future work
We have introduced a framework where model checking of temporal formulae in ACTL or in the universal fragment of the modal -calculus can be reduced to program verification, paving the way to reuse the full range of abstract interpretation techniques. Formulae are mapped to programs of the language, that are then analysed through a sound-by-construction abstract interpretation. This exposes all the possible counterexamples, although false alarms can arise. We show how false alarms can be removed by inspecting the derivability of suitable judgements in LCL, a program logic exploiting under- and over-approximations leveraging the notion of locally complete abstract interpretation. We expect that our approach, relying on , naturally applies also to logics including operators based on regular expressions (see, e.g., [31, 6]). A first candidate is Propositional Dynamic Logic (PDL) [31], a modal logic closely connected to . Its distinctive feature is a modal operator where is a expression, which is satisfied by a state when all the computations of starting from end up in a state satisfying . For instance, the property expressed in the -calculus in Example 4.3 can be equivalently written in PDL as , where, since we work in an unlabelled setting, “” stands for the only action in the system. Indeed, PDL smoothly fits in our setting (we refer the interested reader to [1, Appendix E]).
Future Work.
A number of interesting avenues of future research remain open. Our results are limited to universal fragments of temporal logics and finite state domains. A dual theory can be easily developed for existential fragments, focusing on the generation of witnesses rather than counterexamples. It would be interesting to combine the two approaches for dealing with universal and existential operators at the same time. Some ideas could come from [22] that, for solving the problem, works with two different abstract transition relations. The restriction to finite state domains is due to the fact that our encoding of logical formulae into programs relies on the operator for detecting infinite traces which are identified with looping traces. Further work could overcome this restriction by considering an encoding that captures non-looping infinite traces in the concrete domain and by exploiting ACC domains for the abstraction.
The use of LCL allows us to track the presence of false alarms back to the failure of local completeness proof obligations, which can be resolved by refining the abstract domain. This can be done at different levels: either refining the abstraction over states or refining the equivalence on abstract frames. A proper theory of refinements, possibly identifying optimal ways of patching the domain, is a matter of future investigations.
We point out that providing a general bound for the complexity of the abstract model checking procedure is not straightforward, as it crucially depends on the choice of the abstract domain. Different domains may induce significantly different behaviors, especially for non-partitioning abstractions or when local completeness and domain refinement techniques are applied. A precise complexity analysis tailored to specific domains is an interesting subject for future work.
Concerning the automatisation, the abstract interpreter could be easily implementable leveraging the standard toolset of abstract interpretation. The abstract interpreter should be instrumented to report, when the result is not , an abstract counterexample trace to check whether the counterexample is a false or true alarm. Making refinements effective requires working in a class of domains where local refinements are representable, e.g., by predicate abstractions or state partition abstractions. Developing a theory of refinements within specific subclasses of domains is a direction of future work.
References
- [1] Paolo Baldan, Roberto Bruni, Francesco Ranzato, and Diletta Rigo. Model checking as program verification by abstract interpretation (extended version). CoRR, abs/2506.05525, 2025. URL: https://arxiv.org/abs/2506.05525.
- [2] Paolo Baldan, Barbara König, and Tommaso Padoan. Abstraction, up-to techniques and games for systems of fixpoint equations. In Proceedings of CONCUR 2020, volume 171 of LIPIcs, pages 25:1–25:20, 2020. doi:10.4230/LIPICS.CONCUR.2020.25.
- [3] Thomas Ball, Orna Kupferman, and Greta Yorsh. Abstraction for falsification. In Proceedings of CAV 2005, volume 3576 of LNCS, pages 67–81. Springer, 2005. doi:10.1007/11513988_8.
- [4] Thomas Ball, Andreas Podelski, and Sriram K. Rajamani. Boolean and cartesian abstraction for model checking C programs. In Proceedings of TACAS 2001, volume 2031 of LNCS, pages 268–283. Springer, 2001. doi:10.1007/3-540-45319-9_19.
- [5] Gourinath Banda and John P. Gallagher. Constraint-based abstract semantics for temporal logic: A direct approach to design and implementation. In Proceedings of LPAR 2016, volume 6355 of LNCS, pages 27–45. Springer, 2010. doi:10.1007/978-3-642-17511-4_3.
- [6] Ilan Beer, Shoham Ben-David, and Avner Landver. On-the-fly model checking of RCTL formulas. In Proceedings of CAV 1998, volume 1427 of LNCS, pages 184–194. Springer, 1998. doi:10.1007/BFB0028744.
- [7] Roberto Bruni, Roberto Giacobazzi, Roberta Gori, and Francesco Ranzato. A logic for locally complete abstract interpretations. In Proceedings of LICS 2021. IEEE, 2021. doi:10.1109/LICS52264.2021.9470608.
- [8] Roberto Bruni, Roberto Giacobazzi, Roberta Gori, and Francesco Ranzato. Abstract interpretation repair. In Proceedings of PLDI 2022, pages 426–441. ACM, 2022. doi:10.1145/3519939.3523453.
- [9] Roberto Bruni, Roberto Giacobazzi, Roberta Gori, and Francesco Ranzato. A correctness and incorrectness program logic. Journal of the ACM, 70(2):15:1–15:45, 2023. doi:10.1145/3582267.
- [10] Doron Bustan and Orna Grumberg. Simulation-based minimization. ACM Transactions on Computational Logic, 4(2):181–206, 2003. doi:10.1145/635499.635502.
- [11] Edmund M. Clarke, Orna Grumberg, Somesh Jha, Yuan Lu, and Helmut Veith. Counterexample-guided abstraction refinement. In Proceedings of CAV 2000, volume 1855 of LNCS, pages 154–169. Springer, 2000. doi:10.1007/10722167_15.
- [12] Edmund M. Clarke, Orna Grumberg, Somesh Jha, Yuan Lu, and Helmut Veith. Counterexample-guided abstraction refinement for symbolic model checking. Journal of the ACM, 50(5):752–794, 2003. doi:10.1145/876638.876643.
- [13] Edmund M. Clarke, Orna Grumberg, Daniel Kroening, Doron A. Peled, and Helmut Veith. Model Checking, 2nd Edition. MIT Press, 2018. URL: https://mitpress.mit.edu/books/model-checking-second-edition.
- [14] Edmund M. Clarke, Orna Grumberg, and David E. Long. Model checking and abstraction. ACM Transactions on Programming, Languages and Systems, 16(5):1512–1542, 1994. doi:10.1145/186025.186051.
- [15] Edmund M. Clarke, William Klieber, Milos Novácek, and Paolo Zuliani. Model checking and the state explosion problem. In Tools for Practical Software Verification, LASER, International Summer School 2011, volume 7682 of LNCS, pages 1–30. Springer, 2011. doi:10.1007/978-3-642-35746-6_1.
- [16] Patrick Cousot. Principles of Abstract Interpretation. MIT Press, 2021. URL: https://mitpress.mit.edu/9780262044905/.
- [17] Patrick Cousot and Radhia Cousot. Abstract interpretation: A unified lattice model for static analysis of programs by construction or approximation of fixpoints. In Proceedings of POPL 1977, pages 238–252. ACM, 1977. doi:10.1145/512950.512973.
- [18] Patrick Cousot and Radhia Cousot. Systematic design of program analysis frameworks. In Proceedings of POPL 1979, pages 269–282. ACM Press, 1979. doi:10.1145/567752.567778.
- [19] Patrick Cousot and Radhia Cousot. Refining model checking by abstract interpretation. Automated Software Engineering, 6(1):69–95, 1999. doi:10.1023/A:1008649901864.
- [20] Patrick Cousot and Radhia Cousot. Temporal abstract interpretation. In Proceedings of POPL 2000, pages 12–25. ACM, 2000. doi:10.1145/325694.325699.
- [21] Patrick Cousot, Pierre Ganty, and Jean-François Raskin. Fixpoint-guided abstraction refinements. In Proceedings of SAS 2007, volume 4634 of LNCS, pages 333–348. Springer, 2007. doi:10.1007/978-3-540-74061-2_21.
- [22] Dennis Dams, Rob Gerth, and Orna Grumberg. Abstract interpretation of reactive systems. ACM Transactions on Programming, Languages and Systems, 19(2):253–291, 1997. doi:10.1145/244795.244800.
- [23] Dennis Dams and Orna Grumberg. Abstraction and abstraction refinement. In Edmund M. Clarke, Thomas A. Henzinger, Helmut Veith, and Roderick Bloem, editors, Handbook of Model Checking, pages 385–419. Springer, 2018. doi:10.1007/978-3-319-10575-8_13.
- [24] Brian A. Davey and Hilary A. Priestley. Introduction to Lattices and Order, Second Edition. Cambridge University Press, 2002. doi:10.1017/CBO9780511809088.
- [25] Roberto Giacobazzi and Elisa Quintarelli. Incompleteness, counterexamples, and refinements in abstract model-checking. In Proceedings of SAS 2001, volume 2126 of LNCS, pages 356–373. Springer, 2001. doi:10.1007/3-540-47764-0_20.
- [26] Roberto Giacobazzi and Francesco Ranzato. Incompleteness of states w.r.t. traces in model checking. Information and Computation, 204(3):376–407, 2006. doi:10.1016/J.IC.2006.01.001.
- [27] Roberto Giacobazzi, Francesco Ranzato, and Francesca Scozzari. Making abstract interpretations complete. Journal of the ACM, 47(2):361–416, 2000. doi:10.1145/333979.333989.
- [28] Susanne Graf and Hassen Saïdi. Construction of abstract state graphs with PVS. In Proceedings of CAV 1997, volume 1254 of LNCS, pages 72–83. Springer, 1997. doi:10.1007/3-540-63166-6_10.
- [29] Orna Grumberg, Martin Lange, Martin Leucker, and Sharon Shoham. When not losing is better than winning: Abstraction and refinement for the full mu-calculus. Information and Computation, 205(8):1130–1148, 2007. doi:10.1016/J.IC.2006.10.009.
- [30] Anubhav Gupta and Ofer Strichman. Abstraction refinement for bounded model checking. In Proceedings of CAV 2005, volume 3576 of LNCS, pages 112–124. Springer, 2005. doi:10.1007/11513988_11.
- [31] David Harel, Jerzy Tiuryn, and Dexter Kozen. Dynamic Logic. MIT Press, Cambridge, MA, USA, 2000. URL: https://mitpress.mit.edu/9780262527668/.
- [32] Ranjit Jhala and Rupak Majumdar. Software model checking. ACM Computing Surveys, 41(4):21:1–21:54, 2009. doi:10.1145/1592434.1592438.
- [33] Ranjit Jhala, Andreas Podelski, and Andrey Rybalchenko. Predicate abstraction for program verification. In Edmund M. Clarke, Thomas A. Henzinger, Helmut Veith, and Roderick Bloem, editors, Handbook of Model Checking, pages 447–491. Springer, 2018. doi:10.1007/978-3-319-10575-8_15.
- [34] Dexter Kozen. Kleene algebra with tests. ACM Transactions on Programming, Languages and Systems, 19(3):427–443, 1997. doi:10.1145/256167.256195.
- [35] Kim Guldstrand Larsen and Bent Thomsen. A modal process logic. In Proceedings of LICS 1988, pages 203–210. IEEE Computer Society, 1988. doi:10.1109/LICS.1988.5119.
- [36] Hans Leiß. Towards Kleene algebra with recursion. In Proceedings of CSL 1991, volume 626 of LNCS, pages 242–256. Springer, 1991. doi:10.1007/BFB0023771.
- [37] Claire Loiseaux, Susanne Graf, Joseph Sifakis, Ahmed Bouajjani, and Saddek Bensalem. Property preserving abstractions for the verification of concurrent systems. Formal Methods in System Design, 6(1):11–44, 1995. doi:10.1007/BF01384313.
- [38] Damien Massé. Semantics for abstract interpretation-based static analyzes of temporal properties. In Proceedings of SAS 2002, volume 2477 of LNCS, pages 428–443. Springer, 2002. doi:10.1007/3-540-45789-5_30.
- [39] Antoine Miné. Tutorial on static inference of numeric invariants by abstract interpretation. Foundations and Trends in Programming Languages, 4(3-4):120–372, 2017. doi:10.1561/2500000034.
- [40] Flemming Nielson and Hanne Riis Nielson. Model checking is static analysis of modal logic. In Proceedings of FoSSaCS 2010, volume 6014 of LNCS, pages 191–205. Springer, 2010. doi:10.1007/978-3-642-12032-9_14.
- [41] Flemming Nielson, Helmut Seidl, and Hanne Riis Nielson. A succinct solver for ALFP. Nordic Journal of Computing, 9(4):335–372, 2002.
- [42] Hanne Riis Nielson and Flemming Nielson. Flow logic: A multi-paradigmatic approach to static analysis. In The Essence of Computation, Complexity, Analysis, Transformation. Essays Dedicated to Neil D. Jones [on occasion of his 60th birthday], volume 2566 of LNCS, pages 223–244. Springer, 2002. doi:10.1007/3-540-36377-7_11.
- [43] Peter W. O’Hearn. Incorrectness logic. Proceedings of POPL 2020, 4:10:1–10:32, 2020. doi:10.1145/3371078.
- [44] Francesco Ranzato. On the completeness of model checking. In Proceedings of ESOP 2001, volume 2028 of LNCS, pages 137–154. Springer, 2001. doi:10.1007/3-540-45309-1_10.
- [45] Francesco Ranzato and Francesco Tapparo. Making abstract model checking strongly preserving. In Proceedings of SAS 2002, volume 2477 of LNCS, pages 411–427. Springer, 2002. doi:10.1007/3-540-45789-5_29.
- [46] Francesco Ranzato and Francesco Tapparo. Generalized strong preservation by abstract interpretation. Journal of Logic and Computation, 17(1):157–197, 2007. doi:10.1093/LOGCOM/EXL035.
- [47] David Schmidt. Binary relations for abstraction and refinement. Technical report, Kansas State University, 2001.
- [48] David A. Schmidt. Data flow analysis is model checking of abstract interpretations. In Proceedings of POPL 1998, pages 38–48. ACM, 1998. doi:10.1145/268946.268950.
- [49] David A. Schmidt and Bernhard Steffen. Program analysis as model checking of abstract interpretations. In Proceedings of SAS 1998, volume 1503 of LNCS, pages 351–380. Springer, 1998. doi:10.1007/3-540-49727-7_22.
- [50] Sharon Shoham and Orna Grumberg. Monotonic abstraction-refinement for CTL. In Proceedings of TACAS 2004, volume 2988 of LNCS, pages 546–560. Springer, 2004. doi:10.1007/978-3-540-24730-2_40.
- [51] Bernhard Steffen. Data flow analysis as model checking. In Proceedings of TACS 1991, volume 526 of LNCS, pages 346–365. Springer, 1991. doi:10.1007/3-540-54415-1_54.
- [52] Bernhard Steffen. Generating data flow analysis algorithms from modal specifications. Science of Computer Programming, 21(2):115–139, 1993. doi:10.1016/0167-6423(93)90003-8.
- [53] Colin Stirling and David Walker. Local model checking in the modal mu-calculus. In Proceedings of TAPSOFT 1989, volume 351 of LNCS, pages 369–383. Springer, 1989. doi:10.1007/3-540-50939-9_144.
- [54] Pierre Wolper. Temporal logic can be more expressive. Information and Control, 56(1/2):72–99, 1983. doi:10.1016/S0019-9958(83)80051-5.
- [55] Fuyuan Zhang, Flemming Nielson, and Hanne Riis Nielson. Model checking as static analysis: Revisited. In Proceedings of IFM 2012, volume 7321 of LNCS, pages 99–112. Springer, 2012. doi:10.1007/978-3-642-30729-4_8.
