I have the following gprolog program:
father(charles, harry).
daughter(elizabeth, george).
son(william, charles).
father(X, Y) :- son(Y, X).
father(X, Y) :- daughter(Y, X).
daughter(X, Y) :- \+son(X, Y), father(Y, X).
son(X, Y) :- \+daughter(X, Y), father(Y, X).
Given what I have, I tried this query:
| ?- son(harry, charles).
...and got a no
(a.k.a., from what I understand, "Prolog can't prove this."). When I ran a trace on it, it didn't seem too helpful:
{trace}
| ?- son(harry, charles).
1 1 Call: son(harry,charles) ?
1 1 Fail: son(harry,charles) ?
Since son(harry, charles)
should match up to the last line of my code, I figured the program would simply start by checking the first part: \+daughter(X, Y)
("Prolog can't prove that Harry is the daughter of Charles", right?). Indeed:
| ?- \+daughter(harry, charles).
1 1 Call: \+daughter(harry,charles) ?
2 2 Call: daughter(harry,charles) ?
2 2 Fail: daughter(harry,charles) ?
1 1 Exit: \+daughter(harry,charles) ?
(1 ms) yes
So then it would proceed to the second part, right? It would check for father(Y, X)
, i.e., father(charles, harry)
, which was given as a fact!
| ?- father(charles, harry).
1 1 Call: father(charles,harry) ?
1 1 Exit: father(charles,harry) ?
(1 ms) yes
With both of these true, why doesn't it give a yes
for son(harry, charles)
? As an important note, this did compile with discontiguous predicate warnings:
compiling /Users/nicolejulian/Dropbox/AI/test.pl for byte code...
/Users/nicolejulian/Dropbox/AI/test.pl:4: warning: discontiguous predicate father/2 - clause ignored
/Users/nicolejulian/Dropbox/AI/test.pl:5: warning: discontiguous predicate father/2 - clause ignored
/Users/nicolejulian/Dropbox/AI/test.pl:6: warning: discontiguous predicate daughter/2 - clause ignored
/Users/nicolejulian/Dropbox/AI/test.pl:7: warning: discontiguous predicate son/2 - clause ignored
/Users/nicolejulian/Dropbox/AI/test.pl compiled, 8 lines read - 617 bytes written, 11 ms
(1 ms) yes
A few earlier experiments made it seem like I basically had a choice between warnings and infinite loops, so I went along with this as-is. (for example, grouping all of the left-side labels removes the warnings but then causes the query | ?- father(elizabeth, george).
to crash).
At any rate, provided that I can't just 'cheat' and add son(harry, charles)
in as a fact, what am I not understanding about Prolog's execution steps?