Prolog includes some meta-logical predicates (predicates which cannot be modeled in first-order logic) because they make programming simpler, and they allow the users to have more control on the program executions, controlling clause execution and restoring flexibility to programs using certain builtins. We are listing some of them in Table 4.5.
They never cause error, or instantiate variables, but the state of variables can be inspected safely. They do not have a first-order reading, since the ordering of the goals matters for them:
?- var(X), X = 3. yes ?- X = 3, var(X). no
Although programs usually sort numbers, or strings, or similar entities, Prolog has a notion of a so-called standard order among all terms. This means that, apart from the arithmetical order among numbers, any two terms (being them atoms, structures, variables, numbers, etc.), can be compared for equality, disequality, and precedence. Of course this order is somewhat arbitrary, but it is usually adequate for most applications--in fact, since we are imposing an ordering among heterogeneous entities, either this ordering is highly application-dependent, or it is used just for the sake of keeping those items sorted somehow. Standard order checking primitives are shown in Table 4.6. It is interesting to note that the identity comparison == / 2 compares variables without binding them. In fact, it does not report two variables being equal unless they are the same:
?- X == Y. no ?- X = Y, X == Y. Y = X ? yes
insert([], It, [It]). insert([H|T], It, [H|T]):- H == It. insert([H|T], It, [It, H|T]):- H @> It. insert([H|T], It, [H|NewT]) :- H @< It, insert(T, It, NewT).
Note the use of == / 2 to check for identity, so that variables can be added without further instantiating them.
The order among terms is the following:
subterm(Sub,Term):- Sub == Term. subterm(Sub,Term):- nonvar(Term), functor(Term,F,N), subterm(N,Sub,Term).