Prolog Set List's Head - prolog

append([],U,U).
append([X|U1],U2,[W|U3]) :- **W = X** , append(U1,[X|U2],[I|Quyruk]) ,
**W = I**, U3 = Quyruk .
This code appends first two lists when I delete "W is X".
This code has unnecessary variables like "W is X" but they are about my question.
When I set any value to "W" between ":-" and ",append..." like "W is X" or "W = 3" or "W = 6" -- returns false.
Why can't I set any value to the W at that position in code but I CAN set "W = I" at the end of the code?
The query is append([1,2],[3],U). I want to get [2,1,3] at this code
at append([1,2,3],[4,5,6],U). I want to get [3,2,1,4,5,6].
append([1],[2,3],U). returns [1,2,3] , when I take the length of first list "1" (when first list only has one element) the code is perfect ; but when I take the length of first list >1 (when first list has more than one element) the code returns false.

In prolog, you can't assign variables, and then reassign them. Variables are unified and instantiated. Once instantiated, they cannot be re-instantiated inside of a clause. So if you have this inside of a clause:
W = X,
...
W = I,
Then first W is unified with X (=/2 is the unification operator). That means they either both now have the same value instantiated (if at least one was instantiated before), or their values will be forced to be identical instantiation later in the clause. When W = I is encountered later, then I must be unifiable with W or the clause will fail. If I has a specific value instantiated that is different from the instantiation of W (and, therefore, X), the clause will necessarily fail.
Let's see it happen (note I changed the name to my_append since Prolog rejects redefining the built-in predicate, append):
my_append([],U,U).
my_append([X|U1], U2, [W|U3]) :-
W = X,
my_append(U1, [X|U2], [I|Quyruk]),
write('I = '), write(I), write('; W = '), write(W), nl,
W = I,
U3 = Quyruk.
If we run:
?- my_append([1], [1,2], L).
I = 1; W = 1
L = [1,2,3]
yes
Life is good. Now let's try:
| ?- my_append([1,2], [3,4], L).
I = 2; W = 2 % This will be OK
I = 2; W = 1 % Uh oh... trouble
no
Prolog cannot unify 1 and 2, as I described above. They are two different values. So the predicate fails due to the W = I statement.
The solution is a little simpler than what you're attempting (although you are very close):
% Append empty to list gives the same list
my_append([], U, U).
% Append of [X|U1] and U2 is just append U1 and [X|U2]
% Or, thought of another way, you are moving elements of the first list
% over to the head of the second one at a time
my_append([X|U1], U2, U3) :-
my_append(U1, [X|U2], U3).
| ?- my_append([1,2,3],[4,5,6],L).
L = [3,2,1,4,5,6]
yes
The essence of this was in your code. Those other variables were just getting in the way (as C.B. pointed out). :)

The is operator is specifically used to compare or unify integers. W = I Is attempting to unify W with I (regardless of type). When you Unify W with X (assuming X is an integer), you have already unified W, and if X\=I (doesn't unify) you will return false.
In your example, W unifies with 1, but then you try to unify it with 2.
You have a lot of unnecessary variables, here is a very simple implementation of append:
append([],XS,XS).
append([X|XS],YS,[X|ZS]):- append(XS,YS,ZS).
To understand whats going wrong with your code, lets walk through it
append([],U,U).
append([X|U1],U2,[W|U3]) :- W is X , append(U1,[X|U2],[I|Quyruk]) , W = I, U3 = Quyruk .
?-append([1,2,3],[4,5,6],U).
I will use X1,X2,... to differentiate between different bindings.
In the first call, X unifies with 1, U1 unifies with [2,3] and U2 unifies with [4,5,6]. W and U3 are not yet bound before going into the horn clause.
W is X unifies W with 1.
append(U1,[X|U2],[I|Quyruk]) is calling append([2,3],[1,4,5,6],[I|Quyruk]). Already you should see that your recursion isn't working correctly.

Related

Prolog - Connectivity Graph Beginner

I am a beginner in Prolog and I have a task to do.
I need to check if the graph is connected.
For now I have that...
graph(
[arc(a,b)],
[arc(a,f)],
[arc(b,c)],
[arc(c,d)],
[arc(c,e)],
[arc(e,d)],
[arc(f,c)],
[arc(f,e)],
[arc(f,g)],
[arc(g,c)],
[arc(c,a)]).
edge(X,Y):-arc(X,Y);arc(Y,X).
path(X,Y):-edge(X,Y).
path(X,Y):-edge(X,Z),path(Z,Y).
triangle(X,Y,Z):-arc(X,Y),arc(Y,Z),arc(Z,X).
cycle(X):-arc(X,Y),path(Y,X).
connectivity([]):-forall(member(edge(X,Y)),path(X,Y)).
Check:
connectivity(graph).
upper I have arc(x,y) and I need check if every pair is connected.
Could u help me ?
Since you changed the question after I was almost done I will post what would solve the question before the change and you can figure out how to change it to meet your update.
arc(a,b).
arc(a,f).
arc(b,c).
arc(c,d).
arc(c,e).
arc(e,d).
arc(f,c).
arc(f,e).
arc(f,g).
arc(g,c).
arc(c,a).
edge(X,Y) :-
arc(X,Y), !.
edge(X,Y) :-
arc(Y,X).
path_prime(Visited,X,Y) :-
\+ member(X,Visited),
edge(X,Y), !.
path_prime(Visited,X,Y) :-
\+ member(X,Visited),
edge(X,Z),
path_prime([X|Visited],Z,Y).
path(X,X) :-
ground(X), !.
path(X,Y) :-
path_prime([],X,Y).
nodes(Nodes) :-
setof(A,B^arc(A,B),Starts),
setof(B,A^arc(A,B),Ends),
union(Starts,Ends,Nodes).
connected(X,Y) :-
nodes(Nodes),
member(X,Nodes),
member(Y,Nodes),
path(X,Y).
The first thing that has to be done is to get a list of the unique nodes which will be a set.
This can be done using
nodes(Nodes) :-
setof(A,B^arc(A,B),Starts),
setof(B,A^arc(A,B),Ends),
union(Starts,Ends,Nodes).
Notice that both the start and the end node of an arc are done separately. In particular notice that the node d is only in the destination of an arc.
Since you included edge(X,Y):-arc(X,Y);arc(Y,X). in your question, this indicated that the arcs should not be directional and so it is possible to get cycles. To avoid the cycles the list of visited nodes is added to the argument list and checked before proceeding.
As no test cases or examples of a correct solution were given, some times a node connected to itself is valid and so the clause
path(X,X) :-
ground(X), !.
was added.
This is by no means an optimal or best way to do this, just to give you something that works.
Partial run
?- connected(X,Y).
X = Y, Y = a ;
X = a,
Y = b ;
X = a,
Y = c ;
X = a,
Y = d ;
X = a,
Y = e ;
X = a,
Y = f ;
X = a,
Y = g ;
X = b,
Y = a ;
X = Y, Y = b ;
X = b,
Y = c ;
...
As I often comment, you should do problems with pen an paper first before writing code. If you don't know exactly what the code will be before you start typing the first line of code then why are you typing in code?
Questions from comments:
And setof ,union ,whats mean? Im rly beigneer and I don't understand that language and predicates.
setof/3 collects all of the values from arc/2. Since only one of the two values is needed, ^ tells setup/3 not to bind the variable in the Goal, or in beginner terms to just ignore the values from the variable.
union/3 just combines the to sets into one set; remember that a set will only have unique values.

How is suffix/prefix working internally in prolog?

Can anyone explain how prolog finds a suffix(L1,L2) or prefix(L1,L2) internally?
I know the rule is suffix(L1,L2):- append(_,L2,L1).
But, I can't seem to understand how the variables _, L1 and L2 going inside append and working the query out?
append([],X,X).
append([H|T],Y, [H|W]):- append(T,Y, W).
If you understand append, then the definition
suffix( A, B) :- append( _X, B, A).
is ... well, actually, what is the meaning of append( X, B, A)?
It's that (in pseudocode) [...X, ...B] == A: the list of elements of X, followed by elements of B, together, is the list of elements in A.
This means that B is a (suffix / prefix -- make a choice, please) of A, right? and we don't care what X is. In particular it can be empty, or not.
This explains suffix. For append please see the linked answer, and the answer it links.
This gives us an idea for a follow up question:
Define the predicate proper_suffix(A, B) such that "proper_suffix of A is B" holds, i.e. B is a suffix of A, and B is not the same as A.
You write
I am not understanding how _ for the suffix's argument is going inside append([H|T], Y, [H|W]):- append(T,Y, W). How is append processing the _ for the H of the append to find whether L2 is suffix of L1? if I pass _, how does Prolog figure out the H and T, coz by anonymous variable we mean that 'we don't care about its value' .
So we have
suffix( A, B) :-
append( _X, B,
A).
Whatever the A and B were in the call to suffix(A, B), they will be the same in the call to append( _X, B, A). When that call returns with logic variables _X, A and B holding their (possibly updated) values, the call to suffix returns with its A and B holding those same values as in the append call. The value of _X is not made use of by the suffix/2 predicate, but it is found out just the same, by append/3.
You seem to be confused about the anonymous variable, _. It doesn't matter that it is named that way, it is still a variable. Forget the "don't care" thing, it is confusing and imprecise. Imagine it is named _X, as I showed. it will work exactly the same with _Y, _, Abracadabra, etc., as long as it is not the same as the other variables' names in that rule.
Just one caveat: without the leading _ Prolog will warn us about "singleton variable" i.e. a variable that isn't used anywhere else. It is with respect to this that we signal our intention that "we don't care", with the (leading) _.
Its value is still going to be found, as usual!
And when we use _, the additional convenience is that we don't have to make sure that the name is unique. Each _ is treated as if it were unique, automatically.
You ask (in the comments) how does the query append(_X, [a,b], [1,2,a,b]) work.
Prolog works by choosing a rule whose head matches the query.
This query matches the second clause's head:
append(_X, [a,b], [1,2,a,b]) = append([H|T], Y, [H|W])
with
_X = [H|T], Y = [a,b], [H|W] = [1,2,a,b]
Which also means
H = 1, W = [2,a,b],
and hence
_X = [H|T] = [1|T]
See? This doesn't deconstruct _X, it builds it up!
Since its head matches the query, the second clause of your append definition is thus chosen, and so its body is fired up as the new query under the same substitution, i.e. set of "assignments" to the logic variables involved. So it calls
_X = [H|T], Y = [a,b], [H|W] = [1,2,a,b], append(T,Y,W).
as the new query. That is,
_X = [1|T], Y = [a,b], W = [2,a,b], append(T,Y,W). %% or,
_X = [1|T1], append(T1, [a,b], [2,a,b]).
If we apply the same reasoning, we see again the second clause matching up, and end up with
_X = [1|T1], T1 = [2|T2], append(T2, [a,b], [a,b]).
But now the first clause matches,
append(T2, [a,b], [a,b]) = append([],X,X)
which entails
T2 = [].
Thus
_X = [1|T1]
T1 = [2|T2]
T2 = [].
The list now held by _X has thus been built in a top-down fashion.

How to impelement correspond function in prolog

I am a beginner of Prolog and I'd like to know how to implement this correspond function.
correspond(E1, L1, E2, L2)
this holds when in one place where list L1 has the value E1, L2
has E2. This must work in any mode in which L1 and L2 are proper
lists (that is, either [] or a list whose tail is a proper list).
For example:
correspond(e,[h,e,l,l,o],X,[1,2,3,4,5])
should have only the solution X = 2.
Here is what I have tried by now:
correspond(E1, L1, E2, L2).
correspond(E1,[Elt1|List1],E2,[Elt2|List2]) :-
nth0(Index, [Elt1|List1], E1).
nth0(Index, [Elt2|List2], E2).
I wanted to use Index as intermediate to get the value of E1 or E2, but these code returns either True or False.
This is what I tried, and it works at least for your example :
correspond(e,[h,e,l,l,o],X,[1,2,3,4,5]) has the solution X = 2
Code :
correspond(E1,[E1|_T1],E2,[E2|_T2]).
correspond(E1,[_H1|T1],E2,[_H2|T2]) :-
correspond(E1,T1,E2,T2).
Explanation :
if E1 is the first element of the first list, then E2 should be the first element of the second list.
else, we try the same with tails of lists 1 and 2 and we iterate recursively.
Note that :
correspond(l,[h,e,l,l,o],X,[1,2,3,4,5]) has both solutions X = 3 and X = 4.
Try correspond(X,[h,e,l,l,o],Y,[1,2,3,4,5] and you'll get :
X = h, Y = 1
X = e, Y = 2
X = l, Y = 3
X = l, Y = 4
X = o, Y = 5
false
Edit:
If you really want to get true instead of false after the last result, you might want to prepend the predicate :
correspond(_,[],_,[]).
Resulting in :
correspond(_,[],_,[]).
correspond(E1,[E1|_T1],E2,[E2|_T2]).
correspond(E1,[_H1|T1],E2,[_H2|T2]) :-
correspond(E1,T1,E2,T2).
This means when you try it with empty lists (e.g. the last iteration when lists are of same size), it is true.

Prolog internal variable names

I have a large numbers of facts that are already in my file (position(M,P)), M is the name and P is the position of the player , I am asked to do a player_list(L,N), L is the list of players and N is the size of this list. I did it and it works the problem is that it gives the list without the names it gives me numbers and not names
player_list([H|T],N):- L = [H|T],
position(H,P),
\+ member(H,L),
append(L,H),
player_list(T,N).
what I get is:
?- player_list(X,4).
X = [_9176, _9182, _9188, _9194] .
so what should I do ?
You could use an additional list as an argument to keep track of the players you already have. This list is empty at the beginning, so the calling predicate calls the predicate describing the actual relation with [] as an additional argument:
player_list(PLs,L) :-
pl_l_(PLs,L,[]). % <- actual relation
The definition you posted is missing a base case, that is, if you already have the desired amount of players, you can stop adding others. In this case the number of players to add is zero otherwise it is greater than zero. You also have to describe that the head of the list (PL) is a player (whose position you don't care about, so the variable is preceded by an underscore (_P), otherwise the goal is just like in your code) and is not in the accumulator yet (as opposed to your code, where you check if PL is not in L) but in the recursive call it is in the accumulator. You can achieve the latter by having [PL|Acc0] in the recursive goal, so you don't need append/2. Putting all this together, your code might look something like this:
pl_l_([],0,_). % base case
pl_l_([PL|PLs],L1,Acc0) :-
L1 > 0, % number of players yet to add
L0 is L1-1, % new number of players to add
position(PL,_P), % PL is a player and
\+ member(PL,Acc0), % not in the accumulator yet
pl_l_(PLs,L0,[PL|Acc0]). % the relation holds for PLs, L0 and [PL|Acc0] as well
With respect to your comment, I assume that your code contains the following four facts:
position(zlatan,center).
position(rooney,forward).
position(ronaldo,forward).
position(messi,forward).
Then your example query yields the desired results:
?- player_list(X,4).
X = [zlatan,rooney,ronaldo,messi] ? ;
X = [zlatan,rooney,messi,ronaldo] ? ;
...
If you intend to use the predicate the other way around as well, I suggest the use of CLP(FD). To see why, consider the most general query:
?- player_list(X,Y).
X = [],
Y = 0 ? ;
ERROR at clause 2 of user:pl_l_/3 !!
INSTANTIATION ERROR- =:=/2: expected bound value
You get this error because >/2 expects both arguments to be ground. You can modify the predicate pl_l_/3 to use CLP(FD) like so:
:- use_module(library(clpfd)).
pl_l_([],0,_).
pl_l_([PL|PLs],L1,Acc0) :-
L1 #> 0, % <- new
L0 #= L1-1, % <- new
position(PL,_P),
\+ member(PL,Acc0),
pl_l_(PLs,L0,[PL|Acc0]).
With these modifications the predicate is more versatile:
?- player_list([zlatan,messi,ronaldo],Y).
Y = 3
?- player_list(X,Y).
X = [],
Y = 0 ? ;
X = [zlatan],
Y = 1 ? ;
X = [zlatan,rooney],
Y = 2 ?
...

How can I assert facts about all List members in Prolog?

I'd like to assert facts about all members of a List in prolog, and have any resulting unification retained. As an example, I'd like to assert that each list member is equal to five, but none of the below constructs does this:
?- L=[X,Y,Z], forall(member(E,L), E=5).
L = [_h27057686,_h27057704,_h27057722]
X = _h27057686
Y = _h27057704
Z = _h27057722
yes
?- L=[X,Y,Z], foreach(member(E,L), E=5).
L = [_h27057686,_h27057704,_h27057722]
X = _h27057686
Y = _h27057704
Z = _h27057722
yes
I would like a way to pose the query such that X=5,Y=5, and Z=5.
There is a lot of terminology that you might be getting wrong, or I am misunderstanding you.
"Equal to" is not the same as "could unify", or "unify", but it depends how you mean it.
With SWI-Prolog, from the top level:
?- X == 5.
false. % the free variable X is not the integer 5
?- unifiable(X, 5, U).
U = [X=5]. % you could unify X with 5, then X will be 5
?- X = 5.
X = 5. % X unifies with 5 (and is now bound to the integer 5)
The comment by CapelliC already has the answer that you are most likely after: given a list of variables (either free or not), make so that each variable in the list is bound to the integer 5. This is best done by unification (the third query above). The maplist simply applies the unification to each element of the list.
PS. In case you are wondering how to read the maplist(=(5), L):
These three are equivalent:
maplist(=(5), [X,Y,Z])
maplist(=, [5,5,5], [X,Y,Z])
X=5, Y=5, Z=5
And of course X=5 is the same as =(X,5).

Resources