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.plforeign(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); }