3 ms·
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
by lowbloodsugar 9y ago
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.
- zmonx 9y agoThis 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.