AI-Prolog
view release on metacpan or search on metacpan
lib/AI/Prolog/Article.pod view on Meta::CPAN
person(SOMEONE),
likes(tom, SOMEONE).
This rule states that "Tom will give a book to anyone who Tom likes." Note that
we are not telling Prolog how to figure out to whom Tom will give books.
Instead, we have merely defined the conditions under which Tom is willing to
part with his material possessions.
To understand rules, read the neck operator, C<:->, as "if" and commas outside
of argument lists as "and." Further, arguments beginning with upper-case
letters are I<variables>, such as C<SOMEONE> in the rule above. Note that only
the first letter needs to be capitalized; C<Someone> would also be a variable,
as would C<SomeOne> or C<SOmeoNe>.
Of course, we could simply enumerate the relationships:
gives(tom, book, alice).
gives(tom, book, bob).
gives(tom, book, martin).
gives(tom, book, charlie).
gives(tom, book, ovid).
However, this quickly become unweildy as the number of people in our program
grows.
=head3 Queries
Now that we have a rough understanding of facts and rules, we need to know how
to get answers from them. Queries are typically entered in the "interactive
environment." This would be analogous to the query window in a database GUI.
With C<AI::Prolog>, a shell named C<aiprolog> is included for demonstration
purposes though we'll mainly focus on calling Prolog from within a Perl
program.
?- gives(tom, book, SOMEONE).
This looks just like a fact, but with some minor differences. The C<?-> at the
beginning of the query is a query prompt seen in interactive environments.
You'll also note that C<SOMEONE> is capitalized, making it a variable (only the
first letter needs to capitalized.) Thus, this query is asking who Tom will
gives books to.
?- gives(WHO, book, SOMEONE).
This query looks like the previous one, but since the first argument is
capitalized, we're asking "who will give books to whom?".
?- gives(WHO, WHAT, WHOM).
Finally, because all arguments are variables, we're asking for everyone who
will give anything to anybody.
Note that no code changes are necessary for any of this. Because Prolog facts
and rules define relationships between things, Prolog can automatically infer
additional relationships if they are logically supported by the program.
Let's take a closer look at this, first focusing on the C<aiprolog> shell.
Assuming you've installed C<AI::Prolog> and said "yes" to installing the
C<aiprolog> shell, enter the following text in a file and save it as
I<gives.pro>. Note that lines beginning with a percent sign (C<%>) are
single-line comments.
% who are people?
person(bob).
person(sally).
person(tom).
person(alice).
% who likes whom?
likes(tom, bob).
likes(tom, alice).
likes(alice, bob).
% who has what
has(tom, book).
has(alice, ring).
has(bob, luck).
% who will give what to whom?
gives(WHO, WHAT, WHOM) :-
has(WHO, WHAT),
person(WHOM),
likes(WHO, WHOM).
gives(tom,book,harry).
When starting the shell, you can read in a file by supplying as a name on the
command line:
$ aiprolog gives.pro
Alternately, you can I<consult> the file from the shell:
$ aiprolog
Welcome to AI::Prolog v 0.732
Copyright (c) 2005, Curtis "Ovid" Poe.
AI::Prolog comes with ABSOLUTELY NO WARRANTY. This library is free software;
you can redistribute it and/or modify it under the same terms as Perl itself.
Type '?' for help.
?- consult('gives.pro').
The second notation allows you to consult multiple files and add all of them to
the knowledge base.
After issuing the C<consult/1> command, the shell will appear to hang. Hit
I<Enter> to continue. We'll explain this behavior in a moment.
Now that you've loaded the program into the shell, issue the following query:
?- gives(X,Y,Z).
The shell should respond:
gives(tom, book, bob)
It will appear to hang. It wants to know if you wish for more results or if
you are going to continue. Typing a semicolon (;) tells Prolog that you want
( run in 0.914 second using v1.01-cache-2.11-cpan-7fcb06a456a )