SWI-Prolog plugin on Sublime build error - prolog

I know this is kinda stupid question, but I am really despaired now, because I cant find the way to build it. I always get this error
ERROR: call/2: Undefined procedure: main/1
ERROR: However, there are definitions for:
ERROR: main/0
Even though I tried
father(ahmad,samer).
father(ahmad,lolo).
father(ahmad,koko).
grandfather(X,Y):-
father(U,X),
father(Y,U).
main :- father(ahmad, X), writef('%t\n', [X]).
So can someone help me to do it the right way ?

Works just fine for me.
Just type main.
Don't forget the .,otherwise it won't run.
Here is what I got
2 ?- main.
samer
true ;
lolo
true ;
koko
true.
After true type ; instead of pressing the Enter button if you want to show all three names. If you press Enter, only the first name will appear.
From your code I figured out that ahmad is the father,so about the grandfather query, I think I has to be this way:
granfather(X,Y):- father(X,U),father(U,Y).
Because on your father query the father is on the left

Related

Prolog menu prompt doesn't print properly

I made a menu that compile without error, but has a strange behavior. It's supposed to ask three time for different input, but it only show 2 different prompt.
The goal of the number 1 choice of the menu is to read from the user input the name , the price and the year of the car, and than adding it to the database.
Here is the code:
menu :- write('-- Menu --'),nl, write('0. Quit'), nl, write('1. Add a car'), nl, read(X), pick(X).
pick(0) :- write('The end.'),nl.
pick(1) :-
write("Name:"),
read_line(N),nl,
write("Price :"),
read_line(P),nl,
write("Year :"),
read_line(Y),nl,
assertz(car(N,P,Y)),
menu.
:- dynamic car/3.
car(blue1,2000, 2012 ).
car(blue2,1000, 2006).
car(red1,2000, 2010).
read_line(String) :-
current_input(Input),
read_string(Input, "\n", "\r", _, String).
What is wrong with this code? I tried to decompose the predicate and only use read_string , but I get the same result.
EDIT: While the accepted answer solved my first issue, I still have issues with my program.
You have to put the stuff given to write/1 in quotes:
write('Price :')
or
write("Price :")
so that it is interpreted as a "element of text".
The "element of text" can then be mapped to a Prolog 'atom' or maybe, in SWI-Prolog, an SWI-Prolog 'string'.
If the text only contains alphanumerics and begins with a lowercase letter, there is no need to quote it to get a Prolog atom directly.
?- atom('foo').
true.
?- atom(foo).
true.
?- atom('foo bar baz').
true.
?- atom(foo bar baz).
ERROR: Syntax error: Operator expected
ERROR: atom(foo
ERROR: ** here **
ERROR: bar baz) .
I found the solution if anyone is having a similar issue. You need to add ,nl after the write(X) for it to print properly.

Problems with library(lambda), currying and SWI Prolog

So I run into some troubles while (ab?)using
lambda.pl.
I do a "use_module(library(lambda))."
in the first lines of a file that
I consult via ["a.prolog"].
Then I get an "undefined procedure ()/3"
and some gibberish afterwards.
The same happens for any order of use_modules.
It happens whether I load a.prolog via
[...], consult or as a script from the cmdline.
I reduced the script to the currying-example from Rosseta code
https://rosettacode.org/wiki/Currying#Prolog
use_module(library(lambda)).
:- initialization(main, main).
main :-
N = 5, F = \X^Y^(Y is X+N), maplist(F, [1,2,3], L),
print(L).
It doesn't work.
It works, however, if I a manually load 'lambda'
at the swipl-prompt and immeditately consult
a.prolog. Then the goal N=5,.... works just fine.
If I, however, first consult a.prolog; then manually
use_module and then run the query, I get the error.
Reconsulting doesn't help onwards.
Somehow, the first command at the prompt needs to
be use_module.
Or do I get the loading mechanism completely wrong?
If so, please apologize; but I would love get a
hint how to solve this.
This is a common error when first using modules.
Please have a look at this line:
use_module(library(lambda)).
This is just a fact, saying "use_module(library(lambbda)) holds".
What you want instead is a directive.
A directive is a term with primary functor (:-)/1. That is, you want:
:- use_module(library(lambda)).
EDIT: For the particular case of library(lambda), I would like to add that there is a page with a lot of useful information about it that is a bit hard to find:
http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/ISO-Hiord
"Hiord" stands for higher order.

On ways to work around an unexpected "Undefined procedure" error

NB: Just to be clear, my motivation for the question below is to learn my way around Prolog and SWI-Prolog, not to get past a particular error message. In fact, I already know one way to get past this error. My question asks about whether several other alternatives are also possible.
An exercise in my Prolog textbook asks one to describe the outcome one should expect from several queries, assuming one has consulted the following knowledgebase beforehand:
x(a).
z(b).
z(c).
z(d).
w(V) :- x(V).
w(V) :- y(V).
w(V) :- z(V).
On SWI-Prolog, at least, most of these queries fail, because SWI-Prolog intreprets y as undefined.
From the solutions to the exercises at the end of the book I can tell that this is not the authors' intended outcome. Maybe there's a Prolog implementation for which the exercise would turn as the solution presents it.
Be that as it may, I'd like to learn about good ways to work around the problem.
Consider, for example, the query w(x).. the book's solution claims that the query w(x). should evaluate to false.. In fact, this is what happens:
?- w(x).
ERROR: w/1: Undefined procedure: y/1
Exception: (7) y(x) ?
(At this point, SWI-Prolog is expecting me to enter some letter indicating how to respond to the exception. More about this later.)
I'm looking for ways to either turn the interaction above to
?- w(x).
false.
?-
...or at least for a suitable <ONE-LETTER RESPONSE> I could give to SWI-Prolog so that it arrives at the conclusion false. IOW, so that
?- w(x).
ERROR: w/1: Undefined procedure: y/1
Exception: (7) y(x) ? <ONE-LETTER RESPONSE>
false.
?-
I know of at least one answer to my question, namely simply to delete or comment out the line:
w(V) :- y(V).
I would like to know of other possible solutions, such as, for example, the "suitable " I alluded to earlier.
Another possibility would be some SWI-Prolog global configuration that would result in the above interaction to change to
?- w(x).
false.
?-
A third possibility would be to "define" y in some minimal way. The only way I can come up with is by adding the fact
y(dummy).
to the knowledgebase. Is there a more minimal way to define y, one that does not require introducing an extraneous constant into the domain of discourse?
(This is not specific to SWI)
The first Prolog systems back in the 1970s actually behaved in the way you describe. Soon it became apparent that this is a frequent source of errors. Simple misspellings remained undetected for too long. Current implementations produce a clean existence error. This is standard behaviour since 1995.
However, you can go back into the olden tymes with the ISO Prolog flag unknown which has three values error (default), fail, and warning.
?- inex.
ERROR: Undefined procedure: inex/0 (DWIM could not correct goal)
?- set_prolog_flag(unknown, fail).
Warning: Using a non-error value for unknown in the global module
Warning: causes most of the development environment to stop working.
Warning: Please use :- dynamic or limit usage of unknown to a module.
Warning: See http://www.swi-prolog.org/howto/database.html
true.
?- inex.
false.
?- set_prolog_flag(unknown, warning).
Warning: Using a non-error value for unknown in the global module
Warning: causes most of the development environment to stop working.
Warning: Please use :- dynamic or limit usage of unknown to a module.
Warning: See http://www.swi-prolog.org/howto/database.html
true.
?- inex.
Warning: toplevel: Undefined procedure: inex/0 (DWIM could not correct goal)
false.
As you can read above, SWI proposes to use a dynamic declaration in stead - which in turn has its own problems... It is much better to declare instead:
:- discontiguous(y/1).
An undefined procedure error raises an exception so if you want the exception to be raised because you don't want to change y/1 predicate (delete or define it) you need to catch the exception and then return false like this:
x(a).
z(b).
z(c).
z(d).
w(V) :- x(V).
w(V) :- catch(y(V), error(Err,_Context),my_handler(Err)).
w(V) :- z(V).
my_handler(Err):- write(Err),fail.
Example:
?- w(x).
existence_error(procedure,y/1)
false.

Why does SWI-Prolog only give me the first answer?

I'm new to Prolog. I'm just trying simple examples to learn. I have this .pl file with these lines:
parent(pam,bob).
parent(tom,bob).
parent(tom,lio).
parent(bob,ann).
parent(bob,pat).
parent(pat,jim).
After consulting and testing, it only shows the first answer. For example:
5 ?- parent(X,Y).
X = pam,
Y = bob .
Isn't it supposed to give all the combinations that satisfy the relation parent?
Do anyone have idea what the problem is?
don't hit enter after your first results shows, use spacebar instead
[Enter] stops execution even if the backtracking is not completed yet
[Spacebar] or [;] continues with backtracking from your last result to the next result or false if there are no other results left.

Undefined Procedure in SWI-Prolog does not work

I am just starting to use Prolog, and already I've run into problem with a seemingly simple example. Here is my .pl file:
hacker(P) :- mountaindew(P), doesntsleep(P).
hacker(P) :- writesgoodcode(P).
writesgoodcode(jeff).
Then, after I load the program into swipl, I test it with this line at the prompt
writesgoodcode(jeff).
I thought it would display true, but I get this error:
?- hacker(jeff).
ERROR: hacker/1: Undefined procedure: mountaindew/1
Exception: (7) hacker(jeff) ?
This program works fine, but this doesn't solve my problems:
hacker(P) :- writesgoodcode(P).
writesgoodcode(jeff).
$ swipl -s dumb.pl
% dumb.pl compiled 0.00 sec, 1,112 bytes
?- hacker(jeff).
true.
Can anyone explain why my original program doesn't work? From my understanding, Prolog should "skip" the first statement since it doesn't have enough information, and check the next line. It does have enough info for that second line, and thus it should evaluate true. Any help or a point in the right direction would be great. Thanks.
As the error message says, you have an undefined procedure mountaindew/1. To make your code return true, your options are:
Define this predicate
Declare that this predicate is dynamic: dynamic(mountaindew/1)
Declare that all unknown predicates should fail (not recommended): set_prolog_flag(unknown, fail)
you could also change the order of the predicates (cannot be done always ofc)
but mostly what Kaarel said.
in the end there is not really a point in writing something that will always fail, even if you are still developing the code
This works but as I am a beginner I can't say why. The word "uninstantiated" may apply. Despite not knowing why it works, I think it's helpful to show one way that works.
hacker(P) :- mountaindew(P), doesntsleep(P).
hacker(P) :- writesgoodcode(P).
mountaindew(john).
doesntsleep(john).
writesgoodcode(jeff).

Resources