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.
Related
I have this fact that returns the descendants but it only returns if "ascendente" is father/mother of "descendente". What am I doing wrong?
%descendenteDir(homem,mulher,filho)
descendenteDir('Tywin','Joanna','Ser Jaime').
descendenteDir('Tywin','Joanna','Cersei').
descendenteDir('Robert','Cersei','Joffrey').
descendenteDir('Robert','Cersei','Myrcella').
descendenteDir('Robert','Cersei','Tommen').
descendenteDir('Kevan','Dorna','Lancel').
descendente(Ascendente,Descendente):- descendenteDir(Ascendente,_,Descendente)
;descendenteDir(_,Ascendente,Descendente)
;descendenteDir(descendente(Ascendente,_),_,Descendente)
; descendenteDir(_,descendente(Ascendente,_),Descendente).
The descendente(Ascendente,_) part in the final rule is not quite right. It should be something like this:
descendente(Ascendente,Descendente):- descendenteDir(Ascendente,_,Descendente)
;descendenteDir(_,Ascendente,Descendente)
;descendenteDir(X,_,Descendente), descendente(Ascendente,X)
;descendenteDir(_,X,Descendente), descendente(Ascendente,X).
It's not the same as calling functions and getting returned values in languages like C++/Python/Java. In Prolog, you have a set of facts (the descendenteDir rules at the top), and some inference rules (the descendente rule). In the definition where you would use the rule recursively, you would have to provide a variable which would be bound to the values available (from the facts). That variable would later be used to infer the subsequent rules. Here X is that variable. Prolog will bind different values to it and try to infer the next part from the following clause.
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 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.
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.
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).