C-Prolog User's Manual Version 1.5 June 14, 1988 Edited by Fernando Pereira[1] SRI International, Menlo Park, California from material by David Warren SRI International, Menlo Park, California David Bowen, Lawrence Byrd Dept. of Artificial Intelligence, University of Edinburgh Luis Pereira Dept. de Informatica, Universidade Nova de Lisboa _A_b_s_t_r_a_c_t This is a revised edition of the user's manual for C-Prolog, a Prolog interpreter written in C for 32 bit machines. C-Prolog is based on an earlier Pro- log interpreter written in IMP for the EMAS operat- ing system by Luis Damas, who borrowed many aspects of the design from the DECsystem-10/20 Prolog system developed by David Warren, Fernando Pereira, Lawrence Byrd and Luis Pereira. This manual is based on the EMAS Prolog manual, which in turn was based on the DECsystem-10/20 Prolog manual. ____________________ [1]Formerly at EdCAAD, Dept. of Architecture, University of Edinburgh C-Prolog User's Manual 1 _1. _U_s_i_n_g _C-_P_r_o_l_o_g _1._1. _P_r_e_f_a_c_e This manual describes C-Prolog, a Prolog interpreter written in C. C-Prolog was developed at EdCAAD, Dept. of Architecture, University of Edinburgh, and is based on a previous interpreter, written in IMP for the EMAS operating system by Luis Damas of the Dept. of Computer Science, University of Edinburgh. C-Prolog was designed for machines with a large, uniform, address space, and assumes a pointer cell 32 bits wide. At the time of writing, it has been tested on VAX[2] machines under the UNIX[3] and VAX/VMS operating systems, on the Sun workstation under 4.1/2 UNIX, and has been ported with minor changes to other MC68000- based workstations and to the Three Rivers PERQ. Prolog is a simple but powerful programming language originally developed at the University of Marseilles, as a practical tool for programming in logic. From a user's point of view the major attraction of the language is ease of programming. Clear, readable, concise programs can be written quickly with few errors. Prolog is especially suit- able for high-level symbolic programming tasks and has been applied in many areas of Artificial Intelligence research. The system consists of a Prolog interpreter and a wide range of builtin (system defined) procedures. Its design was based on the (Edinburgh) DECsystem-10 Prolog system and the system is closely compatible with DECsystem-10 Prolog and thus is also reasonably close to PDP-11 UNIX and RT-11 Prolog. This manual is not intended as an introduction to the Prolog language and how to use it. For this purpose you should study: _P_r_o_g_r_a_m_m_i_n_g _i_n _P_r_o_l_o_g W. Clocksin & C. Mellish Springer Verlag 1981 This manual assumes that you are familiar with the principles of the Prolog language, its purpose being to explain how to use C-Prolog, and to describe all the evalu- able predicates provided by C-Prolog. ____________________ [2]VAX, VMS, PDP and DECsystem-10 are trademarks of Digi- tal Equipment Corporation. [3]UNIX is a Trademark of Bell Laboratories. C-Prolog User's Manual 2 _1._2. _U_s_i_n_g _C-_P_r_o_l_o_g -- _O_v_e_r_v_i_e_w C-Prolog offers the user an interactive programming environment with tools for incrementally building programs, debugging programs by following their executions, and modi- fying parts of programs without having to start again from scratch. The text of a Prolog program is normally created in a number of files using a text editor. C-Prolog can then be instructed to read-in programs from these files; this is called _l_c_o_n_s_u_l_t_i_n_g the file. To change parts of a program being run, it is possible to _r_e_c_o_n_s_u_l_t files containing the changed parts. Reconsulting means that definitions for pro- cedures in the file will replace any old definitions for these procedures. It is recommended that you make use of a number of dif- ferent files when writing programs. Since you will be edit- ing and consulting/reconsulting individual files it is use- ful to use files to group together related procedures; keep- ing collections of procedures that do different things in different files. Thus a Prolog program will consist of a number of files, each file containing a number of related procedures. When your programs start to grow to a fair size, it is also a good idea to have one file which just contains com- mands to the interpreter to consult all the other files which form a program. You will then be able to consult your entire program by just consulting this single file. _1._3. _A_c_c_e_s_s _t_o _C-_P_r_o_l_o_g In this manual, we assume that there is a command on your computer cprolog that invokes C-Prolog. We assume that there are three keys or key combinations that achieve the effects of terminating an input line, mark- ing end of input, and interrupting execution of a program. Because these depend on operating system and individual tastes, they are denoted in this manual by END-OF-LINE, END-OF-INPUT and INTERRUPT respectively (they are carriage return, control-Z and control-C on the computer this is being written on). Since Prolog makes syntactic use of the difference between upper and lower case it is important that you have your terminal set up so that it accepts lower case in the C-Prolog User's Manual 3 normal way. This means, for a start, that you must be using an upper and lower case terminal - and not, for example, an upper case only teletype. It is possible to use Prolog using upper case only (see Section 2.4) but it is unneces- sarily painful. We shall assume both upper and lower case throughout this manual. If you type the `cprolog' command, Prolog will output a banner and prompt you for directives as follows: C-Prolog version 1.5 | ?- There will be a pause between the first line and the prompt while the system loads itself. It is possible to type ahead during this period if you get impatient. If you give an argument to the `cprolog' command, C- Prolog will interpret it as the name of a file containing a saved state created earlier, and will restore that saved state. Saved states will be explained fully later. cprolog prog (Restore "prog") C-Prolog uses six major internal data areas: the _h_e_a_p, the _g_l_o_b_a_l _s_t_a_c_k, the _l_o_c_a_l _s_t_a_c_k, the _t_r_a_i_l, the _a_t_o_m _a_r_e_a and the _a_u_x_i_l_i_a_r_y _s_t_a_c_k. Although the system is initially configured with reasonable allocations for each of those areas, a particular program might exceed one of the alloca- tions, causing an error message. Ideally, the system should adjust the available storage among areas automatically, but this facility is not implemented yet. Instead, the user may specify when starting Prolog the allocations (in K bytes) for some or all of the areas. This is done by giving command line switches between the program name and the optional file argument. For example, cprolog -h 1000 -g 1000 -l 500 bigprogram specifies heap and global stack allocations of 1000 K and a local stack allocation of 500 K. The full set of switches is: -h _N heap allocation is _N K bytes -g _N global stack allocation is _N K bytes -l _N local stack allocation is _N K bytes -t _N trail allocation is _N K bytes -a _N atom area allocation is _N K bytes -x _N auxiliary stack allocation is _N K bytes C-Prolog User's Manual 4 _1._4. _R_e_a_d_i_n_g-_i_n _P_r_o_g_r_a_m_s A program is made up of a sequence of clauses, possibly interspersed with directives to the inter- preter. The clauses of a procedure do not have to be immediately consecutive, but remember that their relative order may be important. To input a program from a file _f_i_l_e, give the direc- tive: | ?- [_f_i_l_e]. which will instruct the interpreter to consult the program. The file specification _f_i_l_e must be a Prolog atom. It may be any file name, note that if this file name contains char- acters which are not normally allowed in an atom then it is necessary to surround the whole file specification with sin- gle quotes (since quoted atoms can include any character), for example | ?- ['people/greeks']. The specified file is then read in. Clauses in the file are stored in the database ready to be executed, while any directives are obeyed as they are encountered. When the end of the file is found, the interpreter displays on the ter- minal the time spent in reading-in and the number of bytes occupied by the program. In general, this directive can be any list of filenames, such as: | ?- [myprogram, extras, testbits]. In this case all three files would be consulted. If a filename is preceded by a minus sign, as in: | ?- [-testbits, -moreideas]. then that file is reconsulted. The difference between con- sulting and reconsulting is important, and works as follows: if a file is consulted then all the clauses in the file are simply added to C-Prolog's database. If you consult the same file twice then you will get two copies of all the clauses. However, if a file is reconsulted then the clauses for all the procedures in the file will replace any existing clauses for those procedures, that is any such previously existing clauses in the database get thrown away. Reconsulting is useful for telling Prolog about corrections in your program. Clauses may also be typed in directly at the terminal. To enter clauses at the terminal, you must give the C-Prolog User's Manual 5 directive: | ?- [user]. The interpreter is now in a state where it expects input of clauses or directives. To get back to the top level of the interpreter, type the END-OF-INPUT character. Typing clauses directly into C-Prolog is only recom- mended if the clauses will not be needed permanently, and are few in number. For significant bits of program you should use an editor to produce a file containing the text of the program. _1._5. _D_i_r_e_c_t_i_v_e_s: _Q_u_e_s_t_i_o_n_s _a_n_d _C_o_m_m_a_n_d_s When Prolog is at top level (signified by an initial prompt of "| ?- ", with continuation lines prompted with "| ", that is indented out from the left margin) it reads in terms and treats them as directives to the interpreter to try and satisfy some goals. These directives are called questions. Remember that Prolog terms must terminate with a period ("."), and that therefore Prolog will not execute anything for you until you have typed the period (and then END-OF-LINE) at the end of the directive. Suppose list membership has been defined by: member(X,[X|_]). member(X,[_|L]) :- member(X,L). (Note the use of anonymous variables written "_"). If the goal(s) specified in a question can be satis- fied, and if there are no variables as in this example: | ?- member(b,[a,b,c]). then the system answers yes and execution of the question terminates. If variables are included in the question, then the final value of each variable is displayed (except for anonymous variables). Thus the question | ?- member(X,[a,b,c]). would be answered by X = a C-Prolog User's Manual 6 At this point the interpreter is waiting for you to indicate whether that solution is sufficient, or whether you want it to backtrack to see if there are any more solutions. Simply typing END-OF-LINE terminates the question, while typing ";" followed by END-OF-LINE causes the system to backtrack look- ing for alternative solutions. If no further solutions can be found it outputs no The outcome of some questions is shown below, where a number preceded by "_" is a system-generated name for a variable. | ?- member(X,[tom,dick,harry]). X = tom ; X = dick ; X = harry ; no | ?- member(X,[a,b,f(Y,c)]),member(X,[f(b,Z),d]). Y = b, X = f(b,c), Z = c % Just END-OF-LINE typed here yes | ?- member(X,[f(_),g]). X = f(_1728) yes | ?- When C-Prolog reads terms from a file (or from the terminal following a call to [user]), it treats them all as program clauses. In order to get the interpreter to execute direc- tives from a file they must be preceded by `?-', for ques- tions, or `:-', for commands. Commands are like questions except that they do not cause answers to be printed out. They always start with the symbol ":-". At top level this is simply written after the prompted "?-" which is then effectively overridden. Any required output must be programmed explicitly; for example, the command :- member(3,[1,2,3]), write(ok). directs the system to check whether 3 belongs to the list [1,2,3], and to output "ok" if so. Execution of a command terminates when all the goals in the command have been successfully executed. Other alternative solutions are not sought (one may imagine an implicit "cut" at the end of the command). If no solution can be found, the system gives: C-Prolog User's Manual 7 ? as a warning. The main use for commands (as opposed to questions) is to allow files to contain directives which call various pro- cedures, but for which you don't want to have the answers printed out. In such cases you only want to call the pro- cedures for effect. A useful example would be the use of a directive in a file which consults a whole list of other files, such as[4]: :-([ bits, bobs, mainpart, testcases, data, junk ]). If this directive was contained in the file `program' then typing the following at top level would be a quick way of loading your entire program: | ?- [program]. When you are simply interacting with the top level of the Prolog interpreter the distinction between questions and commands is not very important. At the top level you should normally only type questions. In a file, if you wish to exe- cute some goals then you should use a command. That is, to execute a directive in a file it must be preceded by ":-", otherwise it will be treated as a clause. _1._6. _S_a_v_i_n_g _A _P_r_o_g_r_a_m Once a program has been read, the interpreter will have available all the information necessary for its execution. This information is called a program _s_t_a_t_e. The state of a program may be saved on a file for future execution. To save a program into a file _f_i_l_e, per- form the command: ?- save(_f_i_l_e). Save can be called at top level, from within a break level (q.v.), or from anywhere within a program. ____________________ [4]The extra parentheses, with the `:-' immediately next to them, are currently essential due to a problem with pre- fix operators (like `:-') and lists. They are not required for commands that do not contain lists. This restriction will be eventually removed. C-Prolog User's Manual 8 _1._7. _R_e_s_t_o_r_i_n_g _A _S_a_v_e_d _P_r_o_g_r_a_m Once a program has been saved into a file _f_i_l_e, C- Prolog can be restored to this saved state by invoking it as follows: cprolog _f_i_l_e After execution of this command, the interpreter will be in _e_x_a_c_t_l_y the same state as existed immediately prior to the call to save, except for open files, which are automati- cally closed by save. That is to say execution will start at the goal immediately following the call to save, just as if save had returned successfully. If you saved the state at top level then you will be back at top level, but if you explicitly called save from within your program then the execution of your program will continue. Saved states can only be restored when C-Prolog is ini- tially run from command level. Version 1.5 provides no way of restoring a saved state from inside C-Prolog. Note that when a new version of C-Prolog is installed, saved states created with the old version may become unus- able. You are thus advised to rely on source files for your programs and not on some gigantic saved state. _1._8. _P_r_o_g_r_a_m _E_x_e_c_u_t_i_o_n _A_n_d _I_n_t_e_r_r_u_p_t_i_o_n Execution of a program is started by giving the interpreter a directive which contains a call to one of the program's procedures. Only when execution of one directive is complete does the interpreter become ready for another direc- tive. However, one may interrupt the normal execution of a directive by hitting the INTERRUPT key on your terminal. In response to the prompt Action (h for help): you can type either "a", "t", "d" or "c" followed by END- OF-LINE. The "a" response will force Prolog to abort back to top level, the "t" option will switch on tracing, the "d" response will switch on debugging and continue the execu- tion, and the "c" response will just continue the execution. _1._9. _N_e_s_t_e_d _E_x_e_c_u_t_i_o_n_s -- _B_r_e_a_k _a_n_d _A_b_o_r_t C-Prolog provides a way to suspend the execution of your program and to enter a new incarnation of the top level where you can issue directives to solve goals etc. When the evaluable predicate break is called, the message C-Prolog User's Manual 9 [ Break (level 1) ] will be displayed. This signals the start of a _b_r_e_a_k and except for the effect of aborts (see below), it is as if the interpreter was at top level. If break is called within a break, then another recursive break is started (and the message will say (level 2) etc). Breaks can be arbitrarily nested. Typing the END-OF-INPUT character will close the break and resume the execution which was suspended, starting at the procedure call where the suspension took place. To abort the current execution, forcing an immedi- ate failure of the directive being executed and a return to the top level of the interpreter, call the evaluable predi- cate abort, either from the program or by executing the directive: | ?- abort. within a break. In this case no END-OF-INPUT character is needed to close the break, because _a_l_l break levels are dis- carded and the system returns right back to top level. The "a" response to INTERRUPT (described above) can also be used to force an abort. _1._1_0. _E_x_i_t_i_n_g _F_r_o_m _T_h_e _I_n_t_e_r_p_r_e_t_e_r To exit from C-Prolog interpreter you should give the directive: | ?- halt. This can be issued either at top level, or within a break, or indeed from within your program. If your program is still executing then you should interrupt it and abort to return to top level so that you can call halt. Typing the END-OF-INPUT charater at top level also causes C-Prolog to terminate. _2. _P_r_o_l_o_g _S_y_n_t_a_x _2._1. _T_e_r_m_s The data objects of the language are called _t_e_r_ms. A term is either a _c_o_n_s_t_a_n_t, a _v_a_r_i_a_b_l_e or a _c_o_m_p_o_u_n_d _t_e_r_m. C-Prolog User's Manual 10 The constants include _n_u_m_b_e_rs such as 0 -999 -5.23 0.23E-5 Constants also include _a_t_o_ms such as a void = := 'Algol-68' [] The symbol for an atom can be any sequence of characters, written in single quotes if there is possibility of confu- sion with other symbols (such as variables or numbers). As in other programming languages, constants are definite elementary objects. Variables are distinguished by an initial capital letter or by the initial character "_", for example X Value A A1 _3 _RESULT If a variable is only referred to once, it does not need to be named and may be written as an _a_n_o_n_y_m_o_u_s variable, indicated by the underline character "_". 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 pro- gramming languages; rather it is a local name for some data object, cf. the variable of pure LISP and constant declarations in Pascal. The structured data objects of the language are the compound terms. A compound term comprises a _f_u_n_c_t_o_r (called the _p_r_i_n_c_i_p_a_l functor of the term) and a sequence of one or more terms called _a_r_g_u_m_e_n_t_s. A functor is characterised by its _n_a_m_e, which is an atom, and its _a_r_i_t_y or number of argu- ments. For example the compound term whose functor is named `point' of arity 3, with arguments X, Y and Z, is written point(X,Y,Z) An atom is considered to be a functor of arity 0. 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 s(np(john),vp(v(likes),np(mary))) would be pictured as the structure C-Prolog User's Manual 11 s / \ np vp | / \ john v np | | likes mary Sometimes it is convenient to write certain functors as _o_p_e_r_a_t_o_r_s -- 2-ary functors may be declared as _i_n_f_i_x opera- tors and 1-ary functors as _p_r_e_f_i_x or _p_o_s_t_f_i_x operators. Thus it is possible to write X+Y (P;Q) X ]). :- op( 1200, fx, [ :-, ?- ]). :- op( 1100, xfy, [ ; ]). :- op( 1050, xfy, [ -> ]). :- op( 1000, xfy, [ ',' ]). /* See note below */ :- op( 900, fy, [ not, \+, spy, nospy ]). :- op( 700, xfx, [ =, is, =.., ==, \==, @<, @>, @=<, @>=, =:=, =\=, <, >, =<, >= ]). :- op( 500, yfx, [ +, -, /\, \/ ]). :- op( 500, fx, [ +, - ]). :- op( 400, yfx, [ *, /, //, <<, >> ]). :- op( 300, xfx, [ mod ]). :- op( 200, xfy, [ ^ ]). C-Prolog User's Manual 15 Operator declarations are most usefuly placed in direc- tives 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. 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': X,Y ','(X,Y) represent the same compound term. But note that a comma written as a quoted atom is _n_o_t a standard operator. Note also that the arguments of a compound term written in standard syntax must be expressions of pre- cedence _b_e_l_o_w 1000. Thus it is necessary to bracket the expression "P:-Q" in assert((P:-Q)) The following syntax restrictions serve to remove potential ambiguity associated with prefix operators. - In a term written in standard syntax, the principal functor and its following "(" must _n_o_t be separated by any blankspace. Thus point (X,Y,Z) is invalid syntax. - If the argument of a prefix operator starts with a "(", this "(" must be separated from the operator by at least one space or other non-printable character. Thus :-(p;q),r. (where `:-' is the prefix operator) is invalid syntax, and must be written as :- (p;q),r. - If a prefix operator is written without an argu- ment, 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 X = (?-) C-Prolog User's Manual 16 _2._3. _S_y_n_t_a_x _E_r_r_o_r_s Syntax errors are detected when reading. Each clause, directive or in general any term read-in by the evaluable predicate read that fails to comply with syntax requirements is displayed on the terminal as soon as it is read. A mark indicates the point in the string of sym- bols where the parser has failed to continue its analysis. For example, typing member(X,X L). gives: ***syntax error*** member(X,X ***here*** L). Syntax errors do not disrupt the (re)consulting of a file in any way except that the clause or command with the syntax error will be ignored[5] All the other clauses in the file will have been read-in properly. If the syntax error occurs at top level then you should just retype the ques- tion. Given that Prolog has a very simple syntax it is usu- ally quite straightforward to see what the problems is (look for missing brackets in particular). The book _P_r_o_g_r_a_m_m_i_n_g _i_n _P_r_o_l_o_g gives further examples. _2._4. _U_s_i_n_g _a _T_e_r_m_i_n_a_l _w_i_t_h_o_u_t _L_o_w_e_r-_C_a_s_e The syntax of Prolog assumes that a full ASCII charac- ter set is available. With this _f_u_l_l _c_h_a_r_a_c_t_e_r _s_e_t or `LC' convention, variables are (normally) distinguished by an initial capital letter, while atoms and other functors must start with a lower-case letter (unless enclosed in sin- gle quotes). When lower-case is not available, the _n_o _l_o_w_e_r-_c_a_s_e or `NOLC' convention has to be adopted. With this convention, variables must be distinguished by an initial underline character "_", and the names of atoms and other functors, which now have to be written in upper-case, are implicitly translated into lower-case (unless enclosed in single quotes). For example, _VALUE2 ____________________ [5]After all, it could not be read. C-Prolog User's Manual 17 is a variable, while VALUE2 is `NOLC' convention notation for the atom which is identi- cal to: value2 written in the `LC' convention. The default convention is `LC'. To switch to the no lower-case convention, call the evaluable predicate `NOLC': | ?- 'NOLC'. To switch back to the full character set convention, call the evaluable predicate `LC': | ?- 'LC'. Note that the names of these two procedures consist of upper-case letters (so that they can be referred to on all devices), and therefore the names must _a_l_w_a_y_s be enclosed in single quotes. It is recommended that the `NOLC' convention only be used in emergencies, since the standard syntax is far easier to use and is also easier for other people to read. _3. _T_h_e _M_e_a_n_i_n_g _o_f _P_r_o_l_o_g _P_r_o_g_r_a_m_s _3._1. _P_r_o_g_r_a_m_s A fundamental unit of a logic program is the _l_i_t_e_r_a_l, for instance gives(tom,apple,teacher) reverse([1,2,3],L) X/ is used, for example concatenate/3. Certain predicates are predefined by procedures sup- plied by the Prolog system. Such predicates are called _e_v_a_l_u_a_b_l_e _p_r_e_d_i_c_a_t_e_s. As we have seen, the goals in the body of a clause are linked by the operator `,' which can be interpreted as conjunction ("and"). It is sometimes convenient to use an additional operator `;', standing for disjunction ("or") (The precedence of `;' is such that it dominates `,' but is dominated by `:-'.). An example is the clause. C-Prolog User's Manual 20 grandfather(X,Z) :- (mother(X,Y); father(X,Y)), father(Y,Z). which can be read as "For any X, Y and Z, X has Z as a grandfather if either the mother of X is Y or the father of X is Y, and the father of Y is Z." Such uses of disjunction can always be eliminated by defining an extra predicate - for instance the previous example is equivalent to grandfather(X,Z) :- parent(X,Y), father(Y,Z). parent(X,Y) :- mother(X,Y). parent(X,Y) :- father(X,Y). and so disjunction will not be mentioned further in the following, more formal, description of the semantics of clauses. _3._2. _D_e_c_l_a_r_a_t_i_v_e _a_n_d _P_r_o_c_e_d_u_r_a_l _S_e_m_a_n_t_i_c_s The semantics of definite clauses should be fairly clear from the informal interpretations already given. However it is useful to have a precise definition. The _d_e_c_l_a_r_a_t_i_v_e_s_e_m_a_n_t_i_c_s of definite clauses tells us which goals can be considered true according to a given program, and is defined recursively as follows. A goal is _t_r_u_e if it is the head of some clause instance and each of the goals (if any) in the body of that clause _i_n_s_t_a_n_c_e is true, where an instance of a clause (or term) is obtained by substituting, for each of zero or more of its variables, a new term for all occurrences of the variable. For example, if a program contains the preceding pro- cedure for concatenate, then the declarative semantics tells us that concatenate([a],[b],[a,b]) is true, because this goal is the head of a certain instance of the first clause for concatenate, namely, concatenate([a],[b],[a,b]) :- concatenate([],[b],[b]). and we know that the only goal in the body of this clause instance is true, since it is an instance of the unit clause which is the second clause for concatenate. The declarative semantics makes no reference to the sequencing of goals within the body of a clause, nor to the sequencing of clauses within a program. This C-Prolog User's Manual 21 sequencing information is, however, very relevant for the _p_r_o_c_e_d_u_r_a_l _s_e_m_a_n_t_i_c_s which Prolog gives to definite clauses. The procedural semantics defines exactly how the Prolog system will execute a goal, and the sequencing information is the means by which the Prolog programmer directs the system to execute his program in a sensible way. The effect of executing a goal is to enumerate, one by one, its true instances. Here then is an informal defini- tion of the procedural semantics. To execute a goal, the system searches forwards from the beginning of the program for the first clause whose head _m_a_t_c_h_e_s or _u_n_i_f_i_e_s with the goal. The unification process finds the most general common instance of the two terms, which is unique if it ex- ists. If a match is found, the matching clause instance is then activated by executing in turn, from left to right, each of the goals (if any) in its body. If at any time the system fails to find a match for a goal, it _b_a_c_k_t_r_a_c_k_s, that is it rejects the most recently activated clause, undoing any substitutions made by the match with the head of the clause. Next it reconsiders the original goal which activated the rejected clause, and tries to find a subsequent clause which also matches the goal. For example, if we execute the goal in the query :- concatenate(X,Y,[a,b]). we find that it matches the head of the first clause for concatenate, with X instantiated to [a|X1]. The new variable X1 is constrained by the new goal produced, which is the recursive procedure call concatenate(X1,Y,[b]) Again this goal matches the first clause, instantiat- ing X1 to [b|X2], and yielding the new goal concatenate(X2,Y,[]) Now this goal will only match the second clause, instantiat- ing both X2 and Y to []. Since there are no further goals to be executed, we have a solution X = [a,b] Y = [] representing a true instance of the original goal concatenate([a,b],[],[a,b]) C-Prolog User's Manual 22 If this solution is rejected, backtracking will generate the further solutions X = [a] Y = [b] X = [] Y = [a,b] in that order, by rematching, against the second clause for concatenate, goals already solved once using the first clause. _3._3. _O_c_c_u_r_s _C_h_e_c_k Prolog's unification does not have an _o_c_c_u_r_s _c_h_e_c_k, i.e. when unifying a variable against a term the system does not check whether the variable occurs in the term. When the variable occurs in the term, unification should fail, but the absence of the check means that the unifica- tion succeeds, producing a _c_i_r_c_u_l_a_r _t_e_r_m. Trying to print a circular term, or trying to unify two circular terms, will cause an infinite loop and possibly make Prolog run out of stack space. The absence of the occur check is not a bug or design oversight, but a conscious design decision. The reason for this decision is that unification with the occur check is at best linear on the sum of the sizes of the terms being unified, whereas unification without the occur check is linear on the size of the smallest of the terms being unified. In any practical programming language, basic operations are supposed to take constant time. Unification against a variable should be thought of as the basic operation of Prolog, but this can take constant time only if the occur check is omitted. Thus the absence of a occur check is essential to make Prolog into a practi- cal programming language. The inconvenience caused by this restriction seems in practice to be very slight. Usually, the restriction is only felt in toy programs. _3._4. _T_h_e _C_u_t _S_y_m_b_o_l Besides the sequencing of goals and clauses, Prolog provides one other very important facility for specifying control information. This is the _c_u_t symbol, written "!". It is inserted in the program just like a goal, but is not to be regarded as part of the logic of the program and should be ignored as far as the declarative semantics is concerned. The effect of the cut symbol is as follows. When first encountered as a goal, cut succeeds immediately. If C-Prolog User's Manual 23 backtracking should later return to the cut, the effect is to fail the _p_a_r_e_n_t _g_o_a_l, the goal which matched the head of the clause containing the cut, and caused the clause to be activated. In other words, the cut operation commits the system to all choices made since the parent goal was invoked, and causes other alternatives to be discarded. The goals thus rendered _d_e_t_e_r_m_i_n_a_t_e are the parent goal itself, any goals occurring before the cut in the clause containing the cut, and any subgoals which were exe- cuted during the execution of those preceding goals. For example, the procedure member(X,[X|L]). member(X,[Y|L]) :- member(X,L). can be used to test whether a given term is in a list, and the goal :- member(b,[a,b,c]). will succeed. The procedure can also be used to extract elements from a list, as in :- member(X,[d,e,f]). With backtracking this will successively return each ele- ment of the list. Now suppose that the first clause had been written instead: member(X,[X|L]) :- !. In this case, the above call would extract only the first element of the list (`d'). On backtracking, the cut would immediately fail the whole procedure. A procedure of the form _x :- _p, !, _q. _x :- _r. is similar to _x := if _p then _q else _r; in an Algol-like language. A cut discards all the alternatives since the parent goal, even when the cut appears within a disjunction. This means that the normal method for eliminating a disjunction by defining an extra predicate cannot be applied to a disjunction containing a cut. C-Prolog User's Manual 24 _4. _D_e_b_u_g_g_i_n_g _F_a_c_i_l_i_t_i_e_s This section describes the debugging facilities that are available in C-Prolog. The purpose of these facil- ities is to provide information concerning the control flow of your program. The main features of the debug- ging package are as follows: - The _P_r_o_c_e_d_u_r_e _b_o_x model of Prolog execution which pro- vides a simple way of visualising control flow, especially during backtracking. Control flow is viewed at the procedure level, rather than at the level of individual clauses. - The ability to exhaustively trace your program or to selectively set _s_p_y _p_o_i_n_t_s. Spy points allow you to nominate interesting procedures at which the program is to pause so that you can interact. - The wide choice of control and information options available during debugging. Much of the information in this chapter is similar but not identical to that of Chapter 8 of _P_r_o_g_r_a_m_m_i_n_g _i_n _P_r_o_l_o_g. _4._1. _T_h_e _P_r_o_c_e_d_u_r_e _B_o_x _C_o_n_t_r_o_l _F_l_o_w _M_o_d_e_l During debugging the interpreter prints out a sequence of goals in various states of instantiation in order to show the state the program has reached in its execution. However, in order to understand what is occurring it is necessary to understand when and why the interpreter prints out goals. As in other programming languages, key points of interest are procedure entry and return, but in Prolog there is the additional complexity of backtracking. One of the major confusions that novice Prolog programmers have to face is the question of what actually happens when a goal fails and the system sud- denly starts backtracking. The Procedure Box model of Pro- log execution views program control flow in terms of move- ment about the program text. This model provides a basis for the debugging mechanism in the interpreter, and enables the user to view the behaviour of his program in a con- sistent way. Let us look at an example Prolog procedure: C-Prolog User's Manual 25 *--------------------------------------* Call | | Exit ---------> + descendant(X,Y) :- offspring(X,Y). + ---------> | | | descendant(X,Z) :- | <--------- + offspring(X,Y), descendant(Y,Z). + <--------- Fail | | BackTo *--------------------------------------* The first clause states that Y is a descendant of X if Y is an offspring of X, and the second clause states that Z is a descendant of X if Y is an offspring of X and if Z is a descendant of Y. In the diagram a box has been drawn around the whole procedure and labelled arrows indicate the control flow in and out of this box. There are four such arrows which we shall look at in turn. Call This arrow represents initial invocation of the pro- cedure. When a descendant goal of the form descendant(X,Y) is required to be satisfied, control passes through the Call _p_o_r_t of the descendant box with the intention of matching a component clause and then satisfying any subgoals in the body of that clause. Notice that this is independent of whether such a match is possible, that is first the box is called, and then the attempt to match takes place. Textually we can imagine moving to the code for descen- dant when meeting a call to descendant in some other part of the code. Exit This arrow represents a successful return from the pro- cedure. This occurs when the initial goal has been unified with one of the component clauses and any subgoals have been satisfied. Control now passes out of the Exit port of the descendant box. Textually we stop following the code for descendant and go back to the place we came from. BackTo This arrow indicates that a subsequent goal has failed and that the system has come back to this goal in an attempt to match the goal against another clause. Control passes through the BackTo port of the des- cendant box in an attempt to rematch the original goal with an alternative clause and then try to satisfy any subgoals in the body of this new clause. Textu- ally we follow the code backwards up the way we came looking for new ways of succeeding, possibly C-Prolog User's Manual 26 dropping down on to another clause and following that if necessary. Note that this is somewhat less informative than the Redo port described in _P_r_o_g_r_a_m_m_i_n_g _i_n _P_r_o_l_o_g, because it does not show the path in the program from a failed goal back to the first goal where alternative clauses exist, but only this goal. Fail This arrow represents a failure of the initial goal, which might occur if no clause is matched, or if subgoals are never satisfied, or if any solution pro- duced is always rejected by later processing. Control now passes out of the Fail port of the descendant box and the system continues to backtrack. Textually we move back to the code which called this procedure and keep moving backwards up the code looking for choice points. In terms of this model, the information we get about the procedure box is only the control flow through these four ports. This means that at this level we are not concerned with which clause matches, and how any subgoals are satisfied, but rather we only wish to know the initial goal and the final outcome. However, it can be seen that whenever we are trying to satisfy subgoals, what we are actually doing is passing through the ports of _t_h_e_i_r respective boxes. If we were to follow this, then we would have complete information about the control flow inside the procedure box. Note that the box we have drawn round the procedure should really be seen as an _i_n_v_o_c_a_t_i_o_n _b_o_x. That is, there will be a different box for each different invocation of the procedure. Obviously, with something like a recursive procedure, there will be many different Calls and Exits in the control flow, but these will be for different invoca- tions. Since this might get confusing each invocation box is given a unique integer identifier. _4._2. _B_a_s_i_c _D_e_b_u_g_g_i_n_g _P_r_e_d_i_c_a_t_e_s The interpreter provides a range of evaluable predicates for control of the debugging facilities. The most basic predicates are as follows: debug Switches _d_e_b_u_g _m_o_d_e on. (It is initially off.) In order for the full range of control flow infor- mation to be available it is necessary to have this on from the start. When it is off the system does not remember invocations that are being C-Prolog User's Manual 27 executed. (This is because it is expensive and not required for normal running of programs.) You can switch debug mode on in the middle of execution, either from within your program or after an interrupt (see trace below), but information prior to this will just be unavailable. nodebug switches debug mode off. If there are any spy points set then they will be removed. debugging prints onto the terminal information about the current debugging state. It shows whether debug mode is on or off and gives various other information to be described later. _4._3. _T_r_a_c_i_n_g The following evaluable predicate may be used to com- mence an exhaustive trace of a program. trace Switches debug mode on, if it is not on already, and ensures that the next time control enters a procedure box, a message will be produced and you will be asked to interact. When stopped at a goal being traced, you have a number of options which will be detailed later. In particular, you can just type END-OF-LINE (carriage-return) to creep (or single-step) into your program. If you continue to creep through your program you will see every entry and exit to/from every invocation box. However, you will notice that you are only given the opportunity to interact on Call and BackTo ports, i.e. a single creep decision may take you through several Exit ports or several Fail ports. Normally this is desirable, as it would be tedi- ous to go through all those ports step by step. However, if it is not what you want, the following evaluable predicate gives full control over the ports at which you are prompted. leash(_M_o_d_e) Sets the _l_e_a_s_h_i_n_g _m_o_d_e to _M_o_d_e, where _M_o_d_e can be one of the following full prompt on Call, Exit, BackTo and Fail tight prompt on Call, BackTo and Fail half prompt on Call and BackTo loose prompt on Call off never prompt C-Prolog User's Manual 28 or any other combination of ports as described later. The initial _l_e_a_s_h_i_n_g _m_o_d_e is `half'. _4._4. _S_p_y _P_o_i_n_t_s For programs of any size, it is clearly impractical to creep through the entire program. Spy points make it possi- ble to stop the program whenever it gets to a particular procedure which is of interest. Once there, one can set further spy points in order to catch the control flow a bit further on, or one can start creeping. Setting a spy-point on a procedure indicates that you wish to see all control flow through the various ports of its invocation boxes. When control passes through any port of a procedure with a spy-point set on it, a message is output and the user is asked to interact. Note that the current mode of leashing does not affect spy points: user interaction is requested on _e_v_e_r_y port. Spy points are set and removed by the following evalu- able predicates which are also standard operators: spy _X Sets spy points on all the procedures given by _X. _X is either a single predicate specification, or a list of such specifications. A predicate specification is either of the form /, which means the procedure with the name and an arity of (for example member/2, foo/0, hello/27), or it is of the form , which means all the pro- cedures with the name that currently have clauses in the data-base (e.g. member, foo, hello). This latter form may refer to multiple procedures which have the same name but different arities. If you use the form but there are no clauses for this predicate (of any arity) then nothing will be done. If you really want to place a spy point on a currently non-existent procedure, then you must use the full form /; you will get a warn- ing message in this case. If you set some spy points when debug mode is off then it will be automatically switched on. nospy _X This reverses the effect of spy _X: all the procedures given by _X will have previously set spy points removed from them. The options available when you arrive at a spy-point are described below. C-Prolog User's Manual 29 _4._5. _F_o_r_m_a_t _o_f _D_e_b_u_g_g_i_n_g _M_e_s_s_a_g_e_s We will now look at the exact format of the message output by the system at a port. All trace messages are out- put to the terminal regardless of where the current out- put is directed. (This allows you to trace programs while they are performing file I/O.) The basic format is as fol- lows: ** (23) 6 Call : foo(hello,there,_123) ? The "**" indicates that this is a spy-point. If this port is not for a procedure with a spy-point set, then there will be two spaces there instead. If this port is the requested return from a Skip then the second character becomes ">". This gives four possible combinations: "**" This is a spy-point. "*>" This is a spy-point, and you also did a Skip last time you were in this box. " >" This is not a spy-point, but you did a Skip last time you were in this box. " " This is not a spy-point. The number in parentheses is the unique invocation identifier. This is continuously incrementing regardless of whether or not you are actually seeing the invocations (provided that debug mode is on). This number can be used to cross correlate the trace messages for the various ports, since it is unique for every invocation. It will also give an indication of the number of procedure calls made since the start of the execution. The invocation counter starts again for every fresh execution of a com- mand, and it is also reset when retries (see later) are per- formed. The number following this is the current depth, that is, the number of direct ancestors this goal has. The next word specifies the particular port (Call, Exit, BackTo or Fail). The goal is then printed so that you can inspect its current instantiation state. The final "?" is the prompt indicating that you should type in one of the option codes allowed (see next sec- tion). If this particular port is unleashed then you will obviously not get this prompt since you have specified that you do not wish to interact at this point. C-Prolog User's Manual 30 Notice that not all procedure calls are traced; there are a few basic procedures which have been made invisible since it is more convenient not to see them. These include all primitive I/O evaluable predicates (for example get, put, read, write), all basic control structures (that is, `,', `;', `->') and all debugging control evaluable predicates (for instance, debug, spy, leash, trace). This means that you will never see messages con- cerning these predicates during debugging. _4._6. _O_p_t_i_o_n_s _A_v_a_i_l_a_b_l_e _d_u_r_i_n_g _D_e_b_u_g_g_i_n_g This section describes the particular options that are available when the system prompts you after print- ing out a debugging message. All the options are one letter mnemonics. They are read from the terminal with any blanks being completely ignored up to the next end of line. The _c_r_e_e_p option needs only the new line. The only option which you really have to remember is "h". This provides help in the form of the following list of available options: END-OF-LINE creep a abort c creep f fail l leap b break s skip h help r retry r retry goal q quasi-skip n nodebug g goal stack [ read clauses from terminal e exit Prolog The first three options are the basic control decisions: c, END-OF-LINE: Creep Causes the interpreter to single-step to the very next port and print a message. Then if the port is leashed the user is prompted for further interaction. Otherwise it continues creeping. If leashing is off, creep is the same as leap (see below) except that a complete trace is printed on the terminal. l: Leap causes the interpreter to resume running your pro- gram, only stopping when a spy-point is reached (or when the program terminates). Leaping can thus be used to follow the execution at a higher level than exhaustive tracing. All you need to do is to set spy points on an evenly spread set of pertinent C-Prolog User's Manual 31 procedures, and then follow the control flow through these by leaping from one to the other. s: Skip Skip is only valid for Call and BackTo ports. It skips over the entire execution of the procedure. That is, you will not see anything until control comes back to this procedure (at either the Exit port or the Fail port). Skip is particularly useful while creeping since it guarantees that control will be returned after the (possibly complex) execution within the box. If you skip then no message at all will appear until control returns. This includes calls to procedures with spy points set; they will be masked out during the skip. There are two ways of overriding this : there is a Quasi-skip which does not ignore spy points, and the "t" option after an inter- rupt will disable the masking. Normally, however, this masking is just what is required! q: Quasi-skip Is like Skip except that it does not mask out spy points. If there is a spy-point within the execution of the goal then control returns at this point and any action can be performed there. The initial skip still guarantees an eventual return of control, though, when the internal execution is finished. f: Fail Transfers to the Fail port of the current box. This puts your execution in a position where it is about to backtrack out of the current invocation, that is, you have manually failed the initial goal. r: Retry Transfers to the Call port of the current goal, or if given a numeric argument _n, to the Call port of the invocation numbered _n. IF the invocation being retried has been deleted by the cut control primitive, the most recent active invocation before it will be retried. If _n is out of range, the current invocation is retried. This option is extremely useful to go back to an ear- lier state of computation if some point of interest was overshot in a debugging session. Note however that side effects, such as database modification, are not undone. g: Goal Stack C-Prolog User's Manual 32 Shows the goal that called the current one, and the one that called it, and so on, that is, the stack of pend- ing goals. Goals are printed one per line, from the most recent to the least recent. Each goal is labeled by its recursion level _l, its invocation number _i and the ordinal position _p of the clause currently used to solve the goal. a: Abort Causes an abort of the current execution. All the execution states built so far are destroyed and you are put right back at the top level of the interpreter. (This is the same as the evaluable predicate abort.) [: Read clauses from terminal starts reading clauses typed by the user as if doing a _c_o_n_s_u_l_t(_u_s_e_r). An END-OF-INPUT returns to the debugger. e: Exit from Prolog causes an irreversible exit from the Prolog system. (This is the same as the evaluable predicate halt.) h: Help Displays the table of options given above. b: Break Calls the evaluable predicate break, thus putting you at interpreter top level with the execution so far sitting underneath you. When you end the break with the END-OF-INPUT character, you will be reprompted at the port at which you broke. The new execution is completely separate from the suspended one; the invocation numbers will start again from 1 during the break. Debug mode is not switched off as you call the break, but if you do switch it off then it will be re-switched on when you finish the break and go back to the old execution. However, any changes to the leashing or to spy points will remain in effect. n: Nodebug Turns off debug mode. Notice that this is the correct way to switch debugging off at a trace point. You cannot use the "b" option because it always restores debug mode upon return. C-Prolog User's Manual 33 _4._7. _R_e_c_o_n_s_u_l_t_i_n_g _d_u_r_i_n_g _D_e_b_u_g_g_i_n_g It is possible, and sometimes useful, to reconsult a file whilst in the middle of a program execution. How- ever this can lead to unexpected behaviour under the follow- ing circumstances: a procedure has been successfully exe- cuted; it is subsequently re-defined by a reconsult, and is later re-activated by backtracking. When the backtracking occurs, all the new clauses for the pro- cedure appear to the interpreter to be potential alternative solutions, even though identical clauses may already have been used. Thus large amounts of (unwanted) activity takes place on backtracking. The problem does not arise if you do the reconsult when you are at the Call port of the pro- cedure to be re-defined. _5. _E_v_a_l_u_a_b_l_e _P_r_e_d_i_c_a_t_e_s This section describes all the evaluable predicates available in C-Prolog. These predicates are provided in advance by the system and they cannot be redefined by the user. Any attempt to add clauses or delete clauses to an evaluable predicate fails with an error message, and leaves the evaluable predicate unchanged. The C-Prolog provides a fairly wide range of evaluable predicates to perform the following tasks: Input/Output Reading-in programs Opening and closing files Reading and writing Prolog terms Getting and putting characters Arithmetic Affecting the flow of the execution Classifying and operating on Prolog terms (meta-logical facilities) Sets Term Comparison Manipulating the Prolog program database Manipulating the additional indexed database Debugging facilities Environmental facilities The evaluable predicates will be described according to this classification. Appendix I contains a complete list of the evaluable predicates. _5._1. _I_n_p_u_t _a_n_d _O_u_t_p_u_t A total of 15 I/O streams may be open at any one time for input and output. This includes a stream that is always available for input and output to the user's terminal. A stream to a file _F is opened for input by the first see(_F) executed. _F then becomes the current input stream. C-Prolog User's Manual 34 Similarly, a stream to file _H is opened for output by the first tell(_H) executed. _H then becomes the current output stream. Subsequent calls to see(_F) or to tell(_H) make _F or _H the current input or output stream, respectively. Any input or output is always to the current stream. When no input or output stream has been specified, the standard ersatz file `user', denoting the user's termi- nal, is utilised for both. When the terminal is waiting for input on a new line, a prompt will be displayed as follows: "| ?- " interpreter waiting for command "| " interpreter wating for command continuation line "| " consult(user) wating for continuation line "|:" default for waiting for other user input When the current input (or output) stream is closed, the user's terminal becomes the current input (or output) stream. The only file that can be simultaneously open for input and output is the ersatz file `user'. A file is referred to by its name, _w_r_i_t_t_e_n _a_s _a_n _a_t_o_m, e.g. myfile 'F123' data_lst 'tom/greeks' All I/O errors normally cause an abort, except for the effect of the evaluable predicate nofileerrors decribed below. End of file is signalled on the user's terminal by typ- ing the END-OF-INPUT character. Any more input requests for a file whose end has been reached causes an error failure. _5._1._1. _R_e_a_d_i_n_g-_i_n _P_r_o_g_r_a_m_s consult(_F) Instructs the interpreter to read-in the program which is in file _F. When a directive is read it is immedi- ately executed. When a clause is read it is put after any clauses already read by the interpreter for that procedure. C-Prolog User's Manual 35 reconsult(_F) Like consult except that any procedure defined in the reconsulted file erases any clauses for that procedure already present in the interpreter. recon- sult makes it possible to amend a program without hav- ing to restart from scratch and consult all the files which make up the program. [_F_i_l_e|_F_i_l_e_s] This is a shorthand way of consulting or reconsulting a list of files. A file name may optionally be preceded by the operator `-' to indicate that the file should be reconsulted rather than consulted. Thus | ?- [file1,-file2,file3]. is merely a shorthand for | ?- consult(file1), reconsult(file2), consult(file3). _5._1._2. _F_i_l_e _H_a_n_d_l_i_n_g see(_F) File _F becomes the current input stream. seeing(_F) _F is unified with the name of the current input file. seen Closes the current input stream. tell(_F) File _F becomes the current output stream. telling(_F) _F is unified with the name of the current output file. told Closes the current output stream. close(_F) C-Prolog User's Manual 36 File _F, currently open for input or output, is closed. fileerrors Undoes the effect of nofileerrors. nofileerrors After a call to this predicate, the I/O error conditions "incorrect file name ...", "can't see file ...", "can't tell file ..." and "end of file ..." cause a call to fail instead of the default action, which is to type an error message and then call abort. exists(_F) Succeeds if the file F exists. rename(_F,_N) If File _F is renamed to _N. If _N is `[]', the file is deleted. If _F was a currently open stream, it is closed first. _5._1._3. _I_n_p_u_t _a_n_d _O_u_t_p_u_t _o_f _T_e_r_m_s read(_X) The next term, delimited by a full stop (i.e. a "." followed by a carriage-return or a space), is read from the current input stream and unified with _X. The syntax of the term must accord with current operator declarations. If a call read(_X) causes the end of the current input stream to be reached, _X is unified with the atom `end_of_file'. Further calls to read for the same stream will then cause an error failure. write(_X) The term _X is written to the current output stream according to operator declarations in force. display(_X) The term _X is displayed on the terminal in standard parenthesised prefix notation. writeq(_T_e_r_m) Similar to write(_T_e_r_m), but the names of atoms and functors are quoted where necessary to make the result acceptable as input to read. C-Prolog User's Manual 37 print(_T_e_r_m) Print _T_e_r_m onto the current output. This predicate provides a handle for user defined pretty printing. If _T_e_r_m is a variable then it is written, using write(_T_e_r_m). If _T_e_r_m is non-variable then a call is made to the user defined procedure portray(_T_e_r_m). If this succeeds then it is assumed that _T_e_r_m has been output. Otherwise print is equivalent to write. _5._1._4. _C_h_a_r_a_c_t_e_r _I_n_p_u_t/_O_u_t_p_u_t nl A new line is started on the current output stream. get0(_N) _N is the ASCII code of the next character from the current input stream. If the current input stream reaches its end of file, the ASCII character code for control-Z is returned and the stream closed. get(_N) _N is the ASCII code of the next non-blank printable character from the current input stream. It has the same behaviour as get0 on end of file. skip(_N) Skips to just past the next ASCII character code _N from the current input stream. _N may be an integer expression. Skipping past the end of file causes an error. put(_N) ASCII character code _N is output to the current output stream. _N may be an integer expression. tab(_N) _N spaces are output to the current output stream. _N may be an integer expression. _5._2. _A_r_i_t_h_m_e_t_i_c Arithmetic is performed by evaluable predicates which take as arguments _a_r_i_t_h_m_e_t_i_c _e_x_p_r_e_s_s_i_o_n_s and _e_v_a_l_u_a_t_e them. An arithmetic expression is a term built from _e_v_a_l_u_a_b_l_e _f_u_n_c_t_o_r_s, numbers and variables. At the time of evaluation, each variable in an arithmetic expression C-Prolog User's Manual 38 must be bound to a number or to an arithmetic expression. The result of evaluation will always be converted back to an integer if possible. Each evaluable functor stands for an arithmetic opera- tion. The adjective "integer" in the descriptions below means that the operation only makes sense for integers, and will fail for floating point numbers. Because arithmetic expressions are compound terms, they use up storage that is only recovered on backtracking. The evaluable predicate expanded_exprs can be used to avoid this overhead by preexpanding arithmetic expressions into calls to arithmetic evaluation predicates. However, this makes program read-in slower and clauses bigger. In general, an arithmetic operation that combines integers and floating point numbers will return a floating point number. However, if the result is integral, it is converted back to integer representation, and the same applies to numbers read in by the reader. Thus, the goal | ?- p(2.0). will succeed with the clause p(2). and the result of the query | ?- X is 2*1.5. is X = 5 Numbers may be integers -33 0 9999 or floating point numbers 1.333 -2.6E+7 0.555E-2 Note that the decimal "." cannot be confused with the end of clause because the latter must be followed by blank space (space, tab or END-OF-LINE). However, if an operator "." is declared as infix, it will only be possible to apply it to two numbers if they are separated by blank space from the operator. C-Prolog User's Manual 39 The evaluable functors are as follows, where _X and _Y are arithmetic expressions. _X+_Y addition _X-_Y subtraction _X*_Y multiplication _X/_Y division _X//_Y integer division _X mod _Y _X (integer) modulo _Y -_X unary minus exp(_X) exponential function log(_X) natural logarithm log10(_X) base 10 logarithm sqrt(_X) square root sin(_X) sine cos(_X) C-Prolog User's Manual 40 cosine tan(_X) tangent asin(_X) arc sine acos(_X) arc cosine atan(_X) arc tangent floor(_X) the largest integer not greater than _X _X^_Y _X to the power _Y _X/\_Y integer bitwise conjunction _X/_Y integer bitwise disjunction _X<<_Y integer bitwise left shift of _X by _Y places _X>>_Y integer bitwise right shift of _X by _Y places \_X integer bitwise negation cputime CPU time since C-Prolog was started, in seconds. heapused C-Prolog User's Manual 41 Heap space in use, in bytes. [_X] (a list of just one element) evaluates to _X if _X is an integer. Since a quoted string is just a list of integers, this allows a quoted character to be used in place of its ASCII code; e.g. "A" behaves within arith- metic expressions as the integer 65. The arithmetic evaluable predicates are as follows, where _X and _Y stand for arithmetic expressions, and _Z for some term. Note that this means that is only evaluates one of its arguments as an arithmetic expression (the right-hand side one), whereas all the comparison predicates evaluate both their arguments. _Z is _X Arithmetic expression _X is evaluated and the result, is unified with _Z. Fails if _X is not an arithmetic expres- sion. _X =:= _Y The values of _X and _Y are equal. _X == _Y The values of _X and _Y are not equal. _X < _Y The value of _X is less than the value of _Y. _X > _Y The value of _X is greater than the value of _Y. _X =< _Y The value of _X is less than or equal to the value of _Y. _X >= _Y The value of _X is greater than or equal to the value of _Y. expanded_exprs(_O_l_d,_N_e_w) Unifies _O_l_d to the current value of the expression expansion flag, and sets the value of the flag to _N_e_w. The possible values of the flag are `off' (the default) C-Prolog User's Manual 42 for not expanding arithmetic expressions into procedure calls, and `on' to do the expansion. _5._3. _C_o_n_v_e_n_i_e_n_c_e _P , _Q _P and _Q. _P ; _Q _P or _Q. true Always succeeds. _X = _Y Defined as if by the clause " Z=Z. ", that is _X and _Y are unified. _5._4. _E_x_t_r_a _C_o_n_t_r_o_l ! Cut (discard) all choice points made since the parent goal started execution. \+ _P If the goal _P has a solution, fail, otherwise succeed. It is defined as if by \+(P) :- P, !, fail. \+(_). _P -> _Q ; _R Analogous to "if _P then _Q else _R" i.e. defined as if by P -> Q; R :- P, !, Q. P-> Q; R :- R. _P -> _Q C-Prolog User's Manual 43 When occurring other than as one of the alterna- tives of a disjunction, is equivalent to _P -> _Q; fail. repeat Generates an infinite sequence of backtracking choices. It behaves as if defined by the clauses: repeat. repeat :- repeat. fail Always fails. _5._5. _M_e_t_a-_L_o_g_i_c_a_l var(_X) Tests whether _X is currently instantiated to a vari- able. nonvar(_X) Tests whether _X is currently instantiated to a non- variable term. atom(_X) Checks that _X is currently instantiated to an atom (i.e. a non-variable term of arity 0, other than a number or database reference). number(_X) Checks that _X is currently instantiated to a number. integer(_X) Checks that _X is currently instantiated to an integer. atomic(_X) Checks that _X is currently instantiated to an atom, number or database reference. primitive(_X) C-Prolog User's Manual 44 Checks that _X is currently instantiated to a number or database reference. db_reference(_X) Checks that _X is currently instantiated to a database reference. functor(_T,_F,_N) The principal functor of term _T has name _F and arity _N, where _F is either an atom or, provided _N is 0, a number. Initially, either _T must be instantiated to a non-variable, or _F and _N 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 _T is initially instantiated to a variable, the result of the call is to instantiate _T to the most general term having the principal functor indicated. arg(_I,_T,_X) Initially, _I must be instantiated to a positive integer and _T to a compound term. The result of the call is to unify _X with the _Ith argument of term _T. (The arguments are numbered from 1 upwards.) If the ini- tial conditions are not satisfied or _I is out of range, the call merely fails. _X =.. _Y _Y is a list whose head is the atom corresponding to the principal functor of _X and whose tail is the argument list of that functor in _X. E.g. product(0,N,N-1) =.. [product,0,N,N-1] N-1 =.. [-,N,1] product =.. [product] If _X is instantiated to a variable, then _Y 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. name(_X,_L) If _X is an atom or a number then _L is a list of the ASCII codes of the characters comprising the name of _X. E.g. C-Prolog User's Manual 45 name(product,[112,114,111,100,117,99,116]) i.e. name(product,"product") name(1976,[49,57,55,54]) name(hello,[104,101,108,108,111]) name([],"[]") If _X is instantiated to a variable, _L must be instan- tiated to a list of ASCII character codes. E.g. | ?- name(X,[104,101,108,108,111])). X = hello | ?- name(X,"hello"). X = hello call(_X) If _X is instantiated to a term which would be accept- able as body of a clause, the goal call(_X) is exe- cuted exactly as if that term appeared textually in place of the call(_X), except that any cut ("!") occur- ring in _X will remove only those choice points in _X. If _X is not instantiated as described above, an error message is printed and call fails. _X (where _X is a variable) Exactly the same as call(_X). _5._6. _S_e_t_s 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 back- tracking and gradually building up a list of the solutions. The following evaluable predicates are provided to automate this process. setof(_X,_P,_S) Read this as "_S is the set of all instances of _X such that _P is provable, where that set is non-empty". The term _P specifies a goal or goals as in call(_P). _S is a set of terms represented as a list of those terms, without dupli- cates, in the standard order for terms (see Section 5.3). If there are no instances of _X such that _P is satisfied C-Prolog User's Manual 46 then the predicate fails. The variables appearing in the term _X should not appear anywhere else in the clause except within the term _P. Obvi- ously, the set to be enumerated should be finite, and should be enumerable by Prolog in finite time. It is possi- ble for the provable instances to contain variables, but in this case the list _S will only provide an imperfect representation of what is in reality an infinite set. If there are uninstantiated variables in _P which do not also appear in _X, then a call to this evaluable predicate may backtrack, generating alternative values for _S corresponding to different instantiations of the free vari- ables of _P. (It is to cater for such usage that the set S is constrained to be non-empty.) For example, the call: | ?- setof(X, X likes Y, S). might produce two alternative solutions via backtracking: Y = beer, S = [dick, harry, tom] Y = cider, S = [bill, jan, tom ] The call: | ?- setof((Y,S), setof(X, X likes Y, S), SS). would then produce: SS = [ (beer,[dick,harry,tom]), (cider,[bill,jan,tom]) ] Variables occurring in _P will not be treated as free if they are explicitly bound within _P by an existential quantifier. An existential quantification is written: _Y^_Q meaning "there exists a _Y such that _Q is true", where _Y is some Prolog variable. For example: | ?- setof(X, Y^(X likes Y), S). would produce the single result: X = [bill, dick, harry, jan, tom] in contrast to the earlier example. bagof(_X,_P,_B_a_g) C-Prolog User's Manual 47 This is exactly the same as setof except that the list (or alternative lists) returned will not be ordered, and may contain duplicates. The effect of this relaxation is to save considerable time and space in execution. _X^_P The interpreter recognises this as meaning "there exists an _X such that _P is true", and treats it as equivalent to call(_P). The use of this explicit existential quantifier outside the setof and bagof con- structs is superfluous. _5._7. _C_o_m_p_a_r_i_s_o_n _o_f _T_e_r_m_s These evaluable predicates are meta-logical. They treat uninstantiated variables as objects with values which may be compared, and they never instan- tiate those variables. They should _n_o_t be used when what you really want is arithmetic comparison (Section 5.2) or unification. The predicates make reference to a standard total ordering of terms, which is as follows: - variables, in a standard order (roughly, oldest first - the order is _n_o_t related to the names of variables); - Database references, roughly in order of age; - numbers, from -"infinity" to +"infinity"; - atoms, in alphabetical (i.e. ASCII) order; - complex terms, ordered first by arity, then by the name of principal functor, then by the arguments (in left-to-right order). For example, here is a list of terms in the standard order: [ X, -9, 1, fie, foe, fum, X = Y, fie(0,2), fie(1,1) ] These are the basic predicates for comparison of arbitrary terms: _X == _Y Tests if the terms currently instantiating _X and _Y are literally identical (in particular, variables in equivalent positions in the two terms must be identi- cal). For example, the question C-Prolog User's Manual 48 | ?- X == Y. fails (answers "no") because _X and _Y are distinct uninstantiated variables. However, the question | ?- X = Y, X == Y. succeeds because the first goal unifies the two vari- ables (see page 42). _X \== _Y Tests if the terms currently instantiating _X and _Y are not literally identical. _T_1 @< _T_2 Term _T_1 is before term _T_2 in the standard order. _T_1 @> _T_2 Term _T_1 is after term _T_2 in the standard order. _T_1 @=< _T_2 Term _T_1 is not after term _T_2 in the standard order. _T_1 @>= _T_2 Term _T_1 is not before term _T_2 in the standard order. Some further predicates involving comparison of terms are: compare(_O_p,_T_1,_T_2) The result of comparing terms _T_1 and _T_2 is _O_p, where the possible values for _O_p are: `=' if _T_1 is identical to _T_2, `<' if _T_1 is before _T_2 in the standard order, `>' if _T_1 is after _T_2 in the standard order. Thus compare(=,_T_1,_T_2) is equivalent to _T_1 == _T_2. sort(_L_1,_L_2) The elements of the list _L_1 are sorted into the stan- dard order, and any identical (i.e. `==') elements are merged, yielding the list _L_2. (The time taken to do this is at worst order (N log N) where N is the length C-Prolog User's Manual 49 of _L_1.) keysort(_L_1,_L_2) The list _L_1 must consist of items of the form _K_e_y- _V_a_l_u_e. These items are sorted into order according to the value of _K_e_y, yielding the list _L_2. No merging takes place. (The time taken to do this is at worst order (N log N) where N is the length of L1.) _5._8. _M_o_d_i_f_i_c_a_t_i_o_n _o_f _t_h_e _P_r_o_g_r_a_m The predicates defined in this section allow modifica- tion of the program as it is actually running. Clauses can be added to the program (_a_s_s_e_r_t_e_d) or removed from the pro- gram (_r_e_t_r_a_c_t_e_d). Some of the predicates make use of an implementation-defined identifier or _d_a_t_a_b_a_s_e _r_e_f_e_r_e_n_c_e which uniquely identifies every clause in the interpreted program. This identifier makes it possible to access clauses directly, instead of requiring a search through the program every time. However these facilities are intended for more complex use of the database and are not required (and undoubtedly should be avoided) by novice users. assert(_C) The current instance of _C is interpreted as a clause and is added to the program (with new private variables replacing any uninstantiated variables). The position of the new clause within the procedure concerned is implementation-defined. _C must be instantiated to a non-variable. assert(_C_l_a_u_s_e,_R_e_f) Similar to assert(_C_l_a_u_s_e), but also unifies _R_e_f with the database reference of the clause asserted. asserta(_C) Like assert(_C), except that the new clause becomes the _f_i_r_s_t clause for the procedure concerned. asserta(_C_l_a_u_s_e,_R_e_f) Similar to asserta(_C_l_a_u_s_e), but also unifies _R_e_f with the database reference of the clause asserted. assertz(_C) Like assert(_C), except that the new clause becomes the _l_a_s_t clause for the procedure concerned. C-Prolog User's Manual 50 assertz(_C_l_a_u_s_e,_R_e_f) Similar to assertz(_C_l_a_u_s_e), but also unifies _R_e_f with the database reference of the clause asserted. clause(_P,_Q) _P must be bound to a non-variable term, and the program is searched for a clause whose head matches _P. The head and body of those clauses are unified with _P and _Q respectively. If one of the clauses is a unit clause, _Q will be unified with `true'. clause(_H_e_a_d,_B_o_d_y,_R_e_f) Similar to clause(_H_e_a_d,_B_o_d_y) but also unifies _R_e_f with the database reference of the clause concerned. If _R_e_f is not given at the time of the call, _H_e_a_d must be instantiated to a non-variable term. Thus this predi- cate can have two different modes of use, depending on whether the database reference of the clause is known or unknown. retract(_C) The first clause in the program that matches _C is erased. _C must be initially instantiated to a non- variable. The predicate may be used in a non- determinate fashion, i.e. it will successively retract clauses matching the argument through backtracking. abolish(_N,_A) Completely remove all clauses for the procedure with name _N (which should be an atom), and arity _A (which should be an integer). The space occupied by retracted or abolished clauses will be recovered when instances of the clause are no longer in use. See also erase (Section 5.10) which allows a clause to be directly erased via its database reference[6]. _5._9. _I_n_f_o_r_m_a_t_i_o_n _a_b_o_u_t _t_h_e _S_t_a_t_e _o_f _t_h_e _P_r_o_g_r_a_m listing Lists in the current output stream all the clauses in the program. ____________________ [6]This is a lower level facility, required only for com- plicated database manipulations. C-Prolog User's Manual 51 listing(_A) The argument _A may be a predicate specification of the form _N_a_m_e/_A_r_i_t_y in which case only the clauses for the specified predicate are listed. If _A is just an atom, then the interpreted procedures for all predicates of that name are listed as for listing/0. Finally, it is possible for _A to be a list of predicate specifications of either type, e.g. | ?- listing([concatenate/3, reverse, go/0]). current_atom(_A_t_o_m) Generates (through backtracking) all currently known atoms, and returns each one as _A_t_o_m. current_functor(_N_a_m_e,_F_u_n_c_t_o_r) Generates (through backtracking) all currently known functors, and for each one returns its name and most general term as _N_a_m_e and _F_u_n_c_t_o_r respectively. If _N_a_m_e is given, only functors with that name are generated. current_predicate(_N_a_m_e,_F_u_n_c_t_o_r) Similar to current_functor, but it only generates func- tors corresponding to predicates for which there exists a procedure. _5._1_0. _I_n_t_e_r_n_a_l _D_a_t_a_b_a_s_e This section describes predicates for manipulating an internal indexed database that is kept separate from the normal program database. They are intended for more sophis- ticated database applications and are not really necessary for novice users. For normal tasks you should be able to program quite satisfactorily just using assert and retract. recorded(_K_e_y,_T_e_r_m,_R_e_f) The internal database is searched for terms recorded under the key _K_e_y. These terms are successively unified with _T_e_r_m in the order they occur in the database. At the same time, _R_e_f is unified with the database refer- ence of the recorded item. The key must be given, and may be an atom or complex term. If it is a complex term, only the principal functor is significant. recorda(_K_e_y,_T_e_r_m,_R_e_f) C-Prolog User's Manual 52 The term _T_e_r_m is recorded in the internal database as the first item for the key _K_e_y, where _R_e_f is its data- base reference. The key must be given, and only its principal functor is significant. recordz(_K_e_y,_T_e_r_m,_R_e_f) The term _T_e_r_m is recorded in the internal database as the last item for the key _K_e_y, where _R_e_f is its data- base reference. The key must be given, and only its principal functor is significant. erase(_R_e_f) The recorded item _o_r clause whose database reference is _R_e_f is effectively erased from the internal database or program. An erased item will no longer be accessible through the predicates that search through the data- base, but will still be accessible through its database reference, if this is available in the execution state after the call to erase. Only when all instances of the item's database reference have been forgotten through database erasures and/or backtracking will the item be actually removed from the database. erased(_R) Suceeds if _R is a database reference to a database item that has been erased, otherwise fails. instance(_R_e_f,_T_e_r_m) A (most general) instance of the recorded term whose database reference is _R_e_f is unified with _T_e_r_m. _R_e_f must be instantiated to a database reference. Note that instance will even pick database items that have been erased. _5._1_1. _D_e_b_u_g_g_i_n_g debug Debug mode is switched on. Information will now be retained for debugging purposes and executions will require more space. nodebug Debug mode is switched off. Information is no longer retained for debugging, and spy points are removed. trace C-Prolog User's Manual 53 Debug mode is switched on, and the interpreter starts tracing from the next call to a user goal. If trace was given in a command on its own, the goal(s) traced will be those of the next command. Since this is a once-off decision, a call to trace is necessary when- ever tracing is required right from the start of an execution, otherwise tracing will only happen at spy points. spy _S_p_e_c Spy points will be placed on all the procedures given by _S_p_e_c. All control flow through the ports of these procedures will henceforth be traced. If debug mode was previously off, then it will be switched on. _S_p_e_c can either be a predicate specification of the form _N_a_m_e/_A_r_i_t_y or _N_a_m_e, or a list of such specifications. When the _N_a_m_e is given without the _A_r_i_t_y this refers to all predicates of that name which currently have defin- itions. If there are none, then nothing will be done. Spy points can be placed on particular undefined pro- cedures only by using the full form, _N_a_m_e/_A_r_i_t_y. nospy _S_p_e_c Spy points are removed from all the procedures given by _S_p_e_c (as for spy). leash(_M_o_d_e) Sets the leashing mode to _M_o_d_e, where _M_o_d_e can be one of the following full prompt on Call, Exit, BackTo and Fail tight prompt on Call, BackTo and Fail half prompt on Call and BackTo loose prompt on Call off never prompt _N _N is an integer. If the binary notation of _N is 2'_c_e_b_f, the digits _c, _e, _b and _f correspond to the Call, Exit BackTo and Fail respectively, and are 1 (0) if the corresponding port is leashed (unleashed). The initial _l_e_a_s_h_i_n_g _m_o_d_e is `half'. debugging Outputs information concerning the status of the debug- ging package. This will show whether debug mode is on, and if it is C-Prolog User's Manual 54 what spy points have been set what mode of leashing is in force. _5._1_2. _E_n_v_i_r_o_n_m_e_n_t_a_l 'NOLC' Establishes the no lower-case convention described in Section 2.4. 'LC' Establishes the full character set convention described in Section 2.4. It is the default setting. op(_p_r_i_o_r_i_t_y,_t_y_p_e,_n_a_m_e) Treat name _n_a_m_e as an operator of the stated _t_y_p_e and _p_r_i_o_r_i_t_y (refer to Section 2.2). _n_a_m_e may also be a list of names in which case all are to be treated as operators of the stated _t_y_p_e and _p_r_i_o_r_i_t_y. break Causes the current execution to be suspended at the next procedure call. Then the message "[ Break (level 1) ]" is displayed. The interpreter is then ready to accept input as though it was at top level. If another call of break is encountered, it moves up to level 2, and so on. To close the break and resume the execution which was suspended, type the END-OF-INPUT character. Execution will be resumed at the procedure call where it had been suspended. Alter- natively, the suspended execution can be aborted by calling the evaluable predicate abort. Refer to Section 1.9. abort Aborts the current execution taking you back to top level. Refer to Section 1.9. save(_F) The system saves the current state of the system into file _F. Refer to Section 1.6. save(_F,_W_h_e_n) Saves the current state of the system into file _F. When is unified with 0 or 1 depending on whether the C-Prolog User's Manual 55 system is returning from the save goal in the original Prolog session or after the saved state in _F has been restored by invoking Prlog with file _F as argument. prompt(_O_l_d,_N_e_w) The sequence of characters (prompt) which indicates that the system is waiting for user input is represented as an atom, and matched to _O_l_d; the atom bound to _N_e_w specifies the new prompt. In particular, the goal prompt(X,X) matches the current prompt to X, without changing it. Note that this only affects the prompt issued for reads in the user's program; it will not change the propmts used by the system at top level etc. system(_S_t_r_i_n_g) Calls the operating system with string _S_t_r_i_n_g as argu- ment. For example system("ls") will produce a directory listing on UNIX. sh Suspends C-Prolog and enters a recursive command inter- preter. On UNIX, the shell used will be that specified in the environment variable SHELL. statistics Shows the current allocations and amounts used for each of the six working areas of C-Prolog, and also the run- time since C-Prolog started. For example: | ?- statistics. atom space: 64K (15596 bytes used) aux. stack: 8K (0 bytes used) trail: 64K (48 bytes used) heap: 256K (30664 bytes used) global stack: 256K (0 bytes used) local stack: 256K (300 bytes used) Runtime: 1.42 sec. | ?- C-Prolog User's Manual 56 _5._1_3. _P_r_e_p_r_o_c_e_s_s_i_n_g expand_term(_T_1,_T_2) Each top level term _T_1 read when consulting a file is rewritten into _T_2 before being asserted or executed. The default transformations provided by this predicate are the ones for grammar rules and for inline expansion of arithmetic expressions. The user may define further transformations as clauses for the predicate term_expansion/2, which has similar arguments. User defined transformations are applied _b_e_f_o_r_e system- defined ones. C-Prolog User's Manual 57 _A_p_p_e_n_d_i_x _I -- _S_u_m_m_a_r_y _o_f _E_v_a_l_u_a_b_l_e _P_r_e_d_i_c_a_t_e_s abolish(_F,_N) Abolish the procedure named _F arity _N. abort Abort execution of the current directive. arg(_N,_T,_A) The _Nth argument of term _T is _A. assert(_C) Assert clause _C. assert(_C,_R) Assert clause _C, ref. _R. asserta(_C) Assert _C as first clause. asserta(_C,_R) Assert _C as first clause, ref. _R. assertz(_C) Assert _C as last clause. assertz(_C,_R) Assert _C as last clause, ref. _R. atom(_T) Term _T is an atom. atomic(_T) Term _T is an atom or integer. bagof(_X,_P,_B) The bag of _Xs such that _P is provable is _B. break Break at the next procedure call. call(_P) Execute the procedure call _P. clause(_P,_Q) There is a clause, head _P, body _Q. clause(_P,_Q,_R) There is an clause, head _P, body _Q, ref _R. close(_F) Close file _F. compare(_C,_X,_Y) _C is the result of comparing terms _X and _Y. consult(_F) Extend the program with clauses from file _F. current_atom(_A) One of the currently defined atoms is _A. current_functor(_A,_T) A current functor is named _A, m.g. term _T. current_predicate(_A,_P) A current predicate is named _A, m.g. goal _P. db_reference(_T) _T is a database reference. debug Switch on debugging. debugging Output debugging status information. display(_T) Display term _T on the terminal. erase(_R) Erase the clause or record, ref. _R. erased(_R) The object with ref. _R has been erased. expanded_exprs(_O,_N) Expression expansion if _N=on. expand_term(_T,_X) Term _T is a shorthand which expands to term _X. exists(_F) The file _F exists. fail Backtrack immediately. fileerrors Enable reporting of file errors. functor(_T,_F,_N) The top functor of term _T has name _F, arity _N. get(_C) The next non-blank character input is _C. get0(_C) The next character input is _C. halt Halt Prolog, exit to the monitor. instance(_R,_T) A m.g. instance of the record ref. _R is _T. integer(_T) Term _T is an integer. _Y is _X _Y is the value of arithmetic expression _X. keysort(_L,_S) The list _L sorted by key yields _S. leash(_M) Set leashing mode to _M. listing List the current program. listing(_P) List the procedure(s) _P. name(_A,_L) The name of atom or number _A is string _L. nl Output a new line. nodebug Switch off debugging. nofileerrors Disable reporting of file errors. nonvar(_T) Term _T is a non-variable. nospy _P Remove spy-points from the procedure(s) _P. C-Prolog User's Manual 58 number(_T) Term _T is a number. op(_P,_T,_A) Make atom _A an operator of type _T precedence _P. primitive(_T) _T is a number or a database reference print(_T) Portray or else write the term _T. prompt(_A,_B) Change the prompt from _A to _B. put(_C) The next character output is _C. read(_T) Read term _T. reconsult(_F) Update the program with procedures from file _F. recorda(_K,_T,_R) Make term _T the first record under key _K, ref. _R. recorded(_K,_T,_R) Term _T is recorded under key _K, ref. _R. recordz(_K,_T,_R) Make term _T the last record under key _K, ref. _R. rename(_F,_G) Rename file _F to _G. repeat Succeed repeatedly. retract(_C) Erase the first clause of form _C. save(_F) Save the current state of Prolog in file _F. see(_F) Make file _F the current input stream. seeing(_F) The current input stream is named _F. seen Close the current input stream. setof(_X,_P,_B) The set of _Xs such that _P is provable is _B. sh Start a recursive shell skip(_C) Skip input characters until after character _C. sort(_L,_S) The list _L sorted into order yields _S. spy _P Set spy-points on the procedure(s) _P. statistics Display execution statistics. system(_S) Execute command _S. tab(_N) Output _N spaces. tell(_F) Make file _F the current output stream. telling(_F) The current output stream is named _F. told Close the current output stream. trace Switch on debugging and start tracing. true Succeed. var(_T) Term _T is a variable. write(_T) Write the term _T. writeq(_T) Write the term _T, quoting names if necessary. 'LC' The following Prolog text uses lower case. 'NOLC' The following Prolog text uses upper case only. ! Cut any choices taken in the current procedure. \+ _P Goal _P is not provable. _X<_Y As numbers, _X is less than _Y. _X=<_Y As numbers, _X is less than or equal to _Y. _X>_Y As numbers, _X is greater than _Y. _X>=_Y As numbers, _X is greater than or equal to _Y. _X=_Y Terms _X and _Y are equal (i.e. unified). _T=.._L The functor and args. of term _T comprise the list _L. _X==_Y Terms _X and _Y are strictly identical. _X\==_Y Terms _X and _Y are not strictly identical. _X@<_Y Term _X precedes term _Y. _X@=<_Y Term _X precedes or is identical _Y. _X@>_Y Term _X follows term _Y. _X@>=_Y Term _X follows or is identical to term _Y. [_F|_R] Perform the (re)consult(s) specified by [_F|_R].