1. Introduction
Ranging from commodity devices to business or safety critical environments, digital systems have proliferated into most aspects of our daily lives. Moreover, thanks to Moore’s law and the advent of high-level synthesis, contemporary hardware designs often comprise an extremely high level of complexity. As a direct consequence, design verification has become one of the most relevant aspects of the design and production flow. In such a scenario, guaranteeing the correct behavior of digital systems, with respect to their specification, is becoming an ever more pressing need for manufacturers [
1]. The increasing complexity of hardware designs, together with the demand for short development cycles imposed by ever evolving markets, makes the delivery of defect-free systems an extremely challenging task. This is particularly true when considering sequential designs, in which the behavior of the system depends not only on the inputs applied at a given time but also on the state the system finds itself in. Modern systems are characterized by the presence of several million elements, those being transistors, logic gates, memory elements or other things. In such a scenario, design verification can represent one of the most time consuming, yet necessary, activities to be performed, with reports purporting it in the range between 40% and 70% of the entire cycle’s endeavor [
2]. Oftentimes, the usual testing techniques are not enough to prove the correctness of a whole system in a timely fashion, and further problems arise when taking into account the issue of transferring theoretical results to industrial practice [
3].
Traditionally, hardware designs are verified through
simulation. In simulation, a model of the system is solicited by a set of stimuli while the resulting behavior is checked against the expected behavior. Simulation is scalable, being applicable to designs of virtually any size, but is also costly and incomplete. In fact, it is often unfeasible to completely cover the behaviors of a realistic design through simulation. The incompleteness of simulation is often aggravated by the increasing complexity of hardware designs, which not only increases the number of behaviors to check but may also introduce corner cases difficult to cover. Starting from the late 1980s,
formal hardware verification has become an attractive approach to overcome the coverage limitations of simulation. Formal verification is the use of the formal methods of mathematics and logic to prove (or disprove) the correctness of a design with respect to a given formal specification of its expected behavior. During the last two decades, research in the field of formal verification has led to the development of many techniques. Such techniques can be subdivided into three main approaches to formal verification:
theorem proving [
4,
5],
equivalence checking [
6] and
model checking [
7,
8].
Model checking is the most widely used formal verification approach for sequential hardware designs. In model checking, a model of the design and a formalized representation of its specification are formulated using some mathematically precise and unambiguous language. Then, an algorithmic procedure automatically checks whether or not the model meets the formal specification. Such a procedure exhaustively traverses the modeled behaviors of the system and either confirms that the system behaves correctly or produces a trace that demonstrates a violating behavior (called a counterexample). The main advantages of model checking are its fully automated nature and its ability to produce counterexamples. Usually, the design to be verified is modeled as a transition system, comprising states and transitions between states, and the specification is formalized by writing temporal logic properties. Invariant verification is a particular model checking task in which the system specification is described as an invariant property that must hold true in every reachable state of the model.
From an algorithmic standpoint, in the beginning, model checking was based on explicit state enumeration; thus, its practical application was severely hindered by mere state space representation problems. The introduction of BDD-based representation [
9] was the turning point for model checking applicability to industrial-level scenarios. Despite the huge impact of such an approach to model checking, BDD-based representations still suffered from unpredictable memory requirements and, thus, additional paths of research opened up in order to overcome such limits, such as the introduction of SAT-based approaches.
Today, model checking can exploit explicit state enumeration or symbolic state enumeration, via BDD- or SAT-based representations. Furthermore, solutions based on automatic test pattern generations are admissible. Each of these, in turn, has led to a number of distinct model checking algorithms and techniques.
Up until today, there is not a concrete winner among all the available techniques. The most reliable approach is obtained from running in parallel several of these algorithms, exploiting multi-core environments, and halting verification as soon as one of the engines has found a solution to the verification problem at hand [
10,
11].
Complementary to the verification phase itself, there is then the additional problem of certifying checkers’ results, in order to better support their acquisition in complete design cycles scenarios [
12,
13].
A recent trend in hardware model checking is to exploit the ability of SMT solvers to perform word-level reasoning based on bit-vectors. This trend is demonstrated by the introduction of word-level tracks in recent editions of the Hardware Model Checking Competition [
14]. However, word-level model checking shines for problems with memory modeled with arrays; bit-level solvers are currently the de facto standard in the industry and prove to be still superior on many word-level designs after bit-blasting [
15].
This paper (part of the contents of this paper are a redacted version of the introductory chapters of the PhD thesis of two of its authors, Marco Palena [
16] and Paolo Pasini [
17], which have not been published before besides diffusion within the Politecnico di Torino and the respective thesis defense committees) describes the most relevant algorithms and techniques targeting explicitly bit-level SAT-based hardware model checking, in a formal and theoretically sound fashion. A description of complementary topics and a broader overview of the vast field of model checking and satisfiability is provided in [
18,
19]. A description of topics concerning model checking, with additional examples and applications, is provided in [
8]. Complementary to previous works, a specific focus on the design and verification of cyber-physical systems is provided in [
20].
Outline
The rest of the paper is organized as follows:
In
Section 2, we provide some preliminary notions with the purpose of presenting the adopted notation and terminology and make this work self-contained. In particular, we first provide some general concepts from the field of logic and computer science and then we discuss in more depth the necessary concept to contextualize model checking in detail.
In
Section 8, we present a practical evaluation of model checking algorithms over industrial-level benchmarks.
In
Section 9, we summarize the current work and provide some insights concerning future developments in the field.
2. Background and Notation
In this section, we introduce some notions needed to understand the rest of the paper. In particular, we provide some basic concepts and definitions from the fields of logic and computer science relevant to the topics at hand.
2.1. Mathematical Logic
Model checking aims at verifying whether a finite-state model of a system meets a given specification. In order to solve such a problem algorithmically, both the model of the system and its specification need to be expressed in some precise mathematical language. The fields of mathematical logic and formal language theory provide us the tools we need to reason about the system states in a symbolical and rigorous manner. Mathematical logic is the systematic study of reasoning. By reasoning, we intend the abstract capability to provide
arguments supporting the fact that a given statement, called the
conclusion, follows from some other statements, called the
premises. The steps through which conclusions are reached from premises are termed
inferences. Mathematical logic relies on
formal languages in order to provide a symbolic representation of abstract concepts, like statements about the model of the system we are interested to reason about, that can then be manipulated through formal, mathematical processes. We will rely on common concepts stemming from logic, and we will specifically introduce and define just the ones that are more relevant to this work. We refer the interested reader to [
21,
22] for a comprehensive exposition of those subjects.
2.2. Formal Languages
A formal language is a mathematical object that describes the syntax of a set of finite
strings of
symbols. A formal language is a purely syntactic tool and can be completely defined without making any reference to an interpretation for its symbols. In the following, we provide some basic notions from the field of
formal language theory (we refer the interested reader to [
23] for an more in depth discussion on the subject).
Definition 1 (Alphabet and Words). An alphabet Σ is any non-empty finite set of symbols. A word over Σ is any finite or infinite string of symbols in Σ. The set of all finite words over Σ is denoted by (called the Kleene closure of Σ).
Definition 2 (Formal Languages). Given an alphabet Σ, a formal language over Σ is any set of finite words over Σ, i.e., .
A formal language
is often described by a set of rules that determine how its words are formed (
rules of formation). Many formalisms can be used to describe the rules of formation of a formal language, such as formal grammars, regular expressions and automata [
23].
Definition 3 (Well-formed Formulas). Given a formal language over Σ, a word is said to be a well-formed formula of , often abbreviated with wff, iff .
Note that a formal language can be identified with the set of its well-formed formulas. Throughout the rest of this paper, we simply use the term formula to refer to a well-formed formula of a given formal language.
Formal languages are entirely syntactic in nature but may be given interpretations that provide meaning to their symbols and sentences. Given a formal language , from the semantic standpoint, the symbols of may be subdivided into logical symbols and non-logical symbols.
Definition 4 (Logical Symbols). A symbol of a formal language is said to be a logical symbol if it always has the same meaning, independently from the language interpretation.
Examples of logical symbols in the context of propositional and first-order logic are logical connectives (¬, ∧, ∨, etc.), quantifiers (∀, ∃, etc.) and the equality predicate (=).
Definition 5 (Non-logical Symbols and Signature). A symbol of a formal language is said to be a non-logical symbol if it has a meaning only when one is assigned to it by means of a language interpretation. Given a formal language , its signature σ is defined as the set of its non-logical symbols.
Note that non-logical symbols may have different meanings under different language interpretations. Examples of non-logical symbols in the context of propositional and first-order logic are variables and symbols for constants, function and relation.
A fundamental problem in formal language theory is that of determining the membership of a given word in a formal language.
Definition 6 (Membership Problem). Given a formal language and a word , the membership problem is the problem to determine whether , i.e., whether w is a wff of .
As we show later in
Section 2.6, each problem in the important computational class of
decision problems can be represented as a membership problem for a formal language. SAT-based model checking algorithms encode state reachability problems, defined on a model of the system, as instances of a particular decision problem known as Boolean Satisfiability (SAT).
2.3. Logical Systems
A fundamental concept in mathematical logic is that of logical consequence, describing the relationship between statements that hold true when one statement, called the conclusion, logically follows from one or more other statements, called the premises. Historically, the concept of logical consequence has been studied from two different but interrelated perspectives: syntactic and semantic.
Proof theory is the branch of logic that studies logical consequence from the syntactic standpoint. The formalism of formal systems is used to model deductions (a deduction is a kind of inference that is always valid, i.e., its conclusion is always a logical consequence of its premises) as syntactical transformations (inference rules) applied to strings of symbols (formulas). In this context, the concept of logical consequence is related to the ability to derive a proof, that is, a sequence of syntactic transformations that allow us to derive the conclusion from the premises.
Model theory is the branch of logic that studies logical consequence from the semantic standpoint. Semantics is about associating a meaning with the well-formed formulas of some formal language. Formulas are given a meaning by relating their constituents to elements of the domain of discourse by means of an interpretation. Given an interpretation of the symbols of a formal language, each formula can be related to the concept of truth based on whether or not its meaning holds true in the domain of discourse, i.e., the world we are interested to reason about. The set of all possible interpretations of a formal language define a formal semantic for that language. In this context, the concept of logical consequence is related to whether or not a conclusion would be evaluated as true under all the possible interpretations that evaluate the premises as true.
Even if the syntactic and semantic notions of logical consequence have different definitions, the concepts from the two branches of logic are systematically related. We give the following definitions.
Definition 7 (Logical System). Given a formal language , a logical system (or logic) for is defined as a pair , consisting of a formal system and a formal semantics for .
Definition 8 (Soundness and Completeness). Given a formal language , a logical system for is sound iff every formula that can be derived from is valid according to . A logical system is complete iff every formula that is valid according to can be derived from .
Therefore, in a sound and complete logical system the concepts of semantic and syntactic logical consequence coincide. The same is true for the semantic and syntactic versions of validity, consistency, necessity and impossibility.
2.4. Propositional Logic
Propositional logic (or
Boolean logic) is a sound and complete logical system concerned with the study of propositions. A
proposition is an abstract entity bearing a truth value that is expressed as a statement on a domain of discourse. Boolean logic considers (complex) propositions to be composed of
atomic propositions connected by means of
logical operators. Atomic propositions are propositions whose structure cannot be further decomposed in terms of logical operators. Later, in
Section 2.7, we will use Boolean logic to provide a symbolical representation of hardware-derived state transition systems at the bit level.
2.4.1. Syntax of Propositional Logic
From the syntactic standpoint, the language of propositional logic consists of a set of non-logical symbols called propositional variables and a set of logical symbols, comprising logical connectives (¬, ∧ and ∨) and logical constants (⊤ and ⊥).
Definition 9 (Syntax of Propositional Formulas). Given a set of propositional variables , the syntax of propositional formulas is defined inductively as follows:
⊤ and ⊥ are propositional formulas.
Each is a propositional formula.
Given F, a propositional formula, is a propositional formula.
Given and , propositional formula is a propositional formula.
Given and , propositional formula is a propositional formula.
Note that ⊥ and ∨ can be omitted from Definition 9 without losing expressiveness as they can be easily derived from ⊤, ¬ and ∧. Parentheses “(” and “)” can be used to improve the readability of formulas. We also provide the following definitions about propositional formulas.
Definition 10 (Atomic Formulas). An atomic formula is a propositional formula consisting of a propositional variable only.
Definition 11 (Support)
. Given a propositional formula F, we call support of F, denoted by , the set of propositional variables occurring in F. Accordingly, given a set of propositional formulas Φ, we call support of Φ, denoted by , the set of propositional variables occurring in at least one formula of Φ: 2.4.2. Semantics of Propositional Logic
Intuitively, from the semantic point of view, propositional variables represent atomic propositions, logical constants represent special propositions that are either always true (⊤) or always false ( and logical connectives represent standard Boolean functions such as logical negation (¬), logical conjunction (∧) and logical disjunction (∨).
Each propositional variable is interpreted as an atomic proposition about the domain of discourse which can either be true or false. Such an interpretation is described by means of a truth assignment defined as follows.
Definition 12 (Truth Assignments). Given a set of propositional variables , a truth assignment is a function mapping each propositional variable to a truth value in .
Note that, from the model-theoretic perspective, truth assignments can be seen as equivalent representations of structures along with a definition of truth. Since the only non-logical symbols of propositional logic are propositional variables, a structure for the propositional language is an interpretation of those variables as atomic propositions on the domain of discourse. A definition of truth then maps each atomic proposition to a truth value. The composition of the two is equivalent to a truth assignment.
Definition 13 (Complete or Partial Truth Assignments). Given a propositional formula F, a complete truth assignment for F is a function assigning a truth value to each variable of F. A partial truth assignment for F is a function assigning a truth value to a subset A of the variables of F.
Each logical connective is given a
truth-functional interpretation, mapping it to a specific
Boolean function. Logical connectives are therefore thought as having a certain
arity, according to the Boolean function they represent: logical conjunction and disjunction are binary connectives whereas negation is a unary connective. Under its truth-functional interpretation, each logical connective of arity
n corresponds to a Boolean function
mapping the truth value of its operands to the truth value of its result. The truth-functional interpretation of logical connectives is usually described by means of truth tables. Additional logical connectives, representing other standard Boolean functions such as implication (→), bi-implication (↔) and exclusive disjunction (⊕), may be included in the language of propositional logic according to their usual semantics and and syntactic definition, following.
As a way of reducing the number of necessary parentheses, the following precedence order between logical operators is usually applied (from highest precedence to lowest precedence): ¬, ∧, ∨, →, ↔ and ⊕.
Each propositional formula, therefore, unambiguously represents a given Boolean function, which can be determined combining the function associated with its logical connectives according to the precedence order.
Definition 14 (Semantics of Propositional Logic). Given a set of propositional variables , a propositional formula F over and a truth assignment μ over with , we give the following inductive definition of when μ satisfies F (or equivalently, F evaluates to ⊤ under μ), denoted as :
and .
For each , iff .
iff .
iff and .
iff or .
The semantics of other logical connectives can easily be inferred from their truth tables. We provide the following useful definitions:
Definition 15 ((Propositional) Models). Given a propositional formula F, a truth assignment is a model (or satisfying assignment) of F iff .
Definition 16 ((Propositional or Boolean) Satisfiability). A propositional formula F is said to be satisfiable iff it has at least one model, i.e., there exists μ such that . Otherwise, F is said to be unsatisfiable.
Definition 17 ((Propositional) Consequence). Given a set of propositional formulas Φ and a propositional formula F such that , F is said to be a consequence of Φ iff every model of Φ can be restricted to a model for F, denoted as .
Definition 18 ((Propositional) Equivalence). Given two propositional formulas F and G such that , F is said to be equivalent to G iff every model of F is also a model of G and vice versa, denoted as .
Definition 19 ((Propositional) Validity). An argument from a set of propositional formulas Φ to a conclusion F is valid iff .
Definition 20 ((Propositional) Consistency). A set of propositional formulas Φ is consistent iff there is a complete truth assignment μ that is a model for every formula of Φ.
Definition 21 (Valid Propositional Formulas). A propositional formula F is said to be a valid (or a tautology), denoted as , iff every truth assignment over its variables is a model for it.
Definition 22 (Strength of Propositional Formulas). Given two propositional formulas F and G, if then F is said to be stronger than G and, conversely, G is said to be weaker than F. From the semantics of implication (→), it is clear that, if , then and, thus, F is stronger than G.
We also provide the following remarks about notation for models and truth assignment.
Notation 1 (Formulas as Set of Models). Given a propositional formula F, we denote with the set of all models of F. Any propositional formula F can be seen as a representation of its set of models .
Any truth assignment can be represented as a formula satisfied by it or the set of propositional variables it assigns to ⊤.
Notation 2 (Restriction of Models). Given a propositional formula F, a truth assignment , with can be restricted to a model of F iff its restriction .
Notation 3 (Truth Assignments as Formulas)
. A truth assignment μ over a set of propositional variables can be represented as the following propositional formula: Notation 4 (Truth Assignments as Sets of Propositional Variables)
. A truth assignment μ over a set of propositional variables can be represented by the following set of propositional variables:Vice versa, a set of propositional variables induces a truth assignment equal to the characteristic function of A, i.e.: Following Notation 4, the satisfaction relation for propositional logic (⊧) can be extended to sets of propositional variables: if and only if .
2.4.3. Conjunctive Normal Form
We provide the following definitions about propositional formulas.
Definition 23 (Literals, Clauses and Cubes). A literal is either an atomic formula or the negation of an atomic formula. A clause is a disjunction of literals, whereas a cube is a conjunction of literals.
Definition 24 (Conjunctive Normal Form). A formula F is said to be in Conjunctive Normal Form (CNF) if is is a conjunction of clauses.
For instance, a, b, c and d being propositional variables, a is an atomic formula, both and b are literals, is a clause, is a cube and is a CNF formula. Given a truth assignment is easy to see the following:
A literal is satisfied by iff .
A literal is satisfied by iff .
A clause is satisfied by iff for some .
A cube is satisfied by iff for each .
A CNF formula is satisfied by iff for each .
2.5. Boolean Functions
In this paper we are interested in verifying the properties of hardware digital systems. Such systems can be thought to be made from large assemblies of logic gates which, in turn, are simple electronic implementations of Boolean functions. As described in
Section 2.4, formulas of Propositional Logic can be used to represent Boolean functions and reason about them. In this section, we introduce some basic notions about Boolean functions.
Definition 25 (Boolean Function). A Boolean function is a function , where is the Boolean domain and identifies the arity of the function.
Definition 26 (Functions Monotone in a Variable). Given an n-ary Boolean function and a value , with , we say that f is monotone in the variable if . Thus, when f is monotone in , changing the value of from ⊥ to ⊤ cannot change the value of f from ⊤ to ⊥. The definition here provided of monotonicity in a given variable is also known as unateness or positive monotonicity in that variable.
Definition 27 (Monotone Functions). A Boolean function f is monotone if it is monotone in each of its variables. Thus, changing the value of any of its variables from ⊥ to ⊤ cannot change the value of f from ⊤ to ⊥.
2.6. Decision Problems
In
Section 2.1, we have presented logic as a tool to formalize and reason about a world of interest, whereas in
Section 2.5 we have provided some background knowledge about commonly used models for representing combinational and sequential hardware circuits. Our aim is to use the tool of logic, and in particular Propositional Logic, to provide a formal representation of hardware sequential systems and reason about some of their properties. In particular, we are interested in asking certain questions about the formalized systems and having those questions answered by algorithmic procedures. We are, thus, interested in solving some computational problems arising from those questions, which typically belong to the class of
decision problems.
In this section we provide an overview of decision problems and their properties and we present Boolean Satisfiability (SAT), a fundamental decision problem in computer science of particular interest in the context of this paper.
Definition 28 (Decision Problems and Instances). A decision problem is any arbitrary question admitting a YES or NO answer over an infinite set of inputs. An instance of a decision problem is a particular input for . We distinguish between Yes-instances, instances for which gives a Yes answer, and
No-instances, instances for which gives a No answer.
Traditionally, a decision problem is identified by its set of Yes-instances. Instances of a decision problem are usually encoded as strings over an alphabet . As a consequence, a decision problem is often defined as a formal language over that alphabet and can be formulated as an instance of the membership problem for .
Theorem 1 (Decision Problems as Membership Problems). Given a decision problem , determining whether the answer to a given instance is Yes is equivalent to determining whether an encoding of that instance over an alphabet Σ is in the corresponding language .
In order to solve a decision problem , we are interested in algorithms that terminate with a correct answer for every input of , as formalized by the following definitions.
Definition 29 (Soundness and Completeness of an Algorithm). An algorithm for a given decision problem is sound iff when it returns a YES answer the input is a YES-instance of . An algorithm for a given decision problem is complete iff it always terminates and it returns a YES answer when the input is a YES-instance of .
Unsound algorithms are rarely of practical interest. Incomplete algorithms may be effective in solving only Yes- or No-instances of a decision problem. Ideally, however, we would like to have an algorithm for a decision problem that is both sound and complete.
Definition 30 (Decision Procedure). A decision procedure is an algorithmic procedure that, given an instance of a decision problem , always terminates with a correct Yes or No answer.
Definition 31 (Decidability of a Decision Problem). A decision problem for which there exists a decision procedure is said to be decidable.
Decidability is an important property to determine whether a given problem may be tackled algorithmically. Many important problems are undecidable, such as the so-called Entscheidungsproblem asking for the validity of a first-order formula in the general case (proved undecidable by Church and Turing).
Sometimes, decision procedures are also asked to produce certificates as a way to prove that the results of their computation are correct.
Definition 32 (Certificates). A certificate is a string of symbols that can be used to prove the answer of a decision procedure on a given instance. We distinguish YES-certificates, produced by the algorithm to certify a YES answer, and NO-certificates, produced by the algorithm to certify a NO answer.
The typical decision problems we are interested in concern the satisfiability or validity of formulas in some logical system . Those two problems are interchangeable, as deciding the satisfiability of a formula can be seen as the negation of the decision problem to determine whether the formula is valid. Focusing on the validity problem, we can formulate such a problem as the membership problem of a formula to the language of logically valid formulas of (or the language theorems, supposing to be sound and complete).
In what follows, we assume to be both sound and complete. This is because we are mainly interested in decision problems over propositional logics, which are both sound and complete under the usual semantics and proof systems. Considering logical systems that are both sound and complete, we equate the problem of validity (checking whether a formula is a tautology in ) to the problem of derivability (checking whether the formula is a theorem in ).
Propositional (or Boolean) Satisfiability (SAT) is the problem to decide whether a given propositional formula is satisfiable, as defined in Definition 16.
Definition 33 (Boolean Satisfiability Problem). Given a propositional formula φ over the propositional variables V, SAT is the problem to determine whether . If that is the case, the formula φ is a Yes-instance of the problem and is said to be satisfiable (Sat). The model μ is a Yes-certificate for the problem on φ. Otherwise, the formula φ is a No-instance of the problem and is said to be unsatisfiable (Unsat).
SAT is a fundamental decision problem in computer science, important from both the theoretical and the practical perspective. From the theoretical standpoint, SAT plays a central role in computational complexity theory. From the practical standpoint, SAT can be used as a modeling framework to encode many computationally hard problems.
SAT is known to be a computationally hard problem: it is, in fact, a member of the NP-complete class of complexity [
24]. This briefly means that no algorithm is currently known that is able to solve all instances of SAT in a polynomial amount of time. Despite this theoretical limitation, the SAT problem is considered in many cases to be tractable, thanks to the fact that its instances often present some kind of structure arising from the application domain they originate from. Currently, state-of-the-art SAT solvers are able to handle SAT instances up to millions of variables and constraints.
Definition 34 (SAT-Solving Algorithm). A SAT-solving algorithm is a decision procedure to answer the SAT problem.
A
SAT solver is software that runs a SAT-solving algorithm, taking a propositional formula (usually in CNF) as input and determining whether or not such a formula can be satisfied by a truth assignment of its variables. SAT-solving algorithms are usually designed as search procedures over the space of truth assignments, following the highly influential DPLL [
25] algorithm. To give a better understanding of the subject at hand, Algorithm 1 highlights the top-level procedure of DPLL; a brief description follows as well as a partial example of the assignment’s space exploration.
Figure 1 depicts a search tree enumerating all the truth assignments, one for each leaf node, over three variables, taking into account
as a target formula. Given the visual representation, it is easy to see how looking for a satisfying assignment is equal to looking for a path, and hence a leaf node, that satisfies a given CNF. Furthermore, taking into account the tree topology and the leaf values, it is possible to identify simplifying steps that reduce the search space, e.g., neither
nor
can lead to satisfying assignments; thus, it is irrelevant to evaluate the role of variable
z given a partial assignment that reaches such a branch.
In order to evaluate the amount of work that the DPLL algorithm has to perform, a common notion used is that of the
termination tree, which evaluates the actual search tree considered during exploration.
Figure 2 depicts a partial termination tree taking into account the same example introduced in
Figure 1. Within a termination tree, one can find conflicts (✗) and valid (✓) assignments, as well as a trace for the conditioned CNF at each level of the search space.
Most modern state-of-the-art SAT solvers employs a SAT-solving algorithm called
Conflict-Driven Clause Learning (CDCL) [
26]. CDCL is based on
clause learning and
non-chronological backtracking in order to avoid repeated exploration of regions of the search space that do not lead to a satisfying assignment. During search, CDCL algorithms maintain a
trail of literals representing the current partial assignment. Under a given partial assignment, each clause loaded in the solver can be either
satisfied,
conflicts,
units or
unresolved. Clauses are satisfied if at least one of their literals is satisfied. If each literal in a clause is falsified, then the whole clause is a conflict. If all but one literals of the clause are falsified, then the clause is a unit. Otherwise the clause is unresolved. If a clause is a unit, its only non-falsified literal is implied by the current partial assignment; thus, its variable can be assigned so that the literal is satisfied.
Algorithm 1 Top-level procedure of the DPLL algorithm. |
Input: C a set of clauses. Output: res∈ {Sat, Unsat}.
- 1:
procedure DPLL(C) - 2:
while ∃ unit clause do - 3:
UnitPropagate(C,l) - 4:
while ∃ pure literal do - 5:
PureLiteralAssign(C,l) - 6:
if then - 7:
return Sat - 8:
if empty clause then - 9:
return Unsat - 10:
ChooseLiteral(C) - 11:
return Dpll or Dpll
|
The search starts by selecting a variable, using some suitable heuristic, and assigning it a truth value. This process is called
decision. After a decision has been made, some of the clauses loaded in the solver may have become conflicts or unit clauses. The solver looks up for unit clauses using efficient data structures, called
watch lists, in order to perform
Boolean Constraint Propagation (BCP). During BCP, the solver finds and assigns every clause that is a unit under the current partial assignment. Such a procedure iterates until either no more unit clauses can be found or the solver has found a conflict. In the first case, the solver proceeds with the next decision. In the second case, the solver analyzes the sequence of assignments that have led to the conflict, a process called
conflict analysis [
26]. The result of such an analysis is a
learned clause catching the causes of the conflict. Such a clause is added to the current formula in order to avoid future iterations to enter the region of the search space that led to the conflict (
learning). The algorithm, thus, performs non-chronological backtracking canceling enough of its latest decisions (even all of them) to leave such a region of space and then resume search on another region. Eventually, either a conflict is found when no decisions have been made, meaning that the problem at hand is
Unsat, or every variable has been assigned without incurring a conflict, meaning that the problem at hand is
Sat.
State-of-the-art SAT solvers are sophisticated artifacts of engineering that often include various techniques and heuristics to enhance their performance. Among such techniques, there are those to periodically
restart search in order to better explore the space [
27], simplifying the problem at hand either before starting searching for a solution or during search [
28] and periodically trimming the database of learned clauses.
In many applications, SAT solvers are required to answer a sequence of related calls. In order to preserve useful information about the problem at hand, maintained in the state of the solver, many SAT solvers expose an incremental interface. Incremental interfaces enable the user to load a formula in the solver, solve the corresponding SAT problem, then modify the formula and solve the related SAT problem without losing inferences or other useful information about the problem stored in the state. Between incremental calls, the formula can usually be modified by either specifying variable assumptions or adding or removing clauses.
Many modern SAT solvers can be instructed to provide a
refutation proof in the case a problem is declared to be
Unsat. Such a proof can be thought of as a
No-certificate that can be used by an independent checker to assess the correctness of the SAT solver’s answer. Refutation proofs are usually produced as either
resolution proofs [
29] or
clausal proofs [
30]. A resolution proof is a series of applications of the
resolution rule that derives the empty clause from the clauses of an unsatisfiable propositional formula.
Definition 35 (Binary Resolution Rule)
. Given two clauses and , the (binary) resolution rule is the inference rule: Modern SAT solvers are capable, without incurring too large an additional cost, to generate a resolution proof from unsatisfiable runs [
31]. Clausal proofs can be seen as logs of the sequence of clauses learned by the solver in the order in which they were learned. A resolution proof can be constructed starting from a clausal proof using BCP [
32]. Another common feature of modern SAT solvers is the extraction of
unsatisfiability cores. Given an
Unsat problem, an unsatisfiability core is a subset of the clauses of the original problem that is still unsatisfiable. The set of clauses in a resolution proof can be seen as an unsatisfiability core.
2.7. Model Checking
Model checking is an automated formal verification technique for determining whether a design meets a given specification. The behavior of the design is usually modeled using a transition system. The specification usually consists of a property (or a set of properties) expressed in a temporal logic.
Transition systems and temporal logics are discussed in detail in
Section 2.8 and
Section 2.9, respectively.
Section 2.10 formalizes the model checking problem as well as a particular sub-class of that problem, called invariant verification. In
Section 2.11, a way to symbolically represent transition systems is presented, whereas in
Section 2.12 the invariant verification problem is reduced to a reachability problem on such a symbolic representation. These concepts form the foundation for the discussion in the remaining sections of this paper, which will each focus on specific model checking algorithms and techniques.
2.8. Transition Systems
Transition systems are often used in computer science as models to describe the behavior of real-world systems. They can be seen as directed graphs, with nodes representing states and edges representing transitions. A state describes some unique configuration of information about a given system at a certain moment of its behavior. Transitions specify how the system can evolve from one state to another.
Definition 36 (Transition System)
. A transition system (also known in the literature as a Kripke structure [33]) is a tuple , where S is the set of states, is the set of initial states, is the transition relation, is a set of propositional variables representing atomic propositions and is a labeling function. For each state , the labeling function denotes the set of atomic propositions that hold in s. A transition system can be either finite or infinite, depending on whether or not it admits an infinite set of states (and consequently transitions). In this paper, we are interested in the model checking of bit-level hardware sequential circuits. Since the behavior of such systems can be modeled using finite transition systems, we restrict the discussion to those models. For this reason, we hereinafter use the term transition system as a shorthand for finite transition systems without risk of ambiguity.
Example 1. The sequential hardware system described in Figure 3a, representing a 2-bit synchronous counter that counts up to 2, can be modeled as the following transition system: States represent the four possible states of the counter, corresponding to the combined digital values of the two flip flops; represent the reset state of the system, in which the output of both flip flops is low, R indicates how the system will transition between states at each clock cycle and the labeling function L maps each state to a set of atomic propositions in each indicating that either or is high, respectively. The transition system is visualized in Figure 3b. We will use this system and its model as a running example in the rest of the section. Let be a transition system; we provide the following useful definitions.
Definition 37 (Transition). A transition in is a pair of states such that .
Definition 38 (Successor and Predecessor States). Given a pair of states , p is said to be a predecessor of s iff is a transition in . Vice versa, s is said to be a successor of p.
Definition 39 (Paths). A path in is any sequence of states of arbitrary (even infinite) length such that is a transition in for each . A path is said to be finite if ; otherwise, it is said to be infinite. We denote by the suffix of starting with the -th state of . We also denote by the -th state in .
Definition 40 (Initial Paths). An initial path in is any path such that .
Definition 41 (Exact and Bounded Reachability). A state is reachable in exactly k steps in iff a finite initial path of length such that exists. A state is reachable within k steps (or reachable bounded by k) in iff there is such that s is reachable in exactly i steps in .
Definition 42 (Reachability). A state is reachable in if it is reachable within an arbitrary (finite) number of steps in .
Definition 43 (Sets of Exactly Reachable and Sets of Bounded Reachable States)
. We denote with the set of states reachable in exactly i steps in . We denote with the set of states reachable within i steps in , i.e., Definition 44 (Reachability Diameter)
. We define the reachability diameter of to be the minimal number of steps required for reaching all reachable states in : Definition 45 (Set of Reachable States)
. We denote with the set of states reachable in where d is the reachability diameter of . When considering reachability, we use the term timeframe i, to denote what happens after i transitions from the initial states. It is trivial to prove that, for a finite-state transition system, there always exists a (finite) reachability diameter.
Example 2. Given the hardware design and its transition system described in Example 1, is both a path and an initial path, the set of reachable states is and the reachability diameter of the system is .
2.9. Temporal Logics
Temporal logics are extensions of classical logics that are used to represent, and reason about, statements qualified in terms of time. Both propositional and predicate logic can be extended to include temporal modalities. In this dissertation, we are only interested in Propositional Temporal Logics (PTLs), i.e., temporal logics obtained augmenting propositional logic with temporal operators. This is because they are the logics typically used to express the requirements for bit-level sequential circuits. Hereinafter, when referring to those logics, we will omit the prefix “propositional” for conciseness.
Different temporal logics, with different expressiveness, can be defined based on the temporal operators they use. The two temporal logics used the most in practice are Linear Temporal Logic (LTL) and Computation Tree Logic (CTL). LTL adopts a linear-time perspective, in which every moment in time is followed by a single successor moment. A possible behavior in LTL can, therefore, be seen as an infinite, ordered sequence of moments. CTL, instead, adopts a branching-time perspective, in which every moment in time may be followed by many alternative moments representing different courses of execution. A possible behavior in CTL can, therefore, be seen as an infinite, directed tree of moments. Neither of these logics is a subset of the other, as many temporal properties can be expressed only using one of either LTL or CTL.
The model-theoretic semantics usually given to temporal logics is defined in terms of paths and states of transition systems.
2.9.1. Linear Temporal Logic
Linear Temporal Logic (LTL) was introduced by Pnueli [
34] for the specification and verification of reactive systems. Formulas of LTL are constructed from a set of
propositional variables using the usual
logical connectives (negation ¬, conjunction ∧ and disjunction ∨) and some
temporal operators (“next time”),
(“eventually”),
(“always”) and
(“until”). LTL formulas are interpreted in terms of paths, i.e., sequences of states of a transition system. Their semantics is also extended to states and whole transition systems.
Definition 46 (Syntax of LTL Formulas). Given a set of propositional variables , the syntax of LTL formulas is defined inductively as follows.
Boolean constants ⊤ and ⊥ are LTL formulas.
Each is an LTL formula.
Given ψ, an LTL formula is an LTL formula.
Given and , LTL formula is an LTL formula.
Given and , LTL formula is an LTL formula.
Given ψ, an LTL formula is an LTL formula.
Given ψ, an LTL formula is an LTL formula.
Given ψ, an LTL formula is an LTL formula.
Given and , LTL formula is an LTL formula.
Note that ⊥ and ∨ can be omitted from Definition 46 without losing expressiveness as they can be easily derived from ⊤, ¬ and ∧. Similarly, and can also be omitted, as they can be derived from and as and . Furthermore, the syntax can be extended to other common Boolean operators by means of their usual definitions in Propositional Logic.
Example 3. Given the hardware design and its transition system described in Example 1, we can model the specification describing how the system will never reach a state in which the output of both flip flops is high as the following property in LTL logic: Intuitively, the semantics of the temporal operators of LTL is the following: holds at the current moment if holds at the next moment; holds at the current moment if there is a future moment at which holds; holds at the current moment if holds at the current moment and at every future moment; holds at the current moment if there is some future moment at which holds and holds at each moment until that future moment. Formally, the semantics of LTL formulas is defined with respect to paths, states and transition systems, as follows.
Definition 47 (Semantics of LTL Formulas with Respect to Paths). Given a transition system , let be an infinite path in and let ψ be an LTL formula over . We give the following inductive definition of when satisfies ψ, denoted as :
and .
For each , iff .
iff .
iff and .
iff or .
iff .
iff for some .
iff for every .
iff for some and for every .
Other common Boolean operators have semantics that can easily be inferred from the semantics of ¬, ∧ or ∨.
Definition 48 (Semantics of LTL Formulas with Respect to States). Given a transition system , let be a state and let ψ be an LTL formula over . We say that s satisfies ψ, denoted as , iff for each infinite path with .
Definition 49 (Semantics of LTL Formulas with Respect to Transition Systems). Given a transition system , let ψ be an LTL formula over . We say that satisfies ψ, denoted as , iff for each .
The interpretation of an LTL formula in terms of a state s requires that all the computations starting from s satisfy , in order for s to satisfy . In LTL semantics, therefore, there is an implicit universal quantification over all computations when determining whether a state satisfies a formula. Thus, LTL can be used to express properties holding for every path from a state but it cannot express properties holding only for some of such paths.
2.9.2. Computation Tree Logic
Computation Tree Logic (CTL) was introduced by Clarke et al. [
35] to overcome the semantics limitation of LTL. In CTL, two kinds of formulas are distinguished:
state formulas and
path formulas. CTL also introduces two new temporal operators, called
path quantifiers to allow the specification of properties for some or all the paths starting from a state. These quantifiers are
(“for all paths”) and
(“there exists a path”). CTL formulas are interpreted in terms of trees of paths, i.e., possible alternative paths of a transition system. Their semantics is also extended to states and whole transition systems.
Definition 50 (Syntax of CTL Formulas). Given a set of propositional variables , the syntax of CTL state formulas is defined inductively as follows.
Boolean constants ⊤ and ⊥ are CTL state formulas.
Each is a CTL state formula.
Given ψ, a CTL state formula is a CTL state formula.
Given and , CTL state formula is a CTL state formula.
Given and , CTL state formula is a CTL state formula.
Given φ, a CTL path formula is a CTL state formula.
Given φ, a CTL path formula is a CTL state formula.
The syntax of CTL path formulas is defined inductively as follows:
Given ψ, a CTL state formula is a CTL path formula.
Given ψ, a CTL state formula is a CTL path formula.
Given ψ, a CTL state formula is a CTL path formula.
Given and , CTL state formula is a CTL path formula.
Note that Definition 50 can be restricted to exclude ⊤, ∨, and , without losing expressiveness in the same way as Definition 46. Syntax can also be expanded to other common Boolean operators as usual.
Example 4. Given the hardware design and its transition system described in Example 1, we can model the specification describing how the system will never reach a state in which the output of both flip flops is high as the following property in CTL logic: Intuitively, state formulas describe properties of states, whereas path formulas describe properties of (infinite) paths. Path formulas can be transformed into state formulas by prefixing them with a path quantifier. Note that path quantifiers must immediately precede temporal operators in order for the resulting state formula to be well formed. Intuitively, the semantics of path quantifiers is the following: holds at the current state if holds for all paths starting at the current state; holds at the current state if holds for some paths starting at the current state. Formally, the semantics of CTL formulas is defined with respect to paths, states and transition systems, by means of two satisfaction relations: one for state formulas and the other for path formulas.
Definition 51 (Semantics of CTL Path Formulas with Respect to Paths). Given a transition system , let be an infinite path in and let φ be a CTL path formula over . We give the following inductive definition of when satisfies φ, denoted as :
iff .
iff for some .
iff for every .
iff for some and for every .
Definition 52 (Semantics of CTL State Formulas with Respect to States). Given a transition system , let be a state and let ψ be a CTL state formula over . We give the following inductive definition of when s satisfies ψ, denoted as :
and .
For each , iff .
iff .
iff and .
iff or .
iff for some infinite initial path starting in s.
iff for each infinite initial path starting in s.
Definition 53 (Semantics of CTL State Formulas with Respect to Transition Systems). Given a transition system , let be a state and let ψ be a CTL state formula over . We say that satisfies ψ, denoted as , iff for each .
2.9.3. Temporal Properties
Definition 54 (Temporal Properties). Given a transition system , a temporal property is any property ψ, expressed in a temporal logic, that specifies the admissible (or desired) behaviors of .
Temporal properties typically fall under one of two main categories: safety properties and liveness properties, defined informally as follows.
Definition 55 (Safety Properties). Given a transition system , a safety property asserts that some (undesired) conditions never happen for (“nothing bad ever happens”).
Definition 56 (Liveness Properties). Given a transition system , a liveness property asserts that some (desired) conditions will eventually happen for (“something good eventually happens”).
Typical examples of safety properties include deadlock freedom and mutual exclusion, whereas a typical example of a liveness property is starvation freedom. Both safety and liveness properties can be expressed using LTL and CTL. The main difference between the two categories of properties is that safety properties can be violated by finite computations of a system, whereas liveness properties can only be violated by infinite computations of a system. In practical applications, safety properties are prevalent. The temporal properties defined in Examples 3 and 4 are safety properties.
We distinguish a kind of safety properties of particular interest, called invariant properties, defined as follows:
Definition 57 (Invariant Properties). Given a transition system , an invariant property asserts that the condition described by a given propositional formula φ over , called an invariant condition, always happen for (“some invariant condition φ always happens”).
Invariant properties can be described in LTL as formulas with the invariant condition a formula over . Similarly, invariant properties in CTL take the form with the invariant condition a formula over .
Example 5. The corresponding invariant properties of the safety properties defined in Examples 3 and 4 are as follows:in LTL and CTL, respectively. Properties management [
36,
37] goes beyond the scope of this paper, but it is still a topic as relevant as the proper choice of the actual model checking algorithm to be used given a specific scenario.
2.10. Model Checking Problem
Let be a transition system; the model checking problem can be formalized as follows:
Definition 58 (Model Checking Problem). Given a transition system and a temporal property ψ over , the decision problem to check whether is called a model checking problem. In the case , the model checking procedure is required to provide a counterexample.
Definition 59 (Counterexample). Given a transition system and a temporal property ψ over such that , a counterexample to ψ for is any initial path of such that .
Model checking is therefore a decision problem, as defined in
Section 2.6, that admits a
Yes-answer (
holds for
) or a
No-answer (
does not hold for
).
Definition 60 (Model Checking Algorithm). A model checking algorithm, or model checker, is any decision procedure able to solve a model checking problem.
When a model checking algorithm terminates with a No-answer, it must also emit a No-certificate in the form of a counterexample. Model checking algorithms must systematically traverse all behaviors of the system in order to either confirm that the property holds or provide a counterexample. A model checking algorithm may have either or both of the following qualities.
Definition 61 (Completeness and Soundness (of a Model Checking Algorithm)). A model checking algorithm is said to be complete iff, given a transition system and a property ψ, it is able to either provide a counterexample of ψ for or detect the absence of counterexamples of any length. A model checking algorithm is said to be sound iff, given a transition system and a property ψ, it provides a counterexample of ψ for only when and it proves the absence of counterexamples of any length only when .
Different classes of model checking problems can be distinguished, depending on the category of temporal properties being checked. In this paper, we are interested only in the model checking of invariant properties, also called invariant verification problems, which we show can be solved via reachability analysis on the transition system under verification.
Definition 62 (Invariant Verification Problem). Given a transition system and an invariant property ψ over , the invariant verification problem of ψ for is the model checking problem to decide or to provide a counterexample.
Definition 63 (Invariant). Given a transition system and an invariant property ψ over , if , then the invariant condition φ of ψ is a propositional formula over and is said to be an invariant of .
The invariant verification problem can be reduced to a reachability problem over , as follows.
Theorem 2 (Reduction of Invariant Verification to Reachability). Given a transition system and an invariant property ψ over , let φ over be the invariant condition of ψ; then, the invariant verification problem can be reduced to the problem to check whether a state such that is reachable in . If that is the case, and any initial path to s is a counterexample for the invariant verification problem. Otherwise, . Such a problem is called the reachability problem of in .
Therefore, the invariant verification problem can be simply solved by means of a procedure that traverses the reachable state space of and checks whether or not holds for every traversed state. Since the state space is finite, the procedure eventually terminates either providing a counterexample or confirming as an invariant of . In practice, such a state space is usually too large to be explicitly traversed. State-of-the-art model checking methods rely on a symbolic representation of the system instead.
2.11. Symbolic Representation of Transition Systems
The model checking formulation provided in the previous subsection relies on an explicit representation of states and transitions. Such an explicit representation is not adequate to handle large state spaces. In symbolic model checking, the (explicit) transition system is converted into a more concise, implicit representation based on propositional formulas, called symbolic representation. Using a symbolic representation, model checking algorithms can traverse the state space of the system more efficiently, by manipulating sets of states and transitions directly, instead of being forced to operate on one state or transition at a time. In addition, since the symbolic representation relies on propositional formulas, symbolic model checking algorithms can leverage well-developed automatic techniques for manipulating such formulas such as BDDs or SAT solvers.
In this Subsection we show how to encode a transition system into its symbolic representation and how to formulate the invariant verification problem on such a representation. Given a transition system , to obtain a symbolic representation of , we must define how to encode each of its constituents into propositional formulas.
2.11.1. Symbolic Representation of States
In order to symbolically represent the set of states S of a transition system , we introduce a set of propositional variables V, called state variables, with . Given a transition system and a set of state variables V, we give the following definitions.
Definition 64 (Encoding Function). An encoding function over V is an injective function mapping states to complete truth assignments over V.
Definition 65 (Encoding of States). A state is encoded as a complete truth assignment over V according to an encoding function ϕ. The complete truth assignment is called encoding of s over V.
Note that is bijective if and only if . Otherwise, some pseudo-state representations are introduced in the symbolic representation of S by encoding. Such pseudo-states can be disregarded and treated as unreachable states of .
Propositional formulas over V are used to represent sets of states. Any propositional formula over V represents the set of states such that, for each state , its corresponding encoding over V satisfies , i.e., . Given an encoding function over V, and letting be a state of , many logically equivalent propositional formulas over V can be used to represent q. We define one example of such a formula as follows.
Definition 66 (Characteristic Formula for States)
. The characteristic formula of q is the propositional formula over V such thatwhere . Note that is a cube and it is satisfied only by the complete truth assignment encoding q.
Let be a set of states; many logically equivalent propositional formulas over V can be used to represent Q. We define one example of such a formula as follows.
Definition 67 (Characteristic Formula for Set of States)
. The characteristic formula of Q is the propositional formula over V such that Note that is satisfied only by the complete truth assignments encoding states .
With abuse of notation, hereinafter, we make no distinction among the following concepts:
A state , any propositional formula that is logically equivalent to its characteristic formula and the only model for such formula .
A set of states , any propositional formula that is logically equivalent to its characteristic formula and the set of models for such formula .
Initial states of can be represented symbolically by a propositional formula such that the encodings over V of each initial state satisfy .
Example 6. Given the hardware design and its transition system described in Example 1, the states will be encoded using state variables by the encoding function defined as follows: Individual states will be represented symbolically by their characteristic formulas (cubes): The set of initial states will be encoded as the following formula: 2.11.2. Symbolic Representation of Transitions
In order to symbolically represent transitions (a binary relation on states), we consider two sets of state variables: one to represent the starting state, called present state, and another to represent the final state, called next state, of a transition. The set V is used to encode present states while its primed counterpart is used to encode next states. The same primed notation is used to denote the set of next states and any propositional formula in which the present state variables have been renamed as the next state variables. Furthermore, we use the superscript notation to denote the set of state variables encoding states at timeframe i. The same superscript notation is used accordingly to denote the sets of states after i transitions and any propositional formula referring to timeframe i. We also use the notation as a shorthand for a truth assignment over .
Definition 68 (Next State Encoding Function). Given a transition system , a set of present state variables V and a set of next state variables , let ϕ be an encoding function over S; we define the next state encoding function as .
We give the following definitions.
Definition 69 (Encoding of Transitions). A transition is encoded as a complete truth assignment over . The complete truth assignment is called an encoding of over .
Propositional formulas over are used to represent sets of transitions. Any propositional formula over represents the set of transitions such that, for each , its corresponding encoding over satisfies , i.e., . Given the encoding function and a next state encoding function , and letting be a transition of , many logically equivalent propositional formulas over can be used to represent . We define one example of such a formula as follows.
Definition 70 (Characteristic Formula for Transitions)
. The characteristic formula of is the propositional formula over such thatwhere . Note that is satisfied only by the complete truth assignment encoding .
Let be a set of transitions of . Many logically equivalent propositional formulas over can be used to represent Z. We define one example of such a formula as follows.
Definition 71 (Characteristic Formula for Sets of Transitions)
. The characteristic formula of Z is the propositional formula over such that Note that over is satisfied only by the complete truth assignments over encoding transitions .
With abuse of notation, hereinafter, we make no distinction among the following concepts:
A transition , any propositional formula that is logically equivalent to its characteristic formula and the only model for such formula .
A set of transitions , any propositional formula that is logically equivalent to its characteristic formula and the set of models for such formula .
The transition relation R is, thus, encoded as a propositional formula T over such that the encoding over of each transition satisfies T.
Example 7. Given the hardware design and its transition system described in Example 1, the transition relation R will be encoded as the propositional formula T over : 2.11.3. Symbolic Representation of the Labeling Function
In order to symbolically represent the labeling function L and the set of propositional variables , first, we need to define the reverse labeling function , mapping each propositional variable to the set of states in which holds.
Definition 72 (Reverse Labeling)
. The reverse labeling function of a transition system is the function such that, for each , Each propositional variable is mapped to a set of states by . For each propositional variable , the set of states can be represented as its characteristic formula over V. The labeling function L is therefore symbolically represented as a set of characteristic formulas over V, one for each . A propositional variable is then symbolically represented by a propositional formula encoding the set of states for which holds.
Definition 73 (Characteristic Formula of Atomic Propositions). The characteristic formula of an atomic proposition represented by the propositional variable is the propositional formula .
Note that is satisfied only by those states .
Example 8. Given the hardware design and its transition system described in Example 1, the atomic propositions will be encoded as follows by the reverse labeling function : 2.11.4. Symbolic Representation of Transition Systems
Given a transition system , we define a symbolic representation of the whole system as follows.
Definition 74 (Symbolic Transition System). A symbolic transition system encoding is the tuple , where
V is a set of propositional state variables, with , encoding the states S of .
is a propositional formula over V representing the initial states of .
T is a propositional formula over representing the transition relation R of .
All definitions provided in
Section 2.8 about reachability on transition systems naturally extends to their symbolic counterparts.
Example 9. Given the hardware design and its transition system described in Example 1, the overall encoding of the transition system will be the tuple defined as follows: 2.11.5. Symbolic Representation of Invariant Properties
Given a transition system and an invariant property with invariant condition over , we define a symbolic representation of the invariant condition as follows.
Definition 75 (Symbolic Invariant Property)
. A symbolic invariant property encoding φ is the propositional formula P over V such thatfor each , i.e., the formula obtained by substituting each propositional variable of φ with its characteristic formula over V. Example 10. Given the hardware design and its transition system described in Example 1, the invariant property ψ defined in Example 5 will have an invariant condition φ encoded as follows: 2.12. Symbolic Invariant Verification
As shown in
Section 2.10, the invariant verification problem can be reduced to a problem of reachability in a transition system. Reachability in a transition system (or equally invariant verification) can, in turn, be reduced to reachability in a corresponding symbolic transition system, as follows.
Theorem 3 (Symbolic Invariant Verification). Given a transition system and an invariant property ψ with invariant condition φ over , the reachability problem of in can be reduced to the reachability problem of in where is a symbolic transition system encoding and P a symbolic invariant property encoding φ.
In this paper, we are interested in algorithms for symbolic invariant verification. Therefore, with abuse of notation, we hereinafter use the terms “transition system”, “reachability”, “invariant property” and “invariant verification” to denote their symbolic counterparts.
Notation 5 (Target and Bad States). Given a transition system and an invariant property P, with the notion of target we identify set of states corresponding to . States (or sets of states) which are part of the target, or may reach the target, are called bad states.
Given a transition system and an invariant property P, we provide the following useful definitions for invariant verification algorithms.
Definition 76 (Path Formula)
. A path formula of length , starting from timeframe i and reaching timeframe j, is the propositional formula over : Definition 77 (Initial Path Formula)
. An initial path formula of length k is the following propositional formula: Intuitively, a path formula encodes all paths of length starting at timeframe i in . An initial path formula encodes all paths of length k starting from the initial states in . An initial path formula can thus be used to represent the set of states that can be reached from the initial states in exactly k steps, in .
Definition 78 (Bad Cone)
. A bad cone of length from timeframe i to timeframe j is the propositional formula over : A bad cone encodes all paths starting at timeframe i that can reach the target in at most steps and, thus, it represents the set of bad states that are backward reachable in at most k steps from the target.
Using initial path formulas the reachability problem of in can be reduced to Boolean satisfiability as follows.
Theorem 4 (Reduction of Reachability to Satisfiability)
. Given a transition system and a property P over V, the reachability of can be reduced to the problem of finding a bound
such that the propositional formulais satisfiable. Definition 79 (Induction)
. Given a transition system , let F and G be propositional formulas over V and let initiation, consecution and relative consecution be the conditions defined as follows:A formula F is said to be inductive
if it satisfies consecution. A formula F is said to be an inductive invariant
if it satisfies both initiation and consecution. A formula F is said to be inductive relative
to another formula G if it satisfies relative consecution. A formula F is said to be an inductive invariant relative
to another formula G if it satisfies both initiation and relative consecution. Definition 80 (Safety). Given a transition system and an invariant property P over V, a propositional formula F over V is said to be safe with respect to F iff F is stronger than P, i.e., .
Lemma 1 (Inductive Invariants as Overapproximations of Reachable States). Given a transition system , an inductive invariant F of is an overapproximation of the set of reachable states of , i.e., .
Intuitively, an inductive invariant expresses a quality of reachable states. Note that can be seen as the strongest inductive invariant of .
Definition 81 (Inductive Strengthening). Given a transition system and a property P over V, an inductive invariant F of is called an inductive strengthening of P iff it is safe with respect to P.
Lemma 2 (Invariant Verification as Search of an Inductive Strengthening). Given a transition system and a property P over V, if an inductive strengthening F of P can be found in , then P holds for every reachable state of and is said to be safe.
Many state-of-the-art model checking algorithms are based on a search for an inductive strengthening.
Definition 82 (Traces)
. Given a transition system , a trace of length k with respect to is a sequence in which each is a propositional formula over V, called a frame, such that the following conditions hold:A trace may also satisfy one or both of the following additional conditions, with P a property over V: A trace
that satisfies the monotonicity condition is said to be
monotonic. A trace
that satisfies the safety condition with respect to the transition system
P is said to be
safe. In order to provide a more clear understanding of the various traces natures,
Figure 4 provides a graphical representation as an overview.
The following lemmas hold for traces.
Lemma 3 (Overapproximation of Sets of Exactly Reachable States). Given a transition system and a trace with respect to , each timeframe of , with , is an over-approximation of the set of states reachable in exactly i steps in , i.e., .
Lemma 4 (Overapproximation of Sets of Reachable States). Given a transition system and a monotonic trace with respect to , each timeframe of , with , is an overapproximation of the set of states reachable in within i steps in , i.e., .
Lemma 5 (Safety up to Trace Bound). Given a transition system , a property P over V and a safe and monotonic trace with respect to P and , then there does not exist any counterexample to P of length at most in .
Lemma 6 (Inductive Invariants/Strengthening in Traces). Given a transition system and a trace with respect to , let us define for each . If there is so that then is an inductive invariant of . If is also safe with respect to a property P, then is also an inductive strengthening for P.
Lemma 7 (Inductive Invariants/Strengthening in Monotonic Traces). Given a transition system and a monotonic trace with respect to , if for some then is an inductive invariant of . If is also safe with respect to a property P, then is also an inductive strengthening for P.
These properties makes traces a very useful data structure to aid the search of an inductive strengthening in .
3. Bounded Model Checking
Given a transition system
and an invariant property
P, bounded model checking (BMC) [
38] is an iterative approach whose purpose is to check whether a counterexample to
P of length at most
k in
exists or to prove its absence. In order to carry this out, BMC simply performs a SAT check on a formula defined as follows.
Definition 83 (BMC Formula)
. A BMC formula of length k for P in is the propositional formula over : Intuitively, a BMC formula of length k encodes all initial paths in of length at most k capable of reaching a bad state in . If the BMC formula is Sat, then there exists a counterexample to P of length at most k in . Conversely, no such counterexample exists.
BMC tools iteratively solve BMC formulas of increasing bound, until either a counterexample is found or some maximum bound is reached. Due to the way it operates, BMC is effective in finding counterexamples but it is not able to detect whether P holds in . In order to surpass such a limitation, specific techniques are required to support unbounded model checking. The ability to check reachability fix-points and/or to find inductive invariants is thus the main difference, and additional complication, between BMC and UMC techniques, which will be introduced in the following sections.
Algorithm 2 reports the BMC procedure up to a certain bound
. First, the algorithm checks whether the property
P is satisfied by the initial states (lines 2–3). If an initial state fails to satisfy
P, the procedure terminates by returning
Fail along with a trivial counterexample. Otherwise, the procedure starts iterating over increasing values of
k up to
, checking whether there is at least a path satisfying the BMC formula up to bound
k (Definition 83) at each iteration (lines 6–8). If a satisfying path
is found, the procedure returns
Fail along with the path as a counterexample. If the procedure does not find any counterexample of length up to
, it returns a
Success, indicating that
P holds up to the given bound.
Algorithm 2 Top-level procedure of the BMC algorithm. |
Input: a transition system; P a property over V; maximum bound. Output: with res ∈ {Success, Fail}; a (possibly empty) initial path representing a counterexample.
- 1:
procedure BoundedModelChecking(, P, ) - 2:
if then - 3:
return 〈Fail, (s0)〉 - 4:
- 5:
while do - 6:
- 7:
if then - 8:
return 〈Fail, π0,k〉 - 9:
- 10:
return 〈Success, −〉
|
As explained above, the search for a counterexample of a given length is inherently incomplete, thus the need for additional techniques in order to overcome such a limitation. Nevertheless, BMC find application in several scenarios, due to its relative ease of application, both in hardware and in software model checking. The minimum requirement is being capable of encoding the transition relation of the instance at hand in a suitable way, e.g., a circuital representation. Furthermore, given a proper encoding, it is possible to combine both hardware and software problems in one, thus making BMC applicable to hybrid scenarios in which HW/SW co-design and co-verification take place. Such scenarios include, but are not limited to, RTL implementations to be checked against golden models, the model checking of properties arising from hardware–software interactions and sequential equivalence checking in between high-level synthesis and hardware description languages.
Example of Bounded Model Checking
Let
be a transition system described by the following:
and
P be an invariant property over
V:
Figure 5 illustrates the transition systems here described, for reference. The initial state, 00, is marked with the leftmost ingoing edge. The only bad state, 11, is highlighted with a line hatched filling.
An algorithm based on bounded model checking is capable of identifying a counterexample to the target property in four steps, by applying iteratively the BMC formula described in Definition 83.
In the first step, the algorithm would pose the following query:
which is UNSAT.
In the second step, the algorithm would pose the following query, in which, for the sake of compactness, we represent with
the aforementioned transition relation, at a given timeframe:
which is still UNSAT.
In the last step, the algorithm would pose the following query:
which is SAT, hence identifying the counterexample to the property, which does not hold in state 11.
4. Temporal Induction
BMC, introduced in
Section 3, is characterized by being an incomplete method: it is capable of finding counterexamples but it is unsuitable to prove correctness. In order to support proofs for unbounded depths, BMC has to be complemented with additional techniques. As an intuition, if exploration is capable of reaching a deep enough bound, such as to have explored all the behavior of the model at hand, such a bound could be considered a so-called completeness threshold. Such a threshold can be used as an upper bound for the length of the counterexamples that have to be considered before stating whether a proof holds.
In the context of model checking, SAT-based techniques are particularly suitable for performing checks of inductions, i.e., whether the transition system of the model under verification satisfies a given inductive invariant. The underlying question we are posing is whether a given property holds in the initial states and in all the states reachable from states in which the property is satisfied. The main limitation of such reasoning is due to the fact that, if the second condition fails, nothing can be said about the property at hand.
On these premises, temporal induction [
39], also known as strong induction or
induction, represents a widely used technique in unbounded model checking. Such a technique is a generalization of the notion of inductive invariants, which provide a strengthening factor to the base intuition presented above.
Given a transition system and an invariant formula over V, that formula is said to be invariant if it is true in the first k steps of .
A k-invariant formula is a k-inductive invariant if it is -invariant and is inductive after k steps of . With respect to simple induction, induction strengthen the hypothesis in the induction step. We have that the property is assumed to hold in the first steps, starting from 0, and is established in step k.
Whenever we have a k-invariant formula such that , we say that is a safe inductive invariant with respect to .
Algorithm 3 reports the top-level procedure for a generic
k-induction model checking scheme. First, the algorithm checks whether the property
P is satisfied by the initial states (lines 3–4). If an initial state fails to satisfy
P, the procedure terminates by returning
Fail along with a trivial counterexample (lines 5–6). Otherwise, the procedure starts iterating over increasing values of
k, checking whether there is at least a path satisfying the induction step formula up to bound
k (line 7), and taking into account only non-looping paths (line 8). If a satisfying path is found, the procedure returns
Success (lines 9–10), otherwise the bound
k is increased and the procedure iterates further.
Algorithm 3 Top-level procedure of the k-induction algorithm. |
Input: a transition system; P a property over V. Output: with res ∈ {Success, Fail}; a (possibly empty) initial path representing a counterexample.
- 1:
procedure TemporalInductionModelChecking(, P) - 2:
- 3:
while true do - 4:
- 5:
if then - 6:
return 〈Fail, π0,k〉 - 7:
- 8:
- 9:
if step(k) ∨ unique(k) then - 10:
return 〈Success, −〉 - 11:
|
Theorem 5. Given a transition system , there exists a safe inductive invariant with respect to iff there exists a safe inductive invariant with respect to .
Theorem 5 states that k-induction is as complete as 1-induction.
5. Interpolation-Based Model Checking
Craig’s interpolation theorem is a fundamental result in mathematical logic taking into account the relationship between model theory and proof theory. Interpolation, despite its heavy theoretical foundation, has found many practical applications in different areas of computer science. Originally, the formulation of the theorem introduced by Craig [
40] was given in the context of first-order logic. Variants of the theorem hold for other logical systems as well, including propositional logic, which is the context we will focus on hereinafter, as it is the one typically encountered in the context of model checking.
Theorem 6 (Propositional Craig’s Interpolation Theorem). Given two propositional formulas A and B, if is unsatisfiable then there is a propositional formula I, called interpolant between A and B, such that
Intuitively, I is an abstraction of A from the standpoint of B. The interpolant summarizes and translates in the common language between the two formulas the reasons why A and B are inconsistent. For ease of notation, we denote with I = Itp(A, B) the procedure that derives a Craig’s interpolant starting from a pair of inconsistent formulas A and B.
Interpolants can be derived from refutation proofs of unsatisfiable SAT-solving runs. Given an unsatisfiable formula
, most modern SAT solvers are capable of generating a refutation proof, as described in
Section 2.6, either in resolution-based or clausal form. Given a resolution proof, an interpolant
I =
Itp(
A,
B) can be derived in the form of an AND/OR combinational circuit in polynomial time and space with respect to the size of the proof. Different algorithms for generating interpolants from resolution proofs have been proposed, such as the ones by Huang [
41], Krajícek [
42], Pudlák [
43] and McMillan [
44]. We refer to those algorithms as
interpolation systems. Interpolants can also be derived as CNF formulas, instead of circuits, from either resolution proofs [
45] or clausal proofs [
46]. Although interpolants may be quite large in size, different approaches exist to compact them, also taking into account the relation between the size and strength of the interpolants themselves [
47].
In the context of model checking, if A represents a set of reachable states and B represents a set of bad states, then the interpolant I = Itp(A, B) can be deemed as a safe overapproximation of A with respect to B. In turn, such overapproximations can be used to detect a reachability fix-point.
5.1. McMillan’s Interpolation Algorithm
McMillan [
44] introduced the first complete algorithm for symbolic model checking based on Craig’s interpolation. In the literature, such an algorithm is called
standard interpolation or just ITP for short. The algorithm computes Craig’s interpolants to overapproximate reachable states of the system. The interpolants, as mentioned in the previous section, are computed from refutation proofs of unsatisfiable BMC runs.
The algorithm comprises two nested loops. The outer loop is presented in procedure ItpModelChecking (Algorithm 4) whereas the inner loop is presented in procedure ApproxForwardTraversal (Algorithm 5). At each outer loop iteration, ApproxForwardTraversal is invoked to perform an overapproximated forward traversal of the reachable states while preserving safety with respect to a backward unrolling from the target (bad cone). ApproxForwardTraversal can be seen as computing a safe monotonic trace. Note that such a trace is not explicitly maintained. Only its final frame is kept at each iteration and used as base for computing the next one.
We describe Algorithm 5 first. The procedure ApproxForwardTraversal operates a forward traversal in which interpolation is used as an overapproximated image operator. At each iteration, the procedure checks a BMC formula of fixed length k, composed of two parts:
where
R is a set of overapproximated forward reachable states. In such a scenario,
A represents the image of the set of states at the current traversal step, whereas
B represents the set of backward reachable bad states, reachable in at most
transitions from the target.
Algorithm 4 Top-level procedure of McMillan’s interpolation algorithm. This iterates overapproximated forward traversals of reachable states while keeping safety with respect to a bad cone of increasing depth from the target. |
Input: a transition system; P a property over V. Output: with res ∈ {Success, Fail}; a (possibly empty) initial path representing a counterexample.
- 1:
procedure ItpModelChecking(, P) - 2:
if then - 3:
return 〈Fail, (S0)〉 - 4:
- 5:
while do - 6:
ApproxForwardTraversal - 7:
if is Unreach then - 8:
return 〈Success, −〉 - 9:
else if is Reach then - 10:
return 〈Fail, cex〉 - 11:
|
Algorithm 5 Inner procedure of McMillan’s interpolation algorithm. This operates an overapproximated forward traversal of the reachable state space while keeping safety with respect to a bad cone of fixed depth from the target. |
Input: a transition system; P a property over V; k bound of a backward unrolling from the target. Output: with res ∈ {Reach, Unreach, Undef}; a (possibly empty) initial path representing a counterexample.
- 1:
procedure ApproxForwardTraversal(, P, k) - 2:
- 3:
if then - 4:
return 〈Reach, π0,k〉 - 5:
while ⊤ do - 6:
- 7:
- 8:
if then - 9:
return 〈Undef, −〉 - 10:
else - 11:
I ← Itp(A, B) - 12:
if then - 13:
return 〈Unreach, −〉 - 14:
|
At the first iteration,
R is the set of initial states
(line 2) and therefore is not overapproximated. In that case, the formula
is exactly a BMC formula of length
k. If such a formula is satisfiable, the algorithm has found a counterexample
of length at most
k (lines 3–4). Then, both the nested and the top-level procedures terminate, returning the counterexample found. Otherwise, the algorithm starts traversing the reachable state space, computing overapproximated images by means of interpolation (lines 5–14). After composing
A and
B (lines 6–7), the algorithm checks whether
is satisfiable (line 8). If that is the case, a (possibly spurious) counterexample
is found, i.e., a path of length at most
k from the overapproximated set
R to a bad state in
. Since
R is an overapproximation of the reachable states, the algorithm cannot determine whether
is a
real counterexample or a
spurious counterexample. Therefore, the procedure aborts the current forward traversal and returns the control to the top-level procedure. Otherwise,
is
Unsat and an interpolant
I can be derived from its refutation proof (line 11). Such an interpolant represents a safe overapproximation of the states reachable from
R in one transition with respect to the bad cone
, as illustrated in
Figure 6. Therefore, no counterexample can be reached from
I in
or less transitions, i.e.,
I is safe with respect to
P.
Since the interpolant is an overapproximation of the image of R, it is treated as a candidate inductive invariant. The algorithm checks whether consecution is valid (i.e., is unsatisfiable). In that case, R is an inductive invariant for and, since R is safe with respect to P, it is also an inductive strengthening for P. Conversely, a new set of overapproximated forward reachable states is computed as and the algorithm iterates once again. The result of the nested procedure, i.e., the sequence of R composed at each iteration, can be seen as a safe monotonic trace. Monotonicity stems from having R initialized with (line 2) and from the fact that each consecutive R is a disjunction of the previous one and of an overapproximation of the states reachable from the previous (line 14). Safety with respect to P stems from the fact that was proved to be safe (Algorithm 4, lines 2–4) and taking into the account that each interpolant I used to construct R does not intersect . From Lemma 7 follows the detection of an inductive strengthening for P from that trace. The sequence of interpolants, instead, can be seen as a non-monotonic safe trace.
Taking into account Algorithm 4, in the beginning, the initial states
are checked to be safe (line 2–3). If said check fails, there exists a trivial counterexample consisting of just a single initial state. The procedure can then halt and return the counterexample found. Conversely, the bad cone bound
k is initialized to 1 (line 4) and the procedure starts iterating forward overapproximated traversals of reachable states, while keeping safety with respect to a bad cone of increasing depth
k from the target (lines 5–11). Increasing the value of
k lets the algorithm find real counterexamples and generate more precise overapproximations on subsequent iterations. Since the bad cone from the target unwinds, a few states in the overapproximated images computed at previous iterations might be reached by the unrolling and are therefore excluded from newer images. During each outer loop iteration, the inner procedure starts a forward traversal from scratch from the initial states. As
k increases, the algorithm is guaranteed to find a bound
k in which the computed interpolants are precise enough to find an inductive strengthening if
P holds for the system, or to find a real counterexample otherwise [
44].
5.2. Example of Interpolation-Based Model Checking
Let
be a transition system described by the following:
and
P be an invariant property over
V:
Figure 7 illustrates different steps of the procedure reported in Algorithms 4 and 5 over
. The
ItpModelChecking procedure starts by checking whether or not the initial states
are safe. In the case of the system at hand, the single initial state 000 satisfies
P; therefore, the procedure will continue by invoking
ApproxForwardTraversal with
. During the first iteration of the traversal procedure,
R is set to the initial states
,
A represents the image of
and
B corresponds to the negation of the property
. Suppose that the interpolant
I extracted at line 11 of Algorithm 5 is the one described in
Figure 7a.
I overapproximates the image of
R, comprising both states that are actually reachable from
, like 001, and states that are not reachable from
, like 010 and 011.
Figure 7b describes the situation after the current set of reachable states
R has been updated by disjointing it with the interpolant
I. During the second iteration of the traversal procedure, an intersection between the image of the current set of reachable states
A and the bad states
B will be found (state 111, as indicated by both the solid and the dash–dotted line enclosing it in
Figure 7b). The traversal procedure will then halt reporting an
Undef result: this is the case in which a spurious counterexample to the property has been found, due to the interpolant
I being too loose an overapproximation of the states actually reachable from
, thus including a state (011) that is backward reachable from a bad state but not forward reachable from the initial states. The
ItpModelChecking procedure will then resume by increasing
k and invoking the traversal procedure once again with an enlarged cone of bad states.
Figure 7c describes the situation during the first step of the new traversal, in which
R and
A are left unchanged whereas
B is enlarged to include the pre-image of
(states 011 and 110). Suppose that a new interpolant
I is extracted that includes only states 000, 001, 100 and 101; then, after updating the current set of reachable states
R and performing a second traversal step, a fix-point will be reached as illustrated in
Figure 7d. The overall model checking procedure will end with a
Success result.
6. IC3
IC3 [
48] is a SAT-based algorithm for symbolic invariant verification. Given a transition system
and an invariant property
P over
V to be checked, the target of IC3 is finding an inductive strengthening of
P for
.
In order to carry this out, IC3 maintains two main data structures: a trace and a proof-obligation queue.
The trace is both monotonic and safe with respect to the property P. Each frame , with , is a safe overapproximation of the set of states reachable in at most i steps in (see Lemmas 4 and 5). The purpose of the algorithm is to iteratively refine such an in order to satisfy the condition for some , thus finding an inductive strengthening of according to Lemma 6.
IC3 also maintains a second data structure called a proof-obligation queue, which is used to collect sets of states in that may reach a violation of the property in an arbitrary number of steps. Those sets of states are processed by the algorithm according to a given priority and for each of them IC3 either finds a backward path to the initial states or learns a new inductive lemma that can be used to refine in order to exclude such states from the overapproximation. In case a path to the initial states is found, the algorithm has found a counterexample to P. In the latter case, the algorithm continues its search of an inductive strengthening of P over a tighter approximation of the reachable state sets.
IC3 needs to solve SAT calls at different stages during its run. Such SAT queries are peculiar [
49], in the sense that they are very frequent but involve only a single instance of the transition relation
T. Performing many
local reachability checks, IC3 achieves better control over the precision of the computed overapproximations.
Given , each frame is represented by a set of clauses, denoted by , to enable efficient syntactic checks for frame equality. The base condition of the trace is fulfilled by initializing the first frame with . Monotonicity is maintained syntactically by enforcing the condition . On the other hand, image approximation and safety are guaranteed explicitly by the algorithm operations.
The main procedure of IC3, described in Algorithm 6, is composed of an initialization phase followed by two nested iterations. During initialization, the algorithm sets up the trace and ensures that the initial states are safe (lines 2–5). If that is not the case, a counterexample of length zero, comprising only the initial state
s violating the property, is found and the procedure outputs a failure. During each outer iteration (lines 6–17), the algorithm tries to prove that
P is satisfied up to
k steps in
, for increasing values of
k. Inner iterations of the algorithm refine the trace
computed so far by adding new relative inductive clauses to some of its frames (lines 7–11). The algorithm iterates until either an inductive strengthening of the property is generated (line 16) or a counterexample to the property is found (line 11).
Algorithm 6 Top-level procedure of the IC3 algorithm: Ic3 (, P). |
Input: a transition system; P a property over V. Output: with res ∈ {Success, Fail} and a (possibly empty) initial path representing a counterexample.
- 1:
procedure Ic3(, P) - 2:
- 3:
- 4:
if then - 5:
return 〈Fail, (s)〉 - 6:
repeat - 7:
while do - 8:
Extend(s) - 9:
←BlockCube(q, Q, ) - 10:
if res= Fail then - 11:
return 〈Fail, ces〉 - 12:
- 13:
- 14:
Propagate() - 15:
if for some then - 16:
return 〈Succes, −〉 - 17:
until forever
|
At a given outer iteration k, the algorithm has already computed a monotonic and safe trace. From Lemma 5, it follows that P is satisfied up to steps in . IC3 then tries to prove that P is satisfied up to k steps as well, by enumerating states of that violate P and trying to block them in .
Definition 85 (Cube Blocking). Blocking a state (or, more generally, a cube) q in a frame means to prove q unreachable within k steps in and, consequently, to refine so that q is excluded from its overapproximation.
To enumerate each state of
that violates
P (line 7), the algorithm looks for states
s in
. Such states are called
bad states and can be found as satisfying assignments for the following SAT query:
If a bad state
s can be found (i.e., Query (
57) is SAT), the algorithm tries to block it in
. To increase performance of the algorithm, as suggested in [
50], the bad state
s found is first extended to a bad cube
q by removing, if possible, some of its literals.
Figure 8a visualizes this step. The
Extend(
s) procedure (line 8), not reported here, performs this operation via either ternary simulations [
50] or other SAT-based procedures [
51]. The resulting cube
q is stronger than
s and it still violates
P; it is thus called a
bad cube. The algorithm then tries to block the bad cube
q in frame
k rather than
s. It is shown in [
50] that extending bad states into bad cubes before blocking them dramatically improves IC3 performance. The bad cube
q is blocked in
calling the
BlockCube(
q,
Q,
) procedure (line 9), described in Algorithm 7.
When no further bad states can be found, the conditions in Definition 82 hold for and IC3 can safely move to the next outer iteration, i.e., trying to prove that P is satisfied up to steps. Before moving to the next iteration, a new empty frame is created (line 12). Initially, , so that . Note that ⊤ is a valid overapproximation to the set of states reachable within steps in .
After creating a new frame, a phase called
clause propagation takes place (line 14). During such a phase, IC3 tries to refine every frame
, with
, by checking whether some of its clauses can be pushed forward to the following frame. Possibly, clause propagation refines the outermost frame
so that an inductive invariant is reached. The propagation phase can lead to two adjacent frames becoming equivalent (see
Figure 8g). If that happens, the algorithm has found an inductive strengthening of
P for
(equal to those frames). Therefore, following Lemma 6, property
P holds for every reachable state of
and IC3 returns a successful result (line 16). Procedure
Propagate(
), described and discussed later, handles the clause propagation phase.
The purpose of procedure BlockCube(q, Q, ) is to refine the trace in order to block a bad cube q in . To preserve image approximation, prior to blocking a cube in a certain frame, IC3 has to recursively block predecessors of that cube in the preceding frames. To keep track of the states (or cubes) that must be blocked in certain frames, IC3 uses the formalism of proof obligations.
Definition 86 (Proof Obligation). Given a cube q and a frame , a proof obligation is a couple formalizing the fact that q must be blocked in .
Given a proof obligation , the cube q can either represent a set of bad states or a set of states that can reach a bad state in some number of transitions. The index j indicates the position in the trace where q must be proved unreachable, or else the property fails.
Definition 87 (Discharging Proof Obligations). A proof obligation is said to be discharged when s becomes blocked in .
Algorithm 7 Cube blocking procedure IC3: BlockCube(q, Q, ). |
Input: q a bad cube in ; Q the proof-obligation queue; the trace. Output: with res ∈ {Success, Fail} and a (possibly empty) initial path representing a counterexample.
- 1:
procedure BlockCube(q, Q, ) - 2:
Add proof obligation to Q - 3:
while Q is not empty do - 4:
Extract proof obligation with minimum j from Q - 5:
if or then continue; - 6:
if then return 〈Fail, ReconstructCet(q)〉 - 7:
if then - 8:
Extend(s) - 9:
Add proof obligations and to Q - 10:
else - 11:
Generalize() - 12:
for - 13:
Add proof obligation to Q - 14:
return 〈Success, −〉
|
In order to discharge a proof obligation, new ones may have to be recursively discharged. This can be carried out through a recursive implementation of the cube blocking procedure. However, in practice, handling proof obligations using a priority queue
Q proved to be more efficient [
50] and it is thus the commonly used approach in most state-of-the-art IC3 implementations. While blocking a cube, proof obligations
are extracted from
Q and discharged for increasing values of
j, ensuring that every predecessor of a bad cube
q will be blocked in
(
) before
q will be blocked in
. In the
BlockCube(
q,
Q,
) procedure, described in Algorithm 7, the queue of proof obligations is initialized with
, encoding the fact that
q must be blocked in
(line 2). Then, proof obligations are iteratively extracted from the queue and discharged (lines 3–14).
Prior to discharging a proof obligation
, IC3 checks whether that proof obligation still needs to be discharged. It is in fact possible for an enqueued proof obligation to become discharged as a result of some previous proof-obligation discharging. To perform this check, the algorithm tests whether
q is still included in
(line 5). This can be performed by posing the following SAT query:
If
q is in
(i.e., Query (
58) is SAT), the proof obligation
still needs to be discharged. Otherwise,
q has already been blocked in
and the procedure can move on to the next iteration.
If the proof obligation still needs to be discharged, then IC3 checks whether is the initial frame (line 6). If so, the states represented by q are initial states that can reach a violation of property P. Thus, a counterexample to P can be constructed by following the chain of proof obligations that led to . This is performed by means of the procedure ReconstructCex(q), not described here. In that case, the procedure terminates with a failure and returns the counterexample found.
To discharge a proof obligation
, i.e., to block a cube
q in
, IC3 tries to derive a clause
c such that
and
c is inductive relative to
.
Figure 8b visualizes this step. The
initiation condition of induction (
) holds by construction, whereas the algorithm must check whether or not the
relative consecution condition (
) holds. This can be performed by proving that the following SAT query is unsatisfiable (line 7):
If relative consecution holds (i.e., Query (
59) is UNSAT), then the clause
is inductive relative to
and can be used to refine
, ruling out
q (lines 10–13). To pursue a stronger refinement of
, the inductive clause found undergoes a process called
inductive generalization (line 11) prior to being added to the frame. Inductive generalization is carried out by the
Generalize(
) procedure, described in Algorithm 8, which tries to minimize the number of literals in a clause
while maintaining its inductiveness relative to
, in order to preserve monotonicity.
The resulting clause is added not only to
, but also to every frame
(line 12). Doing so discharges the proof obligation
ruling out
q from every
with
. Since the sets
with
are larger than
,
q may still be present in one of them and
may become a new proof obligation. To address this issue, Algorithm 7 adds
to the proof-obligations queue (line 13).
Figure 8e,f visualize this step.
Otherwise, if the relative consecution does not hold (see
Figure 8c), there is a predecessor
s of
q in
. Such predecessors are called
counterexamples to the inductiveness (CTIs). To preserve image approximation, before blocking a cube
q in a frame
, every CTI of
q must be blocked in
(
Figure 8d). Therefore, the CTI
s is first extended into a cube
p (line 8), and then both proof obligations
and
are added to the queue (line 9).
The
Generalize(
) procedure (Algorithm 8) performs inductive generalization, which is a fundamental step of the algorithm. During inductive generalization, given a clause
relative inductive to
, IC3 tries to compute a clause
c subset of
such that
c is still inductive relative to
. Acting this way, and using
c to refine the frames, the algorithm can block not only the original bad cube
q but potentially also other states, which in turn may lead to faster convergence. Inductive generalization works by dropping literals from the input clause while maintaining relative inductiveness with respect to
. The procedure computes a minimal inductive sub-clause, i.e., a sub-clause that is inductive relative to
and no further literals can be dropped without forgoing inductiveness [
52]. In the general case, though, finding a minimal inductive sub-clause is often inefficient [
48] and, thus, most implementations of IC3 rely on an approximate version of such a procedure. Approximate inductive generalization is significantly less expensive, yet still able to drop a reasonable number of literals.
Algorithm 8 Iterative inductive generalization procedure: Generalize (j, s, ) |
Input: j a frame index; q a cube such that ; the trace. Output: c a clause such that and .
- 1:
procedure Generalize(j, q, ) - 2:
- 3:
for all literals l in c do - 4:
- 5:
if then - 6:
if then - 7:
- 8:
return c
|
In the
Generalize (
) procedure, a clause
c initialized with
(line 2) represents the current inductive sub-clause. For each literal of
c, the candidate clause
t is obtained by discarding that literal from
c (line 4). Dropping literals from a relative inductive clause can violate both initiation and relative consecution conditions of induction. The candidate clause
t must thus be checked for inductiveness relative to
. IC3 checks whether the relative consecution condition (
) keeps holding for
t by posing the following SAT query:
If the relative consecution condition holds (i.e, Query (
60) is UNSAT), the algorithm needs to prove the initiation condition of induction (
). This check (line 6) can be performed either syntactically or semantically. If
can be described as a cube, it is enough to check whether at least one of the literals of
appears in
t with opposite polarity. In such a case,
does not intersect
and the initiation condition holds. Otherwise, the initiation of induction must be checked explicitly by posing the following SAT query:
If Query (
61) is UNSAT, the initiation condition holds for
t. If both the relative consecution and the initiation conditions still hold for the candidate clause
t, the current inductive sub-clause
c can be updated with
t (line 7).
The
Propagate (
) procedure (Algorithm 9) manages the propagation phase. For every clause
c of each frame
, with
, it checks whether
c can be pushed forward to
. This is performed by checking whether
c is inductive relative to
(line 4). The procedure must check whether relative consecution
holds, by answering the following SAT query:
If relative consecution holds (i.e., Query (
62) is UNSAT), then
c is relative inductive to
and can be pushed forward to
. Otherwise,
c cannot be pushed forward and the algorithm moves to the next iteration.
Algorithm 9 Clause propagation procedure: Propagate (). |
Input: : the current trace.
- 1:
procedure Propagate() - 2:
for to do - 3:
for all do - 4:
if then - 5:
- 6:
|
Property Directed Reachability
Property Directed Reachability (PDR) is a variant implementation of IC3 proposed by Een et al. in [
50]. PDR differs from the original IC3 implementation by Bradley [
48] as follows:
The trace is represented as sets of blocked cubes rather than learned clauses. Furthermore, to avoid duplication, PDR only stores a cube in the last frame where it holds. PDR also adds a special frame which will hold cubes that have been proved unreachable from the initial states by any number of transitions.
PDR uses a slightly modified trace semantics with respect to IC3, by not requiring the last frame of the trace to entail the property. Een et al. show that this behavior can be emulated by PDR by preprocessing the input system using a one-step target enlargement of P. This results in a small performance gain, simplifies the implementation and has the extra benefit that is a proper invariant, which can be used to strengthen other proof engines, or exploited for synthesis. Furthermore, in principle, the same target-enlargement idea can be generalized and applied for any number of steps.
PDR proposes the use of ternary simulation as a method to shrink proof obligations before blocking them (implemented as the
Extend procedure in Algorithm 7). In [
50], ternary simulation is shown to have a big impact on performance.
7. IGR
IGR [
53],
Interpolation with Guided Refinement, is a model checking algorithm than can be seen as a variant of standard interpolation. It incorporates, within an interpolation scheme, explicit trace computation and refinement, images and cones simplification under observability don’t care and guided cone unwinding/rewinding.
The main purpose is to improve the standard interpolation in order to support the incremental computation of reachable states sets and dynamic tuning of the backward unrolling from the target. Incremental data structures are used to enable the reuse of previously computed overapproximations and make interpolant-based algorithms better suited for the verification of multiple properties or for integration with abstraction/refinement approaches. Furthermore, maintaining overapproximated reachable state information in an incremental data structure allows the algorithm to dynamically adjust the bound of the BMC formulas checked during each traversal step, for better controlling the precision of the computed image overapproximations.
In order to better describe the proposed variation, it is necessary to introduce first the foundations on which it is built upon, in order to better characterize then the overall algorithm.
7.1. Incremental State Sets in Interpolation
In order to enable the reuse of previously computed interpolants, in IGR, a trace of overapproximations to reachable states is maintained and incrementally refined. Since interpolants are safe image overapproximations with respect to the property under verification, the trace maintained is safe as well.
At each i-th iteration of standard ITP’s inner loop, from the refutation proof of a BMC formula, an overapproximation of the states reachable in i steps in the system is computed by extracting an interpolant. Such an interpolant is then discarded at the end of the iteration. Furthermore, when a spurious counterexample is found, the current forward traversal is interrupted, the backward cone from the target is unwound by one step and the forward traversal of reachable states restarts once again from the initial states. One of the focus point in IGR is to keep track of the overapproximations computed during each run of ApproxForwardTraversal, in order to enable their reuse in further iterations of the outer loop. It is thus necessary to extend the standard interpolation algorithm to keep track of a trace of reachable states. As the bound k of the cone increases, stronger overapproximations are computed at each traversed time frame and used to refine the trace.
A trace is used in order to keep track of previously computed overapproximations. From Lemma 3, it follows that each timeframe of , with , is an overapproximation of the set of states that are reachable in exactly i steps. The trace is constructed so that it is safe with respect to P.
The proposed ITP variant, informally called IncrItpModelChecking, is sketched in Algorithms 10 and 11. The differences between the variant and standard interpolation are the following:
The trace is initialized with before starting the first forward traversal (Algorithm 10, line 5).
Each time the forward traversal reaches the end of the current trace, a new frame is instantiated equal to ⊤ and added to the trace (Algorithm 11, lines 8–10).
Every time a new interpolant, overapproximating states reachable in steps, is computed, the corresponding frame in the trace is refined (Algorithm 11, lines 17).
Refinement is a strengthening step carried out by conjoining the previous set with a new term.
Algorithm 10 Top-level procedure of the proposed ITP variant that keeps track of the computed interpolants using a trace. |
Input: a transition system; P a property over V. Output: with res ∈ {Success, Fail}; a (possibly empty) initial path representing a counterexample.
- 1:
procedure IncrItpModelChecking(, P) - 2:
if then - 3:
return 〈Fail, (s0) - 4:
- 5:
- 6:
while true do - 7:
IncrApproxForwardTraversal - 8:
if is Unreach then - 9:
return 〈Success, −〉 - 10:
else if is Reach then - 11:
return 〈Fail, cex〉 - 12:
|
Algorithm 11 Inner procedure that keeps track of the computed interpolants using a trace. |
Input: a transition system; P a property over V; a trace; k bound of a backward unrolling from the target. Output: with res ∈ {Reach, Unreach, Undef}; a (possibly empty) initial path representing a counterexample.
- 1:
procedure IncrApproxForwardTraversal(, P, , k) - 2:
- 3:
if then - 4:
return 〈Reach, π0,k〉 - 5:
- 6:
while ⊤ do - 7:
if then - 8:
- 9:
- 10:
- 11:
if then - 12:
return 〈Undef, −〉 - 13:
else - 14:
I ← Itp(A, B) - 15:
- 16:
if then - 17:
return 〈Unrea, −〉 - 18:
- 19:
|
7.2. Frames and Cone Simplification
In order to keep cones and overapproximations of reachable states contained in size, the algorithms exploit an optimization that aims at simplifying the representation of frames and/or bad cones through ad hoc redundancy removal, exploiting the general notion of redundancy removal under observability don’t cares. In order to understand the approach, let us denote simplification under a care set as the function Simplify, where F is a formula over V to be simplified and C is another formula over V to be used as a care set for the simplification of F. The care set is defined with respect to a reference formula G over in which F appears as a subformula, as follows.
Definition 88 (Care Set and Don’t Care Set)
. Given a propositional formula F over V and another formula G over such that F is a subformula of G, we define the care set of F with respect to G as the set of assignments over V under which the value of F affects the value of G. A care set for F with respect to G can be represented by the formula:The complement of is called the don’t care set
of F with respect to G. It represents the set of assignments over V under which the value of F does not affect the value of G. Simplification of a formula
F under care set
with respect to a reference formula
G can entail the application of any number of equivalence-preserving or strengthening transformations over
F, as long as the following constraint is preserved:
Computation of care sets and don’t care sets can be costly [
54]. Considering a conjunction
as a reference formula, the following lemma describes two straightforward ways to obtain care sets for either one of the conjoined formulas. We focus on
B, since the same dual reasoning applies to
A.
Lemma 8 (Care Sets for Conjunctive Reference Formulas). Given A and B, two propositional formulas over V, and given , then A is a care set for B with respect to F. Given C, a propositional formula over V, such that , then C is a care set for B with respect to F.
Figure 9a,b illustrate the simplification of a formula
B with respect to a reference formula
under care sets as defined by Lemma 8, in terms of sets of assignments. Given two propositional formulas
and
, the knowledge that any assignment satisfying their conjunction
must be a satisfying assignment of either one can be used to simplify the other. Using
A as a care set for
B, since
is satisfied only by assignments satisfying
A (i.e., assignments
such that
) it is possible to simplify
B through the injection of a constant ⊤ prior to conjoining it to
A, obtaining
. The resulting formula after simplification
Simplify is syntactically more compact than the equivalent
.
Despite the fact that many redundancy removal techniques could be used to perform simplification under a care set, e.g., latch correspondence, signal correspondence and equivalence to constants, most of them are too expensive to be performed at each forward traversal iteration within an ITP scheme. For the sake of having a fast operator, simplify is limited to the removal of equivalences between state variables, i.e., latch correspondences. Given a target formula B and a care set A, the Simplify operator identifies pairs of state variables such that and then B is simplified as .
Simplification under a care set can be used on frames during refinement steps (Algorithm 11, line 17), or to simplify the bad cone prior to checking its intersection with the image of (Algorithm 11, line 13). During forward overapproximated traversal, when checking whether the image of the current set of reachable states intersects with the bad cone , it is possible to simplify using any overapproximation of the states reachable in the next k transitions that is already in the trace. Each frame in , with , can be used as a care set to simplify . With TraceSimplify(, , i, k) we identify the function applying Simplify(Cone(1,k), Fj) for each , i.e., the function applying latch correspondences substitution at each intermediate transition relation boundaries in . In this way, reachability information computed during previous iterations of the algorithm are used to simplify the formula before injecting it into the SAT solver.
7.3. Cone Unwinding and Rewinding
In standard interpolation, when finding a spurious counterexample, the current forward traversal is restarted from the initial states after the bad cone has been expanded by one step. IGR, instead, dynamically unwinds or rewinds the cone during forward traversal, in order to guarantee the refinement of some previously computed overapproximation of reachable states. The depth of the cone is therefore guided by the frames in the trace so that it can lead to a strengthening refinement for some of them.
Supposing that, at a given point during the execution of IncrItpModelChecking, the algorithm has computed a trace , two approaches can be pursued with the goal of potentially expanding and/or refining :
- Cone Unwinding.
When the forward traversal hits the cone, it starts a new traversal at an intermediate step in order to guarantee the refinement of the trace.
- Cone Rewinding.
When the forward traversal hits the cone, it continues the traversal with iteratively smaller cones in order to refine and expand the trace.
Overall, guided cone unwinding/rewinding allows IGR to dynamically tune the unrolling from the target and therefore to have better control over the precision of the computed overapproximations (interpolants). In this respect, standard interpolation is too rigid, as overapproximations are always strengthened expanding the cone by one and restarting the traversal from scratch.
7.3.1. Cone Unwinding
At a given iteration
i of the forward traversal, given
k the bound of the cone, if the formula
is
Sat, then a possibly spurious counterexample is found. In such a scenario, standard interpolation would unwind the bad cone by one step and then start a new traversal from the initial states. When step
i is then reached once again in the traversal, the overapproximation
could have been strengthened enough to exclude the previously found spurious counterexample. If that is not the case, the algorithm restarts the traversal again, incrementing
k until either the spurious counterexample is excluded from the overapproximation or the counterexample is confirmed to be a concrete one. With cone unwinding, the cone is unwound of the minimum depth necessary to strengthen a frame
, with
, in order to eliminate the spurious counterexample directly.
Upon encountering a spurious counterexample, the BMC-like problem described in Equation (
65) is
Sat. Therefore, the algorithm starts an iterative process checking BMC problems of fixed bound in which the cone is unwound by one step and the algorithm moves to the previous frame. Starting from frame
and cone
, at each
j-th iteration it considers the BMC-like problem:
with
. At each iteration it swaps an overapproximated image in
with an exact image in
. If the BMC-like problem in Equation (
66) is
Sat at a given
j, then
is not strong enough to refute the counterexample and the process iterates. Eventually, either it finds
Unsat thus refuting the spurious counterexample, or it reaches the initial states thus confirming the counterexample as a concrete one. In fact, for
we have exactly
bmc(
i +
k). Assuming that it can find a
j, with
, such that Equation (
66) is
Unsat, then it can restart the forward traversal from
with
. This is guaranteed to generate an interpolant and therefore refine the current trace.
7.3.2. Cone Rewinding
When, at a given step i, the forward traversal hits the cone of depth k, rather than starting a new traversal with an unwound cone, the algorithm can optionally continue the current traversal with a sequence of iterations, called refinement sequence. During refinement, each iteration uses a cone of decreasing depth for which the safety of the current reachable state overapproximation is guaranteed.
Assume that, at a given step
i,
is
Sat. Since
was proved to be safe with respect to
at iteration
, there does not exist any counterexample of length at most
k starting from
i, and hence it is guaranteed that
is
Unsat for each
. A new interpolant
can be generated from each of such calls to be used to refine
. Alternatively, one could compute an interpolation sequence directly from the BMC call (
67) and use it to refine the trace.
To summarize, once a cone of depth k is hit at step i of the forward traversal, the algorithm can compute a sequence of k interpolants, each representing an overapproximation of states reachable in transitions, with , that can be used to refine, or generate, the frames of the trace. The main purpose of such a refinement sequence is to let future traversals operate over more precise overapproximations of the reachable states.
On such premises, the overall IGR algorithm can now be presented.
The top-level procedure of IGR is reported in Algorithm 12. The algorithm first checks the safety of the initial states (lines 2–3) and initializes the trace
(line 4). Indexes
and
are also initialized (line 5–6) and they are used to keep track of the traversal step and cone depth at which a cone was hit during the previous traversal, if any. Past initialization, the outer loop starts iterating overapproximated forward traversals (lines 7–13). Procedure
Unwind is invoked first to seek the best frame at which to start the next traversal (line 8), to perform cone unwinding (as described in
Section 7.3.1) starting from the step
and cone depth
, until either a concrete counterexample or a frame that could be refined by computing a new interpolant is found. In the first case,
Unwind returns a
Reach result and a counterexample. The algorithm, thus, terminates with
Fail producing the counterexample as output (lines 9–10). In the second case,
Unwind returns an
Undef result, a step
i and a cone depth
k to be used for the next traversal. Note that, during the first iteration,
and
are initialized to zero and one, respectively; therefore,
Unwind simply checks whether the initial states can reach the target in one transition. If no concrete counterexample is found, the algorithm starts a new forward overapproximated traversal by calling the
IgrApproxForwardTraversal routine (line 11). Upon termination of such a procedure, if the result is
Unreach then an inductive invariant has been found during traversal and thus the algorithm terminates with
Success (lines 12–13). Conversely, the cone was hit and the traversal procedure returns an
Undef result together with the step
and cone depth
at which that occurred. In such a scenario, it means that a spurious counterexample was found during traversal and the algorithm then iterates to perform a new traversal.
On these premises, we can summarize the overall scheme of IgrModelChecking as follows:
Iteratively choose a starting frame and a cone to be unwound with guidance throughout the overapproximated trace .
Initiate a forward traversal from with aiming at refining and filtering out the latest spurious counterexample found within .
The two sub-tasks are performed by
Unwind and
IgrApproxForwardTraversal, respectively.
Algorithm 12 Top-level procedure of IGR. |
Input: a transition system; P a property over V. Output: with res ∈ {Success, Fail}; a (possibly empty) initial path representing a counterexample.
- 1:
procedure IgrModelChecking(, P) - 2:
if then - 3:
return 〈Fail, (s0)〉 - 4:
end if - 5:
- 6:
- 7:
- 8:
← Unwind - 9:
if is Reach then - 10:
return 〈Fail, cex〉 - 11:
← IgrApproxForwardTraversal - 12:
if is Unreach then - 13:
return 〈Success, −〉
|
Procedure
IgrApproxForwardTraversal, described in Algorithm 13, performs an overapproximated forward traversal of reachable states. The procedure starts from a given frame in the trace while preserving safety with respect to a cone of a given depth. It first computes the current overapproximated set of reachable states at step
i by disjoining the first
i frames (line 2). During each iteration of the traversal loop (lines 6–29), the algorithm then proceeds in two different ways taking into account whether or not
cone rewinding (see
Section 7.3.2) has been triggered. If it has not been triggered, the algorithm performs a traversal step using a cone of bound
k. Conversely, the procedure decreases the bound of the cone at each iteration to perform rewinding (lines 9–10). The procedure then performs cone simplification (line 12), as described in
Section 7.2, and checks whether the current set of overapproximated reachable states
R hits the cone (line 13), during each traversal step. In case of a hit, the algorithm saves the current step and cone bound in
and
, respectively, and triggers a refinement sequence (lines 14–16). Conversely, a new overapproximated image is computed through interpolation (lines 18) and the current frame
is refined and simplified (line 19) as described in
Section 7.2. The algorithm then checks whether the overapproximation is an inductive invariant, returning
Unreach if that is the case (lines 20–21). If no inductive invariant has been found, the new set of overapproximated forward reachable states to be used for the next iteration is computed as
(line 22). Each time the forward traversal reaches the end of the current trace, a new frame
is instantiated equal to ⊤ and added to the trace (lines 7–8). At the end of each iteration, if a given depth threshold
D has been reached, the algorithm forces rewinding (line 24–27). When rewinding is triggered, either after finding a spurious counterexample or by force, the algorithm continues the traversal decreasing the cone bound at each iteration. When the cone has been completely rewound, the algorithm terminates returning
Undef alongside the step and cone bound at which either a spurious counterexample was found (lines 15–16) or rewinding has been forced (lines 26–27).
The aforementioned
D threshold heuristically controls activation of cone rewinding. Whenever
, rewinding is always active, so the approach obtains a minimal refinement while mimicking the effect of interpolation sequences [
55]. High values of
D keep the
k value constant until a hit, mimicking a scheme which would result far closer to standard interpolation. Empirically, it occurs that small values tend to be usually better at small sequential depths, as they can enact more, relatively inexpensive, refinement steps.
Algorithm 13 Inner procedure that keeps track of the computed interpolants using a trace. |
Input: a transition system; P a property over V; a trace; i start step of the traversal; k bound of a backward unrolling from the target. Output: with res ∈ {Unreach, Undef}; the step (if any) at which the cone is hit during traversal; the depth of the cone hit.
- 1:
procedure IgrApproxForwardTraversal(, P, , k) - 2:
- 3:
- 4:
- 5:
- 6:
while ⊤ do - 7:
if then - 8:
- 9:
if then - 10:
- 11:
- 12:
B ← TraceSimplify - 13:
if then - 14:
- 15:
- 16:
- 17:
else - 18:
I ← Itp(A, B) - 19:
← Simplify(Fi+1,I) ∧ I - 20:
if then - 21:
return 〈Unreach, −, −〉 - 22:
- 23:
- 24:
if then - 25:
- 26:
- 27:
- 28:
else if then - 29:
return 〈Undef, ihit, khit〉
|
At each iteration, the
Unwind procedure described in Algorithm 14 computes
i and
k, starting from
and
, relative to the previous spurious counterexample. Following the strategy described in
Section 7.3.1, the cone bound
k is extended while
i is decremented (lines 5–6), until either the algorithm encounters an
Unsat BMC check or the initial states are reached (line 4). In the former case,
Unwind managed to find a frame at which starting a traversal is expected to lead to a
refinement and to filtering out the last spurious counterexample found. The procedure then returns an
Undef result alongside the corresponding values for
i and
k (line 9). In the latter case, the procedure has detected an actual counterexample as a side effect. The procedure then returns a
Reach result alongside the counterexample (line 8).
Algorithm 14 Unwinding procedure of IGR. |
Input: a transition system; P a property over V; the step at which the cone was hit during traversal; the depth of the cone hit. Output: with res ∈ {Undef, Reach}; a (possibly empty) initial path representing a counterexample; i step at which resume forward traversal from; k cone depth to use in the resumed traversal.
- 1:
procedure Unwind(, P, , ) - 2:
- 3:
- 4:
while do - 5:
- 6:
- 7:
if then - 8:
return 〈Reach, π0,k, −, −〉 - 9:
return 〈Undef,−,i,k〉
|
8. Comparative Analysis and Experimental Evaluation
In order to compare and evaluate the various model checking algorithms, we here present the data gathered taking into account our own implementation of said techniques on top of the PdTRAV tool [
56], a state-of-the-art model checking academic tool.
The benchmark set considered was derived from past HWMCC suites [
14,
57], starting from the 2014 edition until the most recent one. The set includes hardware- as well as software-derived verification problems, mostly stemming from industrial-level verification instances (such as IBM and intel benchmarks).
Experiments were run on an Intel Core i7-1370, with 16 CPUs running at GHz hosting a Ubuntu LTS Linux distribution. All the experiment were run taking into account a time limit of 3600 s and a memory limit of 32 GB.
Experimental results are reported in
Table 1 and
Table 2, which share the same structure. Both tables highlights solves, split between SAT and UNSAT instances (Result), for each main engine (Engine) of our verification suite. For each group of results, we provide the average number of memory elements (
), input variables (
) and gates (
) of the benchmarks belonging to each set, to provide some insight into the size of the instances at hand. As summary statistics, we also provide average solving time, both in term of CPU time (
) and wall-clock time (
), and memory requirements (
) for each group.
Table 2 provides a subset of the results of
Table 1, filtering out easier instances, i.e., instances that require 60 seconds or less to be solved.
In the tables one can find both SAT-based model checking techniques, which are the focus of this paper, such as IC3 in its PDR variant, BMC, induction-based approaches exploiting lemmas (LMS), interpolation and IGR, as well as some solutions obtained through auxiliary techniques, such as BDD-based reachability, logic synthesis, simulation and combinatorial techniques to circuit manipulation and checking, which go past the scope of the current work. It is worth remembering that the portfolio-based approach awards the solution for a specific instance to the first engine capable of solving the corresponding verification task, for the sake of efficiency. In such a scenario, after (at least) one engine manages to solve a problem, all the concurrent running task are brought to a halt, in order to spare resources.
As mentioned before, there is not currently a definitive winning strategy when it come to bit-level hardware model checking, so portfolio approaches are the de facto standard in the field. Since its introduction, IC3/PDR has proven itself time and time again as one of the most proficient strategies in the state of the art, as also shown by the results here provided. Nevertheless, its contribution need to be complemented with interpolation-based strategies in order to provide better coverage. This is far more evident when we shift the focus to harder-to-solve instances, in which the subset of benchmarks solved by interpolation-based strategies stays basically the same, whereas the number significantly decreases for IC3. IC3 proves itself a high-performing engine, with a significant edge on easier and mid-tier instances. Interpolation-based techniques, in turn, complement it providing orthogonal approaches. The same consideration holds for BMC-based approaches, that focus on falsification with the aim of finding an actual counterexample to the property under verification. Their targets stay basically unchanged, with a scope on instances with deeper unrollings of the corresponding transition relation, which other engines may struggle to tackle.
When taking into account BDD-based approaches, which are not directly the focus of this paper, one can take into account both similarities and differences with their SAT-based counterparts. On the one hand, they both try to address problems encoded in Boolean form but where SAT checkers just need to focus on finding a single satisfying assignment for the formula under verification, BDD-based ones need to encode a function describing all the satisfying assignments. Once such an encoding is available, BDDs are capable of performing tasks which are not supported by SAT-based solutions, such as focusing on optimality given a cost function, provide counting, or supporting variable quantification, at the cost of being able to build such a data structure, though. In general SAT checkers relying on some variant of the DPLL algorithm outperform BDD-based solutions; nevertheless, there are niche scenarios in which BDDs are still the winning strategies, such as specific instances of equivalence and parity checking.
Complementary to all of the techniques referenced above, we have logic synthesis, simulation and combinatorial-based approaches which tackle verification problems from a more circuital and structural point of view. They tend to be applicable to smaller instances or instances with very specific patterns and a large number of equivalent elements, which can be collapsed in a few equivalence classes and/or abstracted away from the actual model under verification.
Practical Considerations Concerning Model Checking Algorithms
The algorithms we have described, falling into the SAT-based and symbolic model checking category, are usually quite resilient to the state space explosion problem, which can be problematic when dealing with large designs, comprising millions, or more, variables and constraints. In such a scenario, though, the trade-off has to be taken into account, which lies in the inherent time complexity, as SAT-based problems are known to be NP-complete.
One the one hand, we have that worst-case complexity indeed falls into exponential time; on the other hand, we have that, exploiting the proper modeling of systems, representation of data and simplification steps, SAT-based model checking algorithms are applicable to real-world scenarios.
One of the major issues with tuning resources for running verification instances is that it is almost impossible, in the general case, to foresee what would be the appropriate amount of time and memory to dedicate to a given task. The experimental evaluation proposed above follows the same setup of model checking competitions to provide comparable results with a well-defined baseline, but at the same time such a setup is nothing more than an executive choice on the matter.
It is not uncommon for industrial-level instances and more complex benchmarks to have to account for timeouts in the order of days, or more, in order to hopefully obtain usable results. Let us also point out once more how there is absolutely no guarantee that any of the engines may actually be able to solve a given instance, regardless of the time spent on the problem. On these premises, there are situations in which the aim is to go as deep as possible in the model exploration, trying to verify as much of the behavior as possible, without any claim of completeness, such as in pure BMC-based runs, where engines are left to run until resource depletion, either in terms of time or memory.
Because of this, orthogonal to the research and development of new techniques, a vast amount of research is targeted at improving the existing base of knowledge in order to make current techniques better performing and more applicable. Such an effort may be directed, among other things, at improving formalism and encoding styles and rules for the models [
58], improving SAT-solver management strategies [
49] or introducing different strategies for task management or exploiting partial results in a collaborative fashion among engines in order to increase their chance of success [
36,
37].
A far more in-depth analysis of practical solutions and techniques to improve the applicability and scalability of SAT-based verification is presented in [
59].
9. Conclusions
This paper provides an in-depth overview of the most common SAT-based algorithms usually applied in bit-level hardware model checking scenarios. In the last two decades, SAT-based model checking brought about a leap in the performance and scalability of symbolic model checking algorithms. SAT-based model checking tools have managed to almost supplant BDD-based ones in both industry and academia. Model checking algorithms based on SAT solving, however, still suffer from non-negligible scalability issues when confronted with the complexity of many industrial-scale designs. Improving the performance and scalability of such algorithms is a very challenging, yet very active, research path.
This paper strives to provide both a thorough overview of the background required to understand the topics at hand, and a complete description of the aforementioned algorithms and their intricacies. Based on the current state of the art, a selection of the most relevant methods has been identified and described, taking into account both bounded and unbounded model checking, with a focus on safety properties. For the sake of generality, this work provides a description of each algorithm from a theoretical standpoint, trying to avoid details which would turn out to be too implementation oriented in favour of the soundness and comprehensiveness of their description and discussion.
As mentioned in the introductory section, as of today, there is no a single winning strategy applicable to the broad range of verification problems one may face. It has thus become almost mandatory to tackle verification tasks using a portfolio of techniques, running in a concurrent/collaborative fashion, in order to maximize the chance of success. Furthermore, additional factors, such as model pre-processing and simplification, property management, engine orchestration, etc., play a role as important as the actual model checking algorithm of choice in determining the success of the verification procedure. This is the main reason why the current research path in this field usually reaches across several different directions, targeting different aspects of the verification chain, rather than focusing on a single specific step. Nevertheless, it is absolutely crucial to develop a firm and sound understanding of the available techniques in order to properly orchestrate verification efforts.
For the future, the current path of research is aimed at supporting hierarchical verification for top-down design, embedding support for verification in the whole design chain, starting from specification languages. Currently, there is a need for being able to write a verifiable high-level design, that can then be refined and implemented, while guaranteeing that it is still consistent with its abstraction. The main aim is for properties that have been verified at a given step of the design chain to hold at any other successive level of refinement. Such a desideratum leads to hybrid and top-down/bottom-up design methodologies, with emphasis on verification as grounding for correctness, as well as introducing the need for some sort of certificate, to guarantee the correctness of each step, transformation and refinement involved in the process. Alongside hierarchical verification, the integration of model checking within design becomes even more pressing, where model checkers represent auxiliary tools within the design chain, to support and validate correctness. Despite its potential usefulness, the adoption of model checking in industrial scenarios is still an ongoing process, where funding and methodology changes are the main limiting factors, in conjunction with the absence of a definitively best approach at tackling verification problems. Because of this, we can foresee that for the coming years portfolio-based approaches, exploiting divide-and-conquer strategies among different verification engines, will still be the most consistent way to address such tasks.