Sophie

Sophie

distrib > Mandriva > 9.1 > ppc > by-pkgid > d1f06a5336fd6bf4a381b72b8d2b5ce1 > files > 205

gprolog-1.2.16-3mdk.ppc.rpm

<!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&nbsp;<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&nbsp;<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&nbsp;<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 &lt; 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>