NAME
AI::Prolog::Engine - Run queries against a Prolog database.
SYNOPSIS
my $engine = AI::Prolog::Engine->new($query, $database).
while (my $results = $engine->results) {
print "$result\n";
}
DESCRIPTION
AI::Prolog::Engine
is a Prolog engine implemented in Perl.
The new()
function actually bootstraps some Prolog code onto your program to give you access to the built in predicates listed in the AI::Prolog::Builtins documentation.
This documentation is provided for completeness. You probably want to use AI::Prolog.
CLASS METHODS
new($query, $database)
This creates a new Prolog engine. The first argument must be of type AI::Prolog::Term
and the second must be a database created by AI::Prolog::Parser::consult
.
my $database = Parser->consult($some_prolog_program);
my $query = Term->new('steals(badguy, X).');
my $engine = Engine->new($query, $database);
Engine->formatted(1);
while (my $results = $engine->results) {
print $results, $/;
}
The need to have a query at the same time you're instantiating the engine is a bit of a drawback based upon the original W-Prolog work. I will likely remove this drawback in the future.
formatted([$boolean])
The default value of formatted
is true. This method, if passed a true value, will cause results
to return a nicely formatted string representing the output of the program. This string will loosely correspond with the expected output of a Prolog program.
If false, all calls to result
will return Perl data structures instead of nicely formatted output.
If called with no arguments, this method returns the current formatted
value.
Engine->formatted(1); # turn on formatting
Engine->formatted(0); # turn off formatting (default)
if (Engine->formatted) {
# test if formatting is enabled
}
Note: if you choose to use the AI::Prolog interface instead of interacting directly with this class, that interface will set formatted
to false. You will have to set it back in your code if you do not wish this behavior:
use AI::Prolog;
my $logic = AI::Prolog->new($prog_text);
$logic->query($query_text);
AI::Logic::Engine->formatted(1); # if you want formatted to true
while (my $results = $logic->results) {
print "$results\n";
}
raw_results([$boolean])
The default value of raw_results
is false. Setting this property to a true value automatically sets formatted
to false. results
will return the raw data structures generated by questions when this property is true.
Engine->raw_results(1); # turn on raw results
Engine->raw_results(0); # turn off raw results (default)
if (Engine->raw_results) {
# test if raw results is enabled
}
trace($boolean)
Set this to a true value to turn on tracing. This will trace through the engine's goal satisfaction process while it's running. This is very slow.
Engine->trace(1); # turn on tracing
Engine->trace(0); # turn off tracing
INSTANCE METHODS
results()
This method will return the results from the last run query, one result at a time. It will return false when there are no more results. If formatted
is true, it will return a string representation of those results:
while (my $results = $engine->results) {
print "$results\n";
}
If formatted
is false, $results
will be an object with methods matching the variables in the query. Call those methods to access the variables:
AI::Prolog::Engine->formatted(0);
$engine->query('steals(badguy, STUFF, VICTIM).');
while (my $r = $engine->results) {
printf "badguy steals %s from %s\n", $r->STUFF, $r->VICTIM;
}
If necessary, you can get access to the full, raw results by setting raw_results
to true. In this mode, the results are returned as an array reference with the functor as the first element and an additional element for each term. Lists are represented as array references.
AI::Prolog::Engine->raw_results(1);
$engine->query('steals(badguy, STUFF, VICTIM).');
while (my $r = $engine->results) {
# do stuff with $r in the form:
# ['steals', 'badguy', $STUFF, $VICTIM]
}
query($query)
If you already have an engine object instantiated, call the query()
method for subsequent queries. Internally, when calling new()
, the engine bootstraps a set of Prolog predicates to provide the built ins. However, this process is slow. Subsequent queries to the same engine with the query()
method can double the speed of your program.
my $engine = Engine->new($query, $database);
while (my $results = $engine->results) {
print $results, $/;
}
$query = Term->new("steals(ovid, X).");
$engine->query($query);
while (my $results = $engine->results) {
print $results, $/;
}
BUGS
A query using [HEAD|TAIL]
syntax does not bind properly with the TAIL
variable when returning a result object. This is due to a bug in AI::Prolog::Term's _to_data()
method.
Solutions: use raw_results
and parse the resulting data structure yourself or restructure you query to not require the [HEAD|TAIL]
syntax.
AUTHOR
Curtis "Ovid" Poe, <moc tod oohay ta eop_divo_sitruc>
Reverse the name to email me.
This work is based on W-Prolog, http://goanna.cs.rmit.edu.au/~winikoff/wp/, by Dr. Michael Winikoff. Many thanks to Dr. Winikoff for granting me permission to port this.
COPYRIGHT AND LICENSE
Copyright 2005 by Curtis "Ovid" Poe
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.