The following queries both return true.
1 @< 2.
true
1 < 2.
true
In class we were told that @< can do more than < because it can also do alphabetic comparison next to arithmetic comparison. Because I thought this sounded like hogwash (why would you need two operators anyway if the one includes another's behaviour) I did some basic testing. For me it seemed more logical that @< only does alphabetic testing in which case digits are nothing more than an extension to the alphabet. Because
9 @< a.
true
Z @< a.
true
it would seem that the 'order of the alphabet' is something like this (excluding diacritics and special characters):
0123456789ABCDEFGHIJKLMNOPQRSTUVWQYZabcdefghijklmnopqrstuvwqyz
The advantage of using < over @< would then be that the former first solves the equations on both sides, whereas the latter does nothing more than a string comparison:
(2/5) < (1/2).
true
(2/5) @< (1/2).
false
Even though the explanation above seems logical (and tested) to me, I am not sure because it was only briefly introduced and faulty or at least ambiguously explained (see the italic quote above). My question is, then, are my assumptions correct and is @< nothing more than a string comparison, whereas < actually solves both sides and then compares? Does < actually do a number comparison after solving both sides, or does it fall back to string comparison? (Which, after solving both sides to a real number would yield the same result as an arithmetic solution. If so, what about irrational numbers?) And is my assumption of the 'alphabet including digits' also correct, or am I missing some important details?
@< compares according to the standard order of terms; < compares arithmetic expressions. Neither can do "more" or "less" than the other, because they do different things. You could say that there are cases where @< can be used but < cannot, but there are also cases where the two will give you opposite answers.
The SWI-Prolog documentation is one place to get details on this. The @< compares using the standard order of terms, along with all other such predicates: ==, \==, @<, @=<, @>, @>=. The most interesting one here is probably the predicate compare/3. But yes, standard order of terms defines an order for any term you might have in a Prolog program, including free variables.
On the other hand, arithmetic comparisons evaluate the arithmetic expressions on both sides, and compare their values. Important is that on both sides, the expression should evaluate to a number, you cannot have variables left there. In other words:
?- X @< 1.
true. % because free variables come before all other terms
?- X < 1.
ERROR: Arguments are not sufficiently instantiated
% An exception is thrown because X is not a valid arithmetic expression
This was an example where @< can give you an answer, "The variable X sorts before the integer 1 in the standard order of terms", while < just tells you "cannot do this" (which neither "yes" nor "no").
Another example:
?- 1 + 2 < 5.
true.
?- 1 + 2 @< 5.
false.
This is an example where the two comparisons give you opposite answers. If you use <, you get the answer "1 + 2 is less than 5", while if you use @< you get the answer "The term +(1, 2) does not sort before the integer 5 in the standard order of terms". This is because all compound terms sort after all numbers.
This means that you cannot use for example sort/2, which sorts according to the standard order of terms, to sort numbers or arithmetic expressions. First, according to ISO, all floating numbers precede all integers (someone correct me if I am wrong on this). Then, SWI-Prolog has support for rational numbers, in the form Numerator rdiv Denominator, for example 1 rdiv 2 means "one half". Because this is currently just a compound term:
?- 1 rdiv 2 < 1.
true.
?- 1 rdiv 2 @< 1.
false.
As for "irrational numbers" from your question, are you sure you don't mean "rational"?
Finally, if you use standard order of terms comparisons, make sure you understand what is the type of the things you are comparing! Again, from the SWI-Prolog documentation:
Variables < Numbers < Strings < Atoms < Compound terms
Number and atom:
?- 9 @< '0'.
true.
String and atom:
?- "Z" @< 'A'.
true.
Variable and string:
?- Z @< "A".
true.
Two compound terms with the same arguments, but '+' @< '-':
?- 1 + 2 @< 1 - 2.
true.
So it is not just about some kind of basic string comparison, the type of the terms you are comparing are important.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With