1% BEGIN LICENSE BLOCK
2% Version: CMPL 1.1
3%
4% The contents of this file are subject to the Cisco-style Mozilla Public
5% License Version 1.1 (the "License"); you may not use this file except
6% in compliance with the License.  You may obtain a copy of the License
7% at www.eclipse-clp.org/license.
8% 
9% Software distributed under the License is distributed on an "AS IS"
10% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11% the License for the specific language governing rights and limitations
12% under the License. 
13% 
14% The Original Code is  The ECLiPSe Constraint Logic Programming System. 
15% The Initial Developer of the Original Code is  Cisco Systems, Inc. 
16% Portions created by the Initial Developer are
17% Copyright (C) 1988 - 2006 Cisco Systems, Inc.  All Rights Reserved.
18% 
19% Contributor(s): David Miller / Joachim Schimpf, ECRC 
20% 
21% END LICENSE BLOCK
22
23%
24
25%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
26% \eclipse Documentation
27%
28% umsmacros.tex
29%
30% REL	DATE	AUTHOR		DESCRIPTION
31% 2.10	090489	David Miller	Update for Latex
32% 3.0	140590	Joachim Schimpf	Update for 3.0
33%
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35% \comment{@(\#)appendices.mss	20.3 9/19/88}
36% \part{appendices, root = `manual.mss'}
37% \pageheading{Odd, Right `\title{Chapter}'}
38% \pageheading{Even, Left `Appendix \ref{Chapter}'}
39
40\chapter{'C' Macros used in External Built-In Predicates}
41\label{chapcmacros}
42
43The following is a summary of the macros used in the C code implementing
44most of the {\eclipse} built-in predicates.
45This set of macros was historically the first "external predicate
46programming interface", but was later replaced by the safer "embedding
47interface" described in the Embedding Manual.
48The built-in predicates implemented in C still use this old, lower
49level interface.
50
51TAt least the following set of include files
52must be included at the start of any file containing external predicate
53definitions:
54\begin{quote}
55\begin{verbatim}
56#include  "config.h"
57#include  "sepia.h"
58#include  "types.h"
59#include  "error.h"
60#include  "dict.h"
61\end{verbatim}
62\end{quote}
63
64\newpage
65\section{Returns}
66The following macros contain a {\tt return} statement and so they
67cannot be used inside nested functions called by the external procedure.
68
69\noindent
70 \\
71\begin{tabular}{|p{5cm}p{10cm}|} 
72\hline
73{\tt Succeed_} & return from procedure successfully.\\  
74
75{\tt Fail_} & return from procedure as a failure.\\ 
76
77{\tt Succeed_If(expr)} &
78return successfully iff {\tt expr} is true, fail otherwise.\\
79
80{\tt Succeed_Last} &
81returns successfully from a backtrackable predicate.\\
82
83{\tt Bip_Error(code)} &
84abnormal return from procedure. {\tt code} is one of the
85error codes defined in `error.h'. The most commonly used will be:
86\begin{itemize}
87\item SYS_ERROR --- operating system error.
88\item INSTANTIATION_FAULT --- unexpected variable.
89\item TYPE_ERROR --- wrong type.
90\item RANGE_ERROR --- out of range.
91\item ARITH_EXCEPTION --- e.g.\ division by 0.
92\end{itemize}
93\\
94
95{\tt Set_Errno} &
96used when the system variable {\tt errno} contains the error code
97of a system call, before the predicate returns using
98{\tt Error(SYS_ERROR)}.\\
99\hline
100\end{tabular}
101
102%\newpage
103
104\section{Dereferencing}
105A variable should be dereferenced before being used. The following
106macro makes sure that a pointer points to the end of a reference
107chain, if there is any.
108
109\noindent
110 \\
111\begin{tabular}{|p{5cm}p{10cm}|} 
112\hline
113{\tt Dereference_(ref)} & 
114{\tt ref} is a pointer to a {\tt pword} structure.
115If this {\tt pword} is not a reference,
116nothing is done. If the pointed {\tt pword} is a reference, 
117this macro follows 
118the whole reference chain and changes the value of {\tt ref}
119so that it points to the chain end.
120If {\tt ref} or the end of the reference chain is a free variable, 
121{\tt ref} will point to the variable itself. The arguments of
122external predicates are dereferenced before being passed to the 
123predicate, so there is no need to dereference them again.
124The compound arguments, on the other hand, may contain
125subarguments that might have to be dereferenced.
126Since the value of {\tt ref} may be changed by this macro, it might
127be necessary to save its previous value. \\
128\hline
129\end{tabular}
130
131\newpage
132\section{Type Checking}
133When checking the type, do the following :
134\begin{itemize}
135\item dereference the value; this is not necessary for the arguments
136of the external predicate. 
137
138%\item check for a reference, using {\tt IsRef()}. 
139
140\item check for the type. 
141\end{itemize}
142When the tag is been compared directly to a tag value (in the 
143{\tt switch} statement), the macro {\tt Ptag(tag.kernel)} must be used.
144The following macros return true if their argument (a tag) is of the correct 
145type.
146
147\noindent
148 \\
149\begin{tabular}{|p{5cm}p{10cm}|} 
150\hline
151{\tt IsRef(tag)} &	a reference or variable (self reference). \\
152{\tt IsVar(tag)} &	a simple variable. \\
153{\tt IsName(tag)} &	a named variable. \\
154{\tt IsMeta(tag)} &	a metaterm (attributed variable). \\
155
156{\tt IsList(tag)} & 	a pair, i.e.\ a nonempty list. \\
157
158{\tt IsStructure(tag)} & a compound term (not a list). \\ 
159
160{\tt IsString(tag)} & a string. \\
161
162{\tt IsNil(tag)} &	{\it nil}. \\
163
164{\tt IsInteger(tag)} & an integer. \\
165
166{\tt IsFloat(tag)} &	single precision float number. \\
167
168{\tt IsDouble(tag)} &	double precision float number. \\
169{\tt IsBignum(tag)} &	large integer number. \\
170{\tt IsRational(tag)} &	rational number. \\
171{\tt IsInterval(tag)} &	 breal number. \\
172
173{\tt IsAtom(tag)} & an atom. \\
174
175{\tt IsSimple(tag)} &	
176a term which is uniquely defined by its tag and value and so a comparison with
177another term has just to check these two. Other terms, namely compound
178terms and strings need to compare more than just the tag and value.\\
179
180{\tt IsCompound(tag)} & a compound term (i.e.\ a structure or a list). \\
181
182{\tt IsNumber(tag)} &	any nof the numeric types. \\
183
184{\tt SameType(t1, t2)} & true if the arguments have the same type. \\
185\hline
186\end{tabular}
187
188%\newpage
189
190\section{Type requirements}
191The following macros test the type of Prolog words and return
192with an error if the type is not correct.
193They must not be used inside nested functions, unless their
194return code is correctly passed back to the system.
195
196\noindent
197 \\
198\begin{tabular}{|ll|} 
199\hline
200{\tt Error_If_Ref(tag)} & 
201return with an instantiation fault if argument is a variable. \\
202
203{\tt Check_Ref(tag)} & 
204return with an instantiation fault if argument is not a \\
205& \ \ variable. \\
206
207{\tt Check_List(tag)} & 
208return with an instantiation fault if argument is a variable, \\
209& \ \ otherwise with a type error if argument is not a list. \\
210
211{\tt Check_Pair(tag)} & 
212return with an instantiation fault if argument is a variable, \\
213& \ \ otherwise with a type error if it is not a non NIL list. \\
214
215{\tt Check_Structure(tag)} & 
216return with an instantiation fault if argument is a variable, \\
217& \ \ otherwise with a type error if it is not a structure. \\
218
219{\tt Check_String(tag)} & 
220return with an instantiation fault if argument is a variable, \\
221& \ \ otherwise with a type error if it is not a string. \\
222
223{\tt Check_Nil(tag)} & 
224return with an instantiation fault if argument is a variable, \\
225& \ \ otherwise with a type error if it is not a nil list. \\
226
227{\tt Check_Integer(tag)} & 
228return with an instantiation fault if argument is a variable, \\
229& \ \ otherwise with a type error if it is not an integer. \\
230
231{\tt Check_Float(tag)} & 
232return with an instantiation fault if argument is a variable, \\
233& \ \ otherwise with a type error if it is not a float. \\
234
235{\tt Check_Atom(tag)} & 
236return with an instantiation fault if argument is a variable, \\
237& \ \ otherwise with a type error if it is not an atom. \\
238
239{\tt Check_Atom_Or_Nil(val, tag)} & 
240return with an instantiation fault if the prolog term \\
241& \ \ represented by the two arguments is a variable, \\
242& \ \ otherwise with a type error if it is not an atom or the \\
243& \ \ null list. \\
244
245{\tt Check_Output_List(tag)} & 
246return with a type error if argument is not a list or a free \\
247& \ \ variable. \\
248
249{\tt Check_Output_Pair(tag)} & 
250return with a type error if argument is not a non NIL list \\
251& \ \ or a free variable. \\
252
253{\tt Check_Output_Structure(tag)} & 
254return with a type error if argument is not a structure or \\
255& \ \ a free variable. \\
256
257{\tt Check_Output_String(tag)} & 
258return with a type error if argument is not a string or a \\
259& \ \ free variable. \\
260
261{\tt Check_Output_Nil(tag)} & 
262return with a type error if argument is not a nil list or a \\
263& \ \ free variable. \\
264
265{\tt Check_Output_Integer(tag)} & 
266return with a type error if argument is not an integer or \\
267& \ \ a free variable. \\
268
269{\tt Check_Output_Float(tag)} & 
270return with a type error if argument is not a float or a \\
271& \ \ free variable. \\
272
273{\tt Check_Output_Atom(tag)} & 
274return with a type error if argument is not an atom or a \\
275& \ \ free variable. \\
276\hline
277\end{tabular}
278
279%\newpage
280
281\section{Unification}
282The macros {\tt Return_Unify_} are used to unify two terms.
283They cause an exit from the external predicate and so they must
284not be used inside nested function calls.
285If the unification of the two terms succeeds, so does the
286external predicate, otherwise it fails.
287
288\noindent
289 \\
290\begin{tabular}{|lp{7.3cm}|} 
291\hline
292{\tt Return_Unify_Integer(val, tag, int)} 
293& unifies a general prolog term with an integer number. \\
294
295{\tt Return_Unify_Float(val, tag, float)} 
296& unifies a general prolog term with an float. \\
297
298{\tt Return_Unify_Atom(val, tag, atom)} 
299& unifies a general prolog term with an atom. \\
300
301{\tt Return_Unify_Nil(val, tag)} 
302& unifies a general prolog term with the null list. \\
303
304{\tt Return_Unify_String(val, tag, ptr)} 
305& unifies a general prolog term with a pointer to an \eclipse string. \\
306
307{\tt Return_Unify_List(val, tag, listptr)} 
308& unifies a general prolog term with a list. \\
309
310{\tt Return_Unify_Structure(val, tag, strptr)} 
311& unifies a general prolog term with a struc\-tu\-re. \\ 
312
313{\tt Return_Unify_Pw(val1, tag1, val2, tag2)} 
314& unify two general Prolog terms. To be used if
315the type of neither of the two terms is
316known. \\
317\hline
318\end{tabular}
319
320\vspace*{0.5cm}
321
322The macros {\tt Request_Unify_} can be used to unify any number
323of term pairs.
324To be able to use it, the macro
325{\tt Prepare_Requests} must appear inside the declaration
326part of the external procedure,
327and the exit from the external procedure must be made
328through the use of the macro {\tt Return_Unify}.
329After the return to the system, all the specified term pairs
330are unified.
331If all these unifications succeed, so does the external predicate,
332otherwise it fails.
333
334\noindent
335 \\
336\begin{tabular}{|p{8.3cm}p{7.0cm}|} 
337\hline
338{\tt Prepare_Requests} & must be used before any {\tt Request_Unify} macro. \\
339
340{\tt Return_Unify} & return from the external and perform the
341unifications requested by {\tt Request_Unify}. \\
342
343{\tt Request_Unify_Integer(val, tag, int)} & request unification of a general prolog term with an integer. \\ 
344
345{\tt Request_Unify_Float(val, tag, float)} & request unification of a general prolog term with a float. \\ 
346
347{\tt Request_Unify_Atom(val, tag, atom)} & request unification of a general prolog term with an atom. \\
348
349{\tt Request_Unify_Nil(val, tag)} & request unification of a general prolog term with a nil list. \\
350
351{\tt Request_Unify_String(val, tag, string)} & request unification of a general prolog term with a string. \\
352
353{\tt Request_Unify_List(val, tag, listptr)} & request unification of a general prolog term with a list. \\ 
354
355{\tt Request_Unify_Structure(val, tag, strptr)} & request unification of a general prolog term with a structure. \\
356
357{\tt Request_Unify_Pw(val1, tag1, val2, tag2)} & unify two general Prolog terms.  To be used if
358the type of neither of the two terms is
359known. \\ 
360\hline
361\end{tabular}
362
363\vspace{0.5cm}
364
365%Note that no space may be allocated from the global stack
366%(i.e.\ no structures, lists or strings created) between two
367%calls to a {\tt Request} macro.
368
369\section{Prolog Term Construction}
370Macros to create tagged Prolog words at a specified address, and to
371allocate list and structure frames.
372
373\noindent
374 \\
375\begin{tabular}{|p{7.3cm}p{8.0cm}|} 
376\hline
377{\tt Make_Atom(pw, did)} & create atom or functor at address pw\\
378{\tt Make_Float(pw, float)} & create float at address pw\\
379{\tt Make_Integer(pw, int)} & create integer at address pw\\
380{\tt Make_Nil(pw)} & create nil at address pw\\
381{\tt Make_List(pw, plist)} & create list reference at address pw\\
382{\tt Make_Ref(pw, pdest)} & create reference at address pw\\
383{\tt Make_String(pw, cstring)} & create string at address pw\\
384{\tt Make_Struct(pw, pstruct)} & create structure reference at address pw\\
385{\tt Make_Var(pw)} & create free variable at address pw\\
386{\tt Push_List_Frame()} & allocate a list cell at address TG\\
387{\tt Push_Struct_Frame(did)} & allocate a structure at address TG and 
388initialise the functor field\\
389{\tt Make_Stack_String(len, val, s)} &
390allocates space for a string of length {\tt len} and sets {\tt val}
391to the string value and {\tt s} to the first string character.
392The {\it len+1} bytes of memory starting at {\tt s} are to be filled
393with the string and a zero terminator.\\
394{\tt Cstring_To_Prolog(cstring, val)} &
395convert a C string to an equivalent Prolog string {\tt val}.\\
396word32 {\tt Did(string, arity)} &
397returns the DID for the functor with name {\tt string} and arity {\tt arity}.\\
398\hline
399\end{tabular}
400
401\index{Did}
402\index{Cstring_To_Prolog}
403\index{Make_Stack_String}
404\index{Push_Struct_Frame}
405\index{Push_List_Frame}
406\index{Make_Var}
407\index{Make_Struct}
408\index{Make_String}
409\index{Make_Ref}
410\index{Make_Nil}
411\index{Make_Nil}
412\index{Make_Integer}
413\index{Make_Float}
414\index{Make_Atom}
415
416\vspace*{0.5cm}
417
418\noindent
419TG is the top of the global stack, on which strings, lists and structures
420are pushed.
421Note that \eclipse strings are not directly compatible with strings in C.
422The value part of a string pword points to a pword which holds
423the string length and which is followed by  a tag and the string proper.
424Despite the explicit length field, the string is zero terminated
425to have a certain degree of C compatibility. However, since Prolog
426strings may contain the NUL character, Prolog strings might be truncated
427when treated as C strings.
428
429%\newpage
430
431\section{Prolog Term Decomposition}
432These are the macros to convert Prolog terms into C data types.
433
434\noindent
435 \\
436\begin{tabular}{|p{7.7cm}p{7.5cm}|}
437\hline
438char * {\tt DidName(did)} &
439gives a pointer to the name of the functor {\tt did} as a C string.\\
440
441long {\tt DidArity(did)} & gives the arity of {\tt did}. \\
442
443pword * {\tt DidString(did)} &
444gives a pointer to the name of the functor {\tt did} as a Prolog string.\\
445
446{\tt Get_Name(val, tag, cstring)} &
447sets {\tt cstring} to the name of an atom or string. \\
448\hline
449\end{tabular}
450\index{Get_Name}
451\index{DidString}
452\index{DidArity}
453\index{DidName}
454
455\noindent
456\begin{tabular}{|p{7.7cm}p{7.5cm}|}
457\hline
458{\tt Get_Proc_Did(val, tag, did)} & 
459if {\tt val} and {\tt tag} specify a compound term of the form
460{\bf Name/Arity}, {\tt did} is assigned the DID of the
461corresponding functor otherwise the corresponding
462error type is raised. Arities greater than MAX_ARITY
463yield a RANGE_ERROR.\\
464
465{\tt Get_Functor_Did(val, tag, did)} & 
466like {\tt Get_Proc_Did}, however there is no arity
467arity restriction and apart from a term {\it Name/Arity}
468it accepts as well an atom and returns its DID.\\
469
470long {\tt StringLength(val)} & given the value of a string pword, it returns the
471length of the string, excluding the terminating zero.\\
472
473char * {\tt StringStart(val)} & given the value of a string pword, it returns a
474pointer to the first character of the string.\\
475
476double {\tt Dbl(val)} & given the value double
477precision Prolog float, return a C double.\\
478\hline
479\end{tabular}
480\index{Dbl}
481\index{StringStart}
482\index{StringLength}
483\index{Get_Functor_Did}
484\index{Get_Proc_Did}
485
486%\section{Arrays}
487%\begin{tabular}{|p{7.3cm}p{7.9cm}|}
488%\hline
489%{\tt \mbox{Get_Visible_Array_Address(adid, vmod,} tmod, address)} &
490%{\tt adid} is the DID of the array functor, {\tt address} must be
491%a {\tt pword} pointer, {\tt vmod} and {\tt tmod} are value and tag
492%of the module from where the array is looked up.
493%{\tt address} is set to point to the
494%beginning of the array or global variable. If
495%no visible array exists, an exception is raised.\\
496%
497%{\tt Get_Array_Address(adid, address)} &
498%The same as above, but we look for a global array rather than the visible one. 
499%This is mainly provided for backward compatibility.\\
500%
501%{\tt \mbox{Get_Visible_Array_Header(adid, vmod, } tmod, address)} & 
502%sets {\tt address} to point to the header of the visible array.
503%An error is raised if no such array is visible.\\
504%{\tt Get_Array_Header(adid, address)} & 
505%The same as above, but we look for a global array rather than the visible one. 
506%This is mainly provided for backward compatibility.\\
507%\hline
508%\end{tabular}
509%\index{Get_Array_Header}
510%\index{Get_Visible_Array_Header}
511%\index{Get_Array_Address}
512%\index{Get_Visible_Array_Address}
513%
514%\vspace*{0.3cm}
515%
516%The array layout is as follows:
517%The header is a pword whose tag specifies the type of the array:
518%\begin{itemize}
519%\item TCOMP - Prolog type
520%
521%\item TINT - integer array
522%
523%\item TFLOAT - float array
524%
525%\item TSTRG - byte array
526%\end{itemize}
527%The value of the pword points to a block of (arity + 1) {\tt word32}'s,
528%the first one is the DID of the array functor
529%and the following ones are its dimensions.
530%The following memory locations are occupied by the array itself.
531%It is stored row-wise (as in C), i.e.\ array elements that differ by
532%one in the last subscript are adjacent in memory.
533%
534%\section{Input / Output}
535%\begin{tabular}{|p{6cm}p{9cm}|}
536%\hline
537%{\tt Fprintf(strm, format, args)} &
538%prints out on the stream {\tt strm} the expression specified by
539%{\tt format} and {\tt args}. {\tt format} is the control string and
540%{\tt args} are the arguments, (as in {\tt printf}). \\
541%
542%{\tt Write(val, tag, strm)} &
543%prints out on the stream {\tt strm} the prolog term specified by
544%{\tt val} and {\tt tag}. \\
545%
546%{\tt Writeq(val, tag, strm)} &
547%prints on the stream {\tt strm} the prolog term specified by 
548%{\tt val} and {\tt tag}. Strings and atoms are quoted if necessary.\\ 
549%\hline
550%\end{tabular}
551
552\section{Backtracking}
553\begin{tabular}{|p{6cm}p{9cm}|}
554\hline
555{\tt Remember(n, val, tag)} & 
556remembers the value which will be given to the {\tt n}-th argument of the
557external predicate when an attempt is made to resatisfy the procedure. \\
558{\tt Cut_External} &
559discards all following alternative solutions. Without the use of this macro
560the predicate never fails.  \\
561\hline
562\end{tabular}
563
564%\section{Suspension}
565%\begin{tabular}{|p{6.7cm}p{8.3cm}|}
566%\hline
567%{\tt Mark_Suspending_Variable_Inst(var)} & 
568%{\tt var} is a pointer to the variable which is responsible for delaying
569%a call, it becomes its {\it suspending variable}.This macro is to be used
570%both in external predicates that occur as conditions in delay clauses
571%and in external predicates which delay themselves.
572%The suspended goal will be woken as soon as the variable is instantiated.\\ 
573%
574%{\tt Mark_Suspending_Variable(var)} & 
575%{\tt var} is a pointer to the variable which is responsible for delaying
576%a call, it becomes its {\it suspending variable}.This macro is to be used
577%both in external predicates that occur as conditions in delay clauses
578%and in external predicates which delay themselves.
579%The suspended goal will be woken as soon as the variable is instantiated
580%or bound to another suspending variable.\\ 
581%
582%{\tt Delay }& 
583%returns to the Prolog system and suspends the external predicate.
584%Some variables must have been marked by
585%{\tt Mark_Suspending_Variable}, otherwise the effect is unpredictable. \\
586%\hline
587%\end{tabular}
588%\index{Delay}
589%\index{Mark_Suspending_Variable}
590%\index{Mark_Suspending_Variable_Inst}
591%
592%\newpage
593%
594%\section{Calling Prolog Procedures}
595%\begin{tabular}{|p{6.8cm}p{8cm}|}
596%\hline
597%{\tt \mbox{Prolog_Call(vgoal, tgoal, vmodule,} tmodule)} &
598%    call the goal in the module and keep all bindings, global stack and trail
599%    state.\\
600%{\tt Prolog_Call_Nobind(vgoal,\hfill tgoal,  vmodule, tmodule)} &
601%    call the goal in the module, but report only success or failure.
602%    In this case no bindings or compound terms created by this
603%    goal are kept.\\
604%\hline
605%\end{tabular}
606
607