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!)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)
If one wants the truth to be derived from the first two facts one would have to say
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.