\chapter{Interface predicate definition} \label{sec:interface} This appendix provides a description of the Prolog predicates to communicate with PCE. Most of these predicates have been introduced informally in the previous sections. \section{Basic predicates} This section describes the basic interface predicates. These predicates reside in the library module `pce', which is loaded when Prolog is started with PCE loaded on top of it. \begin{description} \predicate{new}{2}{?Reference, +TermDescription} Create a \product{} object from \arg{TermDescription} and either unify an integer reference (e.g.\ @2535252) with \arg{Reference} or give the new object the provided atomic reference (e.g. @my_diagram). The argument \arg{TermDescription} is a complex term of the form \mbox{Functor(...InitArg...)}. \arg{Functor} denotes the class from which to create an object and \arg{InitArg} are the initialisation arguments for the object creation. Each \arg{InitArg} is translated to a \product{} data object using the following rules: \begin{itemlist} \item[\var{atom}] Atoms are translated into \product{} \class{name} objects. This is a loss-less transformation. \item[\var{integer}] Prolog integers are translated into \product{} int data-types. The range of \product{} int is half that of Prolog (i.e.\ $\pm 2^30$ on a 32-bit machine). \item[\term{Class}{+InitArg...}] Creates an instance of class \arg{Class} using \arg{InitArg}. \item[\term{new}{+TermDescription}] Same as plain \arg{InitArg}, but an atom is translated to an instance of the named class. E.g.\ the term \exam{new(chain)} is translated to an empty \class{chain} object rather then the atom \const{chain}. \item[\term{new}{?Reference, +TermDescription}] Same as \functor{new}{2}, handling \arg{Reference} the same as the predicate new/2. \item[\term{prolog}{Term}] Pass \arg{Term} as an unmodified Prolog term. \end{itemlist} Below we illustrate the use of embedded \functor{new}{2} terms in \arg{InitArg} to get access to the reference of in-line created objects. The examples are functionally equivalent. \begin{code} 1 ?- new(@icon_viewer, dialog('Icon Viewer 1')), new(P, picture), send(P, below, @icon_viewer), new(TI, text_item(name, '', and(message(P, display, @arg1), message(@arg1, recogniser, new(move_gesture))))), send(TI, type, bitmap), send(@icon_viewer, append, TI), send(@icon_viewer, open). 2 ?- D = @icon_viewer, new(D, dialog('Icon Viewer 1')), send(new(P, picture), below, D), send(D, append, new(TI, text_item(name, '', and(message(P, display, @arg1), message(@arg1, recogniser, new(move_gesture)))))), send(TI, type, bitmap), send(D, open). \end{code} Using new/2 with a variable reference argument is equivalent to invoking `Class <-instance: InitArgs ...'. The arguments needed to instantiate a class are defined by the ->initialise method of this class. See also \secref{classbrowser}. \predicate{send}{2}{+Receiver, +Selector(+Argument...)} % \emptydefinition \predicate{send}{2}{+Receiver, +Selector, +Argument...} Invoke a send-method on the \arg{Receiver}. \arg{Receiver} is processed as the \arg{InitArgs} described with new/2. This implies that a complex term is translated into an object before the method is invoked. An atom is translated into an \product{} name object. \arg{Selector} is a Prolog atom which is translated into a \product{} name object. The \arg{Argument}s are processed as the \arg{InitArgs} described with new/2. The predicate send/[2-12] fails with an error message if one of the arguments cannot be translated or there is a type-error or an argument-error. The method itself may also produce error messages. This predicate only succeeds if the requested method was executed successfully. Trailing arguments that can handle @default (indicated by square brackets in the type declaration) may be omitted. If the method accepts many arguments of which most are default, using the named argument convention may be preferred. For example: \begin{code} ..., send(Graphical, graphics_state, colour := red), ..., \end{code} The first form using \term{Selector}{Argument...} is the principal form. The second is translated by the \productpl{} macro-layer and available for compatibility and style-preference. \predicate{get}{3}{+Receiver, +Selector(+Argument...), -Result} % \emptydefinition \predicate{get}{3}{+Receiver, +Selector, +Argument..., -Result} Invoke a get-method on \arg{Receiver}. \arg{Receiver}, \arg{Selector} and \arg{Argument...} are processed as with send/[2-12]. If the method fails, this predicate fails too. Otherwise the \product{} result of invoking the method is unified with \arg{Result}. If the return value is a \product{} integer, real object or name object, it is unified with a Prolog integer, float or atom. Otherwise if the Prolog return argument is a variable or a term @/1 it is unified with the object reference. Otherwise the Prolog argument should be a compound term. Its functor will be compared with the class-name of the \product{} return value. The arguments will be unified in the same manner with the term-description arguments as declared with the class. Examples: \begin{code} 1 ?- get(@pce, user, User). User = fred 2 ?- get(@display, size, Size). Size = @474573 3 ?- get(@display, size, size(W, H)). W = 1152, H = 900 \end{code} It is not advised to use the latter construct for other objects than elementary objects such as point, area, size, string, etc.. \predicate{free}{1}{+Reference} Send ->free to {\em Reference} if it is a valid reference. Defined as \begin{code} free(Ref) :- object(Ref), !, send(Ref, free). free(_). \end{code} This definition implies free/1 only fails if the object may not be freed (see `object ->protect'). \predicate{send_class}{3}{+Reference, +Class, +Selector(+Arg...)} % \emptydefinition \predicate{get_class}{3}{+Reference, +Class, +Selector(+Arg...), -Result} %\emptydefinition \predicate{send_super}{2}{+Reference, +Selector(+Arg...)} %\emptydefinition \predicate{get_super}{3}{+Reference, +Selector(+Arg...), -Result} %\emptydefinition \predicate{send_super}{2}{+Reference, +Selector, +Arg...} %\emptydefinition \predicate{get_super}{3}{+Reference, +Selector, +Arg..., -Result} The predicates send_class/3 and get_class/4 invoke methods on a super-class of the class \arg{Reference} belongs to. In most cases methods access the {\em immediate} super-class and this is the function of send_super/[2-12] and get_super/[3-13]. The *_super calls are macro-expanded to send_class/3 or get_class/4. They {\bf must} appear within a \product{} class definition. Though not enforced, using any of these predicates or macros outside the context of a method-definition should be considered illegal. See \chapref{udc} for further discussion on defining classes and methods. \predicate{object}{1}{+Reference} Succeeds if \arg{Reference} is a term of the form @/1 and the argument is a valid object reference. Fails silently otherwise. Note that the form @Integer is only save to test whether or not an object has already been freed as a side-effect of freeing another object. Consider the following example: \begin{code} 1 ?- new(P, point(100,100)). P = @235636/point 2 ?- free(@235636). 3 ?- object(@235636). ---> fail 4 ?- new(S, size(50,50)). S = @235636/size \end{code} If ->free is invoked on an object that has no references, its memory will be reclaimed immediately. As long as the memory has not been reused object/1 is guaranteed to fail. If the memory is reused for storing a new object object/1 will succeed, but point to another object than expected. Finally, the memory may be reused by a non-object data structure. In this case object/1 only applies heuristics to detect whether the memory holds an object. See also \secref{debugging} and \secref{global} \predicate{object}{2}{+Reference, -TermDescription} Unify object description with the argument. Normally only used for debugging purposes. Equivalent to: \begin{code} object(Ref, Term) :- object(Ref), get_object(Ref, self, Term). \end{code} \directive{pce_global}{2}{+Reference, :Create} Define exception handler for undefined global (named) reference. When \product{} refers to a non-existing named reference an exception is raised. The standard handler for this exception will scan the pce_global/2 database and execute the \arg{Create} action. \arg{Create} is either a term of the form new(+TermDescription) or another term. In the first case \arg{TermDescription} is transformed into a \product{} object as the second argument of new/2. In the latter case, \arg{Reference} is appended to the list of arguments of the term and the term is called as a Prolog goal: \begin{code} :- pce_global(@succeed, new(and)). :- pce_global(@event_receiver, new(@event?receiver)). :- pce_global(@select_recogniser, make_select_recogniser). make_select_recogniser(R) :- new(G, handler_group), send_list(G, append, [ click_gesture(left, '', single, message(@event_receiver?device, selection, @event_receiver)) , click_gesture(left, s, single, message(@event_receiver, toggle_selected)) ]). \end{code} See \secref{pceprolog} for more examples. \predicate{pce_open}{3}{+Object, +Mode, -Stream} \index{stream,open Object as}% \index{read,text from object}% \index{write,text to object}% \index{open,object as stream}% The predicate pce_open/3 opens an \product{} object as a Prolog stream. Using this stream, the normal Prolog I/O predicates for reading from, or writing to the object can be used. This predicate works on any object that implements the *as_file methods. Currently this is only implemented for class text_buffer. See `text_buffer <-read_as_file', `text_buffer <-size_as_file', `text_buffer ->truncate_as_file' and `text_buffer ->write_as_file'. The stream handle is discarded using Prolog's close/1 predicate. For example, to write to a view, one could use: \begin{code} ... pce_open(View, append, Stream), format(Stream, 'Hello World~n', []), close(View), ... \end{code} See also `text_buffer ->format'. Reading from a stream is used by the PceEmacs editor to verify the syntax of an entered clause. \predicate{pce_catch_error}{2}{+ErrorIds, +Goal} This predicates allows the application to handle errors occuring while \arg{Goal} is called. \arg{ErrorIds} is either an atom representing the id of \product{} error or a chain of such id's. If one of the given errors occurrs the goal will silently fail and `@pce <-last_error' holds the id of the trapped error. Any other error that occurs during the execution of \arg{Goal} will be handled by \product{}'s normal error handling mechanism. See \secref{errors}. \end{description} \subsection{Portable declaration of required library predicates} \label{sec:require} Different Prolog implementations to which \product{} has been connected provide a different library structure and offers different means for accessing library predicates. For this reason, \product{} introduced the require/1 directive. This directive is the preferred way to import library predicates. Below is a typical declaration of an \productpl{} module: \begin{code} :- module(mymodule, [myapp/0]). :- use_module(library(pce)). :- require([ member/2, send_list/3 ]). \end{code} \begin{description} \predicate{require}{1}{:ListOfNameArity} Defines that this module requires the named predicates. It is the task of the Prolog system to make sure the module can make calls to the named predicates and this predicate has the `commonly accepted semantics'. This predicate is built-in for SICStus and SWI-Prolog. It is defined in the module library(pce) for ProWindows-3/Quintus. This is the reason why library(pce) should always be imported explicitely. Note the command Pce/PceInsertRequireDirective in PceEmacs Prolog mode, which automatically determines the required require-directive for the current module-file. \predicate{auto_call}{1}{:Goal} Acts like call/1, but dynamically loads the predicate required by {\em Goal} if this predicate is not defined. On systems not having autoloading, the definition is: \begin{code} auto_call(Goal) :- strip_module(Goal, Module, Predicate), functor(Predicate, Name, Arity), require(Module:[Name/Arity]), Goal. \end{code} \end{description} \section{Additional interface libraries} \index{autoloading}% This section describes Some of the predicates available from the \product{}/Prolog library. \subsection{Library ``pce_util''} The predicates in this section used to be \product{} principal predicates. Changes to \product{}, the interface and our current understanding about programming the \product{}/Prolog environment have made these predicates less important. \begin{description} \predicate{send_list}{2,3}{+Receiver, +Selector [, +Argument]} Invoke send-behaviour as send/[2-12]. Each of the arguments is either as accepted by send/[2-12] or a list of such arguments. The definition of send_list/2 is below. \begin{code} send_list([], _) :- !. send_list(_, []) :- !. send_list([Object|Objects], Selectors) :- !, send_list(Object, Selectors), send_list(Objects, Selectors). send_list(Object, [Selector|Selectors]) :- !, send_list(Object, Selector), send_list(Object, Selectors). send_list(Object, Selector) :- send(Object, Selector). \end{code} Note that, since send/2 accepts \term{Selector}{Arg...} the following is now valid code: \begin{code} ..., send_list(Box, [ colour(red), fill_pattern(colour(greed)) ]), \end{code} \predicate{get_object}{[3-13]}{+Receiver, +Selector, +Argument..., -Result} Equivalent to get/[3-13], but instead of unifying a variable with a reference the variable is unified with the term-description. The arguments are unified as in get/[3-13]. Normally only used from the Prolog top level for debugging purposes. \predicate{chain_list}{2}{?Chain, ?List} Converts between a \product{} chain and a Prolog list. This may be useful to exploit Prolog's list-processing primitives. Note however that \product{} chains define various operations that may be exploited to avoid the translation. Suppose `Pict' is a picture and `Pos' is a point object. We want to determine the topmost graphical object overlapping with `Pos'. The following two programs are identical: \begin{code} topmost_graphical(Pict, Pos, Gr) :- get(Pict, graphicals, Grs0), chain_list(Grs0, Grs1), topmost(Grs1, Pos, @nil, Gr), Gr \== @nil. topmost([], _, Gr, Gr). topmost([H|T], Pos, _, Gr) :- send(H, overlap, Pos), !, topmost(T, Pos, H, Gr). topmost([_|T], Pos, Gr0, Gr) :- topmost(T, Pos, Gr0, Gr). \end{code} Or, using \product{}'s list processing: \begin{code} topmost_graphical(Dev, Pos, Gr) :- get(Dev, graphicals, Grs), get(Grs, find_all, message(@arg1, overlap, Pos), O), get(O, tail, Gr), send(O, done). \end{code} The second implementation is not only shorter, it also requires far less data conversions between Prolog and \product{} and is therefore much faster. \predicate{get_chain}{3}{+Receiver, +Selector, -List} Utility predicate implemented as: \begin{code} get_chain(Receiver, Selector, List) :- get(Receiver, Selector, Chain), chain_list(Chain, List). \end{code} See comments with chain_list/2. \end{description} \subsection{Library ``pce_debug''} The predicates in this section provide shorthands for common commands for debugging \product{} programs. See \secref{debugging} for more information on debugging \productpl{} programs. \begin{description} \predicate{tracepce}{1}{+Class {\tt \string<-|->|-} Selector} Find send- (\verb!->!), get- (\verb!<-!) method or variable (\verb!-!) and cause invocations thereof to be printed on the console. Syntax note: (\verb!->!) is a standard Prolog operator with $priority > 1000$. Therefore many Prolog systems require additional brackets: \begin{code} 1 ?- tracepce((graphical ->selected)). \end{code} In SWI-Prolog this is not necessary. To be able to trace get-methods with this predicate (\verb!<-!) must be declared as an infix operator. \predicate{notracepce}{1}{+Class {\tt \string<-|->|-} Selector} Disables trace-point set with tracepce/1. \predicate{checkpce}{0}{} Collect all global (named-) objects and run `object ->_check' on them. This performs various consistency checks on the objects and prints diagnostic messages if something is wrong. `object ->_check' checks all objects it can (recursively) find through slot-references, chains, vectors and hash-tables and deals properly with loops in the data-structure. \predicate{show_slots}{1}{+Reference} Prints the values of all instance variables of \arg{Reference}: \begin{code} 1 ?- new(@move_gesture, move_gesture). 2 ?- show_slots(@move_gesture). @move_gesture/move_gesture active @on/bool button middle modifier @810918/modifier condition @nil/constant status inactive cursor @default/constant offset @548249/point \end{code} A graphical tool for inspecting instance variables is described in \secref{inspector}. \end{description} \subsection{Accessing the \product{} manual} \label{sec:manpce} \begin{description} \predicate{manpce}{0}{} Start the \product{} online manual tools. This opens a small GUI console at the top-left of the screen, providing access to the manual, demo programs and tools described in this manual. See \chapref{online}. \predicate{manpce}{1}{+Spec} As manpce/0, but immediately opens the the manual from \arg{Spec}. \arg{Spec} is either a class-name, opening the ClassBrowser, or a term \mbox{Class {\tt \string<-|->|-} Selector} (see tracepce/1) to open the manual-card of the specified behaviour. Examples: \begin{code} 1 ?- manpce(box). 2 ?- manpce((view->caret)). \end{code} \end{description}