The logical variable
\prologindex{logical variable}
Apart from being a means to establish the satisfiability of a goal,
the power of logic programming lies in the way values are
computed during an inference.
The output of a goal with variables is a substitution binding these variables to terms.
Terms are the elements of the universe a logic program deals with.
As we have seen in section [programs], defining logic programs,
terms are either constants, variables or compound terms
consisting of a function-symbol
and zero or more argument-terms.
We may use a logic program to define terms in a formal way.
The program
\oprog{terms}{
}
assumes a constant 0 and a one-argument function-symbol s
and defines terms in accordance with the definition
given earlier.
The goal
has as solutions all the possible bindings
of X to the terms contained in the set
[]
which represents the so-called Herbrand universe of the program terms.
The possible output that may result from evaluating the goal
is given by the substitutions
[] , , ,...
binding X to the elements of the Herbrand universe.
The question that we will answer in this section is how we are able
to find these substitutions.
Substitutions
\prologindex{substitutions}
Recall that a substitution is (represented by) a set of the form
that binds each variable to a term ,
for .
Applying a substitution to a term is recursively defined by
\hspace{0.7cm}
\begin{tabular}{l l}
& for a constant c, \\
& for and X otherwise, and \\
& for a compound term
\end{tabular}
In other words, applying a substitution to a constant has no effect.
Applying a substitution to a variable X results in the term t when
the binding X/t occurs in .
Applying a substitution to a compound term
results in the term in which
is applied recursively to the argument terms .
As an example, applying the substitution gives
[] $0%h = 0X %h = s(0)Y %h = Ys(X)%h = s(s(0))%h_2%h_1%h_1%h_2t1%h_2 != t2%h_2%h_1%h_1 %h_2%h_1 = {{X1/t1,...,X_n/t_n}}%h_2 = {{Y1/t1',...,Y_k/t_k'}}{{X1/t1%h_2,...,X_n/t_n%h_2,Y1/t1',...,Y_k/t_k'}}%h_2%h_1%h_1 %h_2.
Moreover, it is easy to check that the composition of substitutions is associative,
that is that $(%h_1 %h_2) %h_3 = %h_1 (%h_2 %h_3)%h_1 = {{ X/s(X1) }} %h_2 = {{ X1/s(X2) }}%h_1 %h_2 = {{X/s(s(X2)), X1/s(X2)}}%ht1%h = t2%h%h%h = {{X/s(0)}}f(X,Y)f(s(0),Y)%h' = {{X/s(0), Y/0}}%h%h%s%g%s = %h %g%h_1%h_2%h_1 \c %h_2%h_1 \c fail = fail fail \c %h_2 = fail%h_2%h_1%h_1 %h_2 = fail%e%h \c %e = %e \c %h = %h%hunify(c1,c2) = %ec1 = c2unify(X,t) = {{X/t}}unify(t,X) = unify(X,t)unify(f(t1,...,t_n), f(t1',...,t_n')) = unify(t1,t1') \c ... \c unify(t_n,t_n')unify(t1,t2) = failunify(p(s(X),0), p(Y,Z)) = {{Y/s(X)}} \c {{Z/0}} = {{ Y/s(X), Z/0 }}unify(p(s(X),0), p(Y,X)) = {{Y/s(X)}} \c {{X/0}} = {{ Y/s(0), X/0 }}unify(p(s(X),0), p(Y,s(Z))) = {{Y/s(X)}} \c fail = failunify(p(s(X),0), p(Y,Y)) = {{Y/s(X)}} \c {{Y/0}} = failfail ~ <- X = s(X){{X/s(X)}}position(1,1)position(1,2)position(8,8)same_row(position(X,Y), position(X,Z)) <-