SLD resolution

\prologindex{sld resolution} In a logic programming system, a goal consisting of a number of literals is evaluated by evaluating each of the goal literals. The evaluation of an atomic goal, that is a single literal, takes place by reducing the goal to its subgoals, that is by replacing it by the body of the clause of which the head matches with the goal literal. When that clause states a fact the resulting subgoal is empty, otherwise the subgoals are the literals contained in the body of that clause. An empty goal is trivially solved. A compound goal consisting of a number of literals is solved when each of its component literals is solved. The SLD-resolution rule, with left-most literal selection built-in, may be phrased as follows. \begin{quotation} \it When we have a goal G_j of the form [] <- B,... and there is a clause C_{j+1} of the form A<-G, with no variables in common with G_j, for which we can find a substitution %h_{j+1} such that A%h_{j+1} = B%h_{j+1} then we may derive the goal G_{j+1} [] <- (G,...)%h_{j+1} that is the original goal with the body of the chosen clause replacing the selected literal, modified by the substitution %h_{j+1}. \end{quotation} The resulting goal G_{j+1} is the resolvent of the goal G_j and the clause C_{j+1}, with both the selected goal literal B and the head A of the chosen clause discarded. When the chosen clause represents a rule the literals of the body of that clause are put in front of the literals of the original goals, otherwise the resulting goal is the original goal minus the selected literal. In both cases, the substitution %h_{j+1} is applied. The proviso that the clause A<-G has fresh variables, not occurring in the goal G_j, is needed to guarantee that the scope of the variables used in the clause is restricted to the clause itself. This requirement can easily be met by renaming the variables of a clause, if necessary. An SLD-refutation of a set of clauses P \u { <-G } is a finite sequence G_0,...,G_k with G = G_0 the original goal literals and G_k the empty goal. If there is no such finite sequence or no finite sequence with G_k empty then the goal <-G is not refutable. The set of ground goals that are refutable is called the success-set of a program. As an example, let P be the program number given by \oprog{number}{
    number(0) <- 
    number(s(X)) <- number(X)
  
} and let <-G be the goal <- number(s(s(0))). The SLD-refutation of <-G may then be depicted by the sequence of goals
    <- number(s(s(0)))
    <- number(s(0))
    <- number(0)
    []
  
Each successive goal results from resolving its predecessor with the appropriate clause. It is easily verified that the success-set of the program number contains the atoms number(0), number(s(0)), number(s(s(0))),... The computed answer substitution %h of a goal <-G is the substitution obtained by restricting the composition of the substitutions %h_1,...,%h_k to the variables of G, where %h_1,...,%h_k is the sequence of substitutions used in the SLD-refutation of P \u { <-G }.\ftn{ Composing substitutions %h_1 = {X1/t1,...,X_n/t_n} and %h_2 = {Y1/t1',...,Yk/t_k'} results in the substitution %h_1 %h_2 = {X1/t1%h_2,...,X_n/t_n %h_2, Y1/t1',...,Y_k/t_k'} where t_i %h_2, for i=1,...,n, is t_i modified by %h_2. The composition %h_1 %h_2 exists only if %h_2 is compatible with %h_1. For further details see section logvar. } \sldindex{answer substitution} Every computed answer substitution for P \u { <- G } is a correct answer substitution. The soundness of the SLD-resolution procedure may be established by noting that if there is an SLD-refutation of P \u { <- G } then P \u { <-G } is unsatisfiable. Also it holds that the success-set of a program P is contained in the least Herbrand model of P.

Search and backtracking

\sldindex{search} \sldindex{backtracking} The SLD-resolution rule is indeterminate with respect to the clause that will be chosen to reduce a goal literal. This non-determinism may lead to multiple refutation sequences and accordingly refuting a goal may result in a number of computed answer substitutions. The search space of an SLD-derivation may be organized as a so-called SLD-tree. \sldindex{SLD tree} An SLD-tree for a goal <-G and a program P is a tree consisting of nodes representing goals. The root node represents the goal <-G. The successor nodes of a non-empty goal node represent the goals that may be derived by resolving the goal with one of the clauses in P. We assume that successor nodes are ordered from left to right corresponding to the textual position in which the clauses occur in the program. The labels of the edges connecting a node with its successor nodes represent the substitution applied in the resolution step. An example of an SLD-tree for the goal <- number(X) is given below. The clauses used are those given in the number program above. .so tree Each path in the tree ending in [] is a possible refutation of the goal <- number(X). The computed answer substitutions corresponding with these refutations are obtained by composing the substitutions labeling the edges that occur on the path. There is an infinite number of possible solutions for the goal <- number(X) and correspondly many bindings for X. In actual logic programming systems, solutions are found by using some strategy to explore the search space of possible solutions as represented by the SLD-tree for a goal. For sequential systems that explore only one solution at a time (depth-first), the order in which solutions are found is determined by a so-called search-rule that prescribes the order in which the clauses that may be used are tried. Common practice is to try the clauses in the order they occur in the program. This leads to a left-to-right depth-first search of the SLD-tree. In the example above, all the paths represent a refutation, except the right-most path which is of infinite length. If clauses were selected in the reverse order, in this example the computation leading to the first solution would not terminate since the right-most path extends infinitely. A path that is finite but does not end with an empty goal represents failure. These paths do not contribute to the possible answers for a goal. When failure is encountered in sequentially exploring the search space in a left-to-right depth-first manner, an alternative path may be found by backtracking to a previous choice, and trying the next clause in the nearest node above. \sldindex{finite failure} As an example, evaluating the goal <- number(X), X = s(s(0)) may be represented by the SLD-tree below. .so failtree Note that the only acceptable solution is given by the binding {X/s(s(0))}.\ftn{ The goal X = s(s(0)) will succeed only if there is a substitution %h for which X%h == s(s(0)). We will comment on the role of the logical variable, and how such a substitution can be found in the following section logvar. } Backtracking results in trying the next clause for a goal, by taking in the SLD-tree the right-neighboring edge of the edge resulting in failure. Such backtracking may also be used to generate all solutions, by inducing failure after a solution is found.