singleton variables in prolog query - prolog

I am new to Prolog and running into a problem. When I ask the query ?-grandfather(daniel,george) on the data below, I get the wrong answer. I don't understand why my query doesn't work. I also received a warning message stating that [C,D] are singleton variables. This warning no longer occurs. Again, I'm unsure why.
mother(jules,mary).
mother(jules,martha).
mother(jules,andy).
mother(mary,annie).
mother(mary,george).
mother(martha,jesse).
mother(martha,june).
mother(june,camile).
father(daniel,mary).
father(daniel,martha).
father(daniel,andy).
father(adrian,annie).
father(adrian,george).
father(carlo,camile).
brothers(A,B):-father(C,A),father(C,B);mother(D,A),mother(D,B).
grandfather(E,W):-father(E,father(C,W));father(E,mother(D,W)).

You can write your grandfather query more simply:
grandfather(E,W):-father(E,A),father(A,W).
grandfather(E,W):-father(E,A),mother(A,W).
or
grandfather(E,W):-father(E,A),father(A,W);father(E,A),mother(A,W).
and now:
6 ?- grandfather(daniel,george).
true .
7 ?- grandfather(daniel,annie).
true .
Here, we ask Prolog to find the grandson of E where: E is the father of A and A is the father/mother of W.
Or more specifically, to check if daniel has a grandson named george. Prolog checks: daniel has a daughter mary and mary has a son george. So it would return true. If you trace it, you see:
[trace] 3 ?- grandfather(daniel,george).
Call: (6) grandfather(daniel, george) ? creep
Call: (7) father(daniel, _G1931) ? creep
Exit: (7) father(daniel, mary) ? creep
Call: (7) father(mary, george) ? creep
Fail: (7) father(mary, george) ? creep
Redo: (7) father(daniel, _G1931) ? creep
Exit: (7) father(daniel, martha) ? creep
Call: (7) father(martha, george) ? creep
Fail: (7) father(martha, george) ? creep
Redo: (7) father(daniel, _G1931) ? creep
Exit: (7) father(daniel, andy) ? creep
Call: (7) father(andy, george) ? creep
Fail: (7) father(andy, george) ? creep
Redo: (6) grandfather(daniel, george) ? creep
Call: (7) father(daniel, _G1931) ? creep
Exit: (7) father(daniel, mary) ? creep
Call: (7) mother(mary, george) ? creep
Exit: (7) mother(mary, george) ? creep
Exit: (6) grandfather(daniel, george) ? creep
true .
[C,D] are singleton variables indicates that there is one or more variable in the clause that appears only once. This isn't affecting the program, you can still run your queries.
Singleton Variables on SWI Documentation

Thanks for the answer, one last question, i tried to do a rule for cousins like this
cousins(X,Y):-mother(A,X),mother(B,Y),mother(D,A),mother(D,B),father(C,A),father(C,B).
it states that if the mother of X and the mother of Y have the same mother and father X,Y are cousins. but when i ask the query ?- cousins(annie,george) prolog answers YES, and it should not be that way because annie and george are brothers, so i guess there must be a logical mistake
A and B (Mothers of X and Y) can be equal, that is why it gives Yes to brothers.
You should specify that they don't have the same mother and father (A\=B).
Off question:
Using "parent" can reduce your coding in this kind of problems (family trees).
mother(A,B) :- parent(A,B).
Or even:
mother(A,B) :- parent(A,B), female(A).
This way you don't need to apply the cousin problem (or any of this kind, like brothers) to the mother and the father.
In the brothers you have:
brothers(A,B):-father(C,A),father(C,B);mother(D,A),mother(D,B).
It could be:
brothers(A,B):-parent(X,A),parent(X,B).

Related

prolog questions.. fails to invoke predicate

I am trying to understand why duck2 is not called.. Should I cover all cases of the two list being empty, non empty.
duck([H|T], something ) :-
write("*"),
write("?"),
duck2([H|T], T, something_else),
write("Over").
duck2([], [], something_else) :- write("AllDone").
duck2([H|T], [H1,T1], something_else) :-
write("I am here").
trace gives this..
Call: (16) duck([dog, eats], [eats], something) ? creep
Call: (17) write("*") ? creep
*
Exit: (17) write("*") ? creep
Call: (17) write("?") ? creep
?
Exit: (17) write("?") ? creep
Call: (17) duck2([dog, eats], [eats], something_else) ? creep
Fail: (17) duck2([dog, eats], [eats], something_else) ? creep
Fail: (16) duck([dog, eats], [eats], something) ? creep
duck2([H|T], [H1,T1], something_else) :-
% spaced out to line up with the below trace
duck2([H|T], [H1,T1], something_else) :-
Call: (17) `duck2([dog, eats], [eats], something_else)` ? creep
[H1, T1] is a list of two items and [eats] is a list of one item; if you try and unify them, they don't unify:
?- [H1, T1] = [eats].
false
so the call fails.
Should I cover all cases
Well, at least cover enough cases to make the code work. All cases is up to you.

Brother in law predicate for Prolog not working

Here's the relevant code:
married(X,Y) :- wife(X,Y);husband(X,Y).
parent(X,Y) :- father(X,Y) ;mother(X,Y).
brother(X,Y) :-
man(X),
parent(Z,X),
parent(Z,Y),
X \= Y.
brother_in_law(X,Y) :-
brother(X,Z),married(Z,Y).
I've googled and it seems other have been using the exact code for the brother in law predicate so it should be fine? I checked the other predicates and they seem good too.. not sure what is happening.
Also, by not working I mean that it's not acknowledging the relevant relation when I check.
Look at the trace and you will see the problem:
?- trace, brother_in_law(prins-daniel, Y).
Call: (9) brother_in_law(prins-daniel, _11346) ? creep
Call: (10) brother(prins-daniel, _11680) ? creep
Call: (11) man(prins-daniel) ? creep
Exit: (11) man(prins-daniel) ? creep
Call: (11) parent(_11678, prins-daniel) ? creep
Call: (12) father(_11678, prins-daniel) ? creep
Fail: (12) father(_11678, prins-daniel) ? creep
Redo: (11) parent(_11678, prins-daniel) ? creep
Call: (12) mother(_11678, prins-daniel) ? creep
Fail: (12) mother(_11678, prins-daniel) ? creep
Fail: (11) parent(_11678, prins-daniel) ? creep
Redo: (11) man(prins-daniel) ? creep
Fail: (11) man(prins-daniel) ? creep
Fail: (10) brother(prins-daniel, _11680) ? creep
Fail: (9) brother_in_law(prins-daniel, _11346) ? creep
false.
Who is prins-daniel's father? You don't have a fact for that. Who is prins-daniel's mother? You don't have a fact for that either. As a result, you can't find any brothers, so the query fails.
Does this mean you are missing facts or missing code? The code says X and Y are brothers-in-law if X has a brother Z who is married to Y. Is this the only way to have a brother-in-law?
Side note: prins-daniel is not an atom in Prolog as it would be in Lisp. This is a term:
?- write_canonical(prins-daniel).
-(prins,daniel)
The situation is compounded by longer terms:
?- write_canonical(johann-georg-av-hohenzollern).
-(-(-(johann,georg),av),hohenzollern)
Just something to be aware of.

Infinite loop in Prolog. How do I prevent this?

I am writing a program in Prolog that represents the rules of a card game. However, I am running into an infinite loop with the following code.
succ(seven_of_hearts,eight_of_hearts).
succ(eight_of_hearts,nine_of_hearts).
succ(nine_of_hearts,ten_of_hearts).
succ(ten_of_hearts,jack_of_hearts).
succ(jack_of_hearts,queen_of_hearts).
succ(queen_of_hearts,king_of_hearts).
succ(king_of_hearts,ace_of_hearts).
succ(X,Y) :-
succ(X,Z),
succ(Z,Y),
!.
beats(X,Y) :-
succ(Y,X).
Basically, my attempt with these few lines is to set up a system for determining if one card beats another according to the succ (or succession) relationships I have established. So the query I am running is beats(X,Y), where X and Y and atoms corresponding to cards. This query terminates successfully if it is true. For example, if I query beats(jack_of_hearts,seven_of_hearts), it returns true and terminates.
However, the query enters an infinite loop if it is false. For example, when I query beats(seven_of_hearts,jack_of_hearts). I traced the query and found that due to the recursive nature of the last succ statement, the query follows the chain of succ statements all the way down to the seven_of_hearts, or all the way up to the ace_of_hearts, and then continuously tries to evaluate succ(seven_of_hearts,X) or succ(ace_of_hearts,X) instead of returning false.
I have two questions: using this current structure, how could I prevent this? Or, if that's not possible, what is an alternative structure I could use to accomplish my goal?
EDIT:
Here is a screenshot of my trace for one of the failing queries:
Call: (267) beats(seven_of_hearts, jack_of_hearts) ? creep
Call: (268) succ(jack_of_hearts, seven_of_hearts) ? creep
Call: (269) succ(jack_of_hearts, _G7104) ? creep
Exit: (269) succ(jack_of_hearts, queen_of_hearts) ? creep
Call: (269) succ(queen_of_hearts, seven_of_hearts) ? creep
Call: (270) succ(queen_of_hearts, _G7104) ? creep
Exit: (270) succ(queen_of_hearts, king_of_hearts) ? creep
Call: (270) succ(king_of_hearts, seven_of_hearts) ? creep
Call: (271) succ(king_of_hearts, _G7104) ? creep
Exit: (271) succ(king_of_hearts, ace_of_hearts) ? creep
Call: (271) succ(ace_of_hearts, seven_of_hearts) ? creep
Call: (272) false ? creep
Fail: (272) false ? creep
Redo: (271) succ(ace_of_hearts, seven_of_hearts) ? creep
Call: (272) succ(ace_of_hearts, _G7104) ? creep
Call: (273) false ? creep
Fail: (273) false ? creep
Redo: (272) succ(ace_of_hearts, _G7104) ? creep
Call: (273) succ(ace_of_hearts, _G7104) ? creep
Call: (274) false ? creep
Fail: (274) false ? creep
Redo: (273) succ(ace_of_hearts, _G7104) ? creep
Call: (274) succ(ace_of_hearts, _G7104) ? creep
Call: (275) false ? creep
Your predicate obviously keeps calling itself: succ(X, Y) :- succ(Y, X), .... A simple solution is not to use the same name for your predicate as you do your facts. Get rid of your succ/2 predicate (leaving the facts) in favor of:
successor(X, Y) :- succ(X, Y).
successor(X, Y) :- succ(X, Z), succ(Z, Y).
beats(X, Y) :- successor(Y, X).

Prolog: Distance between cities

I'm new to Prolog. I'm trying to make a simple program that find the distance between cities using recursive structure. The problem occurs when I try to find sum distance between cities that are not directly connected (e.g. london to sydney).
distance(london,newyork,3.2).
distance(london,capetown,5.8).
distance(london,rome,0.8).
distance(london,panama,4.5).
distance(panama,sydney,7.7).
distance(newyork,sanfrancisco,2.5).
distance(newyork,panama,1.9).
distance(sanfrancisco,sydney,6.2).
distance(sanfrancisco,tokyo,4.5).
distance(tokyo,calcutta,2.5).
distance(tokyo,sydney,4.1).
distance(sydney,calcutta,4.4).
distance(sydney,capetown,6.0).
distance(capetowm,rome,5.1).
distance(calcutta,cairo,2.2).
distance(cairo,rome,0.9).
connected(X,Y,Distance):-
distance(X,Y,Distance).
connected(X,Y,Distance):-
distance(X,Z,NewDistance),
connected(Z,Y,NewDistance),
Distance is Distance+NewDistance.
You can modify your last rule like this:
connected(X,Y,Distance):- distance(X,Z,Distance1),
distance(Z,Y,Distance2),
SumDistance is Distance1+Distance2,
write(SumDistance).
Here is my result:
1 ?- connected(london,sydney,X).
12.2
true .
The route is London -> Panama -> Sydney. I used trace. to see how it works:
2 ?- trace.
true.
[trace] 2 ?- connected(london,sydney,X)
....
Redo: (7) distance(london, _G1945, _G1946) ? creep
Exit: (7) distance(london, panama, 4.5) ? creep
Call: (7) distance(panama, sydney, _G1950) ? creep
Exit: (7) distance(panama, sydney, 7.7) ? creep
Call: (7) _G1955 is 4.5+7.7 ? creep
Exit: (7) 12.2 is 4.5+7.7 ? creep
Call: (7) write(12.2) ? creep
12.2
Exit: (7) write(12.2) ? creep
Exit: (6) connected(london, sydney, _G1871) ? creep
(I have removed some of the tracing because it was too long).

Some doubts about declarative meaning of a program that prints a list of lists in Prolog

Write a rule that take a list whose elements are themselves lists and
print on each line the elements of internals list:
Example:
?- printList[[1,a],[2,b]]).
1 a
2 b
The solution it the following one:
/* BASE CASE: The list is empty, so there is nothing to print */
printList([]).
printList([P|R]):- printList(P),
!,
nl,
printList(R).
printList([X|R]):- write(X),
!,
printList(R).
I have the printList rule that reaches the base case when the list is empty and in this case there is nothing to print.
If I am not in the base case (the list is not empty) it calls the second rule printList([P|R]) and now I have my first doubt:
The element P is a list because Prolog automatically handles an internal list as an element?
So, If I have something like:
[[1,a],[2,b],[3,c],[4,d]] I have that Prolog automatically match in this way:
P = [1,a] (the first list as the head element)
R = [[2,b],[3,c],[4,d]] (the other 3 list are the element of a tail list)
And then the program calls the printList predicate on the head element (the first list) and this version of the rule writes all the elements in the current list.
Is this right this interpretation?
Now I have some doubts about about the trace of this program, for example if I execute this statement I obtain the following trace:
[trace] ?- printList([[1,a], [2,b]]).
Call: (6) printList([[1, a], [2, b]]) ? creep
Call: (7) printList([1, a]) ? creep
Call: (8) printList(1) ? creep
Fail: (8) printList(1) ? creep
Redo: (7) printList([1, a]) ? creep
Call: (8) write(1) ? creep
1
Exit: (8) write(1) ? creep
Call: (8) printList([a]) ? creep
Call: (9) printList(a) ? creep
Fail: (9) printList(a) ? creep
Redo: (8) printList([a]) ? creep
Call: (9) write(a) ? creep
a
Exit: (9) write(a) ? creep
Call: (9) printList([]) ? creep
Exit: (9) printList([]) ? creep
Exit: (8) printList([a]) ? creep
Exit: (7) printList([1, a]) ? creep
Call: (7) nl ? creep
Exit: (7) nl ? creep
Call: (7) printList([[2, b]]) ? creep
Call: (8) printList([2, b]) ? creep
Call: (9) printList(2) ? creep
Fail: (9) printList(2) ? creep
Redo: (8) printList([2, b]) ? creep
Call: (9) write(2) ? creep
2
Exit: (9) write(2) ? creep
Call: (9) printList([b]) ? creep
Call: (10) printList(b) ? creep
Fail: (10) printList(b) ? creep
Redo: (9) printList([b]) ? creep
Call: (10) write(b) ? creep
b
Exit: (10) write(b) ? creep
Call: (10) printList([]) ? creep
Exit: (10) printList([]) ? creep
Exit: (9) printList([b]) ? creep
Exit: (8) printList([2, b]) ? creep
Call: (8) nl ? creep
Exit: (8) nl ? creep
Call: (8) printList([]) ? creep
Exit: (8) printList([]) ? creep
Exit: (7) printList([[2, b]]) ? creep
Exit: (6) printList([[1, a], [2, b]]) ? creep
true.
This is quite clear for me (I think that my previous reasoning is right) but I am not understanding why whenever it reaches an element in an internal list it calls the printList relation on it (that is a simple element and not a list), for example here:
Call: (8) printList(1) ? creep
Fail: (8) printList(1) ? creep
the program had considered the first list of the original list and then, into it to have to print its first element, why call the printList relation on this simple element
Is it because this simple element may in turn be internal lists?
Something like:
[[[1.1,a1,a2],[1.2,b1,b2]], [2,b]] (in which I have a list that contains 2 lists and the first element it is a list that contains 2 lists. So the program checks if an element it is an element or an internal list?
I think you're over-thinking it. Look at the code:
printList([P|R]):- printList(P),
Right there you can see that printList/1 is being unified with the head of the list. The fact that all the rules of printList/1 match lists and only lists is a fact that you, the human, can immediately see. But Prolog does not "notice" this fact, so if you are to call, say,
printList([1])
the first matching rule is the one above, so it will immediately try to unify printList(1). This will fail, naturally, because 1 is not a list and so doesn't match any of the rules for printList/1. Prolog then backtracks and tries the next rule, which is the one that starts like this:
printList([X|R]):- write(X),
This is clearly going to unify [1] with X = 1, R = [], so it's clearly going to write the first element, the one, and then proceed as usual. There is no magic here involving "internal lists," which as far as I'm aware is not a concept in Prolog at all (if such a thing is treated in the compiler it is well hidden from the user of Prolog).
Prolog isn't psychic; it has to try the rules to see if they fail, even if that attempt is essentially a failing pattern-match in the head of the Horn clause.
I am unable to distinguish your first from your second question so I hope this answers both. :)

Resources