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