.\" ---------------------- sec5.2.t ---------------------- .sh 2 "Convenience" .ip \fIP\fP\ \fB,\fP\ \fIQ\fP \fIP\fP and then \fIQ\fP. .(x b (I) `,'/2 .)x .ip \fIP\fP\ \fB;\fP\ \fIQ\fP \fIP\fP or \fIQ\fP. .(x b (I) `;'/2 .)x .lp \fBtrue\fP .ip Always succeeds. .(x b (I) true/0 .)x .ip \fIX\fP\ \fB=\fP\ \fIY\fP Defined as if by the clause \*(lq Z=Z \*(rq, i.e. \fIX\fP and \fIY\fP are unified. .(x b (I) =/2 .)x .sh 2 "Extra Control" .ip \fB!\fP Cut (discard) all choice points made since the parent goal started execution. (The scope of cut in different contexts is discussed in Section 4.2). .(x b (P) !/0 .)x .ip \fBnot\fP\ \fIP\fP If the goal \fIP\fP has a solution, fail, otherwise succeed. It is defined as if by .(l not(P) :\- P, !, fail. not(\(ul\|\|). .)l .(x b (P) not/1 .)x .ip \fIP\fP\ \fB\->\fP\ \fIQ\fP\ \fB;\fP\ \fIR\fP Analogous to \*(lqif \fIP\fP then \fIQ\fP else \fIR\fP\*(rq i.e. defined as if by .(l P \-> Q ; R :\- P, !, Q. P \-> Q ; R :\- R. .)l .ip \fIP\fP\ \fB\->\fP\ \fIQ\fP When occurring other than as one of the alternatives of a disjunction, is equivalent to .(l \fIP\fP \-> \fIQ\fP ; fail. .)l .(x b (P) \->/2 .)x .ip \fBrepeat\fP Generates an infinite sequence of backtracking choices. It is defined by the clauses: .(l repeat. repeat :\- repeat. .)l .(x b (L) repeat/0 .)x .ip \fBfail\fP Always fails. .(x b (I) fail/0 .)x .sh 2 "Meta-Logical" .ip \fBvar\fP(\fIX\fP\^) Tests whether \fIX\fP is currently instantiated to a variable. .(x b (I) var/1 .)x .ip \fBnonvar\fP(\fIX\fP\^) Tests whether \fIX\fP is currently instantiated to a non-variable term. .(x b (I) nonvar/1 .)x .ip \fBatom\fP(\fIX\fP\^) .(x b (B) atom/1 .)x Checks that \fIX\fP is currently instantiated to an atom (i.e. a non-variable term of arity 0, other than a number). .ip \fBinteger\fP(\fIX\fP\^) Checks that \fIX\fP is currently instantiated to an integer. .(x b (B) integer/1 .)x .lp \fBreal\fR(\fIX\fR\^) .(x b (B) real/1 .)x .ip Checks that \fIX\fP is currently instantiated to a floating point number.. .)x .ip \fBnumber\fP(\fIX\fP\^) Checks that \fIX\fP is currently instantiated to a number, i.e. that it is either an integer or a real. .(x b (B) number/1 .)x .ip \fBatomic\fP(\fIX\fP\^) Checks that \fIX\fP is currently instantiated to an atom or number. .(x b (B) atomic/1 .)x .lp \fBstructure\fR(\fIX\fR\^) .(x b (B) structure/1 .)x .ip Checks that \fIX\fP is currently instantiated to a compound term, i.e. to a nonvariable term that is not atomic. .ip \fBfunctor\fP(\fIT\fP,\fIF\fP,\fIN\fP\^) The principal functor of term \fIT\fP has name \fIF\fP and arity \fIN\fP, where \fIF\fP is either an atom or, provided \fIN\fP is 0, a number. Initially, either \fIT\fP must be instantiated to a non-variable, or \fIF\fP and \fIN\fP must be instantiated to, respectively, either an atom and a non-negative integer or an integer and 0. If these conditions are not satisfied, an error message is given. In the case where \fIT\fP is initially instantiated to a variable, the result of the call is to instantiate \fIT\fP to the most general term having the principal functor indicated. .(x b (L) functor/3 .)x .ip \fBarg\fP(\fII\fP,\fIT\fP,\fIX\fP\^) Initially, \fII\fP must be instantiated to a positive integer and \fIT\fP to a compound term. The result of the call is to unify \fIX\fP with the \fII\fPth argument of term \fIT\fP. (The arguments are numbered from 1 upwards.) If the initial conditions are not satisfied or \fII\fP is out of range, the call merely fails. .(x b (B) arg/3 .)x .ip \fIX\fP\ \fB=..\fP\ \fIY\fP \fIY\fP is a list whose head is the atom corresponding to the principal functor of \fIX\fP and whose tail is the argument list of that functor in \fIX\fP. E.g. .(x b (L) =../2 .)x .(l product(0,N,N\-1) =.. [product,0,N,N\-1] N\-1 =.. [\-,N,1] product =.. [product] .)l If \fIX\fP is instantiated to a variable, then \fIY\fP must be instantiated either to a list of determinate length whose head is an atom, or to a list of length 1 whose head is a number. .ip \fBname\fP(\fIX\fP,\fIL\fP) If \fIX\fP is an atom or a number then \fIL\fP is a list of the ASCII codes of the characters comprising the name of \fIX\fP. E.g. .(x b (B) name/2 .)x .(l name(product,[112,114,111,100,117,99,116]) .)l i.e. name(product,"product"). .lp If \fIX\fP is instantiated to a variable, \fIL\fP must be instantiated to a list of ASCII character codes. E.g. .(l | ?- name(X,[104,101,108,108,111])). X = hello | ?- name(X,"hello"). X = hello .)l .ip \fBcall\fP(\fIX\fP\^) If \fIX\fR is a nonvariable term in the program text, then it is executed exactly as if \fIX\fR appeared in the program text instead of \fIcall\fR(\fIX\fR\^), e.g. .(x b (P) call/1 .)x .(l ..., p(a), call( (q(X), r(Y)) ), s(X), ... .)l is equivalent to .(l ..., p(a), q(X), r(Y), s(X), ... .)l However, if X is a variable in the program text, then if at runtime \fIX\fP is instantiated to a term which would be acceptable as the body of a clause, the goal \fBcall\fP(\fIX\fP) is executed as if that term appeared textually in place of the \fBcall\fP(\fIX\fP), \fIexcept that\fR any cut (`!') occurring in \fIX\fP will remove only those choice points in \fIX\fP. If \fIX\fP is not instantiated as described above, an error message is printed and \fBcall\fP fails. .ip \fIX\fP (where \fIX\fP is a variable) Exactly the same as \fBcall\fP(\fIX\fP). However, we prefer the explicit usage of \fIcall\fR/1 as good programming practice, and the use of a top level variable subgoal elicits a warning from the compiler. .lp \fBconlength\fR(\fIC\fR,\fIL\fR\^) .ip Succeeds if the length of the print name of the constant \fIC\fR (which can be an atom, buffer or integer), in bytes, is \fIL\fR. .(x b (B) conlength/2 .)x If \fIC\fR is a buffer (see Section 5.8), it is the length of the buffer; if \fIC\fR is an integer, it is the length of the decimal representation of that integer, i.e., the number of bytes that a $\fIwritename\fR will use. .sh 2 "Sets" .pp When there are many solutions to a problem, and when all those solutions are required to be collected together, this can be achieved by repeatedly backtracking and gradually building up a list of the solutions. The following evaluable predicates are provided to automate this process. .ip \fBsetof\fP(\fIX\fP,\fIP\fP,\fIS\fP) Read this as \*(lq\fIS\fP is the set of all instances of \fIX\fP such that \fIP\fP is provable''. If \fIP\fR is not provable, \fBsetof\fP(\fIX\fP,\fIP\fP,\fIS\fP) succeeds with \fIS\fR instantiated to the empty list [\^]. .(x b (L) setof/3 .)x The term \fIP\fP specifies a goal or goals as in \fBcall\fP(\fIP\fP). \fIS\fP is a set of terms represented as a list of those terms, without duplicates, in the standard order for terms (see Section 5.7). If there are uninstantiated variables in \fIP\fP which do not also appear in \fIX\fP, then a call to this evaluable predicate may backtrack, generating alternative values for \fIS\fP corresponding to different instantiations of the free variables of \fIP\fP. Variables occurring in \fIP\fP will not be treated as free if they are explicitly bound within \fIP\fP by an existential quantifier. An existential quantification is written: .(l \fIY\fP^\fIQ\fP .)l meaning \*(lqthere exists a \fIY\fP such that \fIQ\fP is true\*(rq, where \fIY\fP is some Prolog term (usually, a variable, or tuple or list of variables). .ip \fBbagof\fP(\fIX\fP,\fIP\fP,\fIBag\fP) This is the same as \fBsetof\fP except that the list (or alternative lists) returned will not be ordered, and may contain duplicates. If \fIP\fR is unsatisfiable, \fIbagof\fR succeeds binding \fIBag\fR to the empty list. .(x b (L) bagof/3 .)x The effect of this relaxation is to save considerable time and space in execution. .ip \fBfindall\fR(\fIX\fR,\fIP\fR,\fIL\fR) Similar to \fIbagof\fR/3, except that variables in \fIP\fR that do not occur in \fIX\fR are treated as local, and alternative lists are not returned for different bindings of such variables. The list \fIL\fR is, in general, unordered, and may contain duplicates. If \fIP\fR is unsatisfiable, \fIfindall\fR succeeds binding \fIS\fR to the empty list. .lp \fIX\fP\fB^\fP\fIP\fP .ip The system recognises this as meaning \*(lqthere exists an \fIX\fP such that \fIP\fP is true\*(rq, and treats it as equivalent to \fBcall\fP(\fIP\fP). The use of this explicit existential quantifier outside the \fBsetof\fP and \fBbagof\fP constructs is superfluous. .sh 2 "Comparison of Terms" .pp These evaluable predicates are meta-logical. They treat uninstantiated variables as objects with values which may be compared, and they never instantiate those variables. They should \fInot\fP be used when what you really want is arithmetic comparison (Section 5.2) or unification. .pp The predicates make reference to a standard total ordering of terms, which is as follows: .ip \(de variables, in a standard order (roughly, oldest first \- the order is \fInot\fP related to the names of variables); .ip \(de numbers, from \-\*(lqinfinity\*(rq to +\*(lqinfinity\*(rq; .ip \(de atoms, in alphabetical (i.e. ASCII) order; .ip \(de complex terms, ordered first by arity, then by the name of principal functor, then by the arguments (in left-to-right order). .pp For example, here is a list of terms in the standard order: .(l [ X, \-9, 1, fie, foe, fum, X = Y, fie(0,2), fie(1,1) ] .)l These are the basic predicates for comparison of arbitrary terms: .lp \fIX\fP \fB==\fP \fIY\fP .ip Tests if the terms currently instantiating \fIX\fP and \fIY\fP are literally identical (in particular, variables in equivalent positions in the two terms must be identical). .(x b (B) ==/2 .)x For example, the question .(l | ?- X == Y. .)l fails (answers \*(lqno\*(rq) because \fIX\fP and \fIY\fP are distinct uninstantiated variables. However, the question .(l | ?- X = Y, X == Y. .)l succeeds because the first goal unifies the two variables (see page 42). .lp \fIX\fP \fB\e==\fP \fIY\fP .ip Tests if the terms currently instantiating \fIX\fP and \fIY\fP are not literally identical. .(x b (B) \e==/2 .)x .EQ delim $$ .EN .lp \fIT1\fP \fB@<\fP \fIT2\fP .ip Term \fIT1\fP is before term \fIT2\fP in the standard order. .(x b (B) @\fP \fIT2\fP .ip Term \fIT1\fP is after term \fIT2\fP in the standard order. .(x b (B) @>/2 .)x .lp \fIT1\fP \fB@=<\fP \fIT2\fP .ip Term \fIT1\fP is not after term \fIT2\fP in the standard order. .(x b (B) @==\fP \fIT2\fP .ip Term \fIT1\fP is not before term \fIT2\fP in the standard order. .(x b (B) @>=/2 .)x .sp .lp Some further predicates involving comparison of terms are: .lp \fBcompare\fP(\fIOp\fP,\fIT1\fP,\fIT2\fP) .ip The result of comparing terms \fIT1\fP and \fIT2\fP is \fIOp\fP, where the possible values for \fIOp\fP are: .(l \&`=' if \fIT1\fP is identical to \fIT2\fP, \&`<' if \fIT1\fP is before \fIT2\fP in the standard order, \&`>' if \fIT1\fP is after \fIT2\fP in the standard order. .)l Thus \fBcompare\fP(=,\fIT1\fP,\fIT2\fP) is equivalent to \fIT1\fP \fB==\fP \fIT2\fP. .(x b (B) compare/3 .)x .lp \fBsort\fP(\fIL1\fP,\fIL2\fP) .ip The elements of the list \fIL1\fP are sorted into the standard order, and any identical (i.e. `==') elements are merged, yielding the list \fIL2\fP. .(x b (L) sort/2 .)x .EQ delim @@ .EN .\" -------------------- end of section sec5.2.t -------------------- .