NAME
AI::Prolog::Builtins - Builtin predicates that AI::Prolog supports
REVISION
$Id: Builtins.pod,v 1.5 2005/02/24 07:16:24 ovid Exp $
GRAMMAR
The language is given by the following grammar;
Program ::= Rule | Rule Program
Query ::= Term
Rule ::= Term . | Term :- Terms .
Terms ::= Term | Term , Terms
Term ::= Number | Variable | AtomName | AtomName(Terms)
| [] | [Terms] | [Terms | Term]
| print(Term) | println(Term) | nl | eq(Term , Term)
| if(Term , Term , Term) | or(Term , Term )
| not(Term) | call(Term) | once(Term)
| assert(Term) | retract(Term) | !
| var(Term) | listing | gt(X,Y) | ge(X,Y)
| lt(X,Y) | le(X,Y) | plus(X,Y) | minus(X,Y)
| mult(X,Y) | div(X,Y) | mod(X,Y) | is(X,Y)
Number ::= Digit | Digit Number
Digit ::= 0 | ... | 9
AtomName ::= LowerCase NameChars
Variable ::= UpperCase NameChars
NameChars ::= NameChar | NameChar NameChars
NameChar ::= a | ... | z | A | ... | Z | Digit
Comments
Comments begin with a %
and terminate at the end of the line or begin with /*
and terminate with */
.
Variables
As in Prolog, all variables begin with an upper-case letter and are not quoted. In the following example, STUFF
is a variable.
steals(badguy, STUFF, "Some rich person").
Constants
Constants begin with lower-case letters. If you need a constant that begins with an upper-case letter or contains spaces or other non-alphanumeric characters, enclose the constant in single or double quotes The quotes will not be included in the constant.
In the following example, badguy
and Some rich person
are both constants:
steals(badguy, STUFF, "Some rich person").
Miscellaneous
This will not work:
p(X) :- X. /* does not work */
Use this instead:
p(X) :- call(X).
BUILTINS
!
.The "cut" operator. This is used when you wish to tell Prolog that you only need to satisfy a goal once. For example, if you wish to deny someone the right to rent videos if they have overdue videos, you might use the cut operator as soon as you see they have any overdue video. The fact that they have more than one overdue video doesn't matter.
See the
cut.pl
program in theexamples/
directory that comes with this distribution.assert(X)
.Add new facts to the database. Only facts can be added, not rules. This may change in the future. See
retract(X)
.assert(loves(ovid,perl)).
call(X)
.Invokes
X
as a goal.div(X,Y)
.Succeeds if both terms are bound. The value of the term is X / Y. Use with
is(X,Y)
.is(X, div(N,3)).
eq(X, Y).
Succeeds if
X
andY
are equal.ge(X,Y)
.Succeeds if both terms are bound and X >= Y.
gt(X,Y)
.Succeeds if both terms are bound and X > Y.
if(X, Y, Z).
If
X
succeeds as a goal, tryY
as a goal. Otherwise, tryZ
.thief(badguy). steals(PERP, X) :- if(thief(PERP), eq(X,rubies), eq(X,nothing)).
is(X,Y).
If X is unbound and Y is bound to a number, the goal succeeds and X becomes bound to the value of Y. Otherwise, succeeds if both terms are bound, numbers, and equal.
All other conditions result in failure.
le(X,Y)
.Succeeds if both terms are bound and X <= Y.
listing.
Dumps a listing of all predicates and how they are defined.
lt(X,Y)
.Succeeds if both terms are bound and X < Y.
minus(X,Y)
.Succeeds if both terms are bound. The value of the term is X - Y. Use with
is(X,Y)
.is(X, minus(N,1)).
mod(X,Y)
.Succeeds if both terms are bound. The value of the term is X % Y. (modulus) Use with
is(X,Y)
.is(X, mod(N,3)).
mult(X,Y)
.Succeeds if both terms are bound. The value of the term is X * Y. Use with
is(X,Y)
.is(X, mult(N,3)).
nl
Prints a newline.
not(X).
Succeeds if
X
cannot be proven. This is not negation as we're used to seeing it in procedural languages.once(X)
Stop solving for
X
ifX
succeeds. Defined as:once(X) :- X, !;
or(X, Y)
Succeeds as a goal if either
X
orY
succeeds.plus(X,Y)
.Succeeds if both terms are bound. The value of the term is X + Y. Use with
is(X,Y)
.is(X, plus(N,1)).
print(Term)
.Prints the current Term. If the term is an unbound variable, it will print the an underscore followed by the internal variable number (e.g., "_284").
print(ovid). % prints "ovid" print("Something"). % prints "Something" print(Something). % prints whatever variable Something is bound to
println(Term)
.Same as
print(Term)
, but automatically prints a newline at the end.retract(X)
.Remove facts from the database. You cannot remove rules. This may change in the future. See
assert(X)
.retract(loves(ovid,java)).
var(X)
.Succeeds if X is an unbound variable. Otherwise, this goal fails.
LIMITATIONS
These are known limitations that I am not terribly inclined to fix. See the TODO list for those I am inclined to fix.
IF -> THEN; ELSE not allowed.
Use if(IF, THEN, ELSE)
instead.
= and \= not available.
Use eq(X,Y)
and not(eq(X,Y))
instead.
TODO
There are many things on this list. The core functionality is there, but I do want you to be aware of what's coming.
Anonymous variables
steals(badguy, _).
Currently, that doesn't work. Make up a variable name and only use it once.
Improve printing.
There are some bugs with printing and escaping characters. Maybe I'll look into them :)
Math.
Math is hard. So we don't have it, but we will and we'll probably have it in the form of system predicates that call out to Perl. We can define most of what we need logically, but it's very slow and complicated, so we won't do that.
BUGS
Currently we cannot directly access bound variables in the tail of a list used in a query when using unformatted results:
$prolog->query('foo([Head|Tail], bar).');
while (my $result = $prolog->results) {
print Dumper $result->Head;
print Dumper $result->Tail; # doesn't work
}
You'll have to switch to raw_results
and parse the data manually:
$prolog->raw_results(1);
$prolog->query('foo([Head|Tail], bar).');
while (my $result = $prolog->results) {
print Dumper $result;
}
SEE ALSO
W-Prolog: http://goanna.cs.rmit.edu.au/~winikoff/wp/
X-Prolog: http://www.iro.umontreal.ca/~vaucher/XProlog/
Roman Barták's online guide to programming Prolog: http://kti.ms.mff.cuni.cz/~bartak/prolog/index.html
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.