Node:Train, Next:, Previous:Mixing Examples, Up:Mixing Examples



Train Example (connections)

This is an example of how to create a runtime system. The Prolog program train.pl will display a route from one train station to another. The C program train.c calls the Prolog code and writes out all the routes found between two stations:

     % train.pl
     
     connected(From, From, [From], _):- !.
     connected(From, To, [From| Way], Been):-
             (   no_stop(From, Through)
             ;
                 no_stop(Through, From)
             ),
             not_been_before(Been, Through),
             connected(Through, To, Way, Been).
     
     no_stop('Stockholm', 'Katrineholm').
     no_stop('Stockholm', 'Vasteras').
     no_stop('Katrineholm', 'Hallsberg').
     no_stop('Katrineholm', 'Linkoping').
     no_stop('Hallsberg', 'Kumla').
     no_stop('Hallsberg', 'Goteborg').
     no_stop('Orebro', 'Vasteras').
     no_stop('Orebro', 'Kumla').
     
     not_been_before(Way, _) :- var(Way),!.
     not_been_before([Been| Way], Am) :-
             Been \== Am,
             not_been_before(Way, Am).
     
     /* train.c */
     
     #include <stdio.h>
     #include <sicstus/sicstus.h>
     
     void write_path(SP_term_ref path)
     {
       char *text = NULL;
       SP_term_ref
         tail = SP_new_term_ref(),
         via = SP_new_term_ref();
     
       SP_put_term(tail,path);
     
       while (SP_get_list(tail,via,tail))
       {
         if (text)
           printf(" -> ");
     
         SP_get_string(via, &text);
         printf("%s",text);
       }
       printf("\n");
     }
     
     int user_main(int argc, char **argv)
     {
       int rval;
       SP_pred_ref pred;
       SP_qid goal;
       SP_term_ref from, to, path;
     
       /* Initialize Prolog engine. This call looks up SP_PATH in order to
        * find the Runtime Library.  */
       if (SP_FAILURE == SP_initialize(argc, argv, NULL))
         {
           fprintf(stderr, "SP_initialize failed: %s\n", SP_error_message(SP_errno));
           exit(1);
         }
     
       rval = SP_restore("train.sav");
     
       if (rval == SP_ERROR || rval == SP_FAILURE)
         {
           fprintf(stderr, "Could not restore \"train.sav\".\n");
           exit(1);
         }
     
       /* Look up connected/4. */
       if (!(pred = SP_predicate("connected",4,"user")))
         {
           fprintf(stderr, "Could not find connected/4.\n");
           exit(1);
         }
     
       /* Create the three arguments to connected/4. */
       SP_put_string(from = SP_new_term_ref(), "Stockholm");
       SP_put_string(to = SP_new_term_ref(), "Orebro");
       SP_put_variable(path = SP_new_term_ref());
     
       /* Open the query. In a development system, the query would look like:
        *
        * | ?- connected('Stockholm','Orebro',X).
        */
       if (!(goal = SP_open_query(pred,from,to,path,path)))
         {
           fprintf(stderr, "Failed to open query.\n");
           exit(1);
         }
     
       /*
        * Loop through all the solutions.
        */
       while (SP_next_solution(goal)==SP_SUCCESS)
         {
           printf("Path: ");
           write_path(path);
         }
     
       SP_close_query(goal);
     
       exit(0);
     }
     

Create the saved-state containing the Prolog code:

     % sicstus
     SICStus 3.9 (sparc-solaris-5.7): Thu Sep 30 15:20:42 MET DST 1999
     Licensed to SICS
     | ?- compile(train),save_program('train.sav').
     % compiling [...]/train.pl...
     % compiled [...]/train.pl in module user, 10 msec 2848 bytes
     % [...]/train.sav created in 0 msec
     
     yes
     | ?- halt.
     

Create the executable using the application builder:

     % spld --main=user train.c -o train.exe
     

And finally, run the executable:

     % ./train
     Path: Stockholm -> Katrineholm -> Hallsberg -> Kumla -> Orebro
     Path: Stockholm -> Vasteras -> Orebro