Manual: Looking at Terms


Quintus Prolog Manual


(PREV) (NEXT)

G-9: Looking at Terms

G-9-1: Meta-logical Predicates

Meta-logical predicates are those predicates which allow you to examine the current instantiation state of a simple or compound term, or the components of a compound term. This chapter describes the meta-logical predicates as well as others which deal with terms as such.

G-9-1-1: Type Checking

The following predicates take a term as their argument. They are provided to check the type of that term.

Predicate
Succeeds if term is:
var/1
a variable; the term is currently uninstantiated.
nonvar/1
a non-variable; the term is currently instantiated.
integer/1
an integer
atom/1
an atom
float/1
a float
number/1
an integer or float.
atomic/1
an atom, number or database reference.
simple/1
an atom, number, variable or database reference.
compound/1
a compound term (arity > 0).
callable/1
a term that call/1 would take as an argument; atom or compound term.
ground/1
ground; the term contains no uninstantiated variables.
db_reference/1
a Prolog database reference
Note: Although database references are read and written as compound terms, and formerly were, they now are a distinct atomic term type (see section G-14-2).

The reference pages for these predicates include examples of their use.

G-9-1-2: Unification and Subsumption

To unify two items simply use =/2, which is defined as if by the clause


=(X, X).

Note: Do not confuse this predicate with =:=/2 (arithmetic comparison) or ==/2 (term identity).

Term subsumption is a sort of one-way unification. Term S and T unify if they have a common instance, and unification in Prolog instantiates both terms to that common instance. S subsumes T if T is already an instance of S. For our purposes, T is an instance of S if there is a substitution that leaves T unchanged and makes S identical to T.

Subsumption is checked by subsumes_chk/2. It is especially useful in applications such as theorem provers. The built-in predicate behaves identically to the original library version but is much more efficient.

Related predicates are defined in library(subsumes) and library(occurs). (For information on these packages see Part K).

G-9-2: Analyzing and Constructing Terms

The built-in predicate functor/3 performs these functions

The built-in predicate arg/3 performs these functions:

The built-in predicate Term =.. List performs these functions:

G-9-3: Analyzing and Constructing Lists

To combine two lists to form a third list, use append(+Head, +Tail, -List).

To analyze a list into its component lists in various ways, use append/3 with List instantiated to a proper list. The reference page for append/3 includes examples of its usage, including backtracking.

To check the length of a list call length(+List, -Integer).

To produce a list of a certain length, use length/2 with Integer instantiated and List uninstantiated or instantiated to a list whose tail is a variable.

G-9-4: Converting between Constants and Text

Three predicates convert between constants and lists of ASCII character codes: atom_chars/2, number_chars/2, and name/2.

There is a general convention that a predicate which converts objects of type foo to objects of type baz should have one of these forms:

     

             foo_to_baz(+Foo, -Baz)                (1)

             foo_baz(?Foo, ?Baz)                   (2)

     

Use (1) if the conversion works only one way, or (2) if for any Foo there is exactly one related Baz and for any Baz at most one Foo.

The type name used for lists of ASCII character codes is chars thus, the predicate which relates an atom to its name is atom_chars(?Atom, ?Chars), and the predicate which relates a number to its textual representation is number_chars(?Number, ?Chars).

atom_chars(Atom, Chars) is a relation between an atom Atom and a list Chars consisting of the ASCII character codes comprising the printed representation of Atom. Initially, either Atom must be instantiated to an atom, or Chars must be instantiated to a proper list of character codes.

number_chars(Number, Chars) is a relation between a number Number and a list Chars consisting of the ASCII character codes comprising the printed representation of Number. Initially, either Number must be instantiated to a number, or Chars must be instantiated to a proper list of character codes.

name/2 converts from any sort of constant to a chars representation. Given a chars value, name/2 will convert it to a number if it can, otherwise to an atom. This means that there are atoms which can be constructed by atom_chars/2 but not by name/2. name/2 is retained for backwards compatibility with DEC-10 Prolog and C-Prolog. New programs should use atom_chars/2 or number_chars/2 as appropriate.

G-9-5: Assigning Names to Variables

Each variable in a term is instantiated to a term of the form '$VAR'(N), where N is an integer, by the predicate numbervars/2. The 'write' predicates (write/1, writeq/1, and write_term/1 with the numbervars option set to true) transform these terms into upper case letters.


G-9-6: Copying Terms

The meta-logical predicate copy_term/2 makes a copy of a term in which all variables have been replaced by new variables which occur nowhere else. This is precisely the effect which would have been obtained from the definition


        copy_term(Term, Copy) :-
           recorda(copy, copy(Term), DBref),
           instance(DBref, copy(Temp)),
           erase(DBref),
           Copy = Temp.

 
although the built-in predicate copy_term/2 is more efficient.

When you call clause/[2,3] or instance/2, you get a new copy of the term stored in the database, in precisely the same sense that copy_term/2 gives you a new copy. One of the uses of copy_term/2 is in writing interpreters for logic-based languages; with copy_term/2 available you can keep "clauses" in a Prolog data structure and pass this structure as an argument without having to store the "clauses" in the Prolog database. This is useful if the set of "clauses" in your interpreted language is changing with time, or if you want to use clever indexing methods.

A naive way to attempt to find out whether one term is a copy of another is shown in this example:


        identical_but_for_variables(X, Y) :-
           \+ \+ (
              numbervars(X, 0, N),
              numbervars(Y, 0, N),
              X = Y
           ).

 
This solution is sometimes sufficient, but will not work if the two terms have any variables in common. If you want the test to succeed even when the two terms do have some variables in common, you need to copy one of them; for example,

        identical_but_for_variables(X, Y) :-
           \+ \+ (
              copy_term(X, Z),
              numbervars(Z, 0, N),
              numbervars(Y, 0, N),
              Z = Y
           ).

copy_term/2 is efficient enough to use without hesitation if there is no solution which does not require the use of meta-logical predicates. However, for the sake of both clarity and efficiency, such a solution should be sought before using copy_term/2.

G-9-7: Comparing Terms

G-9-7-0: Introduction

The predicates are described in this section used to compare and order terms, rather than to evaluate or process them. For example, these predicates can be used to compare variables; however, they never instantiate those variables. These predicates should not be confused with the arithmetic comparison predicates (see section G-8-2) or with unification.

G-9-7-1: Standard Order of Terms

These predicates use a standard total order when comparing terms. The standard total order is:


variables @< database references @< numbers @< atoms @< compound terms

 
(Interpret "@<" as "comes before".)

Within these categories, ordering is as follows.

For example, here is a list of terms in the standard order:


[ X, '$ref'(123456,12), -9, 1, 1.0, fie, foe, fum, [1],
     X = Y, fie(0,2), fie(1,1) ]

The predicates for comparison of terms are described below.

T1 == T2
T1 and T2 are literally identical (in particular, variables in equivalent positions in the two terms must be identical).
T1 \== T2
T1 and T2 are not literally identical.
T1 @< T2
T1 is before term T2 in the standard order.
T1 @> T2
T1 is after term T2
T1 @=< T2
T1 is not after term T2
T1 @>= T2
T1 is not before term T2
compare(Op, T1, T2)
the result of comparing terms T1 and T2 is Op, where the possible values for Op are:
            '='   if T1 is identical to T2,
            '<'   if T1 is before T2 in the standard order,
            '>'   if T1 is after T2 in the standard order.
            

G-9-7-2: Sorting Terms

Two predicates, sort/2 and keysort/2 sort lists into the standard order. keysort/2 takes a list consisting of key-value pairs and sorts according to the key.

Further sorting routines are available in library(samsort).

G-9-8: Library Support


     library(occurs)                                                                                   library(subsumes)
     library(samsort)

Regarding list-processing: Chapter K-2

G-9-9: Summary of Predicates

'='/2 atom/1 name/2 '=..'/2 atom_chars/2 nonvar/1 ==/2 atomic/1 number/1 \==/2 compare/3 number_chars/2 @</2 copy_term/2 numbervars/3 @=</2 float/1 sort/2 @>=/2 functor/3 subsumes_chk/2 @>/2 integer/1 var/1 append/3 keysort/2 arg/3 length/2


Copyright (C) 1998 SICS
contact: product support sales information