I'm going through the book Programming for Artificial Intelligence by Ivan Bratko, I'm stuck on a basic problem and running into an error and the previous answers on stack overflow don't seem to be helping.
I'm stuck trying to write a rule using a previous fact as an argument and getting the error
Single variables: [Y]
the code I'm trying to run is this
parent(myfather,me).
parent(mymother,me).
happy(X) :-
parent(X,Y).
I've managed to make rules like this in the past and I think i'm just missing something very obvious as to why this isn't working. I think that when this compiles and I run
happy(myfather).
It will return true as it will replace X in the happy rule with myfather, then check parent(X,Y) with parent(myfather,Y). and try to then see if there is a fact that says parent(myfather,somethingelse....).
I'm also using swipl on macOS if that is relevant, thanks.
EDIT:
I hadn't checked but the program actaully works as it should but still gives the warning, it makes sense however is there any way of getting rid of the error or an understanding of why the error is there?
Singleton variables is a warning, not an error.
It is meant to remind you that you have a named variable occurring only once within a rule.
If you want to suppress the warning for that particular variable, rename it to a name beginning with underscore (e.g. _Y), e.g.:
happy(X) :- parent(X, _Y).
or rename it to _ (anonymous variable), e.g.:
happy(X) :- parent(X, _).
This type of warning is very useful for spotting typos, such a mistyped variable name:
happy(Child) :- parent(Chidl, Parent), happy(Parent).
Warning: Singleton variables: [Child,Chidl]
or other kind of typos, such as a period typed in place of a comma:
happy(Child) :- parent(Child, Parent). happy(Parent).
Warning: Singleton variables: [Parent]
Warning: Singleton variables: [Parent]
or other logical errors.
Without the singleton variable warning, these errors would go unnoticed and would be more difficult to track down.
So, seeing this warning usually rings a bell for looking for other type of errors as well. If there are no other errors, then just fix the singleton variable by making it anonymous.
If you know what you are doing, you can globally disable the warning with:
:- style_check(-singleton).
I know this is an old question, but i get the solution for that, if you got Singleton variables: [Y] error message, please check your code and your Queries is it mixed with upper-case, lower-case or not. Because Prolog is case sensitive.
Related
I'm trying to learn the basics of Prolog and keep running into a existence_error with the following code.
comes_after(m1, m2).
comes_after(m2, m3).
comes_after(m3, m4).
comes_after(m4, m5).
comes_after(m5, m6).
does_come_after(X, Y) :- comes_after(X, Y).
does_come_after(X, Z) :- comes_after(X, Y), does_come_after(Y, Z).
When executing a query such as does_come_after(m1, m3) I keep getting the following error.
uncaught exception: error(existence_error(procedure,comes_after/0),does_come_after/0)
Here's a screenshot showing the error:
Prolog Error
What am I doing wrong, and what should I keep in mind to avoid these errors in the future? Thanks in advance.
The error message tells you that Prolog expects a predicate comes_after/0, but none is found. Further, this problem arises when being called from a predicate does_come_after/0. Now, your definitions all use arity 2. Thus comes_after/2 and does_come_after/2. So what the system expects cannot happen.
And if it does, this must be related to your installation. You have 1.4.5 which is the most recent version, 1.4.4 the still current stable.
It is thus possible that you have another, older, system installed which interferes by providing an incompatible pl2wam compiler. To verify this, say which pl2wam or pl2wam --version.
In particular, versions from 1.3 or even 1.2 may produce such results. There is no version checking for this in GNU.
To ensure that I get always the right version, I say:
export PATH=/opt/gupu/gprolog-1.4.5/bin:${PATH}
Unfortunately, this is a problem with version 1.4.5.
Instead of downgrading, fortunately, there is a trick that you can do:
Instead of using consult(file_name) inside gprolog, you can run this command on your terminal (outside gprolog)
gplc file_name.pl
it will output an executable that you can run by
./file_name
it should solve your existence error problem.
I wanted to figure out the possibility to convert the following statement into terms (not relations) but without the warning of Singleton variables: PERSON while compiling.
Alex likes everyone who likes icecreams.
My following logic gets the Singleton Warning which I want it to remove. The code works fine though.
likes(alex,likes(Person,icecreams)).
The following gives you the same as your try without the warning :
likes(alex,likes(_,icecreams)).
I am trying to perform the following term_expansion with swipl:
a(asda).
a(astronaut).
term_expansion(a(X),b(X)).
But it does not work, i.e. there is no b/1 consulted. I have tried a few variations:
term_expansion(a(X),[b(X)]).
user:term_expansion(a(X),b(X)).
user:term_expansion(a(X),[b(X)]).
user:term_expansion(user:a(X),[user:b(X)]).
None of which works. What is the problem?
As explained by #mat, you need to define the term_expansion/2 predicate before the clauses you want to expand are loaded. Also, the term_expansion/2 predicate is a multifile and dynamic predicate defined for the user pseudo-module. Thus, you should write:
:- multifile user:term_expansion/2.
:- dynamic user:term_expansion/2.
user:term_expansion(a(X), b(X)).
This will ensure that your expansion code will work if you move it into a module.
If portability to other Prolog systems with a term-expansion mechanism (which, btw, is far from standard), than consider moving the term-expansion code to its own file, loaded before the source files you want to expand.
Case: I have a file, solution.pl, where I want to use the rules of another file (this is the definition of the program, not up to me, but I think it's somewhat common).
So I'm using Ciao Prolog and the syntax seems to be ensure_loaded('c:/Path').
but when I try to use the rules of the other file, it tells me he doesn't know what rule I'm trying to use.
On the other hand, if I write on the console that same lane, and then query again, it does work.
So I was wondering maybe the syntax for doing it on the console and on a file are different??
Could someone tell me a step by step so I can figure it out if I'm missing something? What I'm doing right now is loading the program as I would do with smaller programs, then try to query rules of the file included in the ensure_loaded command. And as I said, it does seem to work if write the command outside of the program.
in solution.pl, try
:- ensure_loaded('c:/Path').
or, if the source in c:/Path has a module directive - that is, it begins with :- module(name, [exported/arity, ...]).
:- use_module('c:/Path').
Silly question, but I'm trying to get this simple Prolog program working. I have written other small Prolog programs with no problem, but this one is giving me trouble:
test :- write 'test1234 test1234',nl,halt.
That's it. The file is saved as adventure1.pl. It is loaded into SWI-Prolog on Ubuntu with the command line option:
prolog -s adventure1.pl
When loaded into the Prolog interpreter I enter the following:
start.
However, Prolog says undefined procedure: test/0 (DWIM could not correct goal). What is the error here, is it somthing really simple. I wrote this because I have example programs that use a predecate named start which displays text, yet I can't even get this to work.
write 'test1234 test1234'
is a syntax error, as SWI-Prolog clearly indicates:
ERROR: /tmp/adventure1.pl:2:10: Syntax error: Operator expected
It should be
write('test1234 test1234')
(Of course, that won't solve the problem of start not working, because you've defined test.)