Hacker News new | ask | show | jobs
by YeGoblynQueenne 34 days ago
In that case, your query is a disjunction but suppose you had a set of clauses like this:

  fruit(apples).
  fruit(oranges).
  fruit(bananas).
  likes(sam,X):- fruit(X).
And then entered a query like this:

  ?- likes(sam,X). 
And got results like this:

  X = apples ;
  X = oranges ;
  X = bananas.
Are those the results of a disjunction? I think it's clear that not: our rule says that "sam likes X if X is a fruit, for all X"; "for all" because in Prolog every variable is implicitly universally quantified. So the interpretation of the results of the query is:

  sam likes apples AND sam likes oranges AND sam likes bananas
Not:

  sam likes apples OR sam likes oranges OR sam likes bananas
Sam likes all the fruit! The different values of X are not disjuncts, they're conjuncts.

All that'll probably get me lynched because it flies in the face of a lot of fudging perpetrated by Prolog courses and even some textbooks that should know better, and that tell you that e.g. a set of rules is like an if-then-else and that when you get more results at the top-level those are alternatives. That's just wrong and I don't know why people teach Prolog like this, all it does is confuse students and make them hate Prolog more, but the formal definition of a logic program is that it's a conjunction of definite program clauses; where a definite program clause is a ... clause, therefore a disjunction. So a logic program is a conjunction of disjunctions, i.e. basically a formula in conjunctive normal form.

So the ";" that appears automatically at the end of your query when you press space is not an "OR", otherwise it wouldn't appear when the results of the query are the members of a conjunction. What is it then?

Try this. Instead of pressing ";" after the first result of your query (after the X = 1) press "h" for "help". On SWI-Prolog you'll get this menu:

  ?- X = 1 ; X = 2.
  X = 1
    Possible actions:
    ; (n,r,space,TAB): redo              | t:           trace&redo
    *:                 show choicepoint  | . (c,a,RET): stop
    w:                 write             | p:           print
    +:                 max_depth*5       | -:           max_depth//5
    b:                 break             | h (?):       help

  Action?
Thus finally* revealing the meaning of ";" at the top-level: it instructs the listener (i.e. the Prolog REPL) to enter the redo port. The ";" at the top-level means "redo" not "OR".

And that's true even in your query which is explicitly formulated as a disjunction. With an ";". It's confusing.

_______________

* I know, sorry.