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
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
such that s1 is the initial state equal to s0 and
is a goal state, for which holds.
Moreover, for , the state must be a successor
state of , that is 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.