In static analysis based on abstract interpretation, convex abstract domains such as the interval, octagon, or polyhedra domains are often employed to capture numerical invariants. However, these convex abstractions inherently lose precision when the concrete semantics involve disjunctions of states. In many verification problems, reasoning about disjoint execution paths or mutually exclusive conditions requires abstract domains capable of representing disjunctions explicitly.
To address this limitation, several constructions have been proposed to extend the expressiveness of existing domains:
- Disjunctive completion
- Cardinal power and state partitioning
- Trace partitioning
These constructions can be understood as domain combinators that systematically build new abstract domains from existing ones.
Domain Combinators
A domain combinator (or domain constructor) is a higher-order abstraction mechanism that takes one or more abstract domains as inputs and produces a new domain with well-defined semantics.
Each abstract domain
- a concrete domain
, - an abstraction function
and concretization , - and abstract operators (post, join, widening, etc.).
The advantage of defining such combinators is that they can be defined once and for all, and implemented modularly. In ML-style pseudo-code, a domain is a module implementing a given interface:
module D = (struct ... end : DOMAIN)and a abstract domain combinator is a functor:
module C = functor (D : DOMAIN) -> (struct ... end : DOMAIN)Example: Product and Coalescent Product Domains
Given two abstract domains
That is, the product abstraction expresses conjunctions of elements of
However, this simple product may be imprecise:
A reduction or coalescent product is often applied to improve precision by enforcing consistency between both components.
Given abstract domains
Nontheless, in many cases, the product and coalescent product abstractions remain insufficient to achieve reduction. For instance, combining the interval domain and the congruence domain:
result in an empty concretization, which suggests that mere product is still producing useless elements in the abstract domain. This leads to a question: Can we design abstract domains that inherently capture disjunctive properties?
Limitations of Convex Abstractions
Convex domains such as intervals, octagons, and polyhedra represent convex sets of numerical states. This convexity implies that the abstract join
Such imprecisions may cause verification to fail, as the analyzer may infer spurious states that do not correspond to any concrete execution. Non-convex abstractions aim to overcome this limitation. For instance:
- The congruence domain expresses sets such as
, which are non-convex. - The sign domain includes an element
representing, which is not convex, and , so also describes a non convex set, even though other elements like or correspond to convex sets.
Example 1: Verification Problem with Boolean Guards
Consider the following C program:
bool b0, b1;
int x, y; // uninitialized
b0 = (x > 0);
b1 = (x < 0);
if (b0 && b1)
y = 0;
else
y = 100 / x;At the division point, the operation is safe because:
- if
holds, then ; - if
holds, then ; - if either guard fails, then
cannot occur in a concrete execution reaching the division.
However, a non-relational abstraction such as intervals may represent
bool b0, b1;
int x, y; // uninitialized
b0 = x >= 0;
(b0 && x >= 0) || (!b0 && x < 0)
b1 = x <= 0;
(b0 && b1 && x == 0) || (b0 && !b1 && x > 0) || (!b0 && b1 && x < 0)
if (b0 && b1) {
(b0 && b1 && x == 0)
y = 0;
(b0 && b1 && x == 0 && y == 0)
} else {
(b0 && !b1 && x > 0) || (!b0 && b1 && x < 0)
y = 100 / x;
(b0 && !b1 && x > 0) || (!b0 && b1 && x < 0)
}This shows the necessity of symbolic disjunctions to reason about disjoint cases.
Example 2: Relation Between Variables
Consider another example:
int x, s, y;
if (x > 0)
s = 1;
else
s = -1;
y = x * s;
assert(y >= 0);Here,
int x; // x in Z
int s;
int y;
if (x >= 0){
(x >= 0)
s = 1;
(x >= 0 && s == 1)
} else {
(x < 0)
s = -1;
(x < 0 && s == -1)
}
(x >= 0 && s == 1) || (x < 0 && s == -1)
y = x / s;
(x >= 0 && s == 1 && y >= 0) || (x < 0 && s == -1 && y > 0)
assert(y >= 0);Thus, expressing such relations requires a non-trivial relational and possibly disjunctive numerical abstraction.
Disjunctive Completion
Motivation
As discussed previously, convex abstract domains such as intervals or polyhedra fail to represent disjunctive properties. A natural idea to address this limitation is to extend a given abstract domain so that it can represent disjunctions of its own elements. This leads to the notion of the disjunctive completion (also called the distributive completion) of an abstract domain.
Distributive Abstract Domains
Let
That is, abstract joins correspond exactly to concrete unions.
Examples.
- The flat lattice of constants extended with
and , i.e. , is distributive. - The lattice
of signs is distributive. - The lattice of intervals is not distributive. For example, there is no single abstract interval whose concretization equals the union of
and .
Definition of Disjunctive Completion
Disjunctive Completion.
Given an abstract domain
To build the disjunctive completion domain, we follow these steps:
- include in
all elements of the base abstract domain , - for all finite subsets
, such that there is no and , add the elementto with .
Theorem. The process of adding all distinct disjunctions of abstract elements yields a sound and distributive abstract domain.
Example 1: Completion of the Sign Domain
Consider the sign domain with elements
representing respectively
The disjunctive completion
This completion allows representing non-convex sets such as
Example 2: Completion of the Constant Domain
Let the concrete lattice
The disjunctive completion of
This completion is exact—no loss of information—but it is often infinite and computationally intractable.
A intermediate solution is to define
For
Example 3: Completion of the Interval Domain
We still consider the concrete domain
Its disjunctive completion
This representation is expressive and efficient compared to the powerset of constants, though potentially infinite.
Expressiveness.
Note that
Application to Verification (Example Revisited)
Using the disjunctive completion of
which is impossible in convex domains but naturally expressible here. This demonstrates the gain in precision obtained through disjunctive completion.
Static Analysis with Disjunctive Completion
We recall that for a program semantics defined by a concrete post-condition operator:
where
which applies the abstract transfer function pointwise to each disjunct.
The disjunctive completion also provides an exact join operator:
However, it does not admit a general widening operator due to the combinatorial explosion of disjuncts.
Static Analysis with Disjunctive Completion
To carry out the analysis of a basic imperative language, we define the following components.
Operations for the Computation of Post-Conditions. We require a sound over-approximation for basic program steps.
- The concrete post-condition:
where is the set of concrete states. - The abstract post-condition:
should satisfy the soundness property:
For example, when the post operation is the following cases:
- For assignments:
which inputs a variable, an expression, and an abstract pre-condition, and outputs an abstract post-condition. - For conditional tests:
which inputs a boolean expression, an abstract pre-condition, and outputs an abstract post-condition.
Additional Operators.
- An operator join for over-approximation of concrete unions.
- A widening operator
for the analysis of loops. - A conservative inclusion checking operator.
Transfer Functions for the Computation of Abstract Post-Conditions
We assume a monotone concrete post-condition operation
Convention.
If
Disjunctive Completion.
For the disjunctive completion domain, we can simply define:
Abstract Join, Inclusion, and Widening
- Abstract join: the disjunctive completion provides an exact join (exercise).
- Inclusion check: left as exercise.
- Widening: there is no general definition or solution to the disjunct explosion problem.
Limitations
While theoretically elegant, disjunctive completion suffers from severe practical issues:
- Combinatorial explosion: if
has elements, then may have up to elements. - Representation cost: for numerical domains such as intervals,
can describe arbitrary finite unions of numbers. - Lack of general widening: no universal strategy exists to ensure convergence during fixpoint computation.
A common mitigation technique is
When merging disjunctions beyond this limit, the join operator must heuristically decide which disjuncts to retain or merge.