6.8.1 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. The third arg to SP_initialize is an option block and can be NULL, for default options. */ 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); }
/* train.c */
/* 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 4.1.2 ...
     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
     
     | ?- 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

Send feedback on this subject.