<!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> Defining a new C main() function </TITLE> </HEAD> <BODY TEXT=black BGCOLOR=white> <A HREF="manual069.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> <A HREF="manual065.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></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="htoc378">9.5</A></B></FONT></TD> <TD WIDTH="100%" ALIGN=center><FONT SIZE=4><B>Defining a new C <TT>main()</TT> function</B></FONT></TD> </TR></TABLE></DIV></TD> </TR></TABLE><UL> <LI><A HREF="manual070.html#toc310"> Example: asking for ancestors</A> </UL> <BR> GNU Prolog allows the user to define his own <TT>main()</TT> function. This can be useful to perform several tasks before starting the Prolog engine. To do this simply define a classical <TT>main(argc, argv)</TT> function. The following functions can then be used: <DL COMPACT=compact><DT><DD> <PRE> int Start_Prolog (int argc, char *argv[]) void Stop_Prolog (void) void Reset_Prolog (void) Bool Try_Execute_Top_Level(void) </PRE></DL> The function <TT>Start_Prolog(argc, argv)</TT> initializes the Prolog engine (<TT>argc</TT> and <TT>argv</TT> are the command-line variables). This function collects all linked objects (issued from the compilation of Prolog files) and initializes them. The initialization of a Prolog object file consists in adding to appropriate tables new atoms, new predicates and executing its system directives. A system directive is generated by the Prolog to WAM compiler to reflect a (user) directive executed at compile-time such as <TT>op/3</TT> (section <A HREF="manual021.html#op/3">6.1.10</A>). Indeed, when the compiler encounters such a directive it immediately executes it and also generates a system directive to execute it at the start of the executable. When all system directives have been executed the Prolog engine executes all initialization directives defined with <TT>initialization/1</TT> (section <A HREF="manual021.html#initialization/1">6.1.13</A>). The function returns the number of user directives (i.e. <TT>initialization/1</TT>) executed. This function must be called only once.<BR> <BR> The function <TT>Stop_Prolog()</TT> stops the Prolog engine. This function must be called only once after all Prolog treatment have been done.<BR> <BR> The function <TT>Reset_Prolog()</TT> reinitializes the Prolog engine (i.e. reset all Prolog stacks).<BR> <BR> The function <TT>Try_Execute_Top_Level()</TT> executes the top-level if linked (section <A HREF="manual008.html#Using-the-compiler">3.4.3</A>) and returns <TT>TRUE</TT>. If the top-level is not present the functions returns <TT>FALSE</TT>.<BR> <BR> Here is the definition of the default GNU Prolog <TT>main()</TT> function: <DL COMPACT=compact><DT><DD> <PRE> int Main_Wrapper(int argc, char *argv[]) { int nb_user_directive; Bool top_level; nb_user_directive = Start_Prolog(argc, argv); top_level = Try_Execute_Top_Level(); Stop_Prolog(); if (top_level || nb_user_directive) return 0; fprintf(stderr, "Warning: no initial goal executed\n" " use a directive :- initialization(Goal)\n" " or remove the link option --no-top-level" " (or --min-bips or --min-size)\n"); return 1; } int main(int argc, char *argv[]) { return Main_Wrapper(argc, argv); } </PRE></DL> Note that under some circumstances it is necessary to encapsulate the code of <TT>main()</TT> inside an intermediate function called by <TT>main()</TT>. Indeed, some C compilers (e.g. gcc) treats <TT>main()</TT> particularly, producing an uncompatible code w.r.t GNU Prolog. So it is a good idea to always use a wrapper function as shown above.<BR> <BR> <A NAME="toc310"></A><TABLE CELLPADDING=0 CELLSPACING=0 WIDTH="100%"> <TR><TD BGCOLOR="#98e7ff"><DIV ALIGN=center><TABLE> <TR><TD><B><A NAME="htoc379">9.5.1</A></B></TD> <TD WIDTH="100%" ALIGN=center><B>Example: asking for ancestors</B></TD> </TR></TABLE></DIV></TD> </TR></TABLE><BR> In this example we use the following Prolog code (in a file called <TT>new_main.pl</TT>): <DL COMPACT=compact><DT><DD> <PRE> parent(bob, mary). parent(jane, mary). parent(mary, peter). parent(paul, peter). parent(peter, john). anc(X, Y):- parent(X, Y). anc(X, Z) :- parent(X, Y), anc(Y, Z). </PRE></DL> The following file (called <TT>new_main_c.c</TT>) defines a <TT>main()</TT> function readinf the name of a person and displaying all successors of that person. This is equivalent to the Prolog query: <TT>anc(Result, Name)</TT>. <DL COMPACT=compact><DT><DD> <PRE> static int Main_Wrapper(int argc, char *argv[]) { int func; WamWord arg[10]; char str[100]; char *sol[100]; int i, nb_sol = 0; Bool res; Start_Prolog(argc, argv); func = Find_Atom("anc"); for (;;) { printf("\nEnter a name (or 'end' to finish): "); scanf("%s", str); if (strcmp(str, "end") == 0) break; Pl_Query_Begin(TRUE); arg[0] = Mk_Variable(); arg[1] = Mk_String(str); nb_sol = 0; res = Pl_Query_Call(func, 2, arg); while (res) { sol[nb_sol++] = Rd_String(arg[0]); res = Pl_Query_Next_Solution(); } Pl_Query_End(PL_RECOVER); for (i = 0; i < nb_sol; i++) printf(" solution: %s\n", sol[i]); printf("%d solution(s)\n", nb_sol); } Stop_Prolog(); return 0; } int main(int argc, char *argv[]) { return Main_Wrapper(argc, argv); } </PRE></DL> The compilation produces an executable called <TT>new_main</TT>: <DL COMPACT=compact><DT><DD><TT>% gplc new_main.pl new_main_c.c</TT></DL> Examples of use: <DL COMPACT=compact><DT><DD> <PRE> Enter a name (or 'end' to finish): john solution: peter solution: bob solution: jane solution: mary solution: paul 5 solution(s) Enter a name (or 'end' to finish): mary solution: bob solution: jane 2 solution(s) Enter a name (or 'end' to finish): end </PRE></DL> <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="manual069.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> <A HREF="manual065.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> </BODY> </HTML>