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

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.


Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

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

Search: