Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Because its only first order so its really tedious. So you can say that if a > b and b >c then a > c, but you can't say if a op b and b op c implies a op c then op is transitive.


This is not the case: Prolog has several higher order constructs like the call/N family of predicates, maplist/[3,4] and foldl/N.

Your particular example of transitive relations is one of the most elementary examples that are typically solved in basic Prolog courses as exercises, when defining reachability: B is reachable from A if there is an arc between A and B. Transitivity can easily be defined by a rule, as you correctly mention. For instance, let us take your example:

  fact(a > b).
  fact(b > c).
  
  transitive(A, B) :- fact(F), F =.. [_,A,B].
  transitive(A, C) :- fact(F), F =.. [_,A,B], transitive(B, C).
Here are all solutions:

    ?- transitive(X, Y).
    X = a,
    Y = b ;
    X = b,
    Y = c ;
    X = a,
    Y = c ;
    false.
Note that the operator ">" is not mentioned in the definition of transitive/2. Instead, I am using the meta-predicate (=..)/2 to reason about all functors that can arise, making this a quite general definition of transitive relations.

We can also reason explicitly about the relation, by making the functor (which may, or may not be defined as an operator) available as a predicate argument:

  transitive(Op, A, B) :- fact(F), F =.. [Op,A,B].
  transitive(Op, A, C) :- fact(F), F =.. [Op,A,B], transitive(Op, B, C).

Now we can ask queries like:

    ?- transitive(Op, X, c).
    Op =  (>),
    X = b ;
    Op =  (>),
    X = a ;
    false.
and also in the other direction:

    ?- transitive(Op, a, Y).
    Op =  (>),
    Y = b ;
    Op =  (>),
    Y = c ;
    false.
And we can also ask in the most general way possible, where all arguments are fresh variables.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: