This example demonstrates how you can have nested queries to Prolog
from C. For brevity sake, we don't check the statuses returned by all
the calls to QP_next_solution() for error values. This
is not advised in real applications. This example also shows the use of
QP_cut_query().
books.pl
foreign(print_books, c, print_books).
foreign_file(books, [print_books]).
:- load_foreign_files(books, []),
abolish([foreign/3, foreign_file/2]).
:- extern(author(-atom)).
:- extern(book(+atom,-atom)).
author(hesse).
author(kafka).
author(dostoyevski).
book(dostoyevski, idiot).
book(dostoyevski, gambler).
book(hesse, steppenwolf).
book(hesse, sidhdhartha).
book(hesse, demian).
book(kafka, america).
book(kafka, trial).
book(kafka, castle).
book(kafka, metamorphosis).
books.c
#include <quintus/quintus.h>
#define MAX_BOOKS 3
void print_books()
{
QP_pred_ref author, book;
QP_qid q1, q2;
QP_atom a, b;
int count;
if (!(lookup_predicate("author", 1, "user", &author)))
return;
if (!(lookup_predicate("book", 2, "user", &book)))
return;
if ((q1 = QP_open_query(author, &a)) == QP_BAD_QID) {
printf("Cant open outer query\n");
return;
}
while (QP_next_solution(q1) == QP_SUCCESS) {
/* For each solution returned by author(X) do */
if ((q2 = QP_open_query(book, a, &b)) == QP_BAD_QID) {
printf("Cant open inner query\n");
break;
}
printf("Books by %s:\n", QP_string_from_atom(a));
count = 0;
while ((count < MAX_BOOKS) &&
(QP_next_solution(q2) == QP_SUCCESS)) {
/* Find atmost MAX_BOOKS solns for books(X,Y) */
printf("\t\t%s\n",QP_string_from_atom(b));
count++;
}
QP_close_query(q2);
}
QP_close_query(q1);
}