``` Unification

1. Unification

Unificaiton is a two way matching process.

A substitution w = {x1/t1,...,xn/tn} is a mapping, where
x1,...,xn are distinct variables. Given a term t and a
substitution w,

w(t)

denotes the term obtained from t by simultaneously replacing each
occurrence of the variable xi in w by the term ti.

In the following, we use capital letters to denote variables.

Although here we use "terms" (the objects that are composed
of function symbols, variables, and constants), this
definition of substitution also applies to other objects,
such as atoms, a conjunction of atoms, etc.

For example, let

w = {X/b, Y/f(Z)}.

When it is applied to the term

f(X,g(Y))

we will get

f(b,g(f(Z))).

We may write this as

w[f(X,g(Y))] = f(b,g(f(Z)).

A unifier of two terms C1 and C2 is a substitution such that

w(C1) = w(C2)

That is, a unifier of two terms makes the two identical
after the substitution.

--This definition can be easily extended to the case of an
arbitrary number of terms.

--If there exists a unifier for objects t1 and t2, we then say t1
and t2 are unifiable.

Examples.
(a)  Let t1 = f(a,X), t2 = f(Y,b), and w={X/b,Y/a}.

Then
w(t1) = w(t2).

So w is a unifier of t1 and t2.

(b)  t1 = p(f(g(X,a), X)
t2 = p(Z, b)

w = {X/b, Z/f(g(b,a))}

w(t1) = p(f(g(b,a), b)
w(t2) = p(f(g(b,a), b)

Thus, t1 and t2 are unifiable.

(c)  t1 = p(f(X,X),Y)
t2 = p(f(a,Z),b)
w = {X/a, Z/a, Y/b}

w is a unifier of t1 and t2.

(d)  t1 = p(X,X)
t2 = p(a,b)

There exists no unifier for the two atoms.

(e) t1 = p(f(X,Y), Z)
t2 = p(Z, f(a,Y))

w = {Z/f(a,Y), X/a}

w(t1) = w(p(f(X,Y), Z)) = p(f(a,y), f(a,Y))
w(t2) = w(p(Z, f(a,Y)) = p(f(a,Y), f(a,Y))

Yes, w is a unifier of the two atoms.

2. The Most General Unifier

In example (e) above, where

t1 = p(f(X,Y), Z)
t2 = p(Z, f(a,Y))

we know
w = {Z/f(a,Y), X/a}

is a unifier. There is however a different unifier

w' = {Z/f(a,b), X/a, Y/b}.

This is a unifier since

w'(t1) = w'(t2) = p(f(a,b), f(a,b))

The difference between w and w' is the last substitute Y/b in w'
(which is already applied to the Y in f(a,Y)). In other words,
w' can be obtained from w by replacing the ocurrences of Y in w by b.

On the reverse, w cannot be obtained from w': no matter how you replace
ocurrences of variables in the substitutes of w', you won't end up with w.

Because of this, we say that w is more general than w'.
In fact, if two terms t1 and t2 are unifiable,
there always exists a unique (up to variable renaming) most general
unifier.

3. An Unification Algorithm

We are then interested in an algorithm, hopefully an
efficient one, for generating the most general unifier
for two given terms.

Let us explain a unification algorithm by an example.

Example. Let
t1 = p(f(g(X,a)), X)
t2 = p(f(Y), b)

The unification process can be treated as a process of solving
a system of equations. To start, we want to solve the system of
the single equation

S0 = {p(f(g(X,a)), X) == p(f(Y), b))}        w0 = { }

By this notation we mean that we want to find out substitutes
such that both sides can be made identical. The empty set
at the right is to be used to hold substitutes generated in
this process.

To solve this system of equation is equivalent to solving the
following system of equations:

S1=  {f(g(X,a)) == f(Y), X == b}	         w1 = { }

This means we need to solve both of these equations in order to
solve the original equation. The order in which these equations
are solved is not important. But one may find it easier to solve
the simple ones first. In this case,  X == b.

This equation can be easily solved by having X bound to b. We now
get a partial solution:

w2 = {X/b}

This means we have to commit X to b. This commitment should be
consistent and applied to our system as well as to previously
obtained substitutes. Thus, we get

S2 =  w2(S1)
= {f(g(b,a)) == f(Y), b == b}

The second equation is solved. Continuing, we get

S3 = {g(b,a) == Y,  b == b}
w3 = {Y/g(b,a), X/b}

S4 = w3(S3)
= {g(b,a) == g(b,a),  b == b}

Thus, the original is solved with the substitution

{Y/g(b,a), X/b}

It can be shown that a substitution generated this way is the
most general unifier for the terms in both sides of the original
equation.

The following sequence shows that different orders in which
equations are solved would generate the same solution

S0 = {p(f(g(X,a), X) == p(f(Y), b))}   w0 = { }
S1 = {f(g(X,a)) == f(Y), X == b}
S2 = {g(X,a) == Y, X == b}
w1 = {Y/g(X,a)}
S3 = w1[ {g(X,a) == Y, X == b} ]
= {g(X,a) == g(X,a), X == b}
w2 = {Y/g(b,a), X/b}

S3 = w2[{g(X,a) == g(X,a), X == b}]
= {g(b,a) == g(b,a), b == b}

4. Occur Check

Consider unifying

t1 = likes(X, Y)
t2 = likes(g(Y), f(X))

S0 = {likes(X,Y) == likes(g(Y), f(X))}   w0 = { }
S1 = {X == g(Y), Y == f(X)}
w1 = {X/g(Y)}
S2 = w1(S1)
= {g(Y) == g(Y),  Y == f(g(Y))}
^^^^^^^^^^^^
Y occurs in a term containing it.

An equation that has a variable on one side and a term
containing that variable on the other side cannot be solved
no matter what the substitute is. So the unification fails.

The above phenomenon is called "occur check". In all Prolog
systems, for efficiency reasons, occur checks are not
performed. They simply go ahead to generate a "unifier".
In this example, we will get,

{Y/f(g(Y)), X/g(f(g(Y)))}

We can see that it cannot be used to solve the second equation.

Therefore, Prolog is not a faithful implementation of Horn clause logic.

```