12. Decision Procedures for Equality
In the terminology of logic and computer science, a decision procedure is an
algorithm that accepts a class of yes/no questions and answers them correctly.
Fix a set of first-order sentences,
Given a first-order sentence
, does prove , that is, ?Given a first-order sentence
, does entail , that is, ?Given a first-order sentence
, is is satisfiable, that is, is there a model of in which is true?
The first two questions are equivalent. We
have not yet presented deductive systems for first-order logic, but we will do so in
Chapter 16, and by the soundness and
completeness theorems for those systems, we will have that a sentence
Whether or not a problem of the form above is decidable depends on
Interestingly, adding axioms to
The second type question above asks about the truth of a sentence
Given a first-order formula
, possibly with free variables, is there a variable assignment such that is true in under , that is, ?Given a first-order formula
, possibly with free variables, is is true in under every assignment ?
In the first case,
Remember that a sentence is a formula without free variables.
If
is satisfiable in . is true in . is false in . is not valid in .
It is confusing that there are so many ways to ask the same question! But you have to get used to it: logicians and computer scientists slip back and forth between the different ways of thinking about a problem, sometimes even in the same sentence.
The relationship between the first group of questions, having to do with entailment and
satisfiability, and the second group of questions, having to do with truth in models, is
subtle. Sometimes, for a given model
To muddy the waters even further, instead of asking questions about all first-order formulas,
we can consider restricted problems where we are only allowed to ask about formulas of a certain
kind. A formula is said to be quantifier-free if it has no quantifiers, universal if it consists
of any number of universal quantifiers
In this chapter, we will describe, in detail, a decision procedure for the validity universal formulas in pure first-order logic, that is, first-order logic without any axioms. The central component to this is a decision procedure for equality, and so we start with that.
12.1. Equality
Fix a language,
The problem we are addressing here is this: given a set of equations and disequations, is it satisfiable? Notice that here we are asking about satisfiability in any model. In particular, the set
is unsatisfiable if and only if we have
So we can think of the problem in either way.
For example, consider the following set of sentences:
Is it satisfiable?
Before we answer that, let’s make some general observations. A set that only has equations and
no disequations is easily satisfiable, namely, in a model with a single element, where every
expression is equal to every other one. Similarly, a set that only has disequations is easily
satisfiable, unless one of the disequations is of the form
Coming back to the question, the following considerations show that the answer is “no.” Each of the following is a consequence of the equations above:
from 1 from 2 from 3, 5, and 6.
This contradicts the disequation 4 above. To understand what is going on, it is helpful
to think of
These considerations encapsulate the main ideas behind the proof of the following theorem:
Theorem
The question as to whether a finite set of ground equations and disequations is satisfiable is decidable.
The idea behind the proof is to use a saturation argument: starting from the equations in question, we derive new equations until no more equations are derivable. If we manage to contradict one of the disequations, the original set is not satisfiable. In the case where no contradiction is found, we will argue that the original set is satisfiable.
To make all this precise, we need a set of rules for deriving equations.
The first three rules express the reflexivity, symmetry, and transitivity of equality, respectively. The last rule is called the congruence rule. You should convince yourself that using these rules we can derive
for any terms
Returning to our proof plan, we want to show that if applying these rules successively
does not result in a contradiction, then there is a model in which the original equations
and disequations are all true.
But a problem arises: what if the original set contains an equation
Lemma
Let
The algorithm implicit in this lemma is called congruence closure.
Proof
One direction of the lemma is easy. Since the equational rules preserve truth in any
model, if we can derive a contradiction from the equations and disequations in
Say two elements
To each element
In words,
In other words, what
It is not hard to show that for every term
In the construction of the counter-model, we don’t really need
to introduce a new element
For examples of the algorithm in action, first let us show that the set
is unsatisfiable, where
We start with the equivalence classes
Suppose we start instead with the set
You can check that in this case, the algorithm terminates with the following three equivalence classes:
.
We now construct a model
You can check that this satisfies the original set of equations and disequations.
Our analysis establishes an interesting property of
first-order logic: it is possible to prove a disjunction
We have described the algorithm as working on closed terms, that is, terms with no variables.
Of course, there is no harm if we allow variables in the terms and simply treat them as
constants. The point is that in this formulation of the problem, a hypothesis
12.2. Implementing congruence closure
A high-level overview of the congruence closure algorithm is as follows:
Given a set of equations and disequations, collect the set of all subterms.
Start with each subterm in its own equivalence class.
For each equation in the original problem:
Merge the equivalence classes specified by the equation.
Keep merging classes according to the congruence rule, until it can no longer be applied.
The resulting equivalence classes characterize all the equations that are implied by the set of the equations in the original problem. If they contradict one of the disequations, the original set is unsatisfiable, and otherwise it is satisfiable. Of course, one can stop the procedure early if a contradiction is found.
For example, given the set
Initially, the equivalence classes are
.Processing the equation
, we merge the equivalence classes of and to get .Considering the terms
and , we see that the first immediate subterms of each, and , and the second immediate subterms, both , are pairwise in the same equivalence classes. This means we can merge the equivalence classes containing and to get .This contradicts
, so the original set is unsatisfiable.
Congruence closure can be implemented efficiently (and is implemented efficiently in SMT solvers) using a union-find data structure, a generic means of partitioning a set of nodes into equivalence classes. Each node has a pointer to its parent, which is another element in the equivalence class. Each class has a distinguished element, called the representative, with the property that it is the parent of itself. To initialize the algorithm with a set of elements, each in its own class, we create a new node for each element and set its parent to itself. The union-find structure supports two operations:
The find operation returns the representative of the class of a given element by following the parent pointers. In pseudocode:
def find(x): if x.parent == x: return x else: return find(x.parent)
We can then determine whether two elements
x
andy
are equivalent by checking whetherfind(x)
andfind(y)
are the same.The merge operation takes two nodes,
x
andy
and ensures that they are in the same class, by finding the representatives of each class, and, if they are not the same, making one point to the other:def merge(x, y): xr := find(x) yr := find(y) if xr != yr: yr.parent := xr
In an efficient implementation, there are two important optimizations. First, the find operation can be modified to update the parent pointers of all nodes on the path to the representative, so that future finds are faster. Second, the merge operation can be modified to make the smaller class a child of the larger class, which ensures that the depth of the tree is logarithmic in the number of elements.
Using the union-find data structure, we can straightforwardly implement the congruence closure algorithm outlined at the beginning of this section. Because the set that is being partitioned into equivalence classes consists of the subterms of the terms in the original problem, there are two structures that are relevant:
We need to keep track of the term structure, for example, the fact that
is a subterm of .We need to keep track of the equivalence classes at each stage of the algorithm.
Every time a merge identifies the classes represented by s
and t
respectively, we should
consider each subterm u
that has an immediate subterm equivalent to s
and each
subterm v
that has an immediate subterm equivalent to t
, and ask whether u
and v
should be identified by the congruence rule; in other words, whether u
and v
have the
same function symbol and the arguments have, pairwise, been identified as equivalent.
In the example above, when we merge the equivalence classes of s
, a list of all subterms that have
an immediate subterm in the same class as s
. These are called the predecessors of s
.
Whenever we merge classes with representatives s
and t
, we check each pair
consisting of a predecessor of s
and a predecessor of t
to see if they should be
merged, according to the congruence closure rule, and the predecessors of the
representative of the new class should be set to the union of the previous predecessors of
s
and t
.
In the course repository for this textbook, there is an implementation of the union-find
data structure in LAMR/Util/DisjointSet.lean
, and there is an implementation of the
congruence closure algorithm in the file CongruenceClosure.lean
associated with
this chapter. The latter closely follows the implementation in Harrison’s book,
Handbook of Practical Logic and Automated Reasoning. Zohar and Manna’s book, The Calculus of
Computation, is another good reference.
12.3. Deciding universal sentences
Remember that the following problems are all intertranslatable:
Given a universal sentence
, is valid, that is, true in every model? (Equivalently: if provable?)Given a quantifier-free formula
, does hold for every model and every variable assignment ?Given a quantifier-free formula
, does hold for some model and variable assignment ?Given an existential sentence
, is satisfiable, that is, true in some model?
In particular, a universal formula
Remember that in first-order logic, the atomic formulas include equations
Suppose
Now suppose we are given an existential sentence
Since a sentence is valid if and only if its negation is satisfiable, and since the negation of a universal sentence is an existential sentence, we have shown the following.
Theorem
The validity of universal sentences in pure first-order logic is decidable. Equivalently, the satisfiability of existential sentences is decidable.