Prolog wildcards - prolog

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).

Related

My Swi-prolog code return true for every query

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.

What do these mean in prolog?

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.

SWI-Prolog goal fail variable binding result

Is there any way that I can get a binding for a variable in Prolog even if the goal fails. I have a predicate where I am binding a variable with some value and after this I am failing the goal explicitly, but when I run the query it simply results in a fail without providing any biding for the variable. Something similar:
a(X) :-
X = 'something',
fail.
#Will Ness is correct (+1), assert can be used to capture bindings of variables as shown.
However, if you strictly need to retrieve bindings for variables in predicates like a and you know which parts could fail (and you don't care about them), then you could use combinations of cut (!) and true to permit a to proceed regardless. For example, consider:
a(X) :-
goalA(X), % a goal for which we definitely want a binding
(goalB, ! ; true). % an 'optional' goal which may fail
goalA('something').
goalB :- fail.
Executing this gives a('something'), even though goalB failed. Note that this isn't a commonly used way to program in Prolog, but if you know exactly what you're doing...
yes, this is how it is supposed to happen in Prolog. fail means the rejection of bindings made so far, because it says that these bindings are invalid, do not satisfy the goal.
but you can save some binding that will be undone on backtracking, with e.g. asserta predicate:
a(X) :-
X = 'something',
asserta(saved_x(X)),
fail.
Then, if you query saved_x(Z) afterwards, you will recover that value. Of course this is the part of Prolog that is extra-logical, i.e. outside of the logical programming paradigm.

Variables and how they are set and used in prolog

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.

warning in prolog

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.

Resources