home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / PROG / PASCAL / MISCTI10.ZIP / TI400.ASC < prev    next >
Encoding:
Text File  |  1988-05-02  |  3.5 KB  |  129 lines

  1.  
  2. When writing Turbo C functions to interface with Turbo Prolog, it
  3. is often desirable to have functions which behave
  4. non-deterministically.  Following is an example program which
  5. shows how to write C functions which simulate non-deterministic
  6. Prolog predicates.
  7.  
  8. Type the Turbo Prolog program and compile the code to an .OBJ
  9. file.  After this is done, type the Turbo C program and compile
  10. it to an .OBJ file as well.  Use the following command from the
  11. DOS prompt to compile the C module:
  12.  
  13. TCC -u- -r- -ml -c -O NONDETC.C
  14.  
  15. Once both source code files are successfully compiled into object
  16. code, issue the following link command from the DOS command line
  17. to create the executable file NONDET.EXE.
  18.  
  19. TLINK INIT+CPINIT+NONDET+NONDETC+NONDET.SYM,NONDET,,PROLOG
  20.  
  21. Here is the Turbo Prolog source code:
  22.  
  23. /*--------------------------------------------------------------
  24.  * NONDET.PRO -- Prolog program to demonstrate non-deterministic
  25.  *               calls of C functions.
  26.  *--------------------------------------------------------------
  27.  */
  28.  
  29. global predicates
  30.  c_range(integer,integer,integer,integer) - (i,i,o,i) language c
  31.  cpinit                                   -           language c
  32.  backtrack(integer)                       - (i)       language c
  33.  genenv(integer)                          - (o)       language c
  34.  
  35. predicates
  36.   continue(integer)
  37.   range(integer,integer,integer).
  38. clauses
  39.  
  40. /* Succeeds if the C call with environment Env can be re-
  41.  * satisfied.
  42.  */ 
  43.   continue(_). 
  44.   continue(Env) :- backtrack(Env),  
  45.                    continue(Env).
  46.  
  47. /* This predicate is equivilent to the predicate:
  48.  *    range(Start,End,Start) :- Start <= End.
  49.  *    range(Start,End,X)     :- Start < End, Y = Start + 1,  *                             
  50. range(Y,End,X).
  51.  */
  52.   range(Start,End,X) :- genenv(Env),  
  53.                         continue(Env), 
  54.                         c_range(Start,End,X,Env).  
  55.  
  56.  
  57. /* Display the numbers from 1 to 100.
  58.  */
  59. goal cpinit, 
  60.      clearwindow,
  61.      range(1,100,X), 
  62.      write(X), 
  63.      readchar(_), 
  64.      nl, 
  65.      fail.
  66.  
  67.  
  68. Following is the Turbo C source code:
  69.  
  70. /* Implements a C function equivilent to the Prolog predicate:
  71.  *    range(Start,End,Start) :- Start <= End.
  72.  *    range(Start,End,X)     :- Start < End, Y = Start + 1,  *                             
  73. range(Y,End,X).
  74.  */
  75.  
  76. static int env = 0;
  77. void fail_cc();
  78. #define MAX_ENV 128
  79.  
  80. static int environ[MAX_ENV];
  81.  
  82. /* Returns the index to an unused environment cell */
  83. void genenv_0(int *x)
  84.  
  85. {
  86.    int i;
  87.  
  88.    /* If a cell is 0, it is unused */
  89.    for (i=0; i<MAX_ENV && environ[i]; i++)
  90.      ;
  91.  
  92.    if (i<MAX_ENV)
  93.      *x = i;
  94.    else /* all are in use */
  95.      fail_cc();
  96. }
  97.  
  98. /* Fail if c_range can nolonger be satisfied */
  99. void backtrack_0(int env)
  100. {
  101.   if ( !environ[env] )
  102.     fail_cc();
  103. }
  104.  
  105. void c_range_0(int begin, int end, int *x , int env)
  106. {
  107.   /* If the environment is 0, this is the initial call
  108.    * to c_range.  Tell backtrack() that if all else fails,
  109.    * there is at least one more number to try.  This is
  110.    * done by initiating the environment cell to non-zero.
  111.    */
  112.   if ( !environ[env] )
  113.  
  114.     *x = environ[env] = begin;
  115.   /* Upon backtracking,return the next highest value within range   
  116.    */
  117.  
  118.   else if (environ[env] < end)
  119.    *x = ++environ[env];
  120.   /* All values have been tried, cause the predicate to fail */
  121.   else
  122.   {
  123.     /* Tell backtrack() to fail */
  124.     environ[env] = 0;
  125.     /* Tell prolog I failed */
  126.     fail_cc();
  127.   }
  128. }
  129.