user3105533
user3105533

Reputation: 331

singleton variables in prolog query

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

Upvotes: 3

Views: 428

Answers (2)

Edu
Edu

Reputation: 2643

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

Upvotes: 0

Shevliaskovic
Shevliaskovic

Reputation: 1564

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

Upvotes: 1

Related Questions