First use of SWI-Prolog - prolog

I'm brand new to Prolog. I am simply trying to get some output from Prolog on Windows Vista.
I have downloaded and installed Prolog 5.1; I chose the .pro file extension when installing (not to confuse with Perl files).
I created a file called test.pro.
Inside this file I put the following:
inside(tom).
?-inside(tom).
I double clicked the file and a command line interface popped up. On this interface (after a bunch of generic Prolog version/copyright info) the only output is:
1 ?-
OK, for starters, I did not expect it to ask a question; I expected it to answer a question (something along the line of 'yes').
Anyway, I tried to respond to the query with the following:
In the command line I re-inserted 'inside(tom).', so the whole line looks like:
1 ?- inside(tom).
I pressed Enter and got an error message:
ERROR: toplevel: Undefined procedure: inside/1 (DWIM could not correct goal)

Prolog doesn't answer questions if you haven't told it facts. (Except for some built-in facts such as member(1, [1,2,3]).)
You can tell it who is inside by (comment follow a %):
1 ?- [user]. % get facts and rules from user input
|: inside(mary). % Mary and John are explicitly inside
|: inside(john).
|: inside(X) :- location(X, house). % rule: anyone in the house is inside
|: inside(X) :- location(X, office). % (variables start with a capital letter)
|:
|: location(tom, house).
|: location(bernard, house).
|: location(anne, office).
|: % type Ctrl+D
% user://1 compiled 0.00 sec, 1,220 bytes
true.
2 ?- inside(tom). % Prolog deduces that Tom is inside
true .
If you want to learn Prolog, Learn Prolog Now is a good, free tutorial.

You need to compile this first (also called "consult" in prolog). If I knew which version of prolog you have I could find out the exact key entry for this command (Ctrl-L may work). By the way, welcome to the wonderful world of prolog- I love it :) As soon as you're over this hurdle, it gets a lot better. :)

Quick and dirty. What was missing was 'compiling' the file, known as consult
and the syntax is as follows, all characters in the line are relevant.
?- [filename].
then you can ask questions and do other things with what the database.(the source code in prolog)
http://www.swi-prolog.org/pldoc/man?section=quickstart

Related

Prolog what's the difference between \+ and \=

What is the difference \= and \+?
because
?- 15\=14.
?- \+ 15=14.<--- this gives an error while the above does not.
Why?Aren't they the same?
Edit: here's the error:
Compiling the file:
D:\Program Files\Strawberry Prolog Beta\Games\WarCraft.pro
Warning 4: The string \+ is not an operator. (line 1, before the first clause)
Error 16: Instead of the integer 15 what is expected here is something like an infix operator or a full stop. (line 1, before the first clause)
1 error, 1 warning.
Also I'm using Strawberry prolog I also tried it on SWI prolog still the same.
I think you are putting queries into Prolog source files. That is not where they should go:
predicate definitions go into Prolog source files
queries are typed into the interactive Prolog toplevel
Try running the SWI-Prolog program without an input file. You should get a window with some informational messages about the SWI-Prolog version and then a prompt ?-. That is the toplevel. Try typing your query there. All queries should go there.
I don't know about Strawberry Prolog, but I suspect it's the same there.

How to run prolog queries from within the prolog file in swi-prolog?

If I have a prolog file defining the rules, and open it in a prolog terminal in windows, it loads the facts. However, then it shows the ?- prompt for me to manually type something. How can I add code to the file, so that it will actually evaluate those specific statements as if I typed them in?
something like this
dog.pl
dog(john).
dog(ben).
% execute this and output this right away when I open it in the console
dog(X).
Does anyone know how to do this?
Thanks
There is an ISO directive on this purpose (and more): initialization
If you have a file, say dog.pl in a folder, with this content
dog(john).
dog(ben).
:- initialization forall(dog(X), writeln(X)).
when you consult the file you get
?- [dog].
john
ben
true.
Note that just asserting dog(X). doesn't call dog(X) as a query, but rather attempts to assert is as a fact or rule, which it will do and warn about a singleton variable.
Here's a way to cause the execution the way you're describing (this works for SWI Prolog, but not GNU Prolog):
foo.pl contents:
dog(john).
dog(ben).
% execute this and output this right away when I open it in the console
% This will write each successful query for dog(X)
:- forall(dog(X), (write(X), nl)).
What this does is write out the result of the dog(X) query, and then force a backtrack, via the false call, back to dog(X) which will find the next solution. This continues until there are no more dog(X) solutions which ultimately fails. The ; true ensures that true is called when dog(X) finally fails so that the entire expression succeeds after writing out all of the successful queries to dog(X).
?- [foo].
john
ben
true.
You could also encapsulate it in a predicate:
start_up :-
forall(dog(X), (write(X), nl)).
% execute this and output this right away when I open it in the console
:- start_up.
If you want to run the query and then exit, you can remove the :- start_up. from the file and run it from the command line:
$ swipl -l foo.pl -t start_up
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.2.3)
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.
For help, use ?- help(Topic). or ?- apropos(Word).
john
ben
% halt
$
dog.pl:
dog(john).
dog(ben).
run :- dog(X), write(X).
% OR:
% :- dog(X), write(X).
% To print only the first option automatically after consulting.
Then:
$ swipl
1 ?- [dog].
% dog compiled 0.00 sec, 4 clauses
true.
2 ?- run.
john
true ; # ';' is pressed by the user
ben
true.
3 ?-

running prolog as a script

So, I have some Prolog code that models variable assignments, such as in a programming language, and tries to see if they are compatible with one another. So,
assigned(X, X).
and(P, Q) :- P, Q.
or(P, Q) :- P.
or(P, Q) :- Q.
% and then we should test an expression like this:
and(assigned(X, 5), assigned(X, 6)).
So that last expression fails, since X can't be assigned to both 5 and 6.
Now, what I want to do is have this test a single expression (which can and should be hardcoded into the file), and then simply print out whether or not it's able to be satisfied. But it seems that SWIPL really wants me to run interactively. Ideally, something like this:
> ./test-assignments
false.
Surely this is possible? I'm at my wit's end on this.
There are several ways to get an SWI-Prolog program to run directly from the shell. You can look at this question and the answers:
How to run SWI-Prolog from the command line?
My personal preference now is to have a file example.pl like this:
:- set_prolog_flag(verbose, silent).
:- initialization(main).
main :-
format('Example script~n'),
current_prolog_flag(argv, Argv),
format('Called with ~q~n', [Argv]),
halt.
main :-
halt(1).
which I then run from the command line with:
$ swipl example.pl and a few arguments
Example script
Called with [and,a,few,arguments]
The initialization directive tells the interpreter which goal to evaluate after it loads the program: here it is main/0. The name main is a convention, it could have been called anything else.
See the linked question and answers for other options.

Prolog, getting right answer in terminal, but wrong answer when running a program

Typing "prolog" in terminal gets:
GNU Prolog 1.3.0
By Daniel Diaz
Copyright (C) 1999-2007 Daniel Diaz
| ?-
Typing:
| ?- member(2, [1,2,3]).
Gets:
true ?
Then pressing enter gets:
yes
Typing:
| ?- member(4, [1,2,3]).
gets:
no
When i write a file; test.pl consisting of this:
:- member(4, [1,2,3]), nl, halt.
And then write in the terminal:
| ?- [test2].
I get:
compiling /path/test.pl for byte code...
/path/test.pl:1: warning: unknown directive (',')/2 - maybe use initialization/1 - directive ignored
/path/test.pl compiled, 1 lines read - 139 bytes written, 11 ms
yes
Shouldnt the answer here be no? What am i doing wrong. Also, how would you do this in prolog:
if (testInPrologTerminal(member(4, [1,2,3])) { do this; }
I.e, i want to send queries to the prolog top level, and get an answer
When you type the query member(2, [1,2,3]), GNU Prolog prompts you for a possible additional solution (hence the true ? prompt) as only by backtracking (and looking to the last element in the list, 3) it could check for it. When you press enter, you're telling the top-level interpreter that you are satisfied with the current solution (the element 2 in the list second position). The second query, member(4, [1,2,3]), have no solutions so you get a no.
To execute a query when a file is loaded, the standard and portable way of doing it, is to use the standard initialization/1 directive. In this case, you would write:
:- initialization((member(4, [1,2,3]), nl, halt)).
Note the ()'s surrounding the query, otherwise you may get a warning about an unknown initialization/3 standard, built-in, control construct. If you have more complex queries to be executed when a file is loaded, then define a predicate that makes the queries a call this predicate from the initialization/1 directive. For example:
main :-
( member(4, [1,2,3]) ->
write('Query succeeded!'), nl
; write('Query failed!'), nl
).
:- initialization(main).
Writing arbitrary queries as directives in a source file is legacy practice and thus accepted by several Prolog implementations but using the initialization/1 directive is the more clean, standard, and portable alternative.

yap prolog read predicate

I am experimenting with prolog, reading "Programming in prolog using the ISO standard, fith edition". I have installed yap (yet another prolog) on my ubuntu 10.10 Maverick RC system, installed using synaptic. I am running prolog from within emacs23 using prolog-mode.
The following code (from chapter five of book) does not give results as in book:
/* FILE history_base.pl */
use_module(library(lists)) /* to use member/2 */
event(1505,['Euclid',translated,into,'Latin']).
event(1510,['Reuchlin-Pfefferkorn',controversy]).
event(1523,['Christian','II',flies,from,'Denmark']).
mywhen(X,Y):-event(Y,Z),member(X,Z).
% Restoring file /usr/lib/Yap/startup
YAP version Yap-5.1.3
< reading the above file into yap>
?- mywhen("Denmark",D).
no
which is not what the book gives!
Now adding to the file above the line (from the book):
hello1(Event):- read(Date), event(Date,Event).
Gives this error when reading the file into yap
(using "consult buffer" in the prolog menu in emacs):
?- % reconsulting /tmp/prolcomp14814QRf.pl...
SYNTAX ERROR at /tmp/prolcomp14814QRf.pl, near line 3:
use_module( library( lists ) )
< ==== HERE ====>
event( 1505 , [ Euclid , translated , into
, Latin ] ).
% reconsulted /tmp/prolcomp14814QRf.pl in module user, 0 msec 752 bytes
yes
?-
¿Any comments?
Perhaps you should terminate the use_module(library(lists)) statement with a . and declare it as a directive, i.e.:
:- use_module(library(lists)).
You have to write Denmark between single quotes instead of double quotes, i.e.:
?- mywhen('Denmark', D).
When you put Denmark between double quotes, the prolog interprets it as a list of character codes instead of an atom, but in the definition of event it is written as an atom (between single quotes).

Resources