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

Verification of Component-based Systems with Recursive Architectures

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

problem and model

Bozga, Iosif, and Sifakis define Configuration Logic (CL) for distributed systems with finitely many component types but an unbounded number of instances and recursive architectures. A configuration is a pair of an architecture (component indices and interactions) and a precise marking giving each component one local state (Definition 3, p. 10); finite-state component machines provide behavior. The running token-ring rules define a chain recursively, then close its ends with a transfer connector. “We study a sound verification method for parametric component-based systems.” (abstract, p. 1). The method targets universal safety questions such as deadlock freedom and critical-section exclusion across every architecture size generated by the CL definitions. The paper proves these questions undecidable in general, already for linear (chain) architectures (Theorem 1, section 4.1, p. 14, by simulating Post-Turing machines), so the method is a sound but incomplete semi-algorithm (section 6, p. 29).

technique: Configuration Logic and recursive architecture definitions

What it is. CL uses predicate symbols and a set of inductive definitions (SID) of the form A(x1,...) <- phi (section 3, pp. 10–12). A rule composes disjoint sub-architectures with the associative and commutative separating conjunction *; variables denote component indices and existential variables name instances shared between sub-formulas. The token-ring example has Ring(), Chain(x1,x2), and Comp(x) rules. The base and inductive chain rules (2) and (3) represent every finite chain of length at least two.

When to use it. Use CL when architecture size is unknown and the topology follows recursive patterns such as chains, rings, trees, or nested components.

How to do it.

  1. Declare each component type, its ports, and its finite-state local states (section 1.1, pp. 2–3; signatures and behavior maps in section 2.1, pp. 6–7).
  2. Define a base architecture rule and an inductive rule that adds one component and connector to a smaller predicate instance.
  3. Compose the recursive predicate with additional connectors to close the architecture (the Ring rule).
  4. Supply a behavior map assigning each component type to a finite-state machine and a CL sentence for initial configurations.
  5. Keep * operands disjoint; the paper explains that this prevents two component declarations from denoting the same instance (p. 3).

Verus form. Inference: represent a component instance as a Rust struct and recursive architecture as an inductive ghost predicate over an owned tree or sequence of indices. Use spec fn predicates for topology and local-state ownership, and requires/ensures on transitions. A Verus proof can show disjoint ownership and local invariants for one encoded family, but CL’s unbounded recursive interpretation and automatic rewriting-tree generation would need an external model or manually supplied induction lemmas.

Evidence and limits. The paper gives the formal semantics (section 3), Propositions 1 and 2 (every reachable marking and every CL model marking is precise), and examples (token ring, Example 5 chains, Example 6 trees with leaves in a ring). There is no benchmark in this article; its conclusion refers to experimental results in the authors’ earlier paper [2] (p. 45). Theorem 1 (section 4.1, p. 14) means no complete decision procedure exists for the target class.

technique: rewriting trees and canonical models

What it is. A rewriting tree is a tree labeled with SID rules in which each predicate atom of a node’s rule has exactly one child labeled with a rule defining that predicate (Definition 6, p. 19). Its characteristic formula F(T) is the predicate-free formula obtained by substituting subtree formulas for predicate atoms. Lemma 1 (p. 20) says the models of a sentence are the union of the models of F(T) over all rewriting trees T. In the canonical model (Definition 7, p. 24) the component indices are the tree nodes themselves: each variable is mapped to the unique node whose rule has the component atom containing it (Lemma 2, p. 22).

How to do it.

  1. Start at the CL sentence’s root predicate.
  2. Repeatedly replace predicate atoms with one of their defining rules until only component and interaction atoms remain (section 5.1, pp. 18–21). The paper first adds, for each query sentence, a zero-arity rule A_phi() <- phi to the SID (Assumption 1, p. 18).
  3. Record variable substitutions introduced by existential binders along each tree path (this is what F(T) does).
  4. Construct the canonical model (section 5.2, pp. 22–24): map each variable to its node, take the architecture from the component and interaction atoms of F(T), and take the marking from the states Cq(x) in the atoms. This relies on Assumption 2 (p. 22), a syntactic restriction on rules; the paper notes it is not without loss of generality, since architectures with loose interactions cannot be defined under it.
  5. Use the tree nodes as the indices in the subsequent automata and MSO formulas (section 6).

The paper says that “these rewriting trees describe architectures, up to a permutation of the indices of components of each type” (section 1.2, p. 5). Section 5.3 (pp. 24–29) makes this precise: for a tight sentence (Definitions 9 and 10, pp. 25–26), every model of F(T) is symmetric to the canonical model (Lemma 5, p. 26), and Theorem 2 (p. 28) shows that deadlock and reachability can be decided on canonical models alone.

Verus form. Inference: use a ghost tree datatype and prove by structural induction that each node’s component index is unique and every connector endpoint is present. Verus has no built-in rewriting-tree or canonical-model engine; these artifacts must be represented and proved in Rust ghost code or generated externally.

Evidence and limits. Lemmas 1 to 6 and Theorem 2 are proved in the paper. The symmetry result needs the tightness restriction (every interaction port is attached to a component atom, directly or through a predicate profile). Inference: the verification method remains a semi-algorithm because the underlying decision problems are undecidable (Theorem 1), not because of canonicalization.

technique: path automata and flow formulas

What it is. A path automaton traverses a rewriting tree while tracking where an existential variable is introduced and where it is instantiated in a component atom. From the automata, the method synthesizes a WSÎșS flow formula Ί(X,X',R) (Figure 9, p. 37) describing the pre-set and post-set of some transition of the Petri net of the canonical architecture. Here R is a tuple of second-order variables, one per SID rule, marking which tree nodes carry that rule (RewrTree, Figure 6, p. 32).

How to do it.

  1. Encode rewriting trees by the formula RewrTree_Δ(R), with one set variable R_i per rule ρ_i (section 6.2, pp. 31–32), and sets of places by variables X_q, one per local state q, with m(X,R) (lines 19–20) stating that the set is a precise marking.
  2. For each rule ρ and variable x in it, build the path automaton A^x_ρ that follows x down the tree from the rule where it appears to the rule whose component atom instantiates it (section 6.3, pp. 33–35; Lemma 9; see also section 1.2, p. 5).
  3. Translate each automaton into a WSÎșS path formula Path^x_ρ(x,y,R) (Lemma 8, p. 34).
  4. For each interaction atom in each rule, form ι (lines 25–28) that locates the instance nodes via the path formulas, requires the interacting instances of the same component type to be distinct, and sets the pre-set and post-set according to the component transitions labeled by the interaction’s ports; Ω is the disjunction of all ι (line 24).
  5. Use Ί as the transition relation in all later invariant and error queries.

Verus form. Inference: define a ghost transition relation over sets or maps of component states and prove that each executable Rust step implies Ί. Quantifier-heavy MSO automation is outside ordinary Verus usage; export the relation to an external solver and import only checked lemmas or finite certificates.

Evidence and limits. Lemma 10 (p. 37) states that, for a model of RewrTree, Ω holds exactly when the two sets are the pre-set and post-set of some transition of the canonical Petri net. The approach assumes finite-state component behavior and SIDs satisfying Assumption 2. Inference: the guarantee holds for the abstract model only, so the correspondence between the model and real code is outside the paper’s scope.

technique: structural trap and mutex invariants

What it is. Each unfolding induces a marked Petri net. Instead of iterating abstract interpretation to a fixpoint, the paper synthesizes structural invariants directly (section 6.5, p. 39): a trap is a set of places that, once marked, stays marked, and a mutex is a set of places that holds exactly one token in every reachable marking. The set of markings meeting every trap, intersected with the set meeting every mutex exactly once, over-approximates the reachable markings.

How to do it.

  1. Derive the initial marking Init(Y,R) from the tree’s component-state labels (figure 10, p. 40).
  2. Define Ξ(X,R) (line 30) as: for every transition given by Ί(Y,Z,R), if X meets the pre-set Y then X meets the post-set Z. This is the trap closure condition; the requirement that the trap meets the initial marking is added in Θ.
  3. Define Θ(X,Y,R) (line 31) as: X is a marking (m(X,R)) and every set Z that satisfies Ξ(Z,R) and meets the initial marking Y also meets X.
  4. Define ω(X,R) (line 32) analogously for mutexes: for every transition, X is disjoint from the pre-set exactly when it is disjoint from the post-set, and meets the pre-set in one place exactly when it meets the post-set in one place.
  5. Define Ω(X,Y,R) (line 33) as m(X,R) plus: every Z that meets Y in exactly one place and satisfies ω meets X in exactly one place. Use Θ ∧ Ω as the inductive over-approximation (section 6.5, pp. 38–41).

Definition 11 (p. 39) defines a trap as a set of places that meets the initial marking in at least one place and, for every transition, meets the post-set whenever it meets the pre-set; a mutex meets the initial marking in exactly one place and, for every transition, meets the pre-set and the post-set in the same number of places, at most one. “By substituting the reachable set with the intersection of the trap and mutex invariant, we obtain the following sufficient queries” (section 6.5, p. 39).

Verus form. Inference: encode a trap as a ghost predicate over a Map<ComponentId,State> and prove preservation for every Rust transition; encode a mutex as a uniqueness lemma. Use invariant clauses in loops or transition proofs, and ensures on executable transition functions. The paper’s universal quantification over all generated trees still requires an induction principle or external certificate.

Evidence and limits. The proof of Lemma 11 (pp. 39–40) shows that the trap and mutex invariants are inductive and hence that Reach ⊆ Θ ∩ Ω; Lemma 12 (pp. 41–42) shows that the formulas Θ and Ω define exactly these sets. The invariant is an over-approximation, so it can contain spurious errors. The paper explicitly notes that a satisfiable verification condition “might indicate the presence of a spurious error caused by the over-approximation introduced by the invariant synthesis” (section 1.2, p. 5).

technique: WSÎșS verification conditions for deadlock and reachability

What it is. Error sets are encoded in WSÎșS, the weak second-order calculus of Îș successors, a decidable fragment of monadic second-order logic over trees (section 6.1, pp. 30–31). DeadLock(X,R) (line 34) says no transition pre-set is included in marking X; ErrSet (line 35) requires X_q to have at least as many places as the number of occurrences of q in the target tuple of local states. The final query conjoins the error formula, Θ, Ω, Init, and RewrTree.

How to do it.

  1. Build RewrTree_Δ(R) to constrain R to a legal rewriting tree.
  2. Add Init(Y,R), Θ(X,Y,R), and Ω(X,Y,R).
  3. Add DeadLock(X,R) for deadlock freedom or ErrSet⟹q1,
,qn⟩(X) for forbidden reachability (figure 11, p. 42).
  4. Ask a WSÎșS satisfiability solver for the conjunction; the paper relies on optimized provers such as MONA [14] (section 6, p. 30).
  5. If the conjunction is unsatisfiable, Theorem 3 (p. 42) gives that, for a tight sentence, the deadlock query or the reachability query has a negative answer, that is, no deadlock or no target reachability in any generated instance.

Verus form. Inference: prove the same implication with a Rust ghost state machine and an inductive invariant; encode DeadLock as a lemma that every non-error marking has an enabled transition. Verus does not decide WSÎșS or quantify over arbitrary recursive trees, so use external WSÎșS as a certificate-producing front end and independently verify finite proof obligations where possible.

Evidence and limits. Theorem 3 establishes soundness of unsatisfiability implications (section 6.6, pp. 42–43). The paper says WSÎșS is “decidable with non-elementary complexity, in general” and that checking the verification conditions “is in 4EXPTIME, where 4 is the maximum quantifier alternation depth of these formulé”. It adds that “these checks are quite fast, as shown by the preliminary experiments performed on a similar encoding, reported in our previous work [2]” (p. 43). This article gives no experiments, denominators, or timings. Satisfiability is not a proof of a real bug because invariants over-approximate reachability.

techniques for the catalog

  • recursive configuration logic — define unbounded component architectures with inductive resource rules and disjoint composition
  • rewriting trees and canonical models — expand rules into finite architecture trees and canonical indexed configurations
  • path automata — track recursive variable substitutions to derive component interaction flow
  • structural trap invariants — preserve at least one marked place in every initial trap
  • structural mutex invariants — preserve singleton markings for mutual exclusion
  • WSÎșS verification conditions — conjoin tree legality, initial states, invariants, and error predicates and prove safety via unsatisfiability

Last edited: