<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <HTML> <HEAD> <TITLE>Programming in XPCE/Prolog: Section D.1</TITLE><LINK REL=home HREF="index.html"> <LINK REL=contents HREF="Contents.html"> <LINK REL=index HREF="DocIndex.html"> <LINK REL=summary HREF="summary.html"> <LINK REL=previous HREF="interface.html"> <LINK REL=next HREF="sec-D.2.html"> <STYLE type="text/css"> /* Style sheet for SWI-Prolog latex2html */ dd.defbody { margin-bottom: 1em; } dt.pubdef { background-color: #c5e1ff; } pre.code { margin-left: 1.5em; margin-right: 1.5em; border: 1px dotted; padding-top: 5px; padding-left: 5px; padding-bottom: 5px; background-color: #f8f8f8; } div.navigate { text-align: center; background-color: #f0f0f0; border: 1px dotted; padding: 5px; } div.title { text-align: center; padding-bottom: 1em; font-size: 200%; font-weight: bold; } div.author { text-align: center; font-style: italic; } div.abstract { margin-top: 2em; background-color: #f0f0f0; border: 1px dotted; padding: 5px; margin-left: 10%; margin-right:10%; } div.abstract-title { text-align: center; padding: 5px; font-size: 120%; font-weight: bold; } div.toc-h1 { font-size: 200%; font-weight: bold; } div.toc-h2 { font-size: 120%; font-weight: bold; margin-left: 2em; } div.toc-h3 { font-size: 100%; font-weight: bold; margin-left: 4em; } div.toc-h4 { font-size: 100%; margin-left: 6em; } span.sec-nr { } span.sec-title { } span.pred-ext { font-weight: bold; } /* Footnotes */ sup.fn { color: blue; text-decoration: underline; } span.fn-text: { display: none; } sup.fn span {display: none;} sup:hover span { display: block !important; position: absolute; top: auto; left: auto; width: 80%; color: #000; background: white; border: 2px solid; padding: 5px; margin: 10px; z-index: 100; font-size: smaller; } </STYLE> </HEAD> <BODY BGCOLOR="white"> <DIV class="navigate"><A class="nav" href="index.html"><IMG SRC="home.gif" BORDER=0 ALT="Home"></A> <A class="nav" href="Contents.html"><IMG SRC="index.gif" BORDER=0 ALT="Contents"></A> <A class="nav" href="DocIndex.html"><IMG SRC="yellow_pages.gif" BORDER=0 ALT="Index"></A> <A class="nav" href="summary.html"><IMG SRC="info.gif" BORDER=0 ALT="Summary"></A> <A class="nav" href="interface.html"><IMG SRC="prev.gif" BORDER=0 ALT="Previous"></A> <A class="nav" href="sec-D.2.html"><IMG SRC="next.gif" BORDER=0 ALT="Next"></A> </DIV> <H2><A NAME="sec:D.1"><SPAN class="sec-nr">D.1</SPAN> <SPAN class="sec-title">Basic predicates</SPAN></A></H2> <P>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. <DL> <DT class="pubdef"><A NAME="new/2"><STRONG>new</STRONG>(<VAR>?Reference, +TermDescription</VAR>)</A></DT> <DD class="defbody"> Create a <font size=-1>XPCE</font> object from <VAR>TermDescription</VAR> and either unify an integer reference (e.g. <A NAME="idx:2535252:652"></A><B>@2535252</B>) with <VAR>Reference</VAR> or give the new object the provided atomic reference (e.g. <A NAME="idx:mydiagram:653"></A><B>@my_diagram</B>). The argument <VAR>TermDescription</VAR> is a complex term of the form Functor(...InitArg...) . <VAR>Functor</VAR> denotes the class from which to create an object and <VAR>InitArg</VAR> are the initialisation arguments for the object creation. Each <VAR>InitArg</VAR> is translated to a <font size=-1>XPCE</font> data object using the following rules: <P> <UL> <LI><I><VAR>atom</VAR></I><BR> Atoms are translated into <font size=-1>XPCE</font> <A class="" href="summary.html#class:name">name</A> objects. This is a loss-less transformation. <LI><I><VAR>integer</VAR></I><BR> Prolog integers are translated into <font size=-1>XPCE</font> int data-types. The range of <font size=-1>XPCE</font> int is half that of Prolog (i.e. <VAR>±2^30</VAR> on a 32-bit machine). <LI><I><CODE>Class(+InitArg...)</CODE></I><BR> Creates an instance of class <VAR>Class</VAR> using <VAR>InitArg</VAR>. <LI><I><CODE>new(+TermDescription)</CODE></I><BR> Same as plain <VAR>InitArg</VAR>, but an atom is translated to an instance of the named class. E.g. the term <CODE>new(chain)</CODE> is translated to an empty <A class="" href="summary.html#class:chain">chain</A> object rather then the atom <CODE>chain</CODE>. <LI><I><CODE>new(?Reference, +TermDescription)</CODE></I><BR> Same as new/2 , handling <VAR>Reference</VAR> the same as the predicate <A NAME="idx:new2:654"></A><A class="pred" href="sec-D.1.html#new/2">new/2</A>. <LI><I><CODE>prolog(Term)</CODE></I><BR> Pass <VAR>Term</VAR> as an unmodified Prolog term. </UL> <P>Below we illustrate the use of embedded new/2 terms in <VAR>InitArg</VAR> to get access to the reference of in-line created objects. The examples are functionally equivalent. <PRE class="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). </PRE> <P>Using <A NAME="idx:new2:655"></A><A class="pred" href="sec-D.1.html#new/2">new/2</A> with a variable reference argument is equivalent to invoking <A NAME="idx:classgetinstance:656"></A>`<B>Class<CODE><-</CODE>instance</B>: InitArgs ...'. The arguments needed to instantiate a class are defined by the <B><CODE>-></CODE>initialise</B> method of this class. See also <A class="sec" href="sec-3.3.html">section 3.3.1</A>.</DD> <DT class="pubdef"><A NAME="send/2"><STRONG>send</STRONG>(<VAR>+Receiver, +Selector(+Argument...)</VAR>)</A></DT> <DD class="defbody"> </DD> <DT class="pubdef"><A NAME="send/2"><STRONG>send</STRONG>(<VAR>+Receiver, +Selector, +Argument...</VAR>)</A></DT> <DD class="defbody"> Invoke a send-method on the <VAR>Receiver</VAR>. <VAR>Receiver</VAR> is processed as the <VAR>InitArgs</VAR> described with <A NAME="idx:new2:657"></A><A class="pred" href="sec-D.1.html#new/2">new/2</A>. This implies that a complex term is translated into an object before the method is invoked. An atom is translated into an <font size=-1>XPCE</font> name object. <VAR>Selector</VAR> is a Prolog atom which is translated into a <font size=-1>XPCE</font> name object. The <VAR>Argument</VAR>s are processed as the <VAR>InitArgs</VAR> described with <A NAME="idx:new2:658"></A><A class="pred" href="sec-D.1.html#new/2">new/2</A>. <P>The predicate <A NAME="idx:send212:659"></A><A class="pred" href="sec-7.1.html#send/[2-12]">send/[2-12]</A> 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. <P>Trailing arguments that can handle <A NAME="idx:default:660"></A><B>@default</B> (indicated by square brackets in the type declaration) may be omitted. <P>If the method accepts many arguments of which most are default, using the named argument convention may be preferred. For example: <PRE class="code"> ..., send(Graphical, graphics_state, colour := red), ..., </PRE> <P>The first form using <CODE>Selector(Argument...)</CODE> is the principal form. The second is translated by the <font size=-1>XPCE/P</font>rolog macro-layer and available for compatibility and style-preference.</DD> <DT class="pubdef"><A NAME="get/3"><STRONG>get</STRONG>(<VAR>+Receiver, +Selector(+Argument...), -Result</VAR>)</A></DT> <DD class="defbody"> </DD> <DT class="pubdef"><A NAME="get/3"><STRONG>get</STRONG>(<VAR>+Receiver, +Selector, +Argument..., -Result</VAR>)</A></DT> <DD class="defbody"> Invoke a get-method on <VAR>Receiver</VAR>. <VAR>Receiver</VAR>, <VAR>Selector</VAR> and <VAR>Argument...</VAR> are processed as with <A NAME="idx:send212:661"></A><A class="pred" href="sec-7.1.html#send/[2-12]">send/[2-12]</A>. If the method fails, this predicate fails too. Otherwise the <font size=-1>XPCE</font> result of invoking the method is unified with <VAR>Result</VAR>. <P>If the return value is a <font size=-1>XPCE</font> 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 <font size=-1>XPCE</font> return value. The arguments will be unified in the same manner with the term-description arguments as declared with the class. Examples: <PRE class="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 </PRE> <P>It is not advised to use the latter construct for other objects than elementary objects such as point, area, size, string, etc..</DD> <DT class="pubdef"><A NAME="free/1"><STRONG>free</STRONG>(<VAR>+Reference</VAR>)</A></DT> <DD class="defbody"> Send <B><CODE>-></CODE>free</B> to <EM>Reference</EM> if it is a valid reference. Defined as <PRE class="code"> free(Ref) :- object(Ref), !, send(Ref, free). free(_). </PRE> <P>This definition implies <A NAME="idx:free1:662"></A><A class="pred" href="sec-D.1.html#free/1">free/1</A> only fails if the object may not be freed (see <A NAME="idx:objectsendprotect:663"></A>`<B>object<CODE>-></CODE>protect</B>').</DD> <DT class="pubdef"><A NAME="send_class/3"><STRONG>send_class</STRONG>(<VAR>+Reference, +Class, +Selector(+Arg...)</VAR>)</A></DT> <DD class="defbody"> </DD> <DT class="pubdef"><A NAME="get_class/3"><STRONG>get_class</STRONG>(<VAR>+Reference, +Class, +Selector(+Arg...), -Result</VAR>)</A></DT> <DD class="defbody"> </DD> <DT class="pubdef"><A NAME="send_super/2"><STRONG>send_super</STRONG>(<VAR>+Reference, +Selector(+Arg...)</VAR>)</A></DT> <DD class="defbody"> </DD> <DT class="pubdef"><A NAME="get_super/3"><STRONG>get_super</STRONG>(<VAR>+Reference, +Selector(+Arg...), -Result</VAR>)</A></DT> <DD class="defbody"> </DD> <DT class="pubdef"><A NAME="send_super/2"><STRONG>send_super</STRONG>(<VAR>+Reference, +Selector, +Arg...</VAR>)</A></DT> <DD class="defbody"> </DD> <DT class="pubdef"><A NAME="get_super/3"><STRONG>get_super</STRONG>(<VAR>+Reference, +Selector, +Arg..., -Result</VAR>)</A></DT> <DD class="defbody"> The predicates <A NAME="idx:sendclass3:664"></A><A class="pred" href="sec-7.3.html#send_class/3">send_class/3</A> and <A NAME="idx:getclass4:665"></A><A class="pred" href="sec-7.3.html#get_class/4">get_class/4</A> invoke methods on a super-class of the class <VAR>Reference</VAR> belongs to. In most cases methods access the <EM>immediate</EM> super-class and this is the function of <A NAME="idx:sendsuper212:666"></A><A class="pred" href="sec-7.3.html#send_super/2">send_super/[2-12]</A> and <A NAME="idx:getsuper313:667"></A><A class="pred" href="sec-7.3.html#get_super/3">get_super/[3-13]</A>. <P>The *_super calls are macro-expanded to <A NAME="idx:sendclass3:668"></A><A class="pred" href="sec-7.3.html#send_class/3">send_class/3</A> or <A NAME="idx:getclass4:669"></A><A class="pred" href="sec-7.3.html#get_class/4">get_class/4</A>. They <B>must</B> appear within a <font size=-1>XPCE</font> class definition. Though not enforced, using any of these predicates or macros outside the context of a method-definition should be considered illegal. See <A class="sec" href="udc.html">chapter 7</A> for further discussion on defining classes and methods.</DD> <DT class="pubdef"><A NAME="object/1"><STRONG>object</STRONG>(<VAR>+Reference</VAR>)</A></DT> <DD class="defbody"> Succeeds if <VAR>Reference</VAR> is a term of the form @/1 and the argument is a valid object reference. Fails silently otherwise. Note that the form <A NAME="idx:Integer:670"></A><B>@Integer</B> 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: <PRE class="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 </PRE> <P>If <B><CODE>-></CODE>free</B> is invoked on an object that has no references, its memory will be reclaimed immediately. As long as the memory has not been reused <A NAME="idx:object1:671"></A><A class="pred" href="sec-D.1.html#object/1">object/1</A> is guaranteed to fail. If the memory is reused for storing a new object <A NAME="idx:object1:672"></A><A class="pred" href="sec-D.1.html#object/1">object/1</A> will succeed, but point to another object than expected. Finally, the memory may be reused by a non-object data structure. In this case <A NAME="idx:object1:673"></A><A class="pred" href="sec-D.1.html#object/1">object/1</A> only applies heuristics to detect whether the memory holds an object. See also <A class="sec" href="debugging.html">section 12</A> and <A class="sec" href="namedref.html">section 10.3.3</A></DD> <DT class="pubdef"><A NAME="object/2"><STRONG>object</STRONG>(<VAR>+Reference, -TermDescription</VAR>)</A></DT> <DD class="defbody"> Unify object description with the argument. Normally only used for debugging purposes. Equivalent to: <PRE class="code"> object(Ref, Term) :- object(Ref), get_object(Ref, self, Term). </PRE> </DD> <DT class="pubdef"><A NAME="pce_global/2"><STRONG>pce_global</STRONG>(<VAR>+Reference, :Create</VAR>)</A></DT> <DD class="defbody"> Define exception handler for undefined global (named) reference. When <font size=-1>XPCE</font> refers to a non-existing named reference an exception is raised. The standard handler for this exception will scan the <A NAME="idx:pceglobal2:674"></A><A class="pred" href="sec-D.1.html#pce_global/2">pce_global/2</A> database and execute the <VAR>Create</VAR> action. <VAR>Create</VAR> is either a term of the form new(+TermDescription) or another term. In the first case <VAR>TermDescription</VAR> is transformed into a <font size=-1>XPCE</font> object as the second argument of <A NAME="idx:new2:675"></A><A class="pred" href="sec-D.1.html#new/2">new/2</A>. In the latter case, <VAR>Reference</VAR> is appended to the list of arguments of the term and the term is called as a Prolog goal: <PRE class="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)) ]). </PRE> <P>See <A class="sec" href="pceprolog.html">section 6</A> for more examples.</DD> <DT class="pubdef"><A NAME="pce_open/3"><STRONG>pce_open</STRONG>(<VAR>+Object, +Mode, -Stream</VAR>)</A></DT> <DD class="defbody"> <A NAME="idx:streamopenObjectas:676"></A><A NAME="idx:readtextfromobject:677"></A><A NAME="idx:writetexttoobject:678"></A><A NAME="idx:openobjectasstream:679"></A>The predicate <A NAME="idx:pceopen3:680"></A><A class="pred" href="sec-D.1.html#pce_open/3">pce_open/3</A> opens an <font size=-1>XPCE</font> 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. <P>This predicate works on any object that implements the *as_file methods. Currently this is only implemented for class text_buffer. See <A NAME="idx:textbuffergetreadasfile:681"></A>`<B>text_buffer<CODE><-</CODE>read_as_file</B>', <A NAME="idx:textbuffergetsizeasfile:682"></A>`<B>text_buffer<CODE><-</CODE>size_as_file</B>', `text_buffer <B><CODE>-></CODE>truncate_as_file</B>' and <A NAME="idx:textbuffersendwriteasfile:683"></A>`<B>text_buffer<CODE>-></CODE>write_as_file</B>'. <P>The stream handle is discarded using Prolog's <A NAME="idx:close1:684"></A><SPAN class="pred-ext">close/1</SPAN> predicate. For example, to write to a view, one could use: <PRE class="code"> ... pce_open(View, append, Stream), format(Stream, 'Hello World~n', []), close(View), ... </PRE> <P>See also <A NAME="idx:textbuffersendformat:685"></A>`<B>text_buffer<CODE>-></CODE>format</B>'. Reading from a stream is used by the PceEmacs editor to verify the syntax of an entered clause.</DD> <DT class="pubdef"><A NAME="pce_catch_error/2"><STRONG>pce_catch_error</STRONG>(<VAR>+ErrorIds, +Goal</VAR>)</A></DT> <DD class="defbody"> This predicates allows the application to handle errors occuring while <VAR>Goal</VAR> is called. <VAR>ErrorIds</VAR> is either an atom representing the id of <font size=-1>XPCE</font> error or a chain of such id's. If one of the given errors occurrs the goal will silently fail and <A NAME="idx:objectnamepcegetlasterror:686"></A>`<B><B>@pce</B><CODE><-</CODE>last_error</B>' holds the id of the trapped error. Any other error that occurs during the execution of <VAR>Goal</VAR> will be handled by <font size=-1>XPCE</font>'s normal error handling mechanism. See <A class="sec" href="errors.html">section 10.8</A>. </DD> </DL> <H3><A NAME="sec:D.1.1"><SPAN class="sec-nr">D.1.1</SPAN> <SPAN class="sec-title">Portable declaration of required library predicates</SPAN></A></H3> <A NAME="sec:require"></A> <P>Different Prolog implementations to which <font size=-1>XPCE</font> has been connected provide a different library structure and offers different means for accessing library predicates. For this reason, <font size=-1>XPCE</font> introduced the <A NAME="idx:require1:687"></A><A class="pred" href="sec-D.1.html#require/1">require/1</A> directive. This directive is the preferred way to import library predicates. Below is a typical declaration of an <font size=-1>XPCE/P</font>rolog module: <PRE class="code"> :- module(mymodule, [myapp/0]). :- use_module(library(pce)). :- require([ member/2, send_list/3 ]). </PRE> <DL> <DT class="pubdef"><A NAME="require/1"><STRONG>require</STRONG>(<VAR>:ListOfNameArity</VAR>)</A></DT> <DD class="defbody"> 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. <P>Note the command Pce/PceInsertRequireDirective in PceEmacs Prolog mode, which automatically determines the required require-directive for the current module-file. </DD> <DT class="pubdef"><A NAME="auto_call/1"><STRONG>auto_call</STRONG>(<VAR>:Goal</VAR>)</A></DT> <DD class="defbody"> Acts like <A NAME="idx:call1:688"></A><SPAN class="pred-ext">call/1</SPAN>, but dynamically loads the predicate required by <EM>Goal</EM> if this predicate is not defined. On systems not having autoloading, the definition is: <PRE class="code"> auto_call(Goal) :- strip_module(Goal, Module, Predicate), functor(Predicate, Name, Arity), require(Module:[Name/Arity]), Goal. </PRE> <P></DD> </DL> <P></BODY></HTML>