I've been stuck for quite some time on this issue, my Prolog program has the following line within its operator definitions:
:- op(100, xfx, [has,gives,'does not',eats,lays,isa]).
and then this fact:
fact :: X isa animal :-
member(X, [cheetah,tiger,giraffe,zebra,ostrich,penguin, albatross]).
When I try to use the operator It says it is undefined and I just do not understand why.
?- peter isa tiger.
ERROR: [Thread pdt_console_client_0_Default Process] toplevel: Undefined
procedure: (isa)/2 (DWIM could not correct goal)
Sorry if its something silly (which it probably is) but I am new to Prolog. Any help is much appreciated.
It is working. See for yourself:
stefan#stefan-Lenovo-G510 ~ $ swipl
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.12)
% ...
?- op(100, xfx, [has,gives,'does not',eats,lays,isa]).
true.
?- Term = (peter isa tiger).
Term = peter isa tiger.
The error message that you got ...
procedure: (isa)/2 (DWIM could not correct goal)
... says that too!
Is it clearer now?
Related
Why isn't father/2 recognized and why can't I load a file that calls father/2?
theogony.pl
father(kronos, zeus).
father(zeus, ares).
mythos.pl
consult('theogony.pl').
%% --
%% X is an ancestor of Y
%% --
ancestor(X,Y) :-
father(X,Y).
ancestor(X,Y) :-
ancestor(X,Z),
ancestor(Z,Y).
swipl
?- consult('mythos.pl').
false.
?- consult('theogony.pl').
true.
?- father(X,zeus).
ERROR: Unknown procedure: father/2 (DWIM could not correct goal)
As noted there are two Prolog files with the file type pl. This code works with both files in the same directory, e.g. 'C:/Users/Groot/Example_01'. You can use another directory but be consistent with the directory name.
Directory: 'C:/Users/Groot/Example_01'
File: 'theogony.pl'
:- module(theogony,
[
father/2
]).
father(kronos, zeus).
father(zeus, ares).
Directory: 'C:/Users/Groot/Example_01'
File: 'mythos.pl'
:- module(mythos,
[
ancestor/2
]).
ancestor(X,Y) :-
father(X,Y).
ancestor(X,Y) :-
ancestor(X,Z),
ancestor(Z,Y).
Start SWI-Prolog
Welcome to SWI-Prolog (threaded, 64 bits, version 8.5.15)
...
?-
I know, there is a newer version but this is so basic even the really old versions should work.
Change the working directory.
?- working_directory(_,'C:/Users/Groot/Example_01').
true.
Use consult which is also done using [] to load the Prolog files.
?- [theogony].
true.
?- [mythos].
true.
Run your query.
?- father(X,zeus).
X = kronos.
I have a problem using prolog on a Mac, I figured out how to run it using SWI-Prolog but when I run it, it gives an error and does not give the expected output
Expected output: homer, bart
male(homer).
male(bart).
female(marge).
female(lisa).
female(maggie).
parent(homer, bart).
parent(homer, lisa).
parent(homer, maggie).
parent(marge, bart).
parent(marge, lisa).
parent(marge, maggie).
mother(X, Y) :- parent(X, Y), female(X).
father(X, Y) :- parent(X, Y), male(X).
son(X, Y) :- parent(Y, X), male(X).
daughter(X, Y) :- parent(Y, X), female(X).
?- male(X).
Here is the error I was speaking about earlier
Warning: /Users/[username]/Desktop/simpsons.pl:19:
Warning: Singleton variables: [X]
true.
And instead of outputting homer, bart it outputs true
When programming in Prolog, you put definitions and queries in different places. Definitions go into source files. Queries do not go into source files. You enter them while interacting with the Prolog system in something called the "toplevel" or "prompt" or "shell" or maybe "REPL" (read-eval-print loop).
For example, these are definitions:
male(homer).
male(bart).
female(marge).
female(lisa).
female(maggie).
You have put them in a source file called simpsons.pl. This is correct.
This is not a definition but a query:
?- male(X).
This does not go in a source file. Do not put it in simpsons.pl. Rather, you:
start your Prolog system
load the simpsons.pl file somehow
enter the query male(X). and observe answers
This video: https://www.youtube.com/watch?v=t6L7O7KiE-Q shows these steps with SWI-Prolog on a Mac.
If you are comfortable using a command line, you might also be able to do this simpler. For example, on my (Linux) machine, I can start SWI-Prolog with a command line argument naming a file to be loaded:
$ swipl simpsons.pl
Welcome to SWI-Prolog (threaded, 64 bits, version 7.6.4)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.
For online help and background, visit http://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).
?-
See that ?-? That is the prompt meaning that the toplevel is now waiting for your input. Here is where you enter your male(X) query. You can use ; or Space to cycle through the various answers:
?- male(X).
X = homer ;
X = bart.
The sample program enumerates and counts the number of 8-queen solutions. (sorry if the code is hard to read; this is machine-generated from an S-expression. The original code is https://www.cpp.edu/~jrfisher/www/prolog_tutorial/2_11.html)
rules:
[user].
(perm([X|Y],Z) :- (perm(Y,W),takeout(X,Z,W))).
perm([],[]).
takeout(X,[X|R],R).
(takeout(X,[F|R],[F|S]) :- (takeout(X,R,S))).
(solve(P) :- (perm([1,2,3,4,5,6,7,8],P),combine([1,2,3,4,5,6,7,8],P,S,D),alldiff(S),alldiff(D))).
(combine([X1|X],[Y1|Y],[S1|S],[D1|D]) :- (is(S1,+(X1,Y1)),is(D1,-(X1,Y1)),combine(X,Y,S,D))).
combine([],[],[],[]).
(alldiff([X|Y]) :- (\+ member(X,Y),alldiff(Y))).
alldiff([X]).
end_of_file.
query:
(setof(P,solve(P),Set),length(Set,L),write(L),write('\n'),fail).
swipl returns 92; while yap returns 40320.
Also, when I query solve(P), swipl only returns two solutions (which also contradicts 92); yap returns much more (possibly 40320 of them). So why the difference? Is there such a serious compatibility issue?
Versions:
YAP 6.2.2 (x86_64-linux): Sat Sep 17 13:59:03 UTC 2016
SWI-Prolog version 7.2.3 for amd64
In older versions of YAP, a query for an undefined predicate simply failed. In the case above, it is member/2 which is not defined in YAP. And for this reason your test alldif/1 always succeeds - thus the large number you get.
The behavior for this is governed by the Prolog flag unknown whose default value should be error. In YAP 6.2 the default was (incorrectly) fail. This was corrected in 6.3. Say
:- set_prolog_flag(unknown, error).
to get a clean error for undefined predicates. Then, you would need to define member/2.
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 define an operator as follows:
:- op(500, xfx, =>).
When I try something like:
assert(a => b).
Prolog raises an error that says 'No permission to modify static_procedure (=>)/2'.
Any solution?
As a security, you have to warn SWI that you are going to modify a predicate at runtime:
:- dynamic (=>)/2.
put at the top of the file should do it.
You must have meant another symbol in place of (=>)/2. Probably (->)/2 which is a control construct that cannot be modified.
Welcome to SWI-Prolog (Multi-threaded, 32 bits, Version 6.1.3-116-gf1c7e06)
...
?- asserta((a -> b)).
ERROR: asserta/1: No permission to modify static procedure `(->)/2'
ERROR: Defined at /opt/gupu/pl-devel/lib/swipl-6.1.3/boot/init.pl:194
?- op(500, xfx, =>).
true.
?- asserta(a => b).
true.