Just installed SWI-Prolog on my W8 machine and it's throwing an error.
Here's the error:
ERROR: toplevel: Undefined procedure: mark/0 (DWIM could not correct goal)
Let's say my prolog source file contains one fact:
Prolog source...
it_is_monday. //The fact
So I compile the buffer, and get:
.../documents/prolog/prologSource compiled 0.00 sec, 2 clauses
Now when I input
it_is_monday.
The output as expected is true. However when I input say,
some_other_statement.
I get the error posted above as opposed to false. Can anyone tell me what's going on here?
Solution: Different prolog version.
There's a standard Prolog flag, unknown, that is set by default in SWI-Prolog and other modern Prolog compilers to error, meaning that an attempt to call an unknown predicate will result in an exception. This flag can be set (using the standard set_prolog_flag/2 predicate) instead to fail to get the behavior that you seem to be expecting but that's not advisable as it may make debugging harder. E.g. a simply typo in a predicate name will result in a failure which, in a complex program, could be difficult to trace down while a predicate existence error would pinpoint the culprit at the spot.
You get the error
ERROR: toplevel: Undefined procedure: mark/0 (DWIM could not correct goal)
because you haven't defined the procedure you tried to execute. (that's why it says undefined)
If you define it, by editing your .pl file and writing
some_other_statement.
and you run it again, you'll get
1 ?- some_other_statement.
true.
In Prolog you need to define every procedure you want to execute.
When you try to execute an undefined procedure, the name of the procedure will show up in the error. So, if you haven't defined some_other_statement., the error will be:
2 ?- some_other_statement.
ERROR: toplevel: Undefined procedure: some_other_statement/0 (DWIM could not correct goal)
notice that some_other_statement/0 is being shown on the error that I got.
EDIT : If you wanted to get a false message, you would have to define something like some_other_statement(1). and then execute a query like some_other_statement(12).
2 ?- some_other_statement(12).
false.
if you want to receive false from that you can add the directive
:- dynamic(some_other_statement/0).
at the beggining of the file, so when you execute the query
?- some_other_statement.
you will get false
Related
In SWI-Prolog, if I use assert and retract at the prompt, I get
?- assert(at(1)).
true.
?- retract(at(1)).
true.
However, if I put these statements into a program file called "test" as
assert(at(1)).
retract(at(1)).
and run SWI-Prolog as
> swipl
?- [test].
I get
ERROR: /....../test:2:
No permission to modify static procedure `retract/1'
true.
What does this mean and how should I deal with it?
Put statements within a predicate, e.g.:
:- dynamic at/1.
test_assert :-
assert(at(1)).
test_retract :-
retract(at(1)).
Load the program, and then run:
?- test_assert.
true.
?- at(X).
X = 1.
?- test_retract.
true.
?- at(X).
false.
The prompt and source code files are different environments with slightly different behaviours. It's like the difference between calling Python len(x) in the repl and writing function len(x): in Python source code - you would be overriding the builtin len() with your own one. Python lets you do that, SWI Prolog also does but not easily.
When you type them at the prompt, you call the existing predicate assert/1 and actually do insert the fact at(1). into the database. When you type retract/1 you actually do retract the fact at(1) from the database.
In a fresh prompt, try ?- listing(at). and get an error, then ?- assert(at(1)). then do the listing again and see the fact, then retract it and try the listing and see only the remains of the dynamic declaration and the fact is gone.
When you put them in a source code file, you would be trying to override the existing builtin predicates with your new ones. Your new ones say "assert/1 is a predicate which succeeds when its arugment unifies with at(1)" and "retract/1 is a predicate which succeeds when its arugment unifies with at(1)".
That is, they don't do any asserting or retracting or database changes.
In your test file, put this:
:- redefine_system_predicate(assert(_)).
:- redefine_system_predicate(retract(_)).
assert(at(1)) :- true.
retract(at(1)) :- true.
Then save and consult it:
?- [testing].
true.
?- listing(at). % <-- your code ran, but did not insert `at(1)`.
ERROR: procedure `at' does not exist (DWIM could not correct goal)
^ Exception: (13) setup_call_catcher_cleanup(system:true, prolog_listing:listing_(user:at, []), _19450, prolog_listing:close_sources) ? abort
% Execution Aborted
?- assert(P). % <-- it's now behaving
P = at(1). % <-- like any other predicate.
I have written a simple program to find largest of two number in prolog
domains
x,y,z=integer
predicates
bigger(x,y,z)
clauses
bigger(X,Y,Z):-
X>Y,Z=X.
bigger(X,Y,Z):-
X<Y,Z=Y.
goal
bigger(5,7,X).
but whenever I run the program I get the error:
compiling /home/prabin/large_number.pl for byte code...
/home/prabin/large_number.pl:2:5: syntax error: . or operator expected after expression
/home/prabin/large_number.pl:11:5: syntax error: . or operator expected after expression
2 error(s)
compilation failed
Why is it so?
Your source code is for Visual Prolog (or the older TurboProlog). Delete:
domains
x,y,z=integer
predicates
bigger(x,y,z)
clauses
and
goal
bigger(5,7,X).
leaving only
bigger(X,Y,Z):-
X>Y,Z=X.
bigger(X,Y,Z):-
X<Y,Z=Y.
After saving the fixed code, you can type the goal at the top-level interpreter:
| ?- bigger(5,7,X).
X = 7
yes
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.
just recently started learning Prolog, and I have NO idea why I'm getting this error.I can't understand what can i do .
This is the 'code' :
?- assert(likes(a , beaf)).
?- assert(likes(b , nuduls)).
?- assert(likes(b , hotdog)).
?- assert(likes(c , sandwicth)).
?- assert(likes(c , bargar).
?- assert(likes(d , juice)).
?- assert(likes(d , chicken_curry)).
?- assert(likes(d , nudules)).
?- assert(likes(e , brade)).
?- assert(likes(e , butter)).
?- assert(likes(e , bargar)).
?- friend(e,d).
?- friend(d,a).
?- friend(d,b).
?- friend(d ,c).
?- highlyrecommended(X,L):-friend(X,Y),likes(Y,L).
?- recommended(X,L):-friend(X,Z),friend(Z,Y),likes(Y,L).
?- Is d is the friend of e ?
?- Y
?- Is e is the friend of c ?
?- Y
?-Who are the friend of d?
a , b , e
true.
This all error
2 ?- ERROR: Undefined procedure: (?-)/1
ERROR: ?- is the Prolog prompt
ERROR: See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
3 ?- | ERROR: Undefined procedure: (?-)/1
ERROR: ?- is the Prolog prompt
ERROR: See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
4 ?- ERROR: Undefined procedure: (?-)/1
ERROR: ?- is the Prolog prompt
ERROR: See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
5 ?- | ERROR: Undefined procedure: (?-)/1
ERROR: ?- is the Prolog prompt
ERROR: See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
6 ?- ERROR: Syntax error: Operator expected
ERROR: ?- assert(likes(c , bargar)
ERROR: ** here **
ERROR: .
6 ?- | ERROR: Undefined procedure: (?-)/1
ERROR: ?- is the Prolog prompt
ERROR: See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
7 ?- ERROR: Undefined procedure: (?-)/1
ERROR: ?- is the Prolog prompt
ERROR: See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
8 ?- ERROR: Undefined procedure: (?-)/1
ERROR: ?- is the Prolog prompt
ERROR: See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
9 ?- | ERROR: Undefined procedure: (?-)/1
ERROR: ?- is the Prolog prompt
ERROR: See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
10 ?- ERROR: Undefined procedure: (?-)/1
ERROR: ?- is the Prolog prompt
ERROR: See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
11 ?- ERROR: Undefined procedure: (?-)/1
ERROR: ?- is the Prolog prompt
ERROR: See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
12 ?- | ERROR: Undefined procedure: (?-)/1
ERROR: ?- is the Prolog prompt
ERROR: See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
13 ?- ERROR: Undefined procedure: (?-)/1
ERROR: ?- is the Prolog prompt
ERROR: See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
14 ?- ERROR: Undefined procedure: (?-)/1
ERROR: ?- is the Prolog prompt
ERROR: See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
15 ?- ERROR: Undefined procedure: (?-)/1
ERROR: ?- is the Prolog prompt
ERROR: See FAQ at http://www.swi-prolog.org/FAQ/ToplevelMode.txt
16 ?- | | | | ERROR: Syntax error: Operator priority clash
ERROR: ?-
ERROR: ** here **
ERROR: highlyrecommended(X,L):-friend(X,Y),likes(Y,L) .
16 ?- ERROR: Syntax error: Operator priority clash
ERROR: ?-
ERROR: ** here **
ERROR: recommended(X,L):-friend(X,Z),friend(Z,Y),likes(Y,L) .
Any help please?
Thanks.
The ?- prompt
The ?- that you see is just a prompt. Python's interpreter prints >>>, your shell prints $, and so forth—it's not part of the syntax of the language, it's simply a convention adopted over the years by the language and its users. It's very convenient here on S.O. to have a separate notation for interactive queries because it gives you a visual clue as to where you should enter what you're seeing.
The upshot is that you never need to give Prolog ?-, just other humans (for documentation or copy/pasting into emails or S.O. questions).
If we apply this advice, your code turns into this:
assert(likes(a , beaf)).
assert(likes(b , nuduls)).
assert(likes(b , hotdog)).
assert(likes(c , sandwicth)).
assert(likes(c , bargar).
assert(likes(d , juice)).
assert(likes(d , chicken_curry)).
assert(likes(d , nudules)).
assert(likes(e , brade)).
assert(likes(e , butter)).
assert(likes(e , bargar)).
friend(e,d).
friend(d,a).
friend(d,b).
friend(d ,c).
highlyrecommended(X,L) :- friend(X,Y),likes(Y,L).
recommended(X,L) :- friend(X,Z),friend(Z,Y),likes(Y,L).
Using assert/1
Prolog is unique among programming languages in that it has a built-in database. Most of the time, the database is fairly static, meaning the database usually stays the same during any particular execution. However, the you can modify the fact database at runtime with asserta/1 and assertz/1, which insert new facts at the top or bottom of the database respectively, and retract/1 and retractall/1 which remove a fact or family of facts.
There is no ISO predicate assert/1. You have to decide if you want your new fact to be considered first or last.
Regardless, you do not need to assert anything in this program, because you're not changing the database from within the body of a rule. So you can just remove the assert wrapper you have, changing your code into this:
likes(a , beaf).
likes(b , nuduls).
likes(b , hotdog).
likes(c , sandwicth).
likes(c , bargar.
likes(d , juice).
likes(d , chicken_curry).
likes(d , nudules).
likes(e , brade).
likes(e , butter).
likes(e , bargar).
friend(e,d).
friend(d,a).
friend(d,b).
friend(d ,c).
While we're at it, let's fix your spelling.
likes(a, beef).
likes(b, noodles).
likes(b, hotdog).
likes(c, sandwich).
likes(c, burger).
likes(d, juice).
likes(d, chicken_curry).
likes(d, noodles).
likes(e, bread).
likes(e, butter).
likes(e, burger).
highly_recommended(X,L) :- friend(X,Y), likes(Y,L).
recommended(X,L) :- friend(X,Z), friend(Z,Y), likes(Y,L).
Much better.
Consulting a file
In most languages with an interpreter, the language works the same way whether through the interpreter or through a file. Prolog differs from other languages in this respect. Prolog has two "modes" for handling the input: a mode used by consulting, which defines facts and rules, and a mode used for querying, which is what you get when you run Prolog.
Take all the code above, properly cleaned up, and stick it in a file named "first.pl". Then run Prolog and at the prompt, type in [first]. and hit enter. This is what you should see:
$ swipl
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.1.1)
Copyright (c) 1990-2013 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).
?- [foo].
% foo compiled 0.00 sec, 18 clauses
true.
You are only typing two words in here: swipl and [foo]. Type them in exactly! Now you've consulted your first file and you can run queries.
Querying
The last five lines of your source are questions in English. They do not belong in your input file. You must write them again as queries to Prolog. Here's how we do them:
Is d is the friend of e?
?- friend(e,d).
true.
Once again, all you'll type in here is friend(e,d). and press enter. Try it!
Is e is the friend of c?
?- friend(c,e).
false.
Note that you have the wrong expected value here.
Who are the friends of d?
?- friend(d,X).
X = a ;
X = b ;
X = c.
Note that again, you have the wrong expected answer e instead of c. This time, you're going to type in friend(d,X). and press enter, then just typing a ; will be enough to get Prolog to give you the next answer until it runs out.
Conclusion
Whatever resource you're trying to learn from, you need to slow down and maybe get your hands on another book. Prolog is far too different for you to try and blast through. Be diligent and read carefully. This question is sort of pre-basic, which is why it is so highly downvoted. We're happy to help you learn, but you have to do your share. You can't expect to get this kind of answer for every little speedbump.
I have successfully connected PHP with Prolog and managed to query the desired knowledge base that resides in knowledge_base.pl file and managed to echo the results via php exec function.
I encountered a problem in echoing the true/false value that Prolog returns after each query execution (see previous question) so I came up with a solution that I have trouble implementing.
Let's assume I have a simple knowledge_base.pl file with these facts and rules:
girl(erin).
boy(john).
likes(erin, reading).
likes(john, reading).
hangs_out_with(erin, X) :-
likes(X, reading),
boy(X),
writeln('Someone s got a new friend!!').
Lets say that I want to see if erin is a girl and if so, write that it is true, or else write that it is false. I added this to my knowledge_base.pl file:
girl(erin) :-
girl(erin)
-> write('it is true')
; write('it is not true').
When I enter the query: ?- girl(erin). I get an out of local stack error. I searched the Web and found out that this is due to infinite recursion.
Can someone give me a hint in how to write
girl(X) :-
( girl(X)
-> write('it is true')
; write('it is not true')).
in Prolog? Thanks in advance.
As a new user I'm not allowed to post pictures.
SWI-Prolog's output:
1 ?-hangs_out_with(erin,kosta).
false.
2 ?-hangs_out_with(erin,john).
Someone s got a new friend!!
true.
Command prompt's output:
C:\(directory)>swipl -q -f knowledge_database.pl -g hangs_out_with(erin,kosta),halt.
1 ?-halt. (the halt is inputted by me.)
C:\(directory)>swipl -q -f knowledge_database.pl -g hangs_out_with(erin,john),halt.
Someone s got a new friend!!
The first query fails and the second succeds. As you can see, prolog after the query executions outputs true/false but when i execute the same query in command prompt the true/false values do not get echoed!!
I think you should ask
is_girl(X) :-
girl(X) -> write('t is true') ; write('it is not true').
EDIT
Do you mean this kind of thing ?
is_type(Type, X) :-
call(Type, X) -> writeln(yes); writeln(no).
so you "connect PHP to Prolog" by executing a Prolog query in command shell and capturing and analyzing its output. http://www.swi-prolog.org/man/quickstart.html says
"2.1.1.1 Starting SWI-Prolog on Unix
By default, SWI-Prolog is installed as 'swipl'. The command-line arguments of SWI-Prolog itself and its utility programs are documented using standard Unix man pages."
So do consult a man page about "-q" switch. Is it the "-q" for quiet perhaps? What does "-f" mean (ok, that's probably "file")? But the solution is the same - just use a different name for the new predicate.
Notice that in your first attempt,
C:>swipl -q -f knowledge_database.pl -g hangs_out_with(erin,kosta),halt.
1 ?-halt. (the halt is inputted by me.)
halt isn't executed, precisely because hangs_out_with(erin,kosta) has failed. A comma signifies conjunction (an "and").
All you need to do is create a new predicate that reports whether the goal is true or false, and succeeds always:
report_hangs_out_with(A,B):-
hangs_out_with(A,B)- > writeln(['YES',A,B]) ; writeln('NO').
and use it instead:
C:>swipl -q -f knowledge_database.pl -g report_hangs_out_with(erin,kosta),halt.
Also, Prolog echoing "true" or "false" is part of its interactive session. But you terminate it with halt!
edit: you posted:
1 ?-hangs_out_with(erin,kosta).
false.
So, when you run that query in interactive Prolog shell, it reports the failure. halt/0 exits the Prolog shell. When you run it with a goal specified through command line switch, apparently it does not report the success of failure. That's the fact of nature as far as we users are concerned (a.o.t. the compiler writers). It is easily addressable with what I've shown you. And you yourself say that it works, too. For each predicate that can fail or succeed, define another, reporting predicate, just as I've shown you.
Here's a sample transcript (in Windows, but that's irrelevant). That should clear up your doubts:
C:\Program Files\pl\bin>plcon -q -g (writeln('****'),halt).
**** // didn't say Yes, right??
C:\Program Files\pl\bin>plcon -q
1 ?- writeln('****'),halt.
**** // didn't say Yes here either
C:\Program Files\pl\bin>plcon -q
1 ?- writeln('****').
****
Yes // does say Yes as part of interaction
2 ?- halt.
C:\Program Files\pl\bin>
So that's the way it is. Deal with it. :) Or write Jan and ask him to change it. :)
girl(erin) :-
girl(erin)
-> write('it is true')
; write('it is not true').
This is wrong for two reasons. Prolog tries to resolve the body taking the left-most literal.
So it basically goes in a loop "is erin girl? yes, if erin is girl. Is erin girl?..."
The second reason is you are mixing two different things. Try to keep your knowledge representation part separated from the way you use it.
In Prolog you just say:
girl(erin)
And then query
?- girl(erin)
Prolog will just say "yes". If you want to print it, probably the easiest way is adding a predicate.
check_and_print(X) :- X, write(X), write(" is true").
Probably you need a call(X) instead of X, depending on the implementation you are using.
I'm not sure about the command prompt out, I suspect the outcome is returned in a different way.