Note that there are some explanatory texts on larger screens.

plurals
  1. PONew to gprolog - how can I make this short program reach the correct conclusion?
    primarykey
    data
    text
    <p>I have the following gprolog program:</p> <pre><code>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). </code></pre> <p>Given what I have, I tried this query:</p> <pre><code>| ?- son(harry, charles). </code></pre> <p>...and got a <code>no</code> (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:</p> <pre><code>{trace} | ?- son(harry, charles). 1 1 Call: son(harry,charles) ? 1 1 Fail: son(harry,charles) ? </code></pre> <p>Since <code>son(harry, charles)</code> should match up to the last line of my code, I figured the program would simply start by checking the first part: <code>\+daughter(X, Y)</code> ("Prolog can't prove that Harry is the daughter of Charles", right?). Indeed:</p> <pre><code>| ?- \+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 </code></pre> <p>So then it would proceed to the second part, right? It would check for <code>father(Y, X)</code>, i.e., <code>father(charles, harry)</code>, which was given as a fact! </p> <pre><code>| ?- father(charles, harry). 1 1 Call: father(charles,harry) ? 1 1 Exit: father(charles,harry) ? (1 ms) yes </code></pre> <p>With both of these true, why doesn't it give a <code>yes</code> for <code>son(harry, charles)</code>? As an important note, this did compile with discontiguous predicate warnings:</p> <pre><code>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 </code></pre> <p>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 <code>| ?- father(elizabeth, george).</code> to crash). </p> <p>At any rate, provided that I can't just 'cheat' and add <code>son(harry, charles)</code> in as a fact, what am I not understanding about Prolog's execution steps? </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload