Unificator

interface Unificator

Unifies pairs of Terms, computing the most general unifier (MGU) that makes them syntactically equal, if any exists.

A Unificator does not perform I/O or throw on failure: unification outcomes are represented as values, namely Substitutions. A successful unification yields a Substitution.Unifier (possibly empty, i.e. Substitution.empty); a failed one yields the Substitution.Fail singleton returned by Substitution.failed. match and unify are convenience operations built on top of mgu.

Two orthogonal choices distinguish concrete unification strategies, both obtainable from this interface's companion object:

  • how two non-variable terms are deemed equal while building unification equations (e.g. strict compares with plain Term.equals, while naive additionally compares numeric terms by value); and

  • whether occurs-check is enabled, controlled per-call via the occurCheckEnabled parameter of mgu, match and unify (true by default). Occurs-check prevents a variable from being bound to a term that contains that same variable (which would otherwise produce an infinite/cyclic term); disabling it trades soundness for speed, which is safe only when the caller already knows the operands cannot give rise to such a cycle.

When the operands have distinct semantic roles, the subject term (such as a goal, query, actual value, or sought item) should be passed first, and the reference term (such as a pattern, rule head, expected value, or stored candidate) second. Calls whose operands have no such roles may retain their natural or mathematical order.

Although unifiability is symmetric, the substitutions and unified terms returned by mgu and unify can retain operand orientation. Reordering their arguments is therefore a behavioral change and requires appropriate tests.

val unificator = Unificator.default
val x = Var.of("X")
val substitution = unificator.mgu(x, Atom.of("a")) // {X -> a}
unificator.match(x, Atom.of("a")) // true
unificator.unify(x, Atom.of("a")) // a

To customize how terms are compared, or to observe/alter the equation-solving process, extend AbstractUnificator instead of implementing this interface directly.

Inheritors

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard
abstract val context: Substitution

The bindings assumed as already holding before unification starts; every mgu/merge call is implicitly performed against this context, as if it were merged into the result. If context is Substitution.failed, every operation on this Unificator fails as well.

Functions

Link copied to clipboard
open fun match(term1: Term, term2: Term): Boolean

Tells whether term1 and term2 match each other, that is, whether mgu would succeed for them. Performs unification with occurs-check enabled.

open fun match(term1: Term, term2: Term, occurCheckEnabled: Boolean): Boolean

Tells whether term1 and term2 match each other, that is, whether mgu would succeed for them, optionally enabling occurs-check.

Link copied to clipboard
open fun merge(substitution1: Substitution, substitution2: Substitution): Substitution

Merges substitution1 and substitution2, with occurs-check enabled.

abstract fun merge(substitution1: Substitution, substitution2: Substitution, occurCheckEnabled: Boolean): Substitution

Merges substitution1 and substitution2 into a single Substitution, as if their bindings had been collected while unifying two terms piecewise (e.g. argument by argument): equal-variable bindings from both sides are unified against each other and, optionally, checked for occurrence, rather than simply overwritten.

Link copied to clipboard
open fun mgu(term1: Term, term2: Term): Substitution

Calculates the Most General Unifier of term1 and term2, with occurs-check enabled.

abstract fun mgu(term1: Term, term2: Term, occurCheckEnabled: Boolean = true): Substitution

Calculates the Most General Unifier of term1 and term2, optionally enabling occurs-check.

Link copied to clipboard
open fun unify(term1: Term, term2: Term): Term?

Unifies term1 and term2 if possible, with occurs-check enabled.

open fun unify(term1: Term, term2: Term, occurCheckEnabled: Boolean): Term?

Unifies term1 and term2 if possible, optionally enabling occurs-check.