I wrote this predicate in prolog :
list([]).
list([X|L]) :- list(L).
it works well, but I got this warning :
**Warning: /Users/hw6.pl:2:
Singleton variables: [X]** %
what I can do to avoid it ?
The warning tells you that you have a variable used only once in that clause of the predicate list (in this case the second clause).
Why does it warns you of this ? Because it is more than often that you have misspelled the variable name. The resulting code when you misspell a variable is also a valid prolog program, so debugging would be painful if it does not warn you.
If you are not going to use that variable (X), you can use an anonymous variable instead.
To use an anonymous variable you have to use _ as the term instead of a variable name.
In your example it would be:
list([]).
list([_|L]) :- list(L).
Gusbro is exactly right. When you use a variable only once you will get a singleton variable. Your program is still syntactically correct, but prolog assumes you made a mistake typing your code. The underscore variable will always unify as true if it is given any answer.
Related
I'm trying to write Swi-Prolog code for family relations. There are no error but it always returns true. P
man(_Pete).
man(_Mark).
man(_John).
man(_Frank).
man(_Tom).
man(_Matt).
man(_Henry).
man(_Todd).
woman(_Lilly).
woman(_Kate).
woman(_Anne).
woman(_Alice).
woman(_Jenny).
parent(_Pete,_Mark).
parent(_Pete,_Tom).
parent(_Pete,_Anne).
parent(_Mark,_Lilly).
parent(_Mark,_John).
parent(_Mark,_Frank).
parent(_Tom,_Kate).
parent(_Anne,_Alice).
parent(_Anne,_Matt).
parent(_Alice,_Henry).
parent(_Matt,_Jenny).
parent(_Matt,_Todd).
father(X,Y) :- man(X),parent(X,Y).
mother(X,Y) :- woman(X),parent(X,Y).
sibling(X,Y) :- parent(Z,X),parent(Z,Y).
sister(X,Y) :- woman(X),sibling(X,Y).
brother(X,Y) :- man(X), sibling(X,Y).
grandparent(X,Y) :- parent(X,Z),parent(Z,Y).
I'm expecting to check relations. Like if I try a function ?- parent(Pete,John). I believe it should return false, but it actually returns true for every query. This is my first program on Prolog and might need help to understand the problem.
You probably meant to write names but instead you put anonymous variables in there.
Instead of parent(_Matt,_Todd) you should write parent('Matt', 'Todd') or even parent(matt, todd).
This is an anonymous variable: _X.
This is a normal variable: X.
This is a lower-case atom. It is has a length of 1, so it is also a "char": x.
This is an upper-case char: 'X'.
If you wrap anything in single quotes, it becomes an atom. It can also have spaces in it.
If you put an underscore at the front, you get an anonymous variable. It ends at the first space or operator.
If you are getting "Singleton variable" warnings, it is usually one of two things.
Beginners often mean to write 'Bob' but write Bob instead (without the single quotes).
You are defining a predicate and you forget to use one of the variables in it. You either have to make it an anonymous variable, _Bob, if you really don't care about it, or you find where in the predicate you were supposed to use it.
First when I read up on different predicates on Prolog, like for example http_server, it's written like this: http_server(:Goal, +Options) what does : and + mean here? Sometimes ? is also written.
Secondly sometimes I see variables declared with an underscore before them like _Request, even though there isn't any another Request, why is that?
The +, -, : etc. sigils are called mode declarations. They describe the expected instantiation of predicate arguments, i.e., whether you are expected to call the predicate with an unbound variable, an instantiated term, etc. These are not completely standardized; here is a description of the conventions for SWI-Prolog: http://www.swi-prolog.org/pldoc/man?section=modes
As a first approximation, a + argument is an input to the predicate, you are supposed to provide a ground term. A - argument is an output of the predicate, the predicate will try to unify it with a term. A ? term may be partially instantiated at the call, and the predicate may instantiate it further. A : argument is a meta-argument, i.e., it is a goal to be called by the predicate (as in setof/3, for example).
In the example of http_server(:Goal, +Options), you are supposed to call this predicate with the first argument bound to a goal, probably a predicate name. The second argument must be instantiated, presumably to a list whose format is further described in the documentation. If you do not call this predicate like this, for example, if you pass an unbound variable as the second argument, you might get unexpected behavior or an instantiation error.
As for your second question (which would better have been separate), a variable that begins with an underscore is called an anonymous variable. Every such variable may only occur once per clause, except _ itself, which may occur several times and refers to separate variables at each occurrence.
Prolog systems usually emit a "singleton variable" warning for non-anonymous variables that occur only once, because those might be typos or a sign the programmer forgot something. You use anonymous variables to express the notion that "there must be something here (e.g., a predicate argument), but I don't care what it is". In your example, presumably you call a predicate that has a "request" argument, but in your particular use case you don't care about the request.
I wrote a program in prolog.
parent(Amy,John).
parent(Bob,John).
parent(John,Ben).
parent(Alice,Ben).
I'm using SWI-Prolog on Ubuntu 12.04. When I insert my file in swi-prolog interpreter:
['example.pl']
I'm getting warnings:
Warning: /home/mazix/example1.pl:1:
Singleton variables: [Amy,John]
Warning: /home/mazix/example1.pl:2:
Singleton variables: [Bob,John]
Warning: /home/mazix/example1.pl:3:
Singleton variables: [John,Ben]
Warning: /home/mazix/example1.pl:4:
Singleton variables: [Alice,Ben]
% example1.pl compiled 0.00 sec, 4 clauses
true.
What do these mean? And what does the true at the bottom mean? How should I get rid of this warnings?
Identifiers starting with a capital letter are variables. If you want atoms, enclose them in single quotes:
parent('Amy', 'John').
or start them with a small letter:
parent(amy, john).
A "singleton variable" is a named variable that appears only once in its lexical scope. What this means, in practice, is that you name it, but you don't do anything useful with it, hence the compiler warning.
Ahh.. change all your names to lower case john, ben, etc.
Since they are upper case, prolog thinks they are variables. And since you didn't use those variables, it is warning you that you will hit problems later on.
The 'true' just means that it has loaded the module.. with warnings. Everything you do in prolog returns true or false.. no escape from that.
You are using uppercase names for your relations, which indicates a variable. You should get aware of the different datatypes in Prolog. Boris already gave you the hint.
Singleton variables tells you that you are not using this variable anywhere else. true at the end tells you, that there is no contradiction in your prolog rules (because there are no rules anyhow).
http://www.csupomona.edu/~jrfisher/www/prolog_tutorial/2_1.html
So on that tutorial where it has:
conflict(Coloring) :-
adjacent(X,Y),
color(X,Color,Coloring),
color(Y,Color,Coloring).
Am I understanding this correctly, that Color is a variable and is set to a value after the first call to color and then that value is used in the second call to color?
Variables in Prolog:
All variables and arguments are local in scope to the predicate in which they are declared (aka first used). Excepting of course that variables may be passed as arguments (essentially "by reference") to another predicate.
Prolog variables are only "variable" until bound (unified) with something else. At that point they cease to be variable and become one with that with which they were unified. Hence the use of the term "unification": to unify is to become one.
Backtracking, of course, undoes any unification that might have occurred, returning things to the status quo ante as it were.
The special variable _ is the "anonymous variable". Each use, even within the same clause of a predicate is independent. For instance, given the facts
letter(a).
letter(b).
letter(c).
digit(1).
digit(2).
digit(3).
the predicate:
foo :- letter(A),number(A).
fails, whilst
foo :- letter(_),number(_).
will succeed (9 times, with backtracking).
Color it's a variable, but we can't say if it will get a value (in Prolog this is called binding) from the first or the second call to color/3. All depends on the color/3 definition. But given this code it's probable that your assumption it's ok.
I was wondering, how would I use the underscore twice but check that both instances of that underscore unify?
What I basically need is something that returns true if two elements of the same value in one mapping exist...
I.E member((_,_),[(a,a),(b,a),(c,a)]).
If I use a variable does that make them unified?
I.E member((A,A),[(a,a),(b,a),(c,a)]).
But it returns the variable rather than true.
I need some enlightenment.
Your solution with a variable is correct.
Returning a variable is a way to return true. It really means: this goal is true when var = value, as opposed to this goal is true.
Note that using this as a clause in a different predicate will hide the variable:
contains_identical_pair(List) :- member((A,A),List).
You can use double negation to avoid variable bindings:
?- \+ \+ member((A,A),[(a,a),(b,a),(c,a)]).
true.
The bindings for the variables printed on the prolog screen are just there to make life easier in an interactive prompt so that you don't have to print out the variables you care about each time. They don't affect the logic of your code at all.
They will only be printed for variables are are entered at the prompt. So if the predicate you are writing is part of a larger program, you can just ignore this output, or if you want this to be a top-level predicate that people will call from the prompt and you don't want the output printed, then simply wrap your call in a predicate that has no arguments or has only input arguments. ie:
wrapper :-
predicate(Out1,Out2).
or:
wrapper(In1,In2) :-
predicate(In1,In2,Out1,Out2).