I have a small problem when we are talking about anonymous variables. For example when we make this:
?- [_,2]=[X|Y].
Y=[2].
but my question is about the variable X. Does it have the '_'?
No, X does not "have the _". It is bound to an anonymous variable, which is never bound to anything else. This binding of X to an anonymous variable does not create any additional limitations on X - for all practical purposes, it remains unbound.
The _ variable has been introduced to let Prolog coders express in code that they do not care about a value in a particular position. One could emulate this behavior by using variables that look like UNUSED1, UNUSED2, UNUSED3 and so on instead of the _, and ignoring Prolog warnings about singleton variables:
[UNUSED123,2]=[X|Y].
Using the underscore _ is like telling Prolog that you know that the unused variable is singleton, and that it is indeed your intention.
Related
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.
Here is what I have understood about Prolog variables.
A single underscore stands for anonymous variable, which is like a new variable each time it occurs.
A variable name starting with underscore like _W is not an anonymous variable. Or, the variable names generated inside Prolog, like _G189, is not considered anonymous:
?- append([1,2],X,Y).
X = _G189
Y = [1, 2|_G189]
Could you please help me understand?
By the way, I got the above example from some tutorials, but when I run it in SWI-Prolog version 6, I get the following:
?- append([1,2],X,Y).
Y = [1, 2|X].
Thanking you.
Variables
The anonymous variable _ is the only variable where different occurrences represent different variables. Other variables that start with _ are not anonymous. Different occurrences refer to the same variable (within the same scope). However, many Prologs like SWI will warn you should a variable not starting with an underscore occur only once:
?- [user].
a(V).
Warning: user://1:9:
Singleton variables: [V]
You have to rename that variable to _V to avoid that warning. This is a help for programmers to better spot typos in variable names. There are some more such restrictions in many systems.
a(_V,_V).
Warning: user://1:12:
Singleton-marked variables appearing more than once: [_V]
Again, this is only a warning. If you want that a variable starting with _ should occur twice (without warning), write __ instead. But better stick to more meaningful names without a starting _.
Answers
What you get from Prolog's top level loop are answers ; and in particular answer substitutions. They serve to represent solutions (that's what we are really interested in). There are several ways how answer substitutions may be represented. The tutorial you are using seems to refer to a very old version of SWI. I would say that this version is maybe 15 to 20 years old.
?- append([1,2],X,Y).
X = _G189
Y = [1, 2|_G189]
However, the answer given is not incorrect: A new auxiliary variable _G189 is introduced.
Newer versions of SWI and many other systems try to minimize the output, avoiding auxiliary variables. So
?- append([1,2],X,Y).
Y = [1, 2|X].
is just as fine. It is the answer of a "newer" version (also some 6 years old). Note that this answer tells you much more than the first one: Not only does it show you the answer substitution more compactly, but it also tells you that there is exactly this one answer (and no more). See the dot . at the end? This means: There is no more here to answer. Otherwise there would be a ; for the next answer.
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 know there is a build-in function findall/3 in prolog,
and im trying to find the total numbers of hours(Thrs) and store them in a list, then sum the list up. but it doesnt work for me. here is my code:
totalLecHrs(LN,THrs) :-
lecturer(LN,LId),
findall(Thrs, lectureSegmentHrs(CC,LId,B,E,THrs),L),
sumList(L,Thrs).
could you tell me what's wrong with it? thanks a lot.
You need to use a "dummy" variable for Hours in the findall/3 subgoal. What you wrote uses THrs both as the return value for sumList/2 and as the variable to be listed in L by findall/3. Use X as the first argument of findall and in the corresponding subgoal lectureSegmentHrs/5 as the last argument.
It looks like the problem is that you're using the same variable (Thrs) twice for different things. However it's hard to tell as you've also used different capitalisation in different places. Change the findall line so that the initial variable has the same capitalisation in the lectureSegmentHrs call. Then use a different variable completely to get the final output value (ie the one that appears in sumList and in the return slot of the entire predicate).
You need to use a different variable because Prolog does not support variable reassignment. In a logical language, the notion of reassigning a variable is inherently impossible. Something like the following may seem sensible...
...
X = 10,
X = 11,
...
But you have to remember that , in Prolog is the conjunction operator. You're effectively telling Prolog to find a solution to your problem where X is both 10 and 11 at the same time. So it's obviously going to tell you that that can't be done.
Instead you have to just make up new variable names as you go along. Sometimes this does get a bit annoying but it's just goes with the territory of a logical languages.
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.