<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <HTML> <HEAD> <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <META name="GENERATOR" content="hevea 1.06-7 of 2001-11-14"> <TITLE> Manipulating Prolog terms </TITLE> </HEAD> <BODY TEXT=black BGCOLOR=white> <A HREF="manual066.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> <A HREF="manual065.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> <A HREF="manual068.html"><IMG SRC ="next_motif.gif" ALT="Next"></A> <HR> <TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#66dbff"><DIV ALIGN=center><TABLE> <TR><TD><FONT SIZE=4><B><A NAME="htoc352">9.2</A></B></FONT></TD> <TD WIDTH="100%" ALIGN=center><FONT SIZE=4><B>Manipulating Prolog terms</B></FONT></TD> </TR></TABLE></DIV></TD> </TR></TABLE><UL> <LI><A HREF="manual067.html#toc287"> Introduction</A> <LI><A HREF="manual067.html#toc288"> Managing Prolog atoms</A> <LI><A HREF="manual067.html#toc289"> Reading Prolog terms</A> <LI><A HREF="manual067.html#toc290"> Unifying Prolog terms</A> <LI><A HREF="manual067.html#toc291"> Creating Prolog terms</A> <LI><A HREF="manual067.html#toc292"> Testing the type of Prolog terms</A> <LI><A HREF="manual067.html#toc293"> Comparing Prolog terms</A> <LI><A HREF="manual067.html#toc294"> Copying Prolog terms</A> <LI><A HREF="manual067.html#toc295"> Comparing and evaluating arithmetic expressions</A> </UL> <A NAME="Manipulating-Prolog-terms"></A><BR> <A NAME="toc287"></A><TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#98e7ff"><DIV ALIGN=center><TABLE> <TR><TD><B><A NAME="htoc353">9.2.1</A></B></TD> <TD WIDTH="100%" ALIGN=center><B>Introduction</B></TD> </TR></TABLE></DIV></TD> </TR></TABLE> <A NAME="Introduction:(Manipulating-Prolog-terms)"></A> In the following we presents a set of functions to manipulate Prolog terms. For simple foreign terms the functions manipulate simple C types (section <A HREF="manual066.html#foreign/2-directive">9.1.2</A>). <BR> <BR> Functions managing lists handle an array of 2 elements (of type <TT>PlTerm</TT>) containing the terms corresponding to the head and the tail of the list. For the empty list <TT>NULL</TT> is passed as the array. These functions require to flatten a list in each sub-list. To simplify the management of proper lists (i.e. lists terminated by <TT>[]</TT>) a set of functions is provided that handle the number of elements of the list (an integer) and an array whose elements (of type <TT>PlTerm</TT>) are the elements of the list. The caller of these functions must provide the array.<BR> <BR> Functions managing compound terms handle a functor (the principal functor of the term), an arity <I><TT>N</TT></I> >= 0 and an array of <I><TT>N</TT></I> elements (of type <TT>PlTerm</TT>) containing the sub-terms of the compound term. Since a list is a special case of compound term (functor = <TT>'.'</TT> and arity=2) it is possible to use any function managing compound terms to deal with a list but the error detection is not the same. Indeed many functions check if the Prolog argument is correct. The name of a read or unify function checking the Prolog arguments is of the form <TT><I>Name</I>_Check()</TT>. For each of these functions there is a also check-free version called <TT><I>Name</I>()</TT>. We then only present the name of checking functions.<BR> <BR> <A NAME="toc288"></A><TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#98e7ff"><DIV ALIGN=center><TABLE> <TR><TD><B><A NAME="htoc354">9.2.2</A></B></TD> <TD WIDTH="100%" ALIGN=center><B>Managing Prolog atoms</B></TD> </TR></TABLE></DIV></TD> </TR></TABLE> Each atom has a unique internal key which corresponds to its index in the GNU Prolog atom table. It is possible to obtain the information about an atom and to create new atoms using: <DL COMPACT=compact><DT><DD> <PRE> char *Atom_Name (int atom) int Atom_Length (int atom) Bool Atom_Needs_Quote (int atom) Bool Atom_Needs_Scan (int atom) Bool Is_Valid_Atom (int atom) int Create_Atom (char *str) int Create_Allocate_Atom(char *str) int Find_Atom (char *str) int ATOM_CHAR (char c) int atom_nil int atom_false int atom_true int atom_end_of_file </PRE></DL> The macro <TT>Atom_Name(atom)</TT> returns the internal string of <TT>atom</TT> (this string should not be modified). The function <TT>Atom_Lengh(atom)</TT> returns the length (of the name) of <TT>atom</TT>.<BR> <BR> The function <TT>Atom_Needs_Scan(atom)</TT> indicates if the canonical form of <TT>atom</TT> needs to be quoted as done by <TT>writeq/2</TT> (section <A HREF="manual037.html#write-term/3">7.14.6</A>). In that case <TT>Atom_Needs_Scan(atom)</TT> indicates if this simply comes down to write quotes around the name of <TT>atom</TT> or if it necessary to scan each character of the name because there are some non-printable characters (or included quote characters). The function <TT>Is_Valid_Atom(atom)</TT> is true only if <TT>atom</TT> is the internal key of an existing atom.<BR> <BR> The function <TT>Create_Atom(str)</TT> adds a new atom whose name is the content of <TT>str</TT> to the system and returns its internal key. If the atom already exists its key is simply returned. The string <TT>str</TT> passed to the function should not be modified later. The function <TT>Create_Allocate_Atom(str)</TT> is provided when this condition cannot be ensured. It simply makes a dynamic copy of <TT>str</TT>. <BR> <BR> The function <TT>Find_Atom(str)</TT> returns the internal key of the atom whose name is <TT>str</TT> or <TT>-1</TT> if does not exist.<BR> <BR> All atoms corresponding to a single character already exist and their key can be obtained via the macro <TT>ATOM_CHAR</TT>. For instance <TT>ATOM_CHAR('.')</TT> is the atom associated to <TT>'.'</TT> (this atom is the functor of lists). The other variables correspond to the internal key of frequently used atoms: <TT>[]</TT>, <TT>false</TT>, <TT>true</TT> and <TT>end_of_file</TT>.<BR> <BR> <A NAME="toc289"></A><TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#98e7ff"><DIV ALIGN=center><TABLE> <TR><TD><B><A NAME="htoc355">9.2.3</A></B></TD> <TD WIDTH="100%" ALIGN=center><B>Reading Prolog terms</B></TD> </TR></TABLE></DIV></TD> </TR></TABLE> <A NAME="Reading-Prolog-terms"></A> The name of all functions presented here are of the form <TT>Rd_<I>Name</I>_Check()</TT>. They all check the validity of the Prolog term to read emitting appropriate errors if necessary. Each function has a check-free version called <TT>Rd_<I>Name</I>()</TT>.<BR> <BR> <B>Simple foreign types</B>: for each simple foreign type (section <A HREF="manual066.html#foreign/2-directive">9.1.2</A>) there is a read function (used by the interface when an input argument is provided): <DL COMPACT=compact><DT><DD> <PRE> long Rd_Integer_Check (PlTerm term) long Rd_Positive_Check (PlTerm term) double Rd_Float_Check (PlTerm term) double Rd_Number_Check (PlTerm term) int Rd_Atom_Check (PlTerm term) int Rd_Boolean_Check (PlTerm term) int Rd_Char_Check (PlTerm term) int Rd_In_Char_Check (PlTerm term) int Rd_Code_Check (PlTerm term) int Rd_In_Code_Check (PlTerm term) int Rd_Byte_Check (PlTerm term) int Rd_In_Byte_Check (PlTerm term) char *Rd_String_Check (PlTerm term) char *Rd_Chars_Check (PlTerm term) char *Rd_Codes_Check (PlTerm term) int Rd_Chars_Str_Check(PlTerm term, char *str) int Rd_Codes_Str_Check(PlTerm term, char *str) </PRE></DL> All functions returning a C string (<TT>char *</TT>) use a same buffer. The function <TT>Rd_Chars_Str_Check()</TT> is similar to <TT>Rd_Chars_Check()</TT> but accepts as argument a string to store the result and returns the length of that string (which is also the length of the Prolog list). Similarly for <TT>Rd_Codes_Str_Check()</TT>.<BR> <BR> <B>Complex terms</B>: the following functions return the sub-arguments (terms) of complex terms as an array of <TT>PlTerm</TT> except <TT>Rd_Proper_List_Check()</TT> which returns the size of the list read (and initializes the array <TT>element</TT>). Refer to the introduction of this section for more information about the arguments of complex functions (section <A HREF="#Introduction:(Manipulating-Prolog-terms)">9.2.1</A>). <DL COMPACT=compact><DT><DD> <PRE> int Rd_Proper_List_Check(PlTerm term, PlTerm *arg) PlTerm *Rd_List_Check (PlTerm term) PlTerm *Rd_Compound_Check (PlTerm term, int *functor, int *arity) PlTerm *Rd_Callable_Check (PlTerm term, int *functor, int *arity) </PRE></DL> <A NAME="toc290"></A><TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#98e7ff"><DIV ALIGN=center><TABLE> <TR><TD><B><A NAME="htoc356">9.2.4</A></B></TD> <TD WIDTH="100%" ALIGN=center><B>Unifying Prolog terms</B></TD> </TR></TABLE></DIV></TD> </TR></TABLE> The name of all functions presented here are of the form <TT>Un_<I>Name</I>_Check()</TT>. They all check the validity of the Prolog term to unify emitting appropriate errors if necessary. Each function has a check-free version called <TT>Un_<I>Name</I>()</TT>.<BR> <BR> <B>Simple foreign types</B>: for each simple foreign type (section <A HREF="manual066.html#foreign/2-directive">9.1.2</A>) there is an unify function (used by the interface when an output argument is provided): <DL COMPACT=compact><DT><DD> <PRE> Bool Un_Integer_Check (long n, PlTerm term) Bool Un_Positive_Check(long n, PlTerm term) Bool Un_Float_Check (double n, PlTerm term) Bool Un_Number_Check (double n, PlTerm term) Bool Un_Atom_Check (int atom, PlTerm term) Bool Un_Boolean_Check (int b, PlTerm term) Bool Un_Char_Check (int c, PlTerm term) Bool Un_In_Char_Check (int c, PlTerm term) Bool Un_Code_Check (int c, PlTerm term) Bool Un_In_Code_Check (int c, PlTerm term) Bool Un_Byte_Check (int b, PlTerm term) Bool Un_In_Byte_Check (int b, PlTerm term) Bool Un_String_Check (char *str, PlTerm term) Bool Un_Chars_Check (char *str, PlTerm term) Bool Un_Codes_Check (char *str, PlTerm term) </PRE></DL> The function <TT>Un_Number_Check(n, term)</TT> unifies <TT>term</TT> with an integer if <TT>n</TT> is an integer, with a floating point number otherwise. The function <TT>Un_String_Check(str, term)</TT> creates the atom corresponding to <TT>str</TT> and then unifies term with it (same as <TT>Un_Atom_Check(Create_Allocate_Atom(str), term)</TT>).<BR> <BR> <B>Complex terms</B>: the following functions accept the sub-arguments (terms) of complex terms as an array of <TT>PlTerm</TT>. Refer to the introduction of this section for more information about the arguments of complex functions (section <A HREF="#Introduction:(Manipulating-Prolog-terms)">9.2.1</A>). <DL COMPACT=compact><DT><DD> <PRE> Bool Un_Proper_List_Check(int size, PlTerm *arg, PlTerm term) Bool Un_List_Check (PlTerm *arg, PlTerm term) Bool Un_Compound_Check (int functor, int arity, PlTerm *arg, PlTerm term) Bool Un_Callable_Check (int functor, int arity, PlTerm *arg, PlTerm term) </PRE></DL> All these functions check the type of the term to unify and return the result of the unification. Generally if an unification fails the C function returns <TT>FALSE</TT> to enforce a failure. However if there are several arguments to unify and if an unification fails then the C function returns <TT>FALSE</TT> and the type of other arguments has not been checked. Normally all error cases are tested before doing any work to be sure that the predicate fails/succeeds only if no error condition is satisfied. So a good method is to check if the validity of all arguments to unify and later to do the unification (using check-free functions). Obviously if there is only one to unify it is more efficient to use a unify function checking the argument. For the other cases the interface provides a set of functions to check the type of a term.<BR> <BR> <B>Simple foreign types</B>: for each simple foreign type (section <A HREF="manual066.html#foreign/2-directive">9.1.2</A>) there is check-for-unification function (used by the interface when an output argument is provided): <DL COMPACT=compact><DT><DD> <PRE> void Check_For_Un_Integer (PlTerm term) void Check_For_Un_Positive(PlTerm term) void Check_For_Un_Float (PlTerm term) void Check_For_Un_Number (PlTerm term) void Check_For_Un_Atom (PlTerm term) void Check_For_Un_Boolean (PlTerm term) void Check_For_Un_Char (PlTerm term) void Check_For_Un_In_Char (PlTerm term) void Check_For_Un_Code (PlTerm term) void Check_For_Un_In_Code (PlTerm term) void Check_For_Un_Byte (PlTerm term) void Check_For_Un_In_Byte (PlTerm term) void Check_For_Un_String (PlTerm term) void Check_For_Un_Chars (PlTerm term) void Check_For_Un_Codes (PlTerm term) </PRE></DL> <B>Complex terms</B>: the following functions check the validity of complex terms: <DL COMPACT=compact><DT><DD> <PRE> void Check_For_Un_List (PlTerm term) void Check_For_Un_Compound(PlTerm term) void Check_For_Un_Callable(PlTerm term) void Check_For_Un_Variable(PlTerm term) </PRE></DL> The function <TT>Check_For_Un_List(term)</TT> checks if <TT>term</TT> can be unified with a list. This test is done for the entire list (not only for the functor/arity of <TT>term</TT> but also recursively on the tail of the list). The function <TT>Check_For_Un_Variable(term)</TT> ensures that <TT>term</TT> is not currently instantiated. These functions can be defined using functions to test the type of a Prolog term (section <A HREF="#Testing-the-type-of-Prolog-terms">9.2.6</A>) and functions to raise Prolog errors (section <A HREF="manual068.html#Raising-Prolog-errors">9.3</A>). For instance <TT>Check_For_Un_List(term)</TT> is defined as follows: <DL COMPACT=compact><DT><DD> <PRE> void Check_For_Un_List(PlTerm term) { if (!Blt_List_Or_Partial_List(term)) Pl_Err_Type(type_list, term); } </PRE></DL> <A NAME="toc291"></A><TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#98e7ff"><DIV ALIGN=center><TABLE> <TR><TD><B><A NAME="htoc357">9.2.5</A></B></TD> <TD WIDTH="100%" ALIGN=center><B>Creating Prolog terms</B></TD> </TR></TABLE></DIV></TD> </TR></TABLE> <A NAME="Creating-Prolog-terms"></A> These functions are provided to creates Prolog terms. Each function returns a <TT>PlTerm</TT> containing the created term.<BR> <BR> <B>Simple foreign types</B>: for each simple foreign type (section <A HREF="manual066.html#foreign/2-directive">9.1.2</A>) there is a creation function: <DL COMPACT=compact><DT><DD> <PRE> PlTerm Mk_Integer (long n) PlTerm Mk_Positive(long n) PlTerm Mk_Float (double n) PlTerm Mk_Number (double n) PlTerm Mk_Atom (int atom) PlTerm Mk_Boolean (int b) PlTerm Mk_Char (int c) PlTerm Mk_In_Char (int c) PlTerm Mk_Code (int c) PlTerm Mk_In_Code (int c) PlTerm Mk_Byte (int b) PlTerm Mk_In_Byte (int b) PlTerm Mk_String (char *str) PlTerm Mk_Chars (char *str) PlTerm Mk_Codes (char *str) </PRE></DL> The function <TT>Mk_Number(n, term)</TT> initializes <TT>term</TT> with an integer if <TT>n</TT> is an integer, with a floating point number otherwise. The function <TT>Mk_String(str)</TT> first creates an atom corresponding to <TT>str</TT> and then returns that Prolog atom (i.e. equivalent to <TT>Mk_Atom(Create_Allocate_Atom(str))</TT>).<BR> <BR> <B>Complex terms</B>: the following functions accept the sub-arguments (terms) of complex terms as an array of <TT>PlTerm</TT>. Refer to the introduction of this section for more information about the arguments of complex functions (section <A HREF="#Introduction:(Manipulating-Prolog-terms)">9.2.1</A>). <DL COMPACT=compact><DT><DD> <PRE> PlTerm Mk_Proper_List(int size, PlTerm *arg) PlTerm Mk_List (PlTerm *arg) PlTerm Mk_Compound (int functor, int arity, PlTerm *arg) PlTerm Mk_Callable (int functor, int arity, PlTerm *arg) </PRE></DL> <A NAME="toc292"></A><TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#98e7ff"><DIV ALIGN=center><TABLE> <TR><TD><B><A NAME="htoc358">9.2.6</A></B></TD> <TD WIDTH="100%" ALIGN=center><B>Testing the type of Prolog terms</B></TD> </TR></TABLE></DIV></TD> </TR></TABLE> <A NAME="Testing-the-type-of-Prolog-terms"></A> The following functions test the type of a Prolog term. Each function corresponds to a type testing built-in predicate (section <A HREF="manual024.html#var/1">7.1.1</A>). <DL COMPACT=compact><DT><DD> <PRE> Bool Blt_Var (PlTerm term) Bool Blt_Non_Var (PlTerm term) Bool Blt_Atom (PlTerm term) Bool Blt_Integer (PlTerm term) Bool Blt_Float (PlTerm term) Bool Blt_Number (PlTerm term) Bool Blt_Atomic (PlTerm term) Bool Blt_Compound (PlTerm term) Bool Blt_Callable (PlTerm term) Bool Blt_List (PlTerm term) Bool Blt_Partial_List (PlTerm term) Bool Blt_List_Or_Partial_List(PlTerm term) Bool Blt_Fd_Var (PlTerm term) Bool Blt_Non_Fd_Var (PlTerm term) Bool Blt_Generic_Var (PlTerm term) Bool Blt_Non_Generic_Var (PlTerm term) int Type_Of_Term (PlTerm term) int List_Length (PlTerm list) </PRE></DL> The function <TT>Type_Of_Term(term)</TT> returns the type of <TT>term</TT>, the following constants can be used to test this type (e.g. in a <TT>switch</TT> instruction): <UL><LI> <TT>PLV</TT>: Prolog variable.<BR> <BR> <LI><TT>FDV</TT>: finite domain variable.<BR> <BR> <LI><TT>INT</TT>: integer.<BR> <BR> <LI><TT>FLT</TT>: floating point number.<BR> <BR> <LI><TT>ATM</TT>: atom.<BR> <BR> <LI><TT>LST</TT>: list.<BR> <BR> <LI><TT>STC</TT>: structure </UL> The tag <TT>LST</TT> means a term whose principal functor is <TT>'.'</TT> and whose arity is 2 (recall that the empty list is the atom <TT>[]</TT>). The tag <TT>STC</TT> means any other compound term.<BR> <BR> The function <TT>List_Length(list)</TT> returns the number of elements of the <TT>list</TT> (<TT>0</TT> for the empty list). If list is not a list this function returns <TT>-1</TT>.<BR> <BR> <A NAME="toc293"></A><TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#98e7ff"><DIV ALIGN=center><TABLE> <TR><TD><B><A NAME="htoc359">9.2.7</A></B></TD> <TD WIDTH="100%" ALIGN=center><B>Comparing Prolog terms</B></TD> </TR></TABLE></DIV></TD> </TR></TABLE> The following functions compares Prolog terms. Each function corresponds to a comparison built-in predicate (section <A HREF="manual026.html#(==)/2">7.3.2</A>). <DL COMPACT=compact><DT><DD> <PRE> Bool Blt_Term_Eq (PlTerm term1, PlTerm term2) Bool Blt_Term_Neq(PlTerm term1, PlTerm term2) Bool Blt_Term_Lt (PlTerm term1, PlTerm term2) Bool Blt_Term_Lte(PlTerm term1, PlTerm term2) Bool Blt_Term_Gt (PlTerm term1, PlTerm term2) Bool Blt_Term_Gte(PlTerm term1, PlTerm term2) </PRE></DL> All these functions are based on a general comparison function returning a negative integer if <TT>term1</TT> is less than <TT>term2</TT>, 0 if they are equal and a positive integer otherwise: <DL COMPACT=compact><DT><DD> <PRE> int Term_Compare(PlTerm term1, PlTerm term2) </PRE></DL> <A NAME="toc294"></A><TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#98e7ff"><DIV ALIGN=center><TABLE> <TR><TD><B><A NAME="htoc360">9.2.8</A></B></TD> <TD WIDTH="100%" ALIGN=center><B>Copying Prolog terms</B></TD> </TR></TABLE></DIV></TD> </TR></TABLE> The following functions make a copy of a Prolog term: <DL COMPACT=compact><DT><DD> <PRE> void Copy_Term (PlTerm *dst_adr, PlTerm *src_adr) void Copy_Contiguous_Term(PlTerm *dst_adr, PlTerm *src_adr) int Term_Size (PlTerm term) </PRE></DL> The function <TT>Copy_Term(dst_adr, src_adr)</TT> makes a copy of the term located at <TT>src_adr</TT> and stores it from the address given by <TT>dst_adr</TT>. The result is a contiguous term. If it can be ensured that the source term is a contiguous term (i.e. result of a previous copy) the function <TT>Copy_Contiguous_Term()</TT> can be used instead (it is faster). In any case, sufficient space should be available for the copy (i.e. from <TT>dst_adr</TT>). The function <TT>Term_Size(term)</TT> returns the number of <TT>PlTerm</TT> needed by <TT>term</TT>.<BR> <BR> <A NAME="toc295"></A><TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#98e7ff"><DIV ALIGN=center><TABLE> <TR><TD><B><A NAME="htoc361">9.2.9</A></B></TD> <TD WIDTH="100%" ALIGN=center><B>Comparing and evaluating arithmetic expressions</B></TD> </TR></TABLE></DIV></TD> </TR></TABLE> The following functions compare arithmetic expressions. Each function corresponds to a comparison built-in predicate (section <A HREF="manual029.html#(=:=)/2">7.6.3</A>). <DL COMPACT=compact><DT><DD> <PRE> Bool Blt_Eq (PlTerm expr1, PlTerm expr2) Bool Blt_Neq(PlTerm expr1, PlTerm expr2) Bool Blt_Lt (PlTerm expr1, PlTerm expr2) Bool Blt_Lte(PlTerm expr1, PlTerm expr2) Bool Blt_Gt (PlTerm expr1, PlTerm expr2) Bool Blt_Gte(PlTerm expr1, PlTerm expr2) </PRE></DL> The following function evaluates the expression <TT>expr</TT> and stores its result as a Prolog number (integer or floating point number) in <TT>result</TT>: <DL COMPACT=compact><DT><DD> <PRE> void Math_Load_Value(PlTerm expr, PlTerm *result) </PRE></DL> This function can be followed by a read function (section <A HREF="#Reading-Prolog-terms">9.2.3</A>) to obtain the result.<BR> <BR> <HR SIZE=2> Copyright (C) 1999-2002 Daniel Diaz <BR> <BR> Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved. <BR> <BR> <A HREF="index.html#copyright">More about the copyright</A> <HR> <A HREF="manual066.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> <A HREF="manual065.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> <A HREF="manual068.html"><IMG SRC ="next_motif.gif" ALT="Next"></A> </BODY> </HTML>