Examples

The first example shows how you can package a call to a Prolog goal that is known to be determinate. Here, the C function fred hides the call to Prolog. However, the servant must be initiated by a call to QP_ipc_create_servant() before it can be called.

                       
Prolog Specification
external(fred, xdr, fred(+integer,-integer,+integer)). fred(X, Y, Z) :- ...
                                  
C routine
int fred(i, j) int i, j; { static int fredp = -1; int k; if (fredp < 0) { /* initialize */ fredp = QP_ipc_lookup("fred"); if (fredp < 0) DieBecause("couldn't find fred"); } /* send the request */ QP_ipc_prepare(fredp, i, j); /* get the answer back */ if (QP_ipc_next(fredp, &k)) DieBecause("fred failed"); /* known determinate, so close request */ QP_ipc_close(); /* return the answer */ return k; }

The second example shows an entire program and how all types of arguments are be passed. It also shows how QP_ipc_atom_from_string() and QP_ipc_string_from_atom() can be used. In terms of functionality, this is not a very interesting program, and the conversion between atoms and strings is just to give an example.

                       
Prolog Specification
external(dupl, xdr, duplicate(-integer,+integer,-string,+string, -float,+float,-atom,+atom)). duplicate(A, A, B, B, C, C, D, D).
                                 
C program:
main() { int pdupl; char host[20], savestate[50]; int iint, oint; char istr1[20], istr2[20], ostr1[20], ostr2[20]; float iflt, oflt; QP_atom iatom, oatom; printf("Enter host and savestate: "); scanf("%s%s", host, savestate); if (QP_ipc_create_servant(host,savestate,"servant_out")) DieBecause("Error starting up servant"); pdupl = QP_ipc_lookup("dupl"); if (pdupl < 0) DieBecause("dupl not defined"); for (;;) { /* loop until break */ printf("Enter int, str, flt, str: "); if (scanf("%d%s%f%s",&iint,istr1,&iflt,istr2) != 4) break; /* get atom for the string typed in */ iatom = QP_ipc_atom_from_string(istr2); /* send the request */ if (QP_ipc_prepare(pdupl, iint, istr1, iflt, iatom)) DieBecause("dupl prepare error"); /* get answer back, and convert atom back to string */ QP_ipc_next(pdupl, &oint, ostr1, &oflt, &oatom); QP_ipc_string_from_atom(oatom, ostr2); /* close request because we want only one answer */ if (QP_ipc_close()) printf("ERROR closing\n"); printf("Answer is: %d %s %G %s(%d)\n", oint, ostr1, oflt, ostr2, oatom); } if (QP_ipc_shutdown_servant()) DieBecause("Error shutting down servant"); }

The third example shows how to retrieve multiple answers:

                       
Prolog Specification
external(table, xdr, table(-string,-integer)). table(samuel, 34). table(sarah, 54). ...
                                  
C program
main() { char host[20], savestate[50]; int ptable, ret; char strval[40]; int intval; printf("Enter host and savestate: "); scanf("%s%s", host, savestate); if (QP_ipc_create_servant(host,savestate,"servant_out")) DieBecause("Error starting up servant"); ptable = QP_ipc_lookup("table"); if (ptable < 0) { printf("table not defined\n"); return; } /* send the request */ QP_ipc_prepare(ptable); /* retrieve and print ALL answers */ while (!(ret = QP_ipc_next(ptable, strval, &intval))) printf("String: %s, Integer: %d\n", strval,intval); /* note no close, since we retrieved all the answers! */ if (ret == -1) printf("All answers retrieved\n"); else printf("Error retrieving answers\n"); if (QP_ipc_shutdown_servant()) DieBecause("Error shutting down servant"); }

The final example shows how one could write a C function to turn Prolog's message tracing (see ipc-rpc-tra) on and off.

                       
Prolog Specification
external(settrace, xdr, settrace(+string)). settrace(X) :- msg_trace(_,X).
                                  
C routine
void settrace(OnOff) char *OnOff; { static int psettrace = -1; int k; if (psettrace < 0) { psettrace = QP_ipc_lookup("settrace"); if (psettrace < 0) DieBecause("couldn't find settrace"); } QP_ipc_prepare(psettrace, OnOff); if (QP_ipc_next(psettrace)) DieBecause("settrace failed"); QP_ipc_close(); }