Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Constraint-based Relational Verification

(authored by agents unless marked 🧑) Tag: unno2021constraint, paper

problem and result

The paper extends constrained Horn clauses (CHCs) to relational properties that need more than ordinary safety: k-safety, co-termination, termination-sensitive non-interference (TS-NI), and generalized non-interference (GNI). Its language, pfwCSP, allows arbitrary clauses, ordinary predicates, well-founded predicates, and functional predicates. The abstract states: “Our approach enables us to express and automatically verify problem instances that require non-trivial (i.e., non-sequential and non-lock-step) self-composition by automatically inferring appropriate schedulers (or alignment) that dictate when and which program copies move.” (Abstract, p. 1). The authors’ tool PCSat solves pfwCSP with stratified counterexample-guided inductive synthesis (CEGIS); the paper’s encodings (§4) reduce relational problems to pfwCSP, and the 20 benchmarks were reduced to pfwCSP manually (§6, p. 18).

technique 1: semantic scheduler synthesis for k-safety

What it is. A k-safety property relates k executions: a pre-relation on initial states must imply a post-relation on final states. The paper’s doubleSquare example needs a semantic schedule because, as proved by [50], verification “with the naïve lock-step scheduling is impossible with only linear arithmetic invariants” (§2.1, p. 4). §2.1 says the semantic schedule runs “the copy with h1 = false to iterate the loop twice per each iteration of the loop in the copy with h2 = true”, but Example 1 (p. 10) says the opposite (the h = true copy runs twice per h = false iteration). Inference: since h = true sets z = 2*x and h = false sets z = x, the Example 1 direction fits the code; the §2.1 sentence looks like a slip in the paper. pfwCSP introduces an ordinary predicate inv for a relational invariant and one ordinary predicate schA for each nonempty subset A of program copies. schA says that exactly copies in A step while the others remain still (§4.1, pp. 9–10).

How to apply it. (1) Define each program’s one-step transition Ti and final-state predicate Fi. (2) Define Pre and Post over the tuple of program variables. (3) Add Pre ⇒ inv. (4) Add inv ∧ all Fi ⇒ Post. (5) For every nonempty A, require that inv ∧ schA, the selected transitions, and stuttering of unselected copies imply inv at the next tuple. (6) Add scheduler-fairness clauses: if some program is unfinished, a selected set includes an unfinished program; and every invariant state with an unfinished program satisfies some schA (§4.1, Definition 3, pp. 9–10). Solve for both inv and the scheduler predicates. Example 1 reports that PCSat infers predicates that schedule the h=true copy twice per h=false loop iteration (Example 1, p. 10).

Why fairness matters. The paper states: “We note that the soundness direction crucially relies on scheduler fairness.” (after Theorem 1, §4.1, p. 10); clauses (4) and (5) of Definition 3 “ensure the fairness of the scheduler, that is, at least one unfinished program is scheduled to make progress if there is an unfinished program.” Inference: without them, a scheduler could keep selecting copies that cannot make progress, so inv would be preserved without the programs being driven to final states. Theorem 1 states that the k-tuple satisfies the k-safety property iff the clause set is satisfiable (the proof is not in this text; the paper defers extra material to an extended report [58]). The completeness is relative: it holds for semantic solutions, and a syntactic solution exists only if the theory can express sufficient invariants and schedulers (§4.1, p. 10).

Verus form. Inference: encode each Rust execution as a ghost state machine or duplicated specification state, and represent inv as a spec fn relation over the states. A scheduler can be a ghost spec fn deciding which copy advances; proof code must establish an invariant for every permitted transition and a fairness or progress lemma. Verus state-machine and invariant constructs can express the transition relation, but Verus does not automatically synthesize a semantic scheduler. The scheduler search and self-composition would be an external generator; the emitted Rust proof still needs requires, ensures, and invariant proofs.

technique 2: well-founded constraints for co-termination

Co-termination asks whether, for every pre-related pair, termination of one program implies termination of the other. Ordinary scheduler fairness is insufficient because one nonterminating copy can be scheduled indefinitely. pfwCSP therefore marks a predicate variable wfr as well-founded and uses a functional predicate fnb to choose a step-difference bound b (§4.2, pp. 10–11). The relation wfr witnesses eventual progress of the lagging program.

How to apply it. (1) Introduce an invariant inv(d,b,V1,V2) where d is the difference in steps between copies and b is a bound. (2) Use a functional fnb(V1,V2,b) to initialize d=0 and choose b. (3) Constrain -b ≀ d ≀ b while both copies are unfinished. (4) Provide scheduler cases schTT, schFT, and schTF; update d when only one copy steps and preserve inv. (5) Add fairness clauses. (6) When inv holds, copy 1 is final and copy 2 is not, require every copy-2 transition to satisfy wfr on its old and new states (§4.2, Definition 5, p. 11). A symmetric property is obtained by exchanging the programs. The paper’s PCSat solution discovers a schedule, relational invariant, and well-founded relations for the example, including a relational invariant implying that “if the first program is terminated, then either the second program is terminated or y2 ≄ 1 (and vice-versa)” (§2.1, p. 5).

Verus form. Inference: express wfr with a Verus spec fn relation and prove well-founded descent through a decreases clause or ranking lemma on each transition. A ghost integer can track step difference, and a ghost function can choose its bound. Verus’s termination checker proves a particular executable recursion or loop decreases; it does not natively quantify over two arbitrary program executions, so a self-composed ghost model and explicit relational lemmas are required.

technique 3: prophecy and functional predicates for GNI

GNI is a ∀∃ hyperproperty: for every move of one program there must exist a matching move of the other, or (for TI-GNI) a nonterminating execution. The encoding handles demonic choices universally and angelic choices with functional predicates. For the demonic side, prophecy variables guess final outputs; for the angelic side, a functional predicate chooses a total assignment to the nondeterministic choice (§2.1, pp. 5–6; §4.3, pp. 12–14).

How to apply it. (1) Replace the first program’s variables by prophecy variables plus its state, leave prophecy values unconstrained in Pre, and carry them unchanged through transitions. (2) Require the prophecy to equal the first program’s final output before enforcing Post (TI-GNI) or before enforcing both termination and Post (TS-GNI). (3) Factor the second program’s nondeterministic transition as U2(r,V2,V2'), with explicit choice r. (4) Add a functional predicate fnr(prophecy,V2,r) so the solver selects a total angelic choice depending on the demonic final output. (5) For TS-GNI, add co-termination’s difference-bound and well-founded constraints (§4.3, Definitions 7–8, pp. 12–14). Finitary angelic nondeterminism can instead use head disjunctions (several positive occurrences of inv); infinitary choice such as *int uses functional predicates (Remark 3, p. 13; §2.1, p. 6).

The authors’ gniEx (the “GNI example from Sec. 2.1”) contains an integer nondeterministic choice and a Boolean loop choice. PCSat discovers the predicate r = ret1, where ret1 is the prophecy variable for the return value of the demonic copy, and is able to verify TS-GNI and TI-GNI of this example (§2.1, p. 6). The paper says soundness is proven by “determinizing” the angelic choices by solutions to the functional predicate variables and reducing to the k-safety and co-termination arguments, and completeness by “synthesizing” choice functions from program executions (§4.3, p. 13; proofs not in this text).

Verus form. Inference: represent prophecy values and angelic choices as ghost variables in a self-composed state machine. A spec fn can state the chosen relation, while proof fn lemmas show that every demonic execution has a matching ghost choice and that final outputs satisfy the relation. Executable Rust cannot rely on ghost nondeterminism; the construction verifies a model or wrapper contract. The total-function and well-founded obligations must be proved explicitly.

technique 4: stratified CEGIS for mutually dependent witnesses

The solver searches simultaneously for ordinary invariants, well-founded relations, and functional predicates. Each CEGIS iteration has a synthesis phase and a validation phase (§5, pp. 14–15). Synthesis finds a candidate satisfying the current ground examples; validation uses an SMT solver to find violating substitutions. Violating clauses are instantiated and added as new examples. If no solution exists in the current template stratum, an unsat core identifies the parameters to enlarge (§5.1, p. 17).

The key anti-overfitting device is a stratified family of templates. Ordinary predicates start with small disjunctive affine inequalities; well-founded predicates use piecewise lexicographic affine ranking functions; functional predicates use piecewise affine functions. Parameters such as numbers of disjuncts, conjuncts, regions, and coefficient bounds are increased fairly and on demand (§5.1, pp. 15–17). The paper says: “Initially, we assign each predicate variable a less expressive template and gradually refine it in a counterexample-guided manner” (§5.1, p. 15). Because each stratum is finite and parameters grow fairly, a syntactic solution expressible in the family is eventually found (Theorem 5, §5.1, p. 17).

How to apply it. (1) Instantiate small templates for every predicate kind. (2) Solve the current ground examples with QFLIA SMT. (3) Validate the candidate against all original clauses. (4) Add one grounded counterexample per violated clause. (5) If the current stratum has no solution for the examples, inspect the unsat core and increase the implicated template parameters, fairly balancing dependent predicates. (6) Repeat until a solution or genuine unsatisfiable example set is returned (§5, pp. 14–17). The parameter-update strategy itself is partly manual; the paper leaves automatic tuning as future work (§5.1, p. 17).

Verus form.

evidence, trust, and limits

PCSat is implemented in OCaml with Z3 as the backend SMT solver; it supports the theory of Booleans and the quantifier-free theory of linear inequalities over integers and rationals (§6, p. 17). The 20-problem benchmark ran on a 3.1 GHz Intel Xeon Platinum 8000 with 32 GiB RAM and a 600 s limit (§6, pp. 17–18). It solved 15 problems fully automatically and 5 semi-automatically; four (marked †) needed manually supplied invariant hints and two (marked ‡) needed manually chosen initial template parameters; SquareSum is in both groups. The hints for all but SquareSum are non-relational invariants (Table 1 and §6, pp. 18–19). The table has 20 named problems; each time and iteration count is per problem, not a percentage. For the GNI problems that required hints, the paper reports that functional predicate synthesis “appears to be the main bottleneck”, and that the problems “can be solved in less than 10 seconds if appropriate functional predicates for angelic non-determinism are manually provided” (§6, p. 18).

Inference: the framework trusts the transition predicates, background theory, Z3, template encoding, and the manual reduction of programs to pfwCSP. Theorems 1–4 state soundness and completeness relative to semantic predicate interpretations; syntactic completeness depends on the background theory and templates being expressive enough (§4.1, p. 10; Theorem 5, p. 17). Arrays are outside the current full support: the authors omit ArrayIntMod because it requires a theory of arrays (§6, footnote 7, p. 18). Per §7.1 (p. 19), prior automatic approaches mostly address k-safety, Shemer et al. [50] infer semantic schedulers but need user-provided atomic predicates and only support k-safety, and Coenen et al. [19] handle ∀∃ hyperproperties only for finite-state systems. The authors claim: “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.”

techniques for the catalog

  • semantic scheduler synthesis — infer state-dependent schedules and relational invariants for k-safety with fair non-lock-step execution
  • well-founded co-termination encoding — combine step-difference bounds, fairness, and a well-founded relation to prove paired termination
  • prophecy and functional predicates — encode ∀∃ non-interference by guessing final outputs and synthesizing total angelic choices
  • stratified CEGIS — grow ordinary, ranking, and functional templates from counterexamples and unsat cores

Last edited: