The introduction of extra-logical predicates (such as, for example, the arithmetical ones just presented, and others we will see later), causes the need of testing the type of terms at runtime: we may want to check whether an argument is a number or not, to react accordingly at runtime. This is a feature not taken into account in formal logic, since the type of an object has, actually, no sense at all: all data in formal logic are Herbrand terms, and have no specific meaning per se. But, for practical reasons, it is often advantageous knowing when a variable has been bound to a number, or to a constant, or to a complex structure, or when it is still free. There are a number of unary predicates which deal with the types of terms
These predicates behave approximately as if they where defined via an infinite set of facts. The difference is that they do not enumerate, as facts would have done: when handed down a free variable, they fail (as they should, because a free variable is not a constant):
?- integer(3). yes ?- float(3). no ?- float(3.0). yes ?- atom(3). no ?- atom(logo). yes ?- atomic(logo). yes ?- atom(X). no ?- atomic(X). no
These predicates can fail, but they cannot produce an error. In fact they are intended to be used before calling certain builtins so that no errors are raised. Also, they do not constrain, since they succeed only when the argument is instantiated to the type expressed by the predicate: they will fail when called with a free variable, or when a variable instantiated to a term not in such type. They can be used, for example, to restore some of the lost flexibility to arithmetical predicates:
plus(X, Y, Z):- number(X), number(Y), Z is X + Y. plus(X, Y, Z):- number(X), number(Z), Y is Z - X. plus(X, Y, Z):- number(Y), number(Z), X is Z - Y.
This predicate will succeed whenever called with two arguments instantiated to a number and the third being a free variable. It can fail if the three arguments are numbers, but the first and the second do not add up the third; and finally, it will not generate errors, and will not split a number in other two:
?- plus(4, 5, K). K = 9 ? yes ?- plus(X, 7, 3). X = -4 ? yes ?- plus(8, 7, 3). no ?- plus(8, must, must). no ?- plus(X, Y, 10). no