News for hackers. Stuff that matters.
Re:A Short Introduction to Prolog by route66 on Friday August 05, 2011 @10:27AM (#2850181)
The problem is that transitive builds up a relationship between a functor and it's variables by trying to unify them with already known facts. But no new fact is generated.

     transitive(Functor) :-
       Rel1 =.. [Functor,A,B],
       Rel2 =.. [Functor,B,C],
       Rel3 =.. [Functor,A,C],
       call(Rel1),call(Rel2),call(Rel3).
 
     descendant(a,b).  #fact1
     descendant(b,c).  #fact2
     transitive(descendant) ;; says 'no'
     descendant(a,c).
     transitive(descendant) ;; says 'yes'
This functor only tells us if the database has a transitive relationship recorded.

If one wants the truth to be derived from the first two facts one would have to say

     transitive(F,A,B,C) :-
       R1 =.. [F,A,B],
       R2 =.. [F,B,C],
       call(R1),call(R2).
which derives transitivity from the first two facts, the last relationship (R3) is what we want to conclude, not what we want to find in the database.

Neither call though, will derive from fact1 and fact2 that "descendant(a,c)." is true. To arrive there you would have to "assert" these (new) facts explicitly in the transitive(...) definition.

But Prolog is not my comfort zone, there might be (and probably is) a way out of that dilemma.

Re:A Short Introduction to Prolog by JadeNB on Friday August 05, 2011 @10:34AM (#2850207)
Note that there's another flaw: `transitive` as defined only checks if there's one instance of transitivity that works. If you wanted to check (rather than assert) transitivity, you'd need something more like

    transitive(Functor) :-
        not(
            call(Functor,A,B),
            call(Functor,B,C),
            not(call(Functor,A,C))
        ).
(It's been a while since I've Prologged, so I may be forgetting something subtle about why you'd need to use the dribble `=..` to build something callable; but that's not the point, of course!)
Re:A Short Introduction to Prolog by route66 on Friday August 05, 2011 @10:45AM (#2850251)
Right, I see this as the third way: stating transitivity which must not be asserted explicitly. The question arises what one would want to reach with a call to transitive(descendant).

(aside: the X =.. [F,A,B] is the prolog way of saying eval("F(A,B)"). and make it callable)