Defining a new C main() function

### 8.5 Defining a new C `main()` function

GNU Prolog allows the user to define his own `main()` function. This can be useful to perform several tasks before starting the Prolog engine. To do this simply define a classical `main(argc, argv)` function. The following functions can then be used:

      int  Start_Prolog         (int argc, char *argv[])
      void Stop_Prolog          (void)
      void Reset_Prolog         (void)
      Bool Try_Execute_Top_Level(void)

The function `Start_Prolog(argc, argv)` initializes the Prolog engine (`argc` and `argv` 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 `op/3` (section 5.1.10). 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 `initialization/1` (section 5.1.13). The function returns the number of user directives (i.e. `initialization/1`) executed. This function mst be called only once.
The function `Stop_Prolog()` stops the Prolog engine. This function must be called only once after all Prolog treatment have been done.
The function `Reset_Prolog()` reinitializes the Prolog engine (i.e. reset all Prolog stacks).
The function `Try_Execute_Top_Level()` executes the top-level if linked (section 2.4.3) and returns `TRUE`. If the top-level is not present the functions returns `FALSE`.
Here is the definition of the default GNU Prolog `main()` function:

      int main(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)
           return 0;

       if (nb_user_directive)
           return 0;

       printf("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;
      }

#### 8.5.1 Example: asking for ancestors

In this example we use the following Prolog code (in a file called `prog.pl`):

      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).

The following `main()` function asks for the name of a person and displays all successors of that person (this is equivalent to the Prolog query: `anc(Result, Name)`).

      int main(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;

           arg[0]=Mk_Variable();
           arg[1]=Mk_String(str);
           nb_sol=0;
           res=Pl_Query_Start(func, 2, arg, TRUE);
           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);
          }
       return 0;
      }

The compilation produces an executable called `prog`:

  `% gplc prog.pl utils.c`

Examples of use:

      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

Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.
More about the copyright