home *** CD-ROM | disk | FTP | other *** search
-
- When writing Turbo C functions to interface with Turbo Prolog, it
- is often desirable to have functions which behave
- non-deterministically. Following is an example program which
- shows how to write C functions which simulate non-deterministic
- Prolog predicates.
-
- Type the Turbo Prolog program and compile the code to an .OBJ
- file. After this is done, type the Turbo C program and compile
- it to an .OBJ file as well. Use the following command from the
- DOS prompt to compile the C module:
-
- TCC -u- -r- -ml -c -O NONDETC.C
-
- Once both source code files are successfully compiled into object
- code, issue the following link command from the DOS command line
- to create the executable file NONDET.EXE.
-
- TLINK INIT+CPINIT+NONDET+NONDETC+NONDET.SYM,NONDET,,PROLOG
-
- Here is the Turbo Prolog source code:
-
- /*--------------------------------------------------------------
- * NONDET.PRO -- Prolog program to demonstrate non-deterministic
- * calls of C functions.
- *--------------------------------------------------------------
- */
-
- global predicates
- c_range(integer,integer,integer,integer) - (i,i,o,i) language c
- cpinit - language c
- backtrack(integer) - (i) language c
- genenv(integer) - (o) language c
-
- predicates
- continue(integer)
- range(integer,integer,integer).
- clauses
-
- /* Succeeds if the C call with environment Env can be re-
- * satisfied.
- */
- continue(_).
- continue(Env) :- backtrack(Env),
- continue(Env).
-
- /* This predicate is equivilent to the predicate:
- * range(Start,End,Start) :- Start <= End.
- * range(Start,End,X) :- Start < End, Y = Start + 1, *
- range(Y,End,X).
- */
- range(Start,End,X) :- genenv(Env),
- continue(Env),
- c_range(Start,End,X,Env).
-
-
- /* Display the numbers from 1 to 100.
- */
- goal cpinit,
- clearwindow,
- range(1,100,X),
- write(X),
- readchar(_),
- nl,
- fail.
-
-
- Following is the Turbo C source code:
-
- /* Implements a C function equivilent to the Prolog predicate:
- * range(Start,End,Start) :- Start <= End.
- * range(Start,End,X) :- Start < End, Y = Start + 1, *
- range(Y,End,X).
- */
-
- static int env = 0;
- void fail_cc();
- #define MAX_ENV 128
-
- static int environ[MAX_ENV];
-
- /* Returns the index to an unused environment cell */
- void genenv_0(int *x)
-
- {
- int i;
-
- /* If a cell is 0, it is unused */
- for (i=0; i<MAX_ENV && environ[i]; i++)
- ;
-
- if (i<MAX_ENV)
- *x = i;
- else /* all are in use */
- fail_cc();
- }
-
- /* Fail if c_range can nolonger be satisfied */
- void backtrack_0(int env)
- {
- if ( !environ[env] )
- fail_cc();
- }
-
- void c_range_0(int begin, int end, int *x , int env)
- {
- /* If the environment is 0, this is the initial call
- * to c_range. Tell backtrack() that if all else fails,
- * there is at least one more number to try. This is
- * done by initiating the environment cell to non-zero.
- */
- if ( !environ[env] )
-
- *x = environ[env] = begin;
- /* Upon backtracking,return the next highest value within range
- */
-
- else if (environ[env] < end)
- *x = ++environ[env];
- /* All values have been tried, cause the predicate to fail */
- else
- {
- /* Tell backtrack() to fail */
- environ[env] = 0;
- /* Tell prolog I failed */
- fail_cc();
- }
- }
-