AI-Prolog

 view release on metacpan or  search on metacpan

lib/AI/Prolog/Cookbook.pod  view on Meta::CPAN

=head1 NAME

AI::Prolog::Cookbook - Recipes for common Prolog problems

=head1 REVISION

 $Id: Cookbook.pod,v 1.1 2005/08/06 23:28:40 ovid Exp $

=head1 DESCRIPTION

Logic programming can take some time to get used to.  This document is intended
to provide solutions to common problems encountered in logic programming.  Many
of the predicates listed here will depend on other predicates defined here.  If
in doubt, see L<AI::Prolog::Builtins|AI::Prolog::Builtins> for which predicates
L<AI::Prolog|AI::Prolog> supports directly.

Like most predicates in Prolog, the following predicates can be reused in ways
to generate answers that a human could logically infer from the data presented.
However, many times those "answers" can result in infinite loops.  For example,
in the C<gather/3> predicate listed below, we can gather the items from a list
which match the supplied list of indices.

 gather([1,3], [a,b,c,d], Result). % Result is [a,c]

Or we can figure out which indices in a list match the resulting values:

 gather(Indices, [a,b,c,d], [a,d]). % Indices is [1,4]

However, if we wish to understand which lists will have the given lists for the
given indices, we have an infinite result set.  L<AI::Prolog|AI::Prolog> and
(other Prolog implementations) will return one result and then enter an
infinite loop if you request the goal be resatisfied (i.e., if you ask for
another result).  If you see behavior such as this in your programs, you can
issue the C<trace.> command to see how Prolog is internally attempting to
satisfy your goal.  C<notrace.> will turn off tracing.

=head1 THE PROBLEMS

=head2 Append two lists.

Usage:  C<append(List1, List2, Result).>

 append([], X, X). % appending an empty list to X yields X
 append([W|X], Y, [W|Z]) :-
    append(X, Y, Z).

=head2 Does a list contain a given term?

Usage:  C<member(Item, List).>

 member(X, [X|_]).
 member(X, [_|Tail]) :-
    member(X, Tail). 

=head2 Pick a list member by index.

Usage:  C<member(Index, Item, List).>

 member(1, SearchFor, [SearchFor|_]).
 member(Index, SearchFor, [_|Tail]) :-
    member(Previous, SearchFor, Tail),
    Index is Previous + 1.

Please note that assignment in Prolog is via the C<is/2> infix operator.  The
above code will fail if you use C<=/2>.  This is a common source of bugs for
programmers new to Prolog.  The C<=/2> predicate will unify the right hand side
with the left hand side.  It will I<not> evaluate the left hand side.  Thus:



( run in 0.845 second using v1.01-cache-2.11-cpan-39bf76dae61 )