Prolog: comparing predicate value with constant

4.4k Views Asked by At

I have some problems with prolog, specifically I can't compare a value of a predicate with a constant.

predicate(9).
compare(X,Y) :- X<Y.

Running the program:

?-compare(predicate(X),10).

Why doesn't it work? Thank you for your answers.

2

There are 2 best solutions below

1
Yasel On BEST ANSWER

Like @Boris said before "Predicates don't return values in the way that a function does." Here you must try to instantiate the variables in the head of your rule.
If you are trying with you predicate compare/2 to find a number X greater than Y, and at the same time this number X should be a fact predicate/1, then add both conditions to the body of your rule or predicate compare/2

predicate(9).
compare(X,Y) :- predicate(X), X<Y.

Now if you consult:

?- compare(X,10).

The answer will be

X = 9

As you can see, 9 is smaller than 10, and at the same time 9 is a fact predicate/1. And that is the return value you are looking for.

Caution

Note that the operator >/2, requires that both sides are instantiated, so in this case you won't be able ask for the value Y in your predicate

?- compare(9, Y)
</2: Arguments are not sufficiently instantiated

Maybe and if it make sense, you can try to instantiate this variable to a fact predicate/1 too.

predicate(9).
predicate(10).
compare(X,Y) :- predicate(X), predicate(Y), X<Y.

?- compare(9,Y).
Y = 10
0
AudioBubble On

Predicates don't return values in the way that a function does.

This is C:

int nine() { return 9; }

int main() {
    int x = nine(); /* x is now 9 */
}

This is Prolog:

% source
nine(9).

% from the top level
?- nine(X).
X = 9.

?- nine(X), X < 10.
X = 9.

?- nine(X), compare(C1, X, 10), compare(C2, 10, X).
X = 9,
C1 =  (<),
C2 =  (>).

Few things (trying not to use too much Prolog lingo):

What your predicate/1 and my nine/1 does is to unify its only argument with the integer 9. If the unification succeeds, the predicate succeeds, and now the argument is bound to 9. If the unification fails, the predicate fails.

?- nine(9).
true.

?- nine(nine).
false.

?- nine(X), nine(Y).
X = Y, Y = 9.

You will also notice that there is a standard predicate compare/3 that can be used for comparison of Prolog terms. Because predicates don't have a return value in the way that functions do, it uses an extra argument to report the result of the comparison. You could have instead tried something along the lines of:

% greater_than(X, Y) : true if X is greater than Y according
%                      to the standard order of terms
greater_than(X, Y) :- X @> Y.

But this is just defining an alias for @>/2, which is a predicate itself (but has been declared as an operator so that you can use it in infix notation).

?- @>(a, b).
false.

?- @>(b, a).
true.

Same goes for </2, which is a predicate for comparison of arithmetic expressions:

?- 2 + 4 =< 6.
true.

?- nine(X), X > 10 - X.
X = 9.

?- nine(X), X > 10.
false.