First-order unification Created 2026-10-20 Updated 2026-11-05
First-order unification solves a finite system of equations between first-order terms. A useful rule presentation deletes , orients to when is a variable, decomposes equal outer function symbols into argument equations, and rejects unequal outer function symbols. For , reject a nontrivial occurrence of in by the occurs check; otherwise propagate the substitution through the other equations. A solved system assigns distinct variables that do not occur in its right sides.[ref]
For example,
first becomes . Propagating gives , hence a most general unifier. Keeping without composing the later substitution would leave an unsolved dependency.
The rules preserve the possible unifiers, apart from explicitly rejecting impossible equations. Decomposition works because identical first-order terms have identical constructors and arguments. At a solved system, any other unifier is obtained by instantiating its remaining free variables; this proves the most general unifier property. Efficient implementations share term graphs rather than repeatedly copying growing first-order terms.
Rational tree 2026-11-05
A rational tree is a possibly infinite tree with only finitely many distinct rooted subtrees. It therefore has a finite representation as a term graph, possibly with cycles. Here “rational” describes finite representability, not values in the rational numbers.
For example, the equation describes the infinite expression . A single node labeled with an edge back to itself represents it. There is no solution among finite first-order terms: the occurs check rejects binding a variable to a first-order term containing that variable. Unification over rational trees instead admits this cyclic representation, so implementations must specify which semantics they use. SWI-Prolog explicitly supports cyclic terms for many term operations.[ref]
Term graph 2026-11-05
A term graph represents the structure of first-order terms with labelled nodes and ordered argument graph edges. For finite acyclic first-order terms, the representation can be a directed acyclic graph, allowing identical subterms to share nodes rather than being copied into separate branches of a tree.
The first-order term has five occurrences in its ordinary syntax tree: one , two and two . A shared term graph can use only three nodes, with the two argument graph edges of pointing to the same node. Sharing a variable node is also useful: identifications made by a unification algorithm can be represented once and followed from every occurrence.[ref]
Sharing changes storage, not the meaning of an acyclic finite first-order term. A cycle is different. A node labelled whose argument points back to itself unfolds to an infinite rational tree; it cannot represent a finite solution to . An implementation must therefore state whether it supports infinite rational trees or enforces the finite-term occurs check.