.\" ------------------------------ sec3.t ------------------------------ .sh 1 "Syntax" .pp .sh 2 "Terms" .pp The syntax of SB-Prolog is by and large compatible with that of C-Prolog. The data objects of the language are called \fIterm\fPs. A term is either a \fIconstant\fP, a \fIvariable\fP or a \fIcompound term\fP. Constants can be \fIintegers\fR or \fIatoms\fR. The symbol for an atom must begin with a lower case letter or the dollar sign $, and consist of any number of letters, digits, underscores and dollar signs; if it contains any character other than these, it must be enclosed within single quotes.\** .(f \** Users are advised against using symbols beginning with `$' or `_\|$', however, in order to minimize the possibility of conflicts with symbols internal to the system. .)f As in other programming languages, constants are definite elementary objects. .pp Variables are distinguished by an initial capital letter or by the initial character \*(lq\(ul\|\*(rq, for example .(l X Value A A1 \(ul\|3 \(ul\|RESULT \(ul\|result .)l If a variable is only referred to once, it does not need to be named and may be written as an \fIanonymous\fP variable, indicated by the underline character \*(lq\(ul\|\*(rq. .pp A variable should be thought of as standing for some definite but unidentified object. A variable is not simply a writeable storage location as in most programming languages; rather it is a local name for some data object, cf. the variable of pure LISP and constant declarations in Pascal. .pp The structured data objects of the language are the compound terms. A compound term comprises a \fIfunctor\fP (called the \fIprincipal\fP functor of the term) and a sequence of one or more terms called \fIarguments\fP. A functor is characterised by its \fIname\fP, which is an atom, and its \fIarity\fP or number of arguments. For example the compound term whose functor is named `point' of arity 3, with arguments X, Y and Z, is written .(l point(X,Y,Z) .)l An atom is considered to be a functor of arity 0. .pp A functor or predicate symbol is uniquely identified by its name and arity (in other words, it is possible for different symbols having different arities to share the same name). A functor or predicate symbol \fIp\fR with arity \fIn\fR is usually written \fIp\fR/\fIn\fR. .pp One may think of a functor as a record type and the arguments of a compound term as the fields of a record. Compound terms are usefully pictured as trees. For example, the term .(l s(np(john),vp(v(likes),np(mary))) .)l would be pictured as the structure .(b C s / \e np vp | / \e john v np | | likes mary .)b .pp Sometimes it is convenient to write certain functors as \fIoperators\fP \*- 2-ary functors may be declared as \fIinfix\fP operators and 1-ary functors as \fIprefix\fP or \fIpostfix\fP operators. Thus it is possible to write .(l X+Y (P;Q) X ]). :\- op( 1200, fx, [ :\-, ?- ]). :\- op( 1198, xfx, [ ::\- ]). :\- op( 1100, xfy, [ ; ]). :\- op( 1050, xfy, [ \-> ]). :\- op( 1000, xfy, [ ',' ]). /* See note below */ :\- op( 900, fy, [ not, \e+, spy, nospy ]). :\- op( 700, xfx, [ =, is, =.., ==, \e==, @<, @>, @=<, @>=, \& \& \& =:=, =\e=, <, >, =<, >= ]). :\- op( 661, xfy, [ `.' ]). :\- op( 500, yfx, [ +, \-, /\e, \e/ ]). :\- op( 500, fx, [ +, \- ]). :\- op( 400, yfx, [ *, /, //, <<, >> ]). :\- op( 300, xfx, [ mod ]). :\- op( 200, xfy, [ ^ ]). .TE .)l .pp Operator declarations are most usefully placed in directives at the top of your program files. In this case the directive should be a command as shown above. Another common method of organisation is to have one file just containing commands to declare all the necessary operators. This file is then always consulted first. .pp Note that a comma written literally as a punctuation character can be used as though it were an infix operator of precedence 1000 and type `xfy': .(l X,Y ','(X,Y) .)l represent the same compound term. But note that a comma written as a quoted atom is \fInot\fP a standard operator. .pp Note also that the arguments of a compound term written in standard syntax must be expressions of precedence \fIbelow\fP 1000. Thus it is necessary to parenthesize the expression \*(lqP :\- Q\*(rq in .(l assert((P :\- Q)) .)l The following syntax restrictions serve to remove potential ambiguity associated with prefix operators. .ip - In a term written in standard syntax, the principal functor and its following \*(lq(\*(rq must \fInot\fP be separated by any whitespace. Thus .(l point (X,Y,Z) .)l is invalid syntax (unless \fIpoint\fR were declared as a prefix operator). .ip - If the argument of a prefix operator starts with a \*(lq(\*(rq, this \*(lq(\*(rq must be separated from the operator by at least one space or other non-printable character. Thus .(l :\-(p;q),r. .)l (where `:\-' is the prefix operator) is invalid syntax, and must be written as .(l :\- (p;q),r. .)l .ip - If a prefix operator is written without an argument, as an ordinary atom, the atom is treated as an expression of the same precedence as the prefix operator, and must therefore be bracketed where necessary. Thus the brackets are necessary in .(l X = (?-) .)l .\" ---------------------- end of sec3.t ---------------------- .