next up previous contents index
Next: All Solutions and Aggregate Up: Standard Predicates Previous: Negation and Control   Contents   Index


Meta-Logical

To facilitate manipulation of terms as objects in themselves, XSB provides a number meta-logical predicates. These predicates include the standard meta-logical predicates of Prolog, along with their usual semantics. In addition are provided predicates which provide special operations on HiLog terms. For a full discussion of Prolog and HiLog terms see Section 4.1.

var(?X)

Succeeds if X is currently uninstantiated (i.e. is still a variable); otherwise it fails.

Term X is uninstantiated if it has not been bound to anything, except possibly another uninstantiated variable. Note in particular, that the HiLog term X(Y,Z) is considered to be instantiated. There is no distinction between a Prolog and a HiLog variable.

Examples:

                | ?- var(X).
                yes
                | ?- var([X]).
                no
                | ?- var(X(Y,Z)).
                no
                | ?- var((X)).
                yes
                | ?- var((X)(Y)).
                no

nonvar(?X)

Succeeds if X is currently instantiated to a non-variable term; otherwise it fails. This has exactly the opposite behaviour of var/1.

atom(?X)

Succeeds only if the X is currently instantiated to an atom, that is to a Prolog or HiLog non-numeric constant.

Examples:

                | ?- atom(HiLog).
                no
                | ?- atom(10).
                no
                | ?- atom('HiLog').
                yes
                | ?- atom(X(a,b)).
                no
                | ?- atom(h).
                yes
                | ?- atom(+).
                yes
                | ?- atom([]).
                yes

integer(?X)

Succeeds if X is currently instantiated to an integer; otherwise it fails.

real(?X)

Succeeds if X is currently instantiated to a floating point number; otherwise it fails.

float(?X)

Same as real/1. Succeeds if X is currently instantiated to a floating point number; otherwise it fails. This predicate is included for compatibility with earlier versions of SBProlog.

number(?X)

Succeeds if X is currently instantiated to either an integer or a floating point number (real); otherwise it fails.

atomic(?X)

Succeeds if X is currently instantiated to an atom or a number; otherwise it fails.

Examples:

                | ?- atomic(10).
                yes
                | ?- atomic(p).
                yes
                | ?- atomic(h).
                yes
                | ?- atomic(h(X)).
                no
                | ?- atomic("foo").
                no
                | ?- atomic('foo').
                yes
                | ?- atomic(X).
                no
                | ?- atomic(X((Y))).
                no

compound(?X)

Succeeds if X is currently instantiated to a compound term (with arity greater that zero), i.e. to a nonvariable term that is not atomic; otherwise it fails.

Examples:

                | ?- compound(1).
                no
                | ?- compound(foo(1,2,3)).
                yes
                | ?- compound([foo, bar]).
                yes
                | ?- compound("foo").
                yes
                | ?- compound('foo').
                no
                | ?- compound(X(a,b)).
                yes
                | ?- compound((a,b)).
                yes

structure(?X)

Same as compound/1. Its existence is only for compatibility with SB-Prolog version 3.1.

is_list(?X)

Succeeds if X is a proper list. In other words if it is either the atom [] or [H|T] where H is any Prolog or HiLog term and T is a proper list; otherwise it fails.

Examples:

                | ?- is_list([p(a,b,c), h(a,b)]).
                yes
                | ?- is_list([_,_]).
                yes
                | ?- is_list([a,b|X]).
                no
                | ?- is_list([a|b]).
                no

is_charlist(+X)

Succeeds if X is a Prolog string, i.e., a list of characters. Examples:
                | ?- is_charlist("abc").
                yes
                | ?- is_charlist(abc).
                no

is_charlist(+X,-Size)

Works as above, but also returns the length of that string in the second argument, which must be a variable.

is_attv(+Term)

Succeeds is Term is an attributed variable, and fails otherwise.

is_most_general_term(?X)

Succeeds if X is compound term with all distinct variables as arguments, or if X is an atom. (It fails if X is a cons node.)
                | ?- is_most_general_term(f(_,_,_,_)).
                yes
                | ?- is_most_general_term(abc).
                yes
                | ?- is_most_general_term(f(X,Y,Z,X)).
                no
                | ?- is_most_general_term(f(X,Y,Z,a)).
                no
                | ?- is_most_general_term([_|_]).
                no

callable(?X)

Succeeds if X is currently instantiated to a term that standard predicate call/1 could take as an argument and not give an instantiation or type error. Note that it only checks for errors of predicate call/1. In other words it succeeds if X is an atom or a compound term; otherwise it fails. Predicate callable/1 has no associated error conditions.

Examples:

                | ?- callable(p).
                yes
                | ?- callable(p(1,2,3)).
                yes
                | ?- callable([_,_]).
                yes
                | ?- callable(_(a)).
                yes
                | ?- callable(3.14).
                no

proper_hilog(?X)
HiLog
Succeeds if X is a proper HiLog term; otherwise it fails.

Examples: (In this example and the rest of the examples of this section we assume that h is the only parameter symbol that has been declared a HiLog symbol).

                | ?- proper_hilog(X).
                no
                | ?- proper_hilog(foo(a,f(b),[A])).
                no
                | ?- proper_hilog(X(a,b,c)).
                yes
                | ?- proper_hilog(3.6(2,4)).
                yes
                | ?- proper_hilog(h).
                no
                | ?- proper_hilog([a, [d, e, X(a)], c]).
                yes
                | ?- proper_hilog(a(a(X(a)))).
                yes

functor(?Term, ?Functor, ?Arity)

Succeeds if the functor of the Prolog term Term is Functor and the arity (number of arguments) of Term is Arity. Functor can be used in either the following two ways:
  1. If Term is initially instantiated, then
    • If Term is a compound term, Functor and Arity are unified with the name and arity of its principal functor, respectively.
    • If Term is an atom or a number, Functor is unified with Term, and Arity is unified with 0.
  2. If Term is initially uninstantiated, then either both Functor and Arity must be instantiated, or Functor is instantiated to a number, and
    • If Arity is an integer in the range 1..255, then Term becomes instantiated to the most general Prolog term having the specified Functor and Arity as principal functor and number of arguments, respectively. The variables appearing as arguments of Term are all distinct.
    • If Arity is 0, then Functor must be either an atom or a number and it is unified with Term.
    • If Arity is anything else, then functor/3 aborts.

Exceptions:

domain_error
Functor is instantiated to a compound term.
instantiation_error
Both Term, and either Functor, or Arity are uninstantiated.

Examples:

                | ?- functor(p(f(a),b,t), F, A).
                F = p
                A = 3

                | ?- functor(T, foo, 3).
                T = foo(_595708,_595712,_595716)

                | ?- functor(T, 1.3, A).
                T = 1.3
                A = 0

                | ?- functor(foo, F, 0).
                F = foo

                | ?- functor("foo", F, A).
                F = .
                A = 2

                | ?- functor([], [], A).
                A = 0

                | ?- functor([2,3,4], F, A).
                F = .
                A = 2

                | ?- functor(a+b, F, A).
                F = +
                A = 2

                | ?- functor(f(a,b,c), F, A).
                F = f
                A = 3

                | ?- functor(X(a,b,c), F, A).
                F = apply
                A = 4

                | ?- functor(map(P)(a,b), F, A).
                F = apply
                A = 3

                | ?- functor(T, foo(a), 1).
                ++Error: Wrong type in argument 2 of functor/3
                Aborting...

                | ?- functor(T, F, 3).
                ++Error: Uninstantiated argument 2 of functor/3
                Aborting...

                | ?- functor(T, foo, A).
                ++Error: Uninstantiated argument 3 of functor/3
                Aborting...

hilog_functor(?Term, ?F, ?Arity)
HiLog
The XSB standard predicate hilog_functor/3 succeeds The first of these cases corresponds to the ``usual'' behaviour of Prolog's functor/3, while the second is the extension of functor/3 to handle HiLog terms. Like the Prolog's functor/3 predicate, hilog_functor/3 can be used in either of the following two ways:
  1. If Term is initially instantiated, then
    • If Term is a Prolog compound term, F and Arity are unified with the name and arity of its principal functor, respectively.
    • If Term is an atom or a number, F is unified with Term, and Arity is unified with 0.
    • If Term is any other HiLog term, F and Arity are unified with the name and the number of arguments that F is applied to. Note that in this case F may still be uninstantiated.
  2. If Term is initially uninstantiated, then at least Arity must be instantiated, and
    • If Arity is an integer in the range 1..255, then Term becomes instantiated to the most general Prolog or HiLog term having the specified F and Arity as name and number of arguments F is applied to, respectively. The variables appearing as arguments are all unique.
    • If Arity is 0, then F must be a Prolog or HiLog constant, and it is unified with Term. Note that in this case F cannot be a compound term.
    • If Arity is anything else, then hilog_functor/3 aborts.
In other words, the standard predicate hilog_functor/3 either decomposes a given HiLog term into its name and arity, or given an arity --and possibly a name-- constructs the corresponding HiLog term creating new uninstantiated variables for its arguments. As happens with functor/3 all constants can be their own principal function symbols.

Examples:

               | ?- hilog_functor(f(a,b,c), F, A).
               F = f
               A = 3

               | ?- hilog_functor(X(a,b,c), F, A).
               X = _595836
               F = _595836
               A = 3

               | ?- hilog_functor(map(P)(a,b), F, A).
               P = _595828
               F = map(_595828)
               A = 2

               | ?- hilog_functor(T, p, 2).
               T = p(_595708,_595712)

               | ?- hilog_functor(T, h, 2).
               T = apply(h,_595712,_595716)

               | ?- hilog_functor(T, X, 3).
               T = apply(_595592,_595736,_595740,_595744)
               X = _595592

               | ?- hilog_functor(T, p(f(a)), 2).
               T = apply(p(f(a)),_595792,_595796)

               | ?- hilog_functor(T, h(p(a))(L1,L2), 1).
               T = apply(apply(apply(h,p(a)),_595984,_595776),_596128)
               L1 = _595984
               L2 = _595776

               | ?- hilog_functor(T, a+b, 3).
               T = apply(a+b,_595820,_595824,_595828)

arg(+Index, +Term, ?Argument)

Unifies Argument with the $ \tt Index^{th}_{}$ argument of Term, where the index is taken to start at 1. Initially, Index must be instantiated to any integer and Term to any non-variable Prolog or HiLog term. The arguments of the Term are numbered from 1 upwards. An atomic term has 0 arguments. If the initial conditions are not satisfied or I is out of range, the call quietly fails.

Examples:

                   | ?- arg(2, p(a,b), A).
                   A = b

                   | ?- arg(2, h(a,b), A).
                   A = a

                   | ?- arg(0, foo, A).
                   no

                   | ?- arg(2, [a,b,c], A).
                   A = [b,c]

                   | ?- arg(2, "HiLog", A).
                   A = [105,108,111,103]

                   | ?- arg(2, a+b+c, A).
                   A = c

                   | ?- arg(3, X(a,b,c), A).
                   X = _595820 
                   A = b 

                   | ?- arg(2, map(f)(a,b), A).
                   A = a

                   | ?- arg(1, map(f)(a,b), A). 
                   A = map(f)

                   | ?- arg(1, (a+b)(foo,bar), A).
                   A = a+b

arg0(+Index, +Term, ?Argument)

Unifies Argument with the $ \tt Index^{th}_{}$ argument of Term if Index > 0, or with the functor of Term if Index = 0.

hilog_arg(+Index, +Term, ?Argument)
HiLog
If Term is a Prolog term, it has the same behaviour as arg/3, but if Term is a proper HiLog term, hilog_arg/3 unifies Argument with the ($ \tt Index$ + 1)th argument of the Prolog representation of Term. Semantically, Argument is the $ \tt Index^{th}_{}$ argument to which the HiLog functor of Term is applied. The arguments of the Term are numbered from 1 upwards. An atomic term is taken to have 0 arguments.

Initially, Index must be instantiated to a positive integer and Term to any non-variable Prolog or HiLog term. If the initial conditions are not satisfied or I is out of range, the call quietly fails. Note that like arg/3 this predicate does not succeed for Index=0.

Examples:

                   | ?- hilog_arg(2, p(a,b), A).
                   A = b

                   | ?- hilog_arg(2, h(a,b), A).
                   A = b

                   | ?- hilog_arg(3, X(a,b,c), A).
                   X = _595820
                   A = c

                   | ?- hilog_arg(1, map(f)(a,b), A).
                   A = a

                   | ?- hilog_arg(2, map(f)(a,b), A).
                   A = b

                   | ?- hilog_arg(1, (a+b)(foo,bar), A).
                   A = foo

                   | ?- hilog_arg(1, apply(foo), A). 
                   A = foo

                   | ?- hilog_arg(1, apply(foo,bar), A).
                   A = bar

Note the difference between the last two examples. The difference is due to the fact that apply/1 is a Prolog term, while apply/2 is a proper HiLog term.

?Term =.. [?Functor |?ArgList]

Succeeds when Term is any (Prolog or) HiLog term, Functor is its Prolog functor and ArgList is the list of its arguments. The use of =../2 (pronounced univ) although convenient, can nearly always be avoided. Whenever efficiency is critical, it is advisable to use the predicates functor/3 and arg/3, since =../2 is implemented by calls to these predicates. The behaviour of =../2 is as follows:

Examples:

                   | ?- X - 1 =.. L.
                   X = _595692
                   L = [-,_595692,1]

                   | ?- p(a,b,c) =.. L.
                   L = [p,a,b,c]

                   | ?- h(a,b,c) =.. L.
                   L = [apply,h,a,b,c]

                   | ?- map(p)(a,b) =.. L.
                   L = [apply,map(p),a,b]

                   | ?- T =.. [foo].
                   T = foo

                   | ?- T =.. [3|X].
                   T = 3
                   X = []

                   | ?- T =.. [apply,X,a,b].
                   T = apply(X,a,b)

                   | ?- T =.. [1,2].
                   ++Error: Wrong type(s) in argument 2 of =../2
                   Aborting...

                   | ?- T =.. [a+b,2].
                   ++Error: Wrong type(s) in argument 2 of =../2
                   Aborting..

                   | ?- X =.. [foo|Y].
                   ++Error: Argument 2 of =../2 is not a proper list
                   Aborting...

Exceptions:

instantiation_error
Argument 2 of =../2 is not a proper list.
type_error
Head of argument 2 of =../2 is not an atom or number.

?Term ^ =.. [?F |?ArgList]
HiLog
When Term is a Prolog term, this predicate behaves exactly like the Prolog =../2. However when Term is a proper HiLog term, ^=../2 succeeds unifying F to its HiLog functor and ArgList to the list of the arguments to which this HiLog functor is applied. Like =../2, the use of ^=../2 can nearly always be avoided by using the more efficient predicates hilog_functor/3 and hilog_arg/3. The behaviour of ^=../2, on HiLog terms is as follows: Examples:
                   | ?- p(a,b,c) ^=.. L.
                   L = [p,a,b,c]

                   | ?- h(a,b,c) ^=.. L.
                   L = [h,a,b,c]

                   | ?- map(p)(a,b) ^=.. L.
                   L = [map(p),a,b]

                   | ?- T ^=.. [X,a,b].
                   T = apply(X,a,b)

                   | ?- T ^=.. [2,2].
                   T = apply(2,2)

                   | ?- T ^=.. [a+b,2].
                   T = apply(a+b,2)

                   | ?- T ^=.. [3|X].
                   ++Error: Argument 2 of ^=../2 is not a proper list
                   Aborting...

Exceptions:

instantiation_error
Argument 2 of ^=../2 is not a proper list.

copy_term(+Term, -Copy)

Makes a Copy of Term in which all variables have been replaced by brand new variables which occur nowhere else. It can be very handy when writing (meta-)interpreters for logic-based languages. The version of copy_term/2 provided is space efficient in the sense that it never copies ground terms. Predicate copy_term/2 has no associated errors or exceptions.

Examples:

                   | ?- copy_term(X, Y).

                   X = _598948
                   Y = _598904

                   | ?- copy_term(f(a,X), Y).

                   X = _598892
                   Y = f(a,_599112)

name(?Constant, ?CharList)

The standard predicate name/2 performs the conversion between a constant and its character list representation. If Constant is supplied (and is any atom or number), CharList is unified with a list of ASCII codes representing the ``name'' of the constant. In that case, CharList is exactly the list of ASCII character codes that appear in the printed representation of Constant. If on the other hand Constant is a variable, then CharList must be a proper list of ASCII character codes. In that case, name/2 will convert a list of ASCII characters that can represent a number to a number rather than to a character string. As a consequence of this, there are some atoms (for example '18') which cannot be constructed by using name/2. If conversion to an atom is preferred in these cases, the standard predicate atom_codes/2 should be used instead. The syntax for numbers that is accepted by name/2 is exactly the one which read/1 accepts. Predicate name/2 is provided for backwards compatibility. It is advisable that new programs use the predicates atom_codes/2 and number_codes/2 described below.

In Version 2.5 predicate name/2 is not yet implemented for converting from a real number to its character list representation, and if the representation of a real is provided as CharList, it will be converted to an atom.

If both of the arguments of name/2 are uninstantiated or CharList is not a proper list of ASCII characters, name/2 will abort and an error message will be sent to the standard error stream.

Examples:

                   | ?- name('Foo', L).
                   L = [70,111,111]

                   | ?- name([], L).
                   L = [91,93]

                   | ?- name(431, L).
                   L = [52,51,49]

                   | ?- name(X, [102,111,111]).
                   X = foo
 
                   | ?- name(X, []).
                   X = ''

                   | ?- name(X, "Foo").
                   X = 'Foo'

                   | ?- name(X, [52,51,49]).
                   X = 431

                   | ?- name(X, [45,48,50,49,51]), integer(X).
                   X = -213

                   | ?- name(3.14, L).
                   ++Error: Predicate name/2 for reals is not implemented yet
                   Aborting...

Exceptions:

instantiation_error
Both arguments are uninstantiated, or argument 2 of name/2 contains a variable or is not a proper list.
type_error
Constant is not a variable, an atom or a number.
range_error
CharList is not a list of ASCII characters.
implementation_error
Constant is a real number (conversion from a real to its character list representation is not implemented yet).

atom_codes(?Atom, ?CharCodeList)

The standard predicate atom_codes/2 performs the conversion between an atom and its character list representation. If Atom is supplied (and is an atom), CharList is unified with a list of ASCII codes representing the ``name'' of that atom. In that case, CharList is exactly the list of ASCII character codes that appear in the printed representation of Atom. If on the other hand Atom is a variable, then CharList must be a proper list of ASCII character codes. In that case, Atom is instantiated to an atom containing exactly those characters, even if the characters look like the printed representation of a number.

If both of the arguments of atom_codes/2 are uninstantiated or CharList is not a proper list of ASCII characters, atom_codes/2 aborts, and an error message will be sent to the standard error stream.

Examples:

                   | ?- atom_codes('Foo', L).
                   L = [70,111,111]

                   | ?- atom_codes([], L).
                   L = [91,93]

                   | ?- atom_codes(X, [102,111,111]).
                   X = foo
 
                   | ?- atom_codes(X, []).
                   X = ''

                   | ?- atom_codes(X, "Foo").
                   X = 'Foo'

                   | ?- atom_codes(X, [52,51,49]).
                   X = '431'

                   | ?- atom_codes(X, [52,51,49]), integer(X).
                   no

                   | ?- atom_codes(X, [52,Y,49]).
                   ! Instantiation error in argument 2 of atom_codes/2
                   ! Aborting...

                   | ?- atom_codes(431, L).
                   ! Type error: in argument 1 of atom_codes/2
                   ! atom expected, but something else found
                   ! Aborting...

                   | ?- atom_codes(X, [52,300,49]).
                   ! Range error: in argument 2 of atom_codes/2
                   ! ASCII code expected, but 300 found
                   ! Aborting...

Exceptions:

instantiation_error
Both arguments are uninstantiated, or argument 2 is not a proper list, or it contains a variable.
type_error
Atom is not a variable or an atom.
range_error
CharList is not a list of ASCII characters.

atom_chars(?Number, ?CharAtomList)

Like atom_codes, but the list returned (or input) is a list of characters as atoms rather than ASCII codes. For instance, atom_chars(abc,X) binds X to the list [a,b,c] instead of [97,98,99].

number_codes(?Number, ?CharCodeList)

The standard predicate number_codes/2 performs the conversion between a number and its character list representation. If Number is supplied (and is a number), CharList is unified with a list of ASCII codes comprising the printed representation of that Number. If on the other hand Number is a variable, then CharList must be a proper list of ASCII character codes that corresponds to the correct syntax of a number (either integer or float) In that case, Number is instantiated to that number, otherwise number_codes/2 will simply fail.

If both of the arguments of number_codes/2 are uninstantiated or CharList is not a proper list of ASCII characters, number_codes/2 aborts, and an error message will be sent to the standard error stream.

Examples:

                   | ?- number_codes(123, L).
                   L = [49,50,51];

                   | ?- number_codes(N, [49,50,51]), integer(N).
                   N = 123

                   | ?- number_codes(31.4e+10, L).
                   L = [51,46,49,51,57,57,57,55,69,43,49,48]

                   | ?- number_codes(N, "314e+8").
                   N = 3.14e+10

                   | ?- number_codes(foo, L).
                   ! Type error: in argument 1 of number_codes/2
                   ! number expected, but something else found
                   ! Aborting...

Exceptions:

instantiation_error
Both arguments are uninstantiated, or argument 2 is not a proper list, or it contains a variable.
type_error
Number is not a variable or a number.
range_error
CharList is not a list of ASCII characters.

number_chars(?Number, ?CharAtomList)

Like number_codes, but the list returned (or input) is a list of characters as atoms rather than ASCII codes. For instance, number_chars(123,X) binds X to the list ['1','2','3'] instead of [49,50,51].
number_digits(?Number, ?DigitList)

Like number_chars, but the list returned (or input) is a list of digits as numbers rather than ASCII codes (for floats, the atom '.', '+' or '-', and 'e' will also be present in the list). For instance, number_digits(123,X) binds X to the list [1,2,3] instead of ['1','2','3'], and number_digits(123.45,X) binds X to [1,.,2,3,4,5,0,0,e,+,0,2].


next up previous contents index
Next: All Solutions and Aggregate Up: Standard Predicates Previous: Negation and Control   Contents   Index
Luis Fernando P. de Castro 2003-06-27