Controlling the inference process

Prolog has a declarative nature. But, there are some features which allow to have influence on the inference process. They introduce procedural programming to Prolog. These are:

The fail predicate is denoted by fail/0, and it is always false, forcing backtracking. Figure 6.4 gives an example. Specifying display_parents as a goal the inference engine will display all parents and their children. When the first clause of display_parents is called a parent and the child is displayed and Prolog backtracks upon fail. If there are no more facts concerning parent/2 the inference engine consults the second clause which succeeds. The output is given in Figure 6.5. display_parent/0 resembles a function or procedure.

Figure 6.4: An example of fail/0 predicate.
\begin{figure}\begin{verbatim}parent(john,james).
parent(mary,james).
paren...
...Y), write(','), writeln(X), fail.
display_parents.\end{verbatim}
\end{figure}

Figure 6.5: An example of fail/0 predicate, the output.
\begin{figure}\begin{verbatim}john,james
mary,james
ann,mary
simon,mary
michael,ann
alice,john\end{verbatim}
\end{figure}

The second operator: cut, ceases seeking for alternatives. It removes all alternatives set up since the call was made that the clause containing the cut is trying to solve. The cut itself always succeeds on its first call, and always fails on backtracking. It is used to implement non-logical predicates. The cut semantics is not a subset of the declarative semantics [15]. It can be used to force determinism over non-deterministic predicates.

An example is given in Figure 6.6. This is a search for the maximum value in a set. The example operates on a set of integers which is defined as predicate res/16.2.

Figure 6.6: An example of cut predicate.
\begin{figure}\begin{verbatim}res(1). res(2). res(3). res(4). res(5). res(4)....
...-
res(X),
X>O,!,
search(X,B).search(B,B).\end{verbatim}
\end{figure}

In order to find the greatest value in the set the following goal should be issued: best(X). The best clause takes the first element from the set (using res/1) and unifies it with variable O. It is done only once, no backtracking on the left side of the cut predicate is possible. Then, O serves as a seed for the search operation. The result of search/2 (the second argument) is unified with the argument of best/1.

The first search clause finds an element in the set, which is greater then the seed. If such an element is found, there will be no search for any other, alternate element because the cut is used. Then, the element, becomes a seed for the next, recursive call of search/2.

If at some point there is no such element found, the first clause of search/2 fails, and the inference engine consults the second clause, which succeeds, unifying the seed, for which there is no greater item in the set, with the result.

In this example the cut is used twice. It is used to initialize the search process. Additionally, it is used to find deterministically another element and prevent going to another clause of search/2 predicate.

Igor Wojnicki 2005-11-07