Nested Prolog Queries

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); }