next up previous contents index
Next: 6.8 Manipulation of Atomic Up: 6. Standard Predicates Previous: 6.6.1 Sorting of Terms   Contents   Index


6.7 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 non-variable 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.

Error Cases

atom_or_variable
Functor is not an atom or variable.
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...

Error Cases

instantiation_error
Argument 2 of =../2 is not a proper list.
domain_error(atom_or_number,Functor)
Functor 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...

Error Cases

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)


next up previous contents index
Next: 6.8 Manipulation of Atomic Up: 6. Standard Predicates Previous: 6.6.1 Sorting of Terms   Contents   Index
Terrance Swift 2007-10-05