Keywords

figure a

1 Introduction

We describe a novel constraint-based approach to automatically solving a wide range of relational verification problems including k-safety, co-termination [6, 10], termination-sensitive non-interference (TS-NI) [63], and generalized non-interference (GNI) [40] for infinite-state programs.

A key challenge in relational property verification is the discovery of relational invariants which relate the states of multiple program executions. However, whereas most prior approaches must fix the execution scheduleFootnote 1 (e.g., lock-step or sequential) [8, 20, 21, 42, 54, 57], a recent work by Shemer et al. [50] has proposed a method to automatically infer sufficient fair schedulers to prove the goal relational property. Importantly, the schedulers in their approach can be semantic in which the choice of which program to execute can depend on the states of the programs as opposed to the classic syntactic schedulers such as lock-step and sequential that can only depend on the control locations. However, their approach requires the user to provide appropriate atomic predicates and is not fully automatic. Moreover, they only support k-safety properties. A recent work has proposed a method for automatically verifying non-hypersafety relational properties but only for finite state systems [19].

Meanwhile, today’s constraint-based frameworks are also insufficient at automating relational verification. The class of predicate constraints called Constrained Horn Clauses (\(\mathrm {CHCs}\)) [13] has been widely adopted as a “common intermediate language” for uniformly expressing verification problems for various programming paradigms, such as functional and object-oriented languages. Example uses of the \(\mathrm {CHCs}\) framework include safety property verification [29, 30, 35] and refinement type inference [33, 36, 53, 56, 66]. The separation of constraint generation and solving has facilitated the rapid development of constraint generation tools such as RCaml [56], SeaHorn [30], and JayHorn [35] as well as efficient constraint solving tools such as SPACER [37], Eldarica [32], and HoIce [14]. Unfortunately, \(\mathrm {CHCs}\) lack the ingredients to sufficiently express these relational verification problems.

In this paper we introduce automated support for relational verification by generalizing \(\mathrm {CHCs}\) and introducing a new class of predicate Constraint Satisfaction Problems called \(\mathrm {pfwCSP}\). This language allows constraints that are arbitrary (i.e., possibly non-Horn) clauses modulo first-order theories over predicate variables that can be functional predicates, well-founded predicates or ordinary predicates. We then show that, thanks to the enhanced predicate variables, \(\mathrm {pfwCSP}\) can express non-hypersafety relational properties such as co-termination [11], termination-sensitive non-interference (TS-NI) [63], and generalized non-interference (GNI) [40]. In addition, our approach effectively quantifies over the schedule, expressing arbitrary fair semantic scheduling thanks to non-Horn clauses and functional predicates (functional predicates are needed to express fairness in the presence of non-termination which is needed for properties like co-termination and TS-GNI). The flexibility allows our approach to automatically discover a fair semantic schedule and verify difficult relational problem instances that require non-trivial schedules. We prove that our encodings are sound and complete. Expressing relational invariants with such flexible scheduling is not possible with \(\mathrm {CHCs}\). However, \(\mathrm {pfwCSP}\) retains a key benefit of \(\mathrm {CHCs}\): the idea of separating constraint generation from solving.

We next present a novel constraint solving method for \(\mathrm {pfwCSP}\) based on stratified CounterExample-Guided Inductive Synthesis (CEGIS) of ordinary, well-founded, and functional predicates. In our method, ordinary predicates represent relational inductive invariants, well-founded predicates witness synchronous termination, and functional predicates represent Skolem functions witnessing existential quantifiers that encode angelic non-determinism. These witnesses for a relational property are often mutually dependent and involve many variables in a complicated way (see the extended report [58] for examples). The synthesis thus needs to use expressive templates without compromising the efficiency. Stratified CEGIS combines CEGIS [51] with stratified families of templates [55] (i.e., decomposing templates into a series of increasingly expressive templates) to achieve completeness in the sense of [34, 55], a theoretical guarantee of convergence, and a faster and stable convergence by avoiding the overfitting problem of expressive templates to counterexamples [44]. The constraint solving method naturally generalizes a number of previous techniques developed for \(\mathrm {CHCs}\) solving and invariant/ranking function synthesis, addressing the challenges due to the generality of \(\mathrm {pfwCSP}\) that is essential for relational verification.

We have implemented the above framework and have applied our tool PCSat to a diverse collection of 20 relational verification problems and obtained promising results. The benchmark problems go beyond the capabilities of the existing related tools (such as \(\mathrm {CHCs}\) solvers and program verification tools). PCSat has solved 15 problems fully automatically by synthesizing complex witnesses for relational properties, and for the 5 problems that could not be solved fully automatically within the time limit, PCSat was able to solve them semi-automatically provided that a part of an invariant is manually given as a hint.

2 Overview

2.1 Relational Verification Problems

k-safety. Consider the following program taken from [50] that uses a summation to calculate the square of x, and then doubles it.

figure b

This program also takes another input h and, if the value of h is true, calculates the result differently. The classical relational property termination-insensitive non-interference (TI-NI) says that, roughly, an observer cannot infer the value of high security variables (h in this case) by observing the outputs (y). This is a 2-safety property [17, 54]: it relates two executions of the same program. In this example, we ask whether two executions that initially agree on x (i.e., \(\texttt {x}_1= \texttt {x}_2\)) will agree on the resulting y (i.e., \(\texttt {y}_1 = \texttt {y}_2\)). The subscripts in these relations indicate copies of the program: \(\texttt {x}_1\) is variable x in the first copy of the program and \(\texttt {x}_2\) is variable x in the second copy. More generally, k-safety means that if the initial states of a k-tuple of programs satisfy a pre-relation \( Pre \), then when they all terminate the k-tuple of post states will satisfy post-relation \( Post \).

The literature proposes many ways to reason about k-safety including methods of reducing a multi-program problem to a single-program problem, such as through self-composition [8, 54, 57], product programs [7], and their variants [21, 46, 50, 52, 59]. Their key challenge is that of scheduling: how to interleave the programs’ executions so that invariants in the combined program are able to effectively describe cross-program relationships. Indeed, as proved by [50], verifying this example with the naïve lock-step scheduling is impossible with only linear arithmetic invariants while linear arithmetic invariants suffice with a more “semantic” scheduling that schedules the copy with \(\texttt {h}_1 = {\texttt {false}}\) to iterate the loop twice per each iteration of the loop in the copy with \(\texttt {h}_2 = {\texttt {true}}\).

In this paper, we will describe a way to pose the scheduling problem as a part of a series of constraints so that the search for an effective scheduler is relegated to the solver level. In our approach, a k-safety verification problem is encoded as a set of constraints containing (ordinary) predicate variables that represent the scheduler to be discovered and a relational invariant preserved by the scheduler. Specially, we introduce a predicate variable \(\textsf {inv}\) that represents a relational invariant and for each \(A \subseteq \{1,\ldots ,k\}\), a predicate variable \(\textsf {sch}_A(\widetilde{{V}}_1,\ldots ,\widetilde{{V}}_k)\) where \(\widetilde{{V}}_i\) are the variables of the ith program, and add constraints that say that if the predicate is \({\texttt {true}}\), then the programs whose index are in A will step forward while the rest remain still and also \(\textsf {inv}\) is preserved by the step. For soundness, it is important to constrain the scheduler to be fair, i.e., at least one program that can progress must be scheduled to progress if there is a program that can progress. As we shall show in Sect. 4, non-Horn clauses are essential to expressing the fairness constraint. Roughly, the idea is to use a clause with multiple positive predicate variables (i.e., head disjunction) to say “if the relational invariant holds, then at least one of the unfinished programs must be scheduled to progress.”

Our approach is similar to and is inspired by the approach of [50] that also infers a fair semantic scheduler. However, their approach requires the user to provide sufficient atomic predicates manually and is not fully automated. By contrast, our approach soundly-and-completely encodes the k-safety verification problem together with scheduler inference as a set of constraints thanks to the expressiveness of \(\mathrm {pfwCSP}\), and automatically solves those constraints by the stratified CEGIS algorithm (cf. Sect. 7 for further comparison).

Co-termination. Now consider the following pair of programs.

A (non-safety) relational question is whether these programs \(P^{cot}_1\) and \(P^{cot}_2\) agree on termination [6, 10]. In general they do not: if, for example, \(P^{cot}_1\) is executed with \(\texttt {x}<0\) and \(P^{cot}_2\) with \(\texttt {x}>0 \wedge \texttt {y}=0\), the first will terminate while the second will diverge. However, under the pre-relation \( Pre \equiv \texttt {x}_1=\texttt {x}_2 \wedge \texttt {y}_1 = \texttt {y}_2\), they will agree on termination: the first program terminates iff the second one does. The property falls outside of the k-safety fragment as it cannot be refuted by finite execution traces. It is worth noting that termination-sensitive non-interference (TS-NI) is the conjunction of TI-NI and co-termination of two copies of the same target program with \( Pre \) equating the copies’ low inputs.

Proving co-termination, like k-safety, can be aided by scheduler and we can again use our constraints over predicate variables. But this is not enough. We need additional constraints to ensure that whenever one of the two has terminated, the other is also guaranteed to terminate. To address this, we next introduce well-founded predicate variables. These predicate variables will appear in our generalized language of constraints as terms of the form \(\mathsf {wfr}(\widetilde{{V}}_i,\widetilde{{V}}_i')\), where the relation \(\mathsf {wfr}\) must be discovered by the constraint solving method. (In Sect. 5 we describe how to achieve this through our stratified CEGIS algorithm.) For the above example, our stratified CEGIS algorithm and our tool PCSat automatically discovers (1) a schedule where the two programs step together when \(x_1>0\) and \(x_2>0\), (2) a relational invariant that implies that if the first program is terminated, then either the second program is terminated or \(y_2 \ge 1\) (and vice-versa), and (3) well-founded relations that (combined with the relational invariant) witness that if the loop has terminated in the second program (\(x_2 \le 0\)) but not in the first (\(x_1 > 0\)), then a transition in the first is well-founded (and vice-versa). In Sect. 4, we show how co-termination problems can be soundly-and-completely encoded in \(\mathrm {pfwCSP}\).

Generalized Non-interference. Now consider the following program.

figure c

The \(*{}^\texttt {int}\) (resp. \(*{}^\texttt {bool}\)) above indicates an integer (resp. a binary) non-deterministic choice. Termination-insensitive generalized non-interference (TI-GNI) [40] is an extension of non-interference to non-deterministic programs, and it says that for any two copies of the program with possibly different values for the high security input (\(\mathtt{high}\) in this example) and with the same value for the low security input (\(\mathtt{low}\) in this example), if one copy has a terminating execution that ends in some output (the final value of \(\texttt {x}\) in this example), then the other copy has either a terminating execution ending in the same output or a non-terminating execution. The termination-sensitive variant (TS-GNI) strengthens the condition by asserting that if one copy has a terminating execution then the other copy has a terminating execution that ends in the same output. Both GNI variants are \(\forall \exists \) hyperproperties and fall outside of the k-safety fragment.

Verifying GNI requires handling non-determinism. Note that non-determinism occurs both demonically (i.e., as \(\forall \)) and angelically (i.e., as \(\exists \)) in GNI. While handling demonic non-determinism is straightforward in a constraint-based verification since the term variables are implicitly universally quantified, handling angelic non-determinism is less straightforward.

Fig. 1.
figure 1

Overview of the contributions and how they achieve a constraint-based strategy for relational verification.

Our approach handles finitary angelic non-determinism like \(*{}^\texttt {bool}\) by adding non-Horn clauses with head disjunctions that roughly express the condition “the relational invariant remains true in one of the finitely many next step choices”. To handle infinitary non-determinism like \(*{}^\texttt {int}\), we introduce functional predicate variables denoted \(\textsf {f}(\widetilde{{V}},r)\). In these terms, f is a predicate variable to be discovered but with a new wrinkle: this predicate involves a return value r and the interpretation of f is a total function over \(\widetilde{{V}}\). For this example, we introduce the term \(\textsf {f}(\widetilde{{V}},r)\) where r represents the value chosen non-deterministically at \(*{}^\texttt {int}\) and \(\widetilde{{V}}\) are program variables and prophecy variables that represent the final return values of the demonic copy. For this example, PCSat automatically discovers the predicate \(r = \texttt {ret}_1\) where \(\texttt {ret}_1\) is the prophecy variable for the return value of the demonic copy. With it, PCSat is able to verify TS-GNI and TI-GNI of this example. We remark that functional predicates are also used to encode scheduler fairness in the presence of non-termination and is needed to ensure soundness for properties like co-termination and TS-GNI. In Sect. 4.3, we show how TI-GNI and TS-GNI can be soundly-and-completely encoded in \(\mathrm {pfwCSP}\).

2.2 Challenges and Contributions

There are several challenges that we face in supporting relational verification problems with a constraint-based approach. The subsequent sections of this paper are organized around addressing those challenges as follows:

  • We first ask how to generalize the constraint language to go beyond CHCs to express a more general class of relational verification problems. To this end, in Sect. 3, we present a new language called predicated constraint satisfaction problems (\(\mathrm {pfwCSP}\)), which incorporate non-Horn clauses, (ordinary) predicate variables, well-founded predicate variables, and functional predicate variables.

  • We next return to the above relational verification problems –k-safety, co-termination, and generalized non-interference– and describe how \(\mathrm {pfwCSP}\) can express each of them in a sound and complete manner in Sect. 4.

  • The next major contribution of our research is a novel stratified CEGIS algorithm for solving \(\mathrm {pfwCSP}\) constraints. Our approach integrates advanced verification techniques: stratified family of templates [55] and CEGIS of invariants/ranking functions [14, 26, 28, 45]. While the individual ideas have been proposed previously, they have only been designed for less expressive frameworks such as CHCs, and substantial extensions are needed to combine and apply them to the new \(\mathrm {pfwCSP}\) framework as we shall show in Sect. 5.

  • We next turn to an implementation and experimental validation on a diverse collection of 20 relational verification problems, consisting of k-safety problems from Shemer et al. [50] and new co-termination and GNI problems in Sect. 6. As far as we know, none of the existing automated tools other than our new tool called PCSat can solve them.

In sum, Fig. 1 depicts each of these sections and how, together, they enable relational verification. For space, extra materials are deferred to the extended report [58].

3 Predicate Constraint Satisfaction Problems \(\mathrm {pfwCSP}\)

As discussed in Sect. 2, \(\mathrm {CHCs}\) are insufficient to express important relational verification problems. In the section we introduced a generalized language of constraints called \(\mathrm {pfwCSP}\). The language of constraint satisfaction problems (CSP) permits non-Horn clauses, predicate variable terms, including those for functional predicates and well-founded relations (pfw). We now define \(\mathrm {pfwCSP}\).

Let \(\mathcal {T}\) be a (possibly many-sorted) first-order theory with the signature \(\varSigma \). The syntax of \(\mathcal {T}\)-formulas and \(\mathcal {T}\)-terms is:

$$\begin{aligned} \text {(formulas)} \; \phi&{:}{:}= X(\widetilde{{t}}) \mid p(\widetilde{{t}}) \mid \lnot \phi \mid \phi _1 \vee \phi _2 \mid \phi _1 \wedge \phi _2 \\ \text {(terms)} \; t&{:}{:}= x \mid f(\widetilde{{t}}) \end{aligned}$$

Here, the meta-variables x and X respectively range over term and predicate variables. The meta-variables p and f respectively denote predicate and function symbols of \(\varSigma \). We use s as a meta-variable ranging over sorts of the signature \(\varSigma \). We write \(\star \) for the sort of propositions and \(s_1 \rightarrow s_2\) for the sort of functions from \(s_1\) to \(s_2\). We write \(\mathrm {ar}(o)\) and \(\mathrm {sort}(o)\) respectively for the arity and the sort of a syntactic element o. A function f represents a constant if \(\mathrm {ar}(f)=0\). We write \( ftv (\phi )\) and \( fpv (\phi )\) respectively for the set of free term and predicate variables that occur in \(\phi \). We write \(\widetilde{{x}}\) for a sequence of term variables, \(|{\widetilde{{x}}}|\) for the length of \(\widetilde{{x}}\), and \(\epsilon \) for the empty sequence. We often abbreviate \(\lnot \phi _1 \vee \phi _2\) as \(\phi _1 \Rightarrow \phi _2\). We henceforth consider only well-sorted formulas and terms. We use \(\varphi \) as a meta-variable ranging over \(\mathcal {T}\)-formulas without predicate variables.

We now define a \(\mathrm {pCSP}\) \(\mathcal {C}\) (with ordinary but without well-founded and functional predicate variables) to be a finite set of clauses of the form

$$\begin{aligned} \textstyle \varphi \vee \left( \bigvee _{i=1}^{\ell } X_i(\widetilde{{t}}_i) \right) \vee \left( \bigvee _{i=\ell +1}^m \lnot X_i(\widetilde{{t}}_i) \right) \end{aligned}$$
(1)

where \(0 \le \ell \le m\). We write \( ftv (c)\) for the set of free term variables of a clause c. The set of free term variables of \(\mathcal {C}\) is defined by \( ftv (\mathcal {C}) = \bigcup _{c \in \mathcal {C}} ftv (c)\). We regard the variables in \( ftv (c)\) as implicitly universally quantified. We write \( fpv (\mathcal {C})\) for the set of free predicate variables that occur in \(\mathcal {C}\). A predicate substitution \(\sigma \) is a finite map from predicate variables X to closed predicates of the form \(\lambda x_1,\dots ,x_{\mathrm {ar}(X)}.\varphi \). We write \(\sigma (\mathcal {C})\) for the application of \(\sigma \) to \(\mathcal {C}\) and \(\mathrm {dom}(\sigma )\) for the domain of \(\sigma \). We call \(\sigma \) a syntactic solution for \(\mathcal {C}\) if \( fpv (\mathcal {C}) \subseteq \mathrm {dom}(\sigma )\) and \(\models \bigwedge \sigma (\mathcal {C})\). Similarly, we call a predicate interpretation \(\rho \) a semantic solution for \(\mathcal {C}\) if \( fpv (\mathcal {C}) \subseteq \mathrm {dom}(\rho )\) and \(\rho \models \bigwedge \mathcal {C}\).

Remark 1

The language \(\mathrm {pCSP}\) generalizes over existing languages of constraints. \(\mathrm {CHCs}\) can be obtained as a restriction of \(\mathrm {pCSP}\) where \(\ell \le 1\) in (1) for all clauses. We can also define \(\mathrm {coCHCs}\) as \(\mathrm {pCSP}\) but with the restriction that \(m \le \ell +1\) for all clauses. A linear \(\mathrm {CHCs}\) is a \(\mathrm {pCSP}\) that is both \(\mathrm {CHCs}\) and \(\mathrm {coCHCs}\).

We next extend \(\mathrm {pCSP}\) to \(\mathrm {pfwCSP}\) by adding well-foundedness and function-ness constraints. A \(\mathrm {pfwCSP}\) \((\mathcal {C},\mathcal {K})\) consists of

  • a finite set \(\mathcal {C}\) of \(\mathrm {pCSP}\)-clauses over predicate variables and

  • a kinding function \(\mathcal {K}\) that maps each predicate variable \(X \in fpv (\mathcal {C})\) to its kind: any one of \(\bullet \), \(\Downarrow \), or \(\lambda \) which respectively represent ordinary, well-founded, and functional predicate variables.

We write \(\rho \models WF (X)\) if the interpretation \(\rho (X)\) of the predicate variable X is well-founded, that is, \(\mathrm {sort}(X)=(\widetilde{{s}},\widetilde{{s}}) \rightarrow \star \) for some \(\widetilde{{s}}\) and there is no infinite sequence \(\widetilde{{v}}_1,\widetilde{{v}}_2,\dots \) of sequences \(\widetilde{{v}}_i\) of values of the sorts \(\widetilde{{s}}\) such that \((\widetilde{{v}}_i,\widetilde{{v}}_{i+1}) \in \rho (X)\) for all \(i\ge 1\). We write \(\rho \models FN (X)\) if X is functional, that is, \(\mathrm {sort}(X)=(\widetilde{{s}},s) \rightarrow \star \) for some \(\widetilde{{s}}\) and s, and \(\rho \models \forall \widetilde{{x}} :\widetilde{{s}}. (\exists y :s. X(\widetilde{{x}},y)) \wedge \forall y_1,y_2 :s. (X(\widetilde{{x}},y_1) \wedge X(\widetilde{{x}},y_2) \Rightarrow y_1=y_2)\) holds. We call a predicate interpretation \(\rho \) a semantic solution for \((\mathcal {C},\mathcal {K})\) if \(\rho \) is a semantic solution of \(\mathcal {C}\), \(\rho \models WF (X)\) for all X such that \(\mathcal {K}(X)=\Downarrow \), and \(\rho \models FN (X)\) for all X such that \(\mathcal {K}(X)=\lambda \). The notion of syntactic solution can be similarly generalized to \(\mathrm {pfwCSP}\).

Definition 1

(Satisfiability of \(\mathrm {pfwCSP}\)). The predicate satisfiability problem of a \(\mathrm {pfwCSP}\) \((\mathcal {C},\mathcal {K})\) is that of deciding whether it has a semantic solution.

Remark 2

Recall that we assume that the \(\mathcal {T}\)-formulas \(\varphi \) in \(\mathrm {pCSP}\) clauses do not contain quantifiers. The assumption, however, is not a restriction for \(\mathrm {pfwCSP}\) because we can Skolemize quantifiers using functional predicates.

4 Relational Verification with Constraints

We now present reductions from relational verification problems to \(\mathrm {pfwCSP}\), thus enabling a new route to automation of these problems. We begin with k-safety, and then move toward liveness and non-determinism, which are thorny problems in the relational setting. We first provide some basic definitions and notations.

Programs. We consider programs \(P_1\),...,\(P_k\) on variables \(\widetilde{{V_1}}\),...,\(\widetilde{{V_k}}\), respectively. A state of the program \(P_i\) is a valuation of the variables \(\widetilde{{V_i}}\). We represent such a valuation by a sequence of values \(\widetilde{{v}}\) such that \(|{\widetilde{{v}}}| = |{\widetilde{{V_i}}}|\). We assume that each \(P_i\) is defined by the predicate \(T_i(\widetilde{{V_i}},\widetilde{{V_i}}')\) denoting its one-step transition relation i.e., \(T_i(\widetilde{{v}},\widetilde{{v}}')\) implies that evaluating \(P_i\) one step from the state \(\widetilde{{v}}\) reaches the state \(\widetilde{{v}}'\). We also assume that there is a predicate \(F_i(\widetilde{{V_i}})\) that represents the final states of the program such that \(F_i(\widetilde{{v}})\) and \(T_i(\widetilde{{v}},\widetilde{{v}}')\) implies \(\widetilde{{v}} = \widetilde{{v}}'\), i.e., the program self-loops when it reaches a final state. We say that a state \(\widetilde{{v}}\) (multi-step) reaches a final state \(\widetilde{{v}}'\) in the evaluation of \(P_i\), written \(\widetilde{{v}} \rightsquigarrow _i \widetilde{{v}}'\), if there exists a non-empty finite sequence of states \(\pi \) such that \(\pi [1] = \widetilde{{v}}\), \(\pi [|{\pi }|] = \widetilde{{v}}'\), \(T_i(\pi [j-1],\pi [j])\) for all \(1 < j \le |{\pi }|\), and \(F_i(\widetilde{{v}}')\). We write \(\widetilde{{v}} \rightsquigarrow _i \bot \) if there exists a non-terminating evaluation from \(\widetilde{{v}}\) in \(P_i\), i.e., if there exists an infinite sequence of states \(\varpi \) such that \(\varpi [1] = \widetilde{{v}}\), \(T_i(\varpi [j-1],\varpi [j])\) for all \(1 < j\), and \(\lnot F_i(\varpi [j])\) for all \(0 < j\). We note that a program may be non-deterministic, that is, \(T_i(\widetilde{{v}},\widetilde{{v}}')\) and \(T_i(\widetilde{{v}},\widetilde{{v}}'')\) may both be true for some \(\widetilde{{v}}' \ne \widetilde{{v}}''\).

4.1 k-Safety

A k-safety property is given by predicates \( Pre (\widetilde{{V}})\) and \( Post (\widetilde{{V}})\) that respectively denote the pre and the post relations across the k-tuple.

Definition 2

(k-safety). The k -safety property verification problem is to decide if the following holds:

$$\begin{aligned} \begin{array}{l} \forall \widetilde{{v}} = \widetilde{{v_1}},\dots ,\widetilde{{v_k}}.\forall \widetilde{{v}}' = \widetilde{{v_1}}',\dots ,\widetilde{{v_k}}'. Pre (\widetilde{{v}}) \wedge \bigwedge _{i\in [k]} \widetilde{{v_i}} \rightsquigarrow _i\widetilde{{v_i}}' \Rightarrow Post (\widetilde{{v}}') \end{array} \end{aligned}$$

That is, any k-tuple of final states reachable from a k-tuple of states satisfying the precondition satisfies the post condition. For instance, the TI-NI verification from Sect. 2.1 is a 2-safety property where \(P_1\) and \(P_2\) are copies of the same program, \( Pre \) states that the low inputs of the two programs are equal (i.e., \(\texttt {x}_1 = \texttt {x}_2\) in the example), and \( Post \) states that the low outputs of the two programs are equal (i.e., \(\texttt {y}_1 = \texttt {y}_2\) in the example).

We now describe a new way to pose the k-safety relational verification problem via constraints written in \(\mathrm {pfwCSP}\). We write [k] for the set \(\{1,\dots ,k \}\). We define \(\mathcal {P}^+{[k]} = \{ S \subseteq [k] \mid S \ne \emptyset \}\). Let \(\widetilde{{V}} = \widetilde{{V_1}}\),...,\(\widetilde{{V_k}}\) be a k-tuple of vectors, corresponding to the variables of the k programs.

Definition 3

(k-safety through constraints). We define \(\mathrm {pfwCSP}\) constraints \(\mathcal {C}_\mathrm {S}\) be the set of following clauses:

  1. (1)

    \( Pre (\widetilde{{V}}) \Rightarrow \mathsf {inv}(\widetilde{{V}})\)

  2. (2)

    \(\mathsf {inv}(\widetilde{{V}}) \wedge \bigwedge _{i \in [k]} F_i(\widetilde{{V_i}}) \Rightarrow Post (\widetilde{{V}})\)

  3. (3)

    For each \(A \in \mathcal {P}^+{[k]}\),    \( \mathsf {inv}(\widetilde{{V}}) \wedge \mathsf {sch}_A(\widetilde{{V}}) \wedge \bigwedge _{i \in A} T_i(\widetilde{{V_i}},\widetilde{{V_i}}') \wedge \bigwedge _{i \in [k]\setminus A} \widetilde{{V_i}} = \widetilde{{V_i}}' \Rightarrow \mathsf {inv}(\widetilde{{V}}') \)

  4. (4)

    For each \(A \in \mathcal {P}^+{[k]}\), \(\mathsf {inv}(\widetilde{{V}}) \wedge \mathsf {sch}_A(\widetilde{{V}}) \wedge \bigvee _{i \in [k]} \lnot F_i(\widetilde{{V_i}}) \Rightarrow \bigvee _{i \in A} \lnot F_i(\widetilde{{V_i}})\)

  5. (5)

    \(\mathsf {inv}(\widetilde{{V}}) \wedge \bigvee _{i \in [k]} \lnot F_i(\widetilde{{V_i}}) \Rightarrow \bigvee _{A \in \mathcal {P}^+{[k]}} \mathsf {sch}_A(\widetilde{{V}})\).

Here, \(\mathsf {inv}\) and \(\mathsf {sch}_A\) (for each \(A \in \mathcal {P}^+{[k]}\)) are ordinary predicate variables. Roughly, the predicate variables \(\mathsf {sch}_A\) describe a scheduler. The scheduler stipulates that when \(\mathsf {sch}_A(\widetilde{{v_1}},\dots ,\widetilde{{v_k}})\) is true, each \(P_i\) such that \(i \in A\) takes a step from the state \(\widetilde{{v_i}}\) while the others remain still. Note that the scheduler is semantic in the sense that which programs are scheduled to be executed next can depend on the current states of the programs. Clauses (1)–(3) assert that \(\mathsf {inv}\) is an invariant sufficient to prove the given safety property with the scheduler defined by \(\mathsf {sch}_A\)’s. Clauses (4) say that if an \(\mathsf {inv}\)-satisfying state is such that the processes in A are allowed to move and some program has not yet terminated, then at least one process in A has not yet terminated. Clause (5) says that any state satisfying \(\mathsf {inv}\) has to satisfy some \(\mathsf {sch}_A\). Clauses (4) and (5) ensure the fairness of the scheduler, that is, at least one unfinished program is scheduled to make progress if there is an unfinished program.

Theorem 1

(Soundness and Completeness of \(\mathcal {C}_\mathrm {S}\)). The given k-tuple of programs satisfies the given k-safety property iff \(\mathcal {C}_\mathrm {S}\) is satisfiable.

We note that the soundness direction crucially relies on scheduler fairness. The completeness is with respect to semantic solutions (cf. Definition 1) and it is only “relative” with respect to syntactic solutions: a syntactic solution only exists when the predicates of the background theory are able to express sufficient invariants and schedulers (impossible in general for any decidable theory when the class of programs is Turing-powerful as in our case when the background theory of predicates is QFLIA).

It is important to note that \(\mathcal {C}_\mathrm {S}\) is not \(\mathrm {CHCs}\) because clause (5) has a head disjunction. \(\mathcal {C}_\mathrm {S}\) may be seen as a constraint-based formulation of the approach proposed in [50]. However, their approach requires the user to provide sufficient predicates manually and is not fully automated, while our approach can fully automatically solve the problems by constraint solving (cf. Sect. 5).

Example 1

The formalization allows flexible scheduling. For instance, for the TI-NI example from Sect. 2.1, our approach is able to infer the predicate substitution that maps \(\mathsf {sch}_{\{1\}}\), \(\mathsf {sch}_{\{2\}}\), and \(\mathsf {sch}_{\{1,2\}}\) to \(\lambda \widetilde{{V}}.\texttt {h}_1 \wedge \lnot \texttt {h}_2 \wedge \texttt {z}_1 = 2\texttt {z}_2\), \(\lambda \widetilde{{V}}.\lnot \texttt {h}_1 \wedge \texttt {h}_2 \wedge \texttt {z}_2 = 2\texttt {z}_1\), and \(\lambda \widetilde{{V}}.(\texttt {h}_1 \wedge \lnot \texttt {h}_2 \Rightarrow \texttt {z}_1+1 = 2\texttt {z}_2) \wedge (\lnot \texttt {h}_1 \wedge \texttt {h}_2 \wedge \texttt {z}_2+1 = 2\texttt {z}_1)\) respectively, where \(\widetilde{{V}}\) is the list of the variables in the two program copies. The inferred predicates stipulate that the copy with \(\texttt {h}= {\texttt {true}}\) is scheduled to execute the loop two times per every loop iteration of the copy with \(\texttt {h}= {\texttt {false}}\). The extended report [58] shows the \(\mathrm {pfwCSP}\) encoding of the example. A solution generated by PCSat is also shown in [58].

4.2 Co-termination

Intuitively, co-termination means that if one program terminates, then a second program must terminate [6, 10]. This can also be thought of as a form of relational termination problem.Footnote 2

Definition 4 (Co-termination)

The co-termination verification problem is to decide if for all \(\widetilde{{v_1}},\widetilde{{v_2}}\) such that \( Pre (\widetilde{{v_1}},\widetilde{{v_2}})\), if \(\widetilde{{v_1}} \rightsquigarrow _1 \widetilde{{v_1'}}\) then .

Roughly, the property says that from any pair of states related by \( Pre \), if \(P_1\) terminates, then \(P_2\) must also terminate. Note that this is an asymmetric property. A symmetric version can be obtained by also asserting the property with the positions of the two programs exchanged. The symmetric version implies, assuming that there is at least one execution from any \( Pre \)-related state, that from any pair of \( Pre \)-related states, all executions from one state terminates iff all executions from the other one do as well. We now present an encoding of conditional co-termination in \(\mathrm {pfwCSP}\).

Definition 5 (Co-termination through constraints)

Let \(\widetilde{{V}} = \widetilde{{V_1}}, \widetilde{{V_2}}\). We define \(\mathrm {pfwCSP}\) constraints \(\mathcal {C}_\mathrm {CoT}\) be the set of following clauses:

  1. (1)

    \( Pre (\widetilde{{V}}) \wedge \textsf {fnb}(\widetilde{{V}},b) \Rightarrow \mathsf {inv}(0,b,\widetilde{{V}})\)

  2. (2)

    \(\mathsf {inv}(d,b,\widetilde{{V}}) \wedge \lnot F_1(\widetilde{{V_1}}) \wedge \lnot F_2(\widetilde{{V_2}}) \Rightarrow (-b \le d \wedge d \le b \wedge b \ge 0)\)

  3. (3a)

    \(\mathsf {inv}(d,b,\widetilde{{V}}) \wedge \mathsf {sch}_{\mathsf {FT}}(d,b,\widetilde{{V}}) \wedge T_2(\widetilde{{V_2}},\widetilde{{V_2}}') \wedge (F_1(\widetilde{{V_1}}) \vee F_2(\widetilde{{V_2}}) \vee d' = d-1) \Rightarrow \mathsf {inv}(d',b,\widetilde{{V_1}},\widetilde{{V_2}}')\)

  4. (3b)

    \(\mathsf {inv}(d,b,\widetilde{{V}}) \wedge \mathsf {sch}_{\mathsf {TF}}(d,b,\widetilde{{V}}) \wedge T_1(\widetilde{{V_1}},\widetilde{{V_1}}') \wedge (F_1(\widetilde{{V_1}}) \vee F_2(\widetilde{{V_2}}) \vee d' = d+1) \Rightarrow \mathsf {inv}(d',b,\widetilde{{V_1}}',\widetilde{{V_2}})\)

  5. (3c)

    \(\mathsf {inv}(d,b,\widetilde{{V}}) \wedge \mathsf {sch}_{\mathsf {TT}}(d,b,\widetilde{{V}}) \wedge T_1(\widetilde{{V_1}},\widetilde{{V_1}}') \wedge T_2(\widetilde{{V_2}},\widetilde{{V_2}}') \Rightarrow \mathsf {inv}(d,b,\widetilde{{V_1}}',\widetilde{{V_2}}')\)

  6. (4a)

    \(\mathsf {inv}(d,b,\widetilde{{V}}) \wedge \mathsf {sch}_{\mathsf {FT}}(d,b,\widetilde{{V}}) \wedge \lnot F_1(\widetilde{{V_1}}) \Rightarrow \lnot F_2(\widetilde{{V_2}})\)

  7. (4b)

    \(\mathsf {inv}(d,b,\widetilde{{V}}) \wedge \mathsf {sch}_{\mathsf {TF}}(d,b,\widetilde{{V}}) \wedge \lnot F_2(\widetilde{{V_2}}) \Rightarrow \lnot F_1(\widetilde{{V_1}})\)

  8. (5)

    \(\mathsf {inv}(d,b,\widetilde{{V}}) \wedge (\lnot F_1(\widetilde{{V_1}}) \vee \lnot F_2(\widetilde{{V_2}})) \Rightarrow \bigvee _{a\in \{\mathsf {TT},\mathsf {FT},\mathsf {TF}\}} \textsf {sch}_{a}(d,b,\widetilde{{V}})\)

  9. (6)

    \(\mathsf {inv}(d,b,\widetilde{{V}}) \wedge F_1(\widetilde{{V_1}}) \wedge \lnot F_2(\widetilde{{V_2}}) \wedge T_2(\widetilde{{V_2}},\widetilde{{V_2}}') \Rightarrow \mathsf {wfr}(\widetilde{{V_2}},\widetilde{{V_2}}')\)

Here, \(\mathsf {sch}_\mathsf {TT}\), \(\mathsf {sch}_\mathsf {FT}\), and \(\mathsf {sch}_\mathsf {TF}\) are 2-specialization of the k-safety scheduler of Definition 3. Clauses (3x)’s are similar to (3) of Definition 3 and assert that \(\mathsf {inv}\) is an invariant under the scheduler. Clauses (4x)’s and (5), like (4) and (5) of Definition 3, are used to ensure the scheduler fairness. However, they are insufficient for co-termination as a non-terminating copy can be scheduled indefinitely leaving the other copy unscheduled. Clauses (1) and (2) are added to amend the issue. In (1), \(\textsf {fnb}\) is a functional predicate variable that is used to select a bound b, and (2) asserts that the difference d between the numbers of steps taken by the two copies is within b in any state in \(\mathsf {inv}\) when neither copy has terminated. Note that d is initialized to 0 by (1) and properly updated in (3x)’s. Finally, by using the well-founded predicate variable \(\mathsf {wfr}\), (6) asserts that if \(P_1\) has terminated, then so must eventually \(P_2\).

Theorem 2

(Soundness and Completeness of \(\mathcal {C}_\mathrm {CoT}\)). The given pair of programs co-terminate iff \(\mathcal {C}_\mathrm {CoT}\) is satisfiable.

As with Theorem 1, the soundness direction relies on scheduler fairness.

Example 2

Via the encoding, our PCSat tool is able to verify the symmetric co-termination example from Sect. 2.1 by automatically inferring the solution described there. For space, the concrete constraint set and solution are given in the extended report [58].

4.3 Generalized Non-interference

We now turn to another relational property that cannot simply be captured by k-safety or co-termination. So-called termination-insensitive (resp. -sensitive) generalized non-interference (resp. TI-GNI, TS-GNI) are \(\forall \exists \) hyperproperties: from any pre-related pair of states whenever one side can take a move to a post state, there must be a way for the other side to also move to a post state such that the post-relation holds. As remarked in Sect. 2, verifying GNI requires reasoning about both demonic (i.e., for all) and angelic (i.e., exists) non-determinism.

Definition 6 (TI/TS-GNI)

The GNI verification problem is to decide if the following holds. If \( Pre (\widetilde{{v_1}},\widetilde{{v_2}})\) and \(\widetilde{{v_1}} \rightsquigarrow _1 \widetilde{{v_1}}'\) then (TI-GNI) \((\exists \widetilde{{v_2}}'.\widetilde{{v_2}} \rightsquigarrow _2 \widetilde{{v_2}}' \wedge Post (\widetilde{{v_1}}',\widetilde{{v_2}}')) \vee \widetilde{{v_2}} \rightsquigarrow _2 \bot \); or (TS-GNI) \(\exists \widetilde{{v_2}}'.\widetilde{{v_2}} \rightsquigarrow _2 \widetilde{{v_2}}' \wedge Post (\widetilde{{v_1}}',\widetilde{{v_2}}')\).

Note that our definition is parameterized by \( Pre \) and \( Post \). The standard GNI definitions [40] can be obtained by letting \(P_1\) and \(P_2\) be copies of the same target program and letting \( Pre \) be the predicate equating the low inputs of the copies and \( Post \) be the predicate equating the low outputs of the copies.

To formalize the \(\mathrm {pfwCSP}\) encodings of the GNI verification problems, we define a relation \(U_2\) to be one such that \(T_2(\widetilde{{v}},\widetilde{{v}}') \Leftrightarrow \exists r. U_2(r,\widetilde{{v}},\widetilde{{v}}')\) and \(U_2(r,\widetilde{{v}},\widetilde{{v}}') \wedge U_2(r,\widetilde{{v}},\widetilde{{v}}'') \Rightarrow \widetilde{{v}}' = \widetilde{{v}}''\). Roughly, \(U_2\) is a function version of the transition relation \(T_2\) with the extra parameter r to make the non-deterministic choices explicit.

We now show the \(\mathrm {pfwCSP}\) encodings of TI-GNI and TS-GNI. The key idea is to augment the encodings for k-safety and/or co-termination with functional predicate variables and prophecy variables that respectively represent the non-deterministic choices of the angelic side (i.e., \(P_2\)) and the final outputs of the demonic side (i.e., \(P_1\)).

Definition 7 (TI-GNI through constraints)

We define \(\mathrm {pfwCSP}\) constraints \(\mathcal {C}_\mathrm {TIGNI}\) as \(\mathcal {C}_\mathrm {S}\) in Definition 3 for \(k=2\) but with the following modifications:

  • (m1) The parameters representing the inputs and outputs of \(P_1\) is extended with prophecy variables \(\widetilde{{p}}\) where \(|{\widetilde{{p}}}| = |{\widetilde{{V_1}}}|\). Accordingly, each occurrence of \(\widetilde{{V_1}}\) is replaced by \(\widetilde{{p}},\widetilde{{V_1}}\), and each occurrence of \(\widetilde{{V_1}}'\) is replaced by \(\widetilde{{p}}',\widetilde{{V_1}}'\).

  • (m2) \( Pre \) is replaced by \( Pre '\) which is defined by \( Pre '(\widetilde{{p}},\widetilde{{V_1}},\widetilde{{V_2}}) \Leftrightarrow Pre (\widetilde{{V_1}},\widetilde{{V_2}})\), i.e., the prophecy values are unconstrained in the precondition.

  • (m3) \(F_1\) is replaced by \(F_1'\) defined by \(F_1'(\widetilde{{p}},\widetilde{{V_1}}) \Leftrightarrow F_1(\widetilde{{V_1}})\).

  • (m4) \(T_1\) is replaced by \(T_1'\) defined by \(T_1'(\widetilde{{p}},\widetilde{{V_1}},\widetilde{{p}}',\widetilde{{V_1}}') \Leftrightarrow T_1(\widetilde{{V_1}},\widetilde{{V_1}}') \wedge \widetilde{{p}} = \widetilde{{p}}'\).

  • (m5) \( Post \) is replaced by \( Post '\) defined by \( Post '(\widetilde{{p}},\widetilde{{V_1}},\widetilde{{V_2}}) \Leftrightarrow (\widetilde{{p}} = \widetilde{{V_1}} \Rightarrow Post (\widetilde{{V_1}},\widetilde{{V_2}}))\), i.e., if the prophecy was correct then the original post condition must hold.

  • (m6) Each occurrence of \(T_2(\widetilde{{V_2}},\widetilde{{V_2}}')\) is replaced by \(\textsf {fnr}(\widetilde{{p}},\widetilde{{V_2}},r) \wedge U_2(r,\widetilde{{V_2}},\widetilde{{V_2}}')\) where \(\textsf {fnr}\) is a functional predicate variable.

Modifications (m1)–(m5) concern prophecy variables. They are initialized arbitrarily as shown in (m2), propagated unmodified through the transitions as shown in (m4), and finally checked if they match \(P_1\)’s outputs in (m5). Modification (m6) adds functional predicate variables to express the angelic non-deterministic choices of \(P_2\). The functional predicate variables shift the onus of making the right choices to the solver’s task of discovering sufficient assignments to them. Importantly, the functional predicate takes the prophecy variables as parameters, thus allowing dependence on the final outputs of the demonic side.

Definition 8 (TS-GNI through constraints)

We define \(\mathrm {pfwCSP}\) constraints \(\mathcal {C}_\mathrm {TSGNI}\) as \(\mathcal {C}_\mathrm {CoT}\) in Definition 5 but with modifications of Definition 7 except (m3) and (m5), and with the following modifications:

  • (m3’) \(F_1\) is replaced by \(F_1'\) defined by \(F_1'(\widetilde{{p}},\widetilde{{V_1}}) \Leftrightarrow F_1(\widetilde{{V_1}}) \wedge \widetilde{{p}} = \widetilde{{V_1}}\).

  • (m5’) The clause \(\mathsf {inv}(\widetilde{{p}},\widetilde{{V_1}},\widetilde{{V_2}}) \wedge F_1'(\widetilde{{p}},\widetilde{{V_1}}) \wedge F_2(\widetilde{{V_2}}) \Rightarrow Post (\widetilde{{V_1}},\widetilde{{V_2}})\) is added.

\(\mathcal {C}_\mathrm {TSGNI}\) is similar to \(\mathcal {C}_\mathrm {TIGNI}\) except that it contains the difference bound and well-foundedness constraints to handle the “co-termination” aspect of TS-GNI, i.e., if \(P_1\) terminates and makes an output then \(P_2\) must also be able terminate and make a matching output. One subtle aspect of the encoding is that (m3’) modifies the final state predicate for \(P_1\) to enforce co-termination only when the prophecy is correct. However, it is worth noting that TS-GNI is not a conjunction of TI-GNI and co-termination. For instance, the GNI example from Sect. 2.1 satisfies TS-GNI but does not satisfy co-termination.

Theorem 3 (Soundess and Completeness of TI-GNI)

The given pair of programs satisfy TI-GNI iff \(\mathcal {C}_\mathrm {TIGNI}\) is satisfiable.

Theorem 4 (Soundess and Completeness of TS-GNI)

The given pair of programs satisfy TS-GNI iff \(\mathcal {C}_\mathrm {TSGNI}\) is satisfiable.

The soundness directions are proven by “determinizing” the angelic choices by solutions to the functional predicate variables and reducing the argument to those of k-safety and co-termination. The completeness directions are proven by “synthesizing” sufficient angelic choice functions from program executions.

Example 3

Via the encoding, our PCSat tool is able to verify the TS-GNI example from Sect. 2.1 by automatically inferring not only the functional predicate described there but also relational invariants and well-founded relations given in the extended report [58]. For space, the concrete constraint set is also given in [58].

Remark 3

The angelic non-determinism encoding can be optimized by using head disjunctions when the non-determinism is finitary (i.e., \(\max _{\widetilde{{v}}} |{\{ \widetilde{{v}}' \mid T_2(\widetilde{{v}},\widetilde{{v}}')\}}|\) is finite) instead of using functional predicate variables. For this, we modify clauses (3) and (3x)’s of Definition 7 and 8 to contain multiple positive occurrences of \(\mathsf {inv}\) where each occurrence represents one of the finitely many possible choices.

Remark 4

Recall that we allow any program to be non-deterministic. The k-safety and co-termination encodings treat non-determinism in all programs as demonic, whereas the GNI encodings treat those in one program (i.e., \(P_1\)) as demonic and those in the other program (i.e., \(P_2\)) as angelic. In general, an arbitrary program can be made angelic by applying the transformation done in the angelic side of GNI encodings (to factor out non-determinism).

5 Constraint Solving Method for \(\mathrm {pfwCSP}\)

We describe a CEGIS-based method for finding a (syntactic) solution of the given \(\mathrm {pfwCSP}\) \((\mathcal {C},\mathcal {K})\). Our method iterates the following phases until convergence. The iteration maintains and builds a sequence \(\sigma \) of candidate solutions and a sequence \(\mathcal {E}\) of example instances where \(\mathcal {E}^{(i)}\) are ground clauses obtained from \(\mathcal {C}\) by instantiating the term variables and serve as a counterexample to the candidate solution \(\sigma ^{(i-1)}\), for each i-th iteration. The iteration starts from \(\mathcal {E}^{(1)}=\emptyset \).

Synthesis Phase: We check if \((\mathcal {E}^{(i)},\mathcal {K})\) is unsatisfiable. If so, we stop by returning \(\mathcal {E}^{(i)}\) as a genuine counterexample to the input problem \((\mathcal {C},\mathcal {K})\). Otherwise, we use the synthesizer \(\mathcal {S}_{ T B}\) (cf. Sect. 5.1) to find a solution \(\sigma ^{(i)}\) of \((\mathcal {E}^{(i)},\mathcal {K})\), which will be used as the next candidate solution.

Validation Phase: We check if \(\sigma ^{(i)}\) is a genuine solution to \((\mathcal {C},\mathcal {K})\) by using an SMT solver. If so, we stop by returning \(\sigma ^{(i)}\) as a solution. Otherwise, for each clause \(c \in \mathcal {C}\) not satisfied by \(\sigma ^{(i)}\), we obtain a term substitution \(\theta _c\) such that \(\mathrm {dom}(\theta _c)= ftv (c)\) and \(\not \models \theta _c(\sigma ^{(i)}(c))\). We then update the example set by adding a new example instance for each unsatisfied clause (i.e., \(\mathcal {E}^{(i+1)}=\mathcal {E}^{(i)} \cup \{\,\theta _c(c) \mid c \in \mathcal {C}\wedge \not \models \sigma ^{(i)}(c)\,\}\)), and proceed to the next iteration.

The above procedure satisfies the usual progress property of CEGIS: discovered counterexamples and candidate solutions are not discovered again in succeeding iterations. Furthermore, as discussed in Sect. 5.1, by carefully designing the synthesizer \(\mathcal {S}_{ T B}\) by incorporating stratified CEGIS, we achieve completeness in the sense of [34, 55]: if the given \(\mathrm {pfwCSP}\) \((\mathcal {C},\mathcal {K})\) has a syntactic solution expressible in the stratified families of templates, a solution of the \(\mathrm {pfwCSP}\) is eventually found by the procedure. In Sect. 5.1, we discuss the details of the synthesis phase. There, for space, we focus on the theory of quantifier-free linear integer arithmetic (QFLIA). For space, we defer the details of the unsatisfiability checking process to the extended report [58].

Remark 5

The implementation described in Sect. 6 contains an additional phase called resolution phase for accelerating the convergence. There, we first apply unit propagation repeatedly to the given \(\mathcal {E}^{(i)}\) to obtain positive examples \(\mathcal {E}^{(i)+}\) of the form \(X(\widetilde{{v}})\) and negative examples \(\mathcal {E}^{(i)-}\) of the form \(\lnot X(\widetilde{{v}})\). We then repeatedly apply resolution principle to the clauses in the input clauses \(\mathcal {C}\) and the clauses \(\mathcal {E}^{(i)+} \cup \mathcal {E}^{(i)-}\) to obtain additional positive and negative examples.

5.1 Predicate Synthesis with Stratified Families of Templates

We describe our candidate solution synthesizer \(\mathcal {S}_{ T B}\). \(\mathcal {S}_{ T B}\) performs a template-based search for a solution to the given example instances. As we shall show, our approach allows searching for assignments to all predicate variables (of all three kinds) in the given instance which is important because satisfying assignments to different predicate variables often inter-dependent. There, however, is a trade-off between expressiveness and generalizability. With less expressive templates like intervals, we may miss actual solutions. But with very expressive templates like polyhedra, there could be many solutions, and a solution thus returned is liable to overfitting, i.e., the solution to the example instances becomes too specific to be an actual solution to the original input clauses. [44] discusses a similar overfitting issue in the context of grammar-based synthesis.

Fig. 2.
figure 2

Stratified families of templates

Our remedy to the issue is stratified families of predicate templates, inspired by a similar approach proposed in the context of predicate abstraction with CEGAR [34, 55]. Initially, we assign each predicate variable a less expressive template and gradually refine it in a counterexample-guided manner: if no solution exists in the current template, we generate and analyze an unsat core to identify the parameters of the families of templates that should be updated. The stratification of templates thus automatically pushes the template to an expressive one (e.g., polyhedra) when it needs to. Importantly, with our approach, expressive templates are not always used but only when they should be used.

Stratified Families of Templates. We have designed three stratified families of templates shown in Fig. 2, respectively for ordinary (\(\bullet \)), well-founded (\(\Downarrow \)), and functional (\(\lambda \)) predicate variables. First, for each ordinary predicate variable X, we prepare the stratified family of templates \(T_X^\bullet ( nd , nc , ac , ad )\) with unknowns \(c_{i,j,k}\)’s to be inferred and its accompanying constraint \(\phi _X^\bullet ( nd , nc , ac , ad )\). The body of \(T_X^\bullet \) is a DNF with affine inequalities as atoms. The parameter \( nd \) (resp. \( nc \)) is the number of disjuncts (resp. conjuncts). The parameter \( ac \) is the upper bound of the sum of the absolute values of coefficients \(c_{i,j,k}\ (k > 0)\), and \( ad \) is the upper bound of the absolute value of \(c_{i,j,0}\).

Secondly, for each functional predicate variable X, we prepare the stratified family of templates \(T_X^\Downarrow ( np , nl , nc , rc , rd , dc , dd )\) with unknowns \(c_{i,j,k}\)’s and \(c_{i,j,k}'\)’s and its accompanying constraint \(\phi _X^\Downarrow ( np , nl , nc , rc , rd , dc , dd )\). \(T_X^\Downarrow \) represents the well-founded relation induced by a piecewise-defined lexicographic affine ranking function [2, 39, 39, 60, 61] where \(r_{i,j}\) is the affine ranking function template for the j-th lexicographic component of the i-th region specified by the discriminator \(D_i\). The parameter \( np \) (resp. \( nl \)) is the number of regions (resp. lexicographic components). The parameters \( rc , rd , dc , dd \) are the upper bounds of (the sums of) the absolute values of unknowns, similar to \( ac \) and \( ad \) of \(T_X^\bullet \). The first conjunct of \(T_X^\Downarrow \) asserts that the return value of each ranking functions is non-negative. The second and the third conjuncts assert that the discriminators cover all relevant states. Note that discriminators may overlap, and for such overlapping regions, the maximum return value of the ranking functions is used. The fourth conjunct asserts that the return value of the piecewise-defined ranking function strictly decreases from \(\widetilde{{x}}\) to \(\widetilde{{y}}\). Here, \( DEC _{i,j}(\widetilde{{x}},\widetilde{{y}})\) asserts that the return value of the lexicographic ranking function for the i-th region at \(\widetilde{{x}}\) is greater than that for the j-th region at \(\widetilde{{y}}\). It follows that for any substitution \(\theta \) for the unknowns in \(T_X^\Downarrow \), \(\theta (T_X^\Downarrow )\) represents a well-founded relation. Our implementation PCSat uses a refined version of \(T_X^\Downarrow \) shown in the extended report [58].

Finally, for each functional predicate variable X, we prepare the stratified family of templates \(T_X^\lambda ( nd , nc , dc , dd , ec , ed )\) with unknowns \(c_{i,j}\)’s and \(c_{i,j,k}'\)’s and its accompanying constraint \(\phi _F^\lambda ( nd , nc , dc , dd , ec , ed )\). \(T_X^\lambda \) characterizes a piecewise-defined affine function with discriminators \(D_1,\dots ,D_{ nd -1}\) and branch expressions \(e_1,\dots ,e_{ nd }\). The parameter \( nc \) is the number of conjuncts in each discriminator. The parameters \( dc , dd , ec , ed \) are the upper bounds of (the sums of) the absolute values of unknown, similar to \( ac \) and \( ad \) of \(T_X^\bullet \). Note that for any substitution \(\theta \) for the unknowns in \(T_X^\lambda \), \(\theta (T_X^\lambda )(\widetilde{{x}},r)\) expresses a total function that maps \(\widetilde{{x}}\) to r.

Next, we give the details of the candidate solution synthesis process. Let \(\widetilde{{p}} \in \mathbb {Z}^n\) where n is the number of parameters summed across all templates, and let \(T_X^\alpha (\widetilde{{p}})\) and \(\phi _X^\alpha (\widetilde{{p}})\) (for \(\alpha \in \left\{ \bullet , \Downarrow , \lambda \right\} \)) project the corresponding parameters. Each \(\widetilde{{p}} \in \mathbb {Z}^n\) induces a solution space \({\llbracket \widetilde{{p}}\rrbracket }_{} \triangleq \{ T(\widetilde{{p}})[\theta ] \mid \theta \models Con (\widetilde{{p}})\}\) where \(T(\widetilde{{p}})[\theta ] \triangleq \{ X \mapsto \theta (T_X^{\mathcal {K}(X)}(\widetilde{{p}})) \mid X \in fpv (\mathcal {C})\}\) and \( Con (\widetilde{{p}}) \triangleq \bigwedge _{X \in fpv (\mathcal {C})} \phi _X^{\mathcal {K}(X)}(\widetilde{{p}})\).

Let \(\widetilde{{p_1}} \le \widetilde{{p_2}}\) be the point-wise ordering. Note that \({\llbracket \widetilde{{p}}\rrbracket }_{}\) is a finite set for any \(\widetilde{{p}} \in \mathbb {Z}^n\), and \(\widetilde{{p_1}} \le \widetilde{{p_2}}\) implies \({\llbracket \widetilde{{p}}_1\rrbracket }_{} \subseteq {\llbracket \widetilde{{p}}_2\rrbracket }_{}\). We start the CEGIS process with some small initial parameters \(\widetilde{{p}}^{(0)}\) (the parameters will be maintained as a state of the CEGIS process). The synthesis phase of each iteration tries to find a solution \(\theta \in {\llbracket \widetilde{{p}}^{(i)}\rrbracket }_{}\) to the given example instances \((\mathcal {E},\mathcal {K})\) where \(\widetilde{{p}}^{(i)}\) are the current parameters. This is done by using an SMT solver for QFLIA to find \(\theta \) satisfying \(\bigwedge T(\widetilde{{p}}^{(i)})[\theta ](\mathcal {E}) \wedge \theta ( Con (\widetilde{{p}}^{(i)}))\). If such \(\theta \) is found, we return \(T(\widetilde{{p}}^{(i)})[\theta ]\) as the candidate solution for the next validation phase of the CEGIS process. Note that, by construction of the templates, the solution is guaranteed to assign each well-founded (resp. functional) predicate variable a well-founded relation (resp. total function). Otherwise, no solutions to the given example instances \((\mathcal {E},\mathcal {K})\) can be found in \({\llbracket \widetilde{{p}}^{(i)}\rrbracket }_{}\), and we update the parameters to some \(\widetilde{{p}}^{(i+1)} > \widetilde{{p}}^{(i)}\) such that \({\llbracket \widetilde{{p}}^{(i+1)}\rrbracket }_{}\) contains a solution for \((\mathcal {E},\mathcal {K})\). Here, it is important to do the update in a fair manner [34, 55], that is, in any infinite series of updates \(\widetilde{{p}}^{(0)},\widetilde{{p}}^{(1)},\dots \), every parameter is updated infinitely often (the details are deferred to below). By the progress property and the fact that every \({\llbracket \widetilde{{p}}\rrbracket }_{}\) is finite, this ensures that every parameter is updated infinitely often in an infinite series of CEGIS iterations. We thus obtain the following property.

Theorem 5

Our CEGIS-procedure based on stratified families of templates is complete in the sense of [34, 55]: if there is \(\widetilde{{p}}\) and \(\sigma \in {\llbracket \widetilde{{p}}\rrbracket }_{}\) such that \(\sigma \) is a syntactic solution to the given \(\mathrm {pfwCSP}\) \((\mathcal {C},\mathcal {K})\), a syntactic solution to \((\mathcal {C},\mathcal {K})\) is eventually found by the procedure.

Note that, while the solution space of each stratum (i.e., \({\llbracket \widetilde{{p}}^{(i)}\rrbracket }_{}\)) is finite, our procedure searches the infinite solution space obtained by taking the infinite union of the solution spaces of the template family strata (i.e., \(\bigcup _{i \in \omega }{\llbracket \widetilde{{p}}^{(i)}\rrbracket }_{}\)).

Remark 6

Our template-based synthesis simultaneously finds ordinary, well-founded, and functional predicates that are mutually dependent through the given \((\mathcal {E},\mathcal {K})\). This means that templates for different kinds of predicate variables are updated in a synchronized and balanced manner, which benefits the synthesis of mutually dependent witnesses for a relational property (see the extended report [58] for examples).

Updating Parameters of Template Families via Unsat Cores. We now describe the parameter update process. We first obtain the unsat core of the unsatisfiability of \(\bigwedge T(\widetilde{{p}}^{(i)})[\theta ](\mathcal {E}) \wedge \theta ( Con (\widetilde{{p}}^{(i)}))\) from the SMT solver. We then analyze the core to obtain the parameters of template families, such as the number of conjuncts and disjuncts, that have caused the unsatisfiability. Here, there could be a dependency between predicate variables and in such a case our unsat core analysis enumerates all the involved predicate variables from which we obtain the parameters of template families to be updated. We then increment these parameters in some fair manner, by limiting the maximum differences between different parameters to some bounded threshold, and repeatedly solve the resulting constraint until a solution is found. Thus, the parameters of stratified families of templates are grown on-the-fly guided by the reasons for unsatisfiability. We found that a careful design of parameter update strategies important for scaling the stratified CEGIS to hard relational verification problems. The manual tuning, however, is tiresome and suboptimal. We leave as future work to investigate methods for automatic tuning of parameter update strategies.

6 Evaluation

To evaluate the presented verification framework, we have implemented PCSat, a satisfiability checking tool for \(\mathrm {pfwCSP}\) based on stratified CEGIS. PCSat supports the theory of Booleans and the quantifier-free theory of linear inequalities over integers and rationals. The tool is implemented in OCaml, using Z3 [41] as the backend SMT solver. We ran the tool on a diverse collection of 20 relational verification problems, consisting of k-safety, co-termination, and GNI problems. Though we have manually reduced them to \(\mathrm {pfwCSP}\) using the presented method in Sect. 4, this process can be easily automated. The full benchmark set is provided in the extended report [58]. All experiments have been conducted on 3.1 GHz Intel Xeon Platinum 8000 CPU and 32 GB RAM with the time limit of 600 s.

The experimental results are summarized in Table 1. The columns “Time (s)” and “#Iters” respectively show elapsed wall clock time in seconds and numbers of CEGIS iterations. PCSat solved 15 verification problems fully automatically and 5 problems labeled with the symbol \(\dag \) and/or \(\ddag \) semi-automatically. For the 4 problems labeled with \(\dag \), we manually provided small hints for invariant synthesis (interested readers are referred to [58]). The provided hints for all but SquareSum are non-relational invariants that can be inferred prior to relational verification by using a \(\mathrm {CHCs}\) solver or an invariant synthesizer. For the 2 problems labeled with \(\ddag \), we manually chose the initial value for the parameters of the template family for ordinary predicate variables to reduce the elapsed time. This can be automated by running PCSat with different initial values in parallel.

The problems DoubleSquareNI_h**, HalfSquareNI, ArrayInsert, and SquareSum are k-safety verification problems obtained from [50] that require non-lock-step scheduling.Footnote 3 The problems DoubleSquareNI_h** are generated from Example 1 by a case analysis of the valuation for the boolean variables \(h_1\) and \(h_2\). PCSat solved all the k-safety problems but SquareSum fully automatically. The tool Pdsc proposed in [50] can verify them but requires the user to provide the atomic predicates for expressing relational invariants and schedulers. The problems CotermIntro1 and CotermIntro2 are asymmetric co-termination problems obtained from the symmetric problem in Example 2 and are verified by PCSat fully automatically. The problems TS_GNI_h** are generated from Example 3 by a case analysis and are verified by PCSat with small non-relational hints. We have also tested PCSat on various TS-GNI (SimpleTS_GNI1, SimpleTS_GNI2, InfBranchTS_GNI) and TI-GNI problems (TI_GNI_h**) and obtained promising results. As far as we know, no existing tools can verify these non-k-safety relational problems.

Furthermore, manual inspection of the PCSat’s output logs for the GNI problems that required hints revealed that the functional predicate synthesis appears to be the main bottleneck of the current version. In fact, we confirmed that the problems can be solved in less than 10 s if appropriate functional predicates for angelic non-determinism are manually provided. As future work, we plan to investigate methods for improved functional predicate synthesis.

7 Related Work

7.1 Relational Verification

There has been substantial work on verifying relational properties. They include program logics, type systems, or program analysis frameworks such as abstract interpretation and model checking [1, 5, 9, 19, 25, 52, 62], program transformation approaches such as self-composition or product programs [4, 7, 15, 20, 21, 42, 47, 54, 57, 64], and various other approaches [3, 18, 23, 46, 59]. We refer to [43] for an excellent survey. However, most prior automatic approaches address only the k-safety fragment [17, 54] and cannot verify non-k-safety (actually, not even hypersafety) properties such as co-termination, TS-NI, TI-GNI, and TS-GNI [6, 11, 40]. The only exception that we are aware is the recent work by Coenen et al. [19] that proposes a sound method for automatically verifying \(\forall \exists \) hyperproperties such as GNI for finite state systems. To our knowledge, we are the first to propose a sound-and-complete approach to automatically verifying these non-hypersafety properties for infinite state programs.Footnote 4

A key task in many relational verification methods, including ours, is the discovery of relational invariants which relate the states of multiple program executions. While most prior approaches are limited to fixed execution schedule (or alignment) such as lock-step and sequential [7, 8, 20, 21, 42, 54, 57], a recent work by Shemer et al. [50] has proposed a k-safety property verification method that automatically infers fair schedulers sufficient to prove the goal property. Importantly, the schedulers in their approach can be semantic in which the choice of which program to execute can depend on the states of the programs as opposed to the classic syntactic schedulers such as lock-step and sequential that can only depend on the control locations. Our approach also infers such fair semantic schedulers, and as remarked before, they enable solving instances like doubleSquare that are difficult for previous approaches. However, [50] requires the user to provide appropriate atomic predicates and is not fully automatic. By contrast, our approach soundly and completely encodes the problem as a constraint satisfaction problem and fully automatically verifies hard instances like doubleSquare by constraint solving.

Furthermore, our work extends the fair semantic scheduler synthesis to beyond k-safety problems like co-termination, TI-GNI and TS-GNI, in a sound and complete manner. We note that the extensions are non-trivial and involves delicate uses of functional predicate variables and well-founded predicate variables to ensure scheduler fairness in the presence of non-termination as well as uses of prophecy variables and functional predicate variables to handle angelic non-determinism. The higher-degree of automation and the extension to non-k-safety properties are thanks to the expressive power of our novel constraint framework \(\mathrm {pfwCSP}\).

Table 1. Experimental results of PCSat on the relational verification benchmarks

7.2 Predicate Constraint Solving

Our \(\mathrm {pfwCSP}\) solving technique builds on and generalizes a number of techniques developed for \(\mathrm {CHCs}\) solving as well as invariant and ranking function discovery. Most closely related to our constraint solving method are CEGIS-based [51] and data-driven approaches to solving \(\mathrm {CHCs}\) [14, 22, 24, 26, 27, 38, 44, 45, 48, 49, 65]. As remarked before, the new \(\mathrm {pfwCSP}\) framework is strictly more expressive than \(\mathrm {CHCs}\) and extending the prior techniques to the new framework is non-trivial.

Our stratified CEGIS is inspired by the idea of stratified languages of predicates proposed in the context of predicate abstraction with CEGAR [34, 55]. It is also similar in spirit to the work by Padhi et al. [44], but they use a stratified family of grammars. Also none of these prior works use unsat cores for updating the language/grammar stratum, synthesize well-founded relations and functional predicates, or support non-Horn clauses.

Our class of \(\mathrm {pfwCSP}\) constraints is related to existentially-quantified Horn clauses (E-CHCs) introduced by Beyene et al. [12]. E-CHCs does not have non-Horn clauses or functional predicate variables. However, it has disjunctive well-foundedness constraints which are similar to our well-founded predicate variables. Also, existential quantifiers can be used to encode head disjunctions and functional predicates. We conjecture that \(\mathrm {pfwCSP}\) and E-CHCs are inter-reducible, but it is not trivial to fill the gap. Also, inter-reducibility is a desirable feature: different formats may have different benefits. For relational verification, as we have shown, \(\mathrm {pfwCSP}\) enables direct sound-and-complete encodings of the problems. For instance, head disjunctions allow direct encoding of scheduler fairness and finitary angelic non-determinism (cf. Remark 3). And, functional predicate variables can be explicitly given necessary-and-sufficient parameters to encode angelic non-determinism and difference bounds for ensuring scheduler fairness in the presence of non-termination. The tight encodings also lead to reduction in search space and benefited the constraint solving.

8 Conclusion

We have introduced the class \(\mathrm {pfwCSP}\) of predicate constraint satisfaction problems that generalizes \(\mathrm {CHCs}\) with arbitrary clauses, well-foundedness constraints, and functionality constraints. We have then established a program verification framework based on \(\mathrm {pfwCSP}\) by showing that (1) \(\mathrm {pfwCSP}\) can soundly-and-completely encode various classes of relational problems of infinite-state non-deterministic programs, including hard instances of k-safety, co-termination, and termination-sensitive generalized non-interference that benefit from state-dependent scheduling/alignment (Theorems 14), and (2) existing \(\mathrm {CHCs}\) solving and invariants/ranking function synthesis techniques can be adopted to \(\mathrm {pfwCSP}\) solving and further improved with the idea of stratified CEGIS for simultaneously achieving completeness (Theorem 5) and practical effectiveness.

In future work we plan to investigate ways to improve functional predicate synthesis, automatic tuning of parameter update strategies for constraint solving, and whether a constraint-based approach (and the techniques presented in the present paper) can be extended to reason about relational temporal properties such as the ones expressed in hyper temporal logics [16, 25].