The problem of the farmer, the wolf, the goat and the cabbage discussed in section farmer presented an example of searching in a state space. Abstractly, a search problem can be specified by the predicates [D move(Current, Next) goal(State) D] defining, respectively, the transitions from a state to its successor states and a goal state. More than one goal state may be given. In addition, an initial state s0 must be specified from which the search is started. A solution of a search problem is a sequence of states s1,...,s_k such that s1 is the initial state equal to s0 and s_k is a goal state, for which goal(s_k) holds. Moreover, for i = 1,...,k, the state s_{i+1} must be a successor state of s_i, that is move(s_i, s_{i+1}) must hold. Variants of this scheme may be devised by specifying for each transition a cost which allows to search a path of minimal cost, or by specifying for each state a value which allows to search heuristically, by choosing the highest valued state as a successor to a given state. Regarding a particular state space as an object defining both the predicates move and goal, control with respect to searching the state space can be factored out using inheritance or by making the state space a parameter of the search procedure.

Inheritance

\dlpindex{inheritance} An example search procedure is defined in the object search below. \yprog{search}{ .ds search.pl } As a solution only the goal state is delivered, when reached. The second clause of the predicate search specifies that each successor of the given state is tried for reaching a solution. The albeit trivial maze defined below inherits the search procedure by using the object search as a base class. \yprog{maze}{ .ds maze1.pl } The maze can now directly be asked to search for a solution starting from the initial state a as in the goal .ds maze1.g Evaluating this goal will result in binding the variable S to the goal state e. The simple search procedure specified above can be used to search for a solution to the 8-queens problem by defining the transition between states as the addition of a non-attacking queen to a (possibly empty) list of queens. \yprog{8-queens}{ .ds qstate.t } The clause representing the goal state enforces that there must be eight queens in the final list, none of which attack any of the other queens. The goal .ds state.g will result in the desired outcome.

Parametrization

\dlpindex{parametrization} The simple search procedure specified above sufficed for the examples given because in both examples the search space contained no cycles. For a search space containing cycles, such as the maze defined below, we have to use a different search procedure, for example the depth-first search procedure used in solving the problem of the farmer, the wolf, the goat and the cabbage. \yprog{maze}{ .ds maze2.pl } The object dfs specifies a search procedure that has the state space as an extra parameter. As an object, the state space is known to have the methods goal and move defining the characteristics of the state space. The depth-first search procedure defined in dfs has a built-in check for cycles. \yprog{dfs}{ .ds xdfs.pl } We may now search the maze by stating the goal .ds maze2.g The check for cycles prevents us from infinitely recurring in already visited states. These examples demonstrate how a variety of search procedures may be used, dependent on the needs imposed by the characteristics of the search space. Examples of such search procedures are, apart from depth-first search, for instance breadth-first search and best-first search. The reader is referred to  [Bratko] for a more detailed exposition of search procedures.