Path: utzoo!utgpu!attcan!uunet!tut.cis.ohio-state.edu!ucbvax!agate!apple!sun-barr!newstop!sun!quintus!jbeard
From: jbeard@quintus.UUCP (Jeff Beard)
Newsgroups: comp.lang.prolog
Subject: Re: set predicates for db-access
Keywords: prolog, database, set predicates
Message-ID: <1240@quintus.UUCP>
Date: 11 Aug 89 17:06:01 GMT
References: <303@unizh.UUCP>
Reply-To: jbeard@quintus.UUCP (Jeff Beard)
Organization: Quintus Computer Systems, Inc: Mountain View, Ca
Lines: 98


Article 1533 of comp.lang.prolog:
>From: draxler@unizh.UUCP (draxler)
Posted: Thu Aug 10 15:02:25 1989

> 
> Question:
>   Does it make sense to use Prolog's all solutions set predicates as
>   database predicates to access external relational database systems?
> 
> These systems either rely on Prolog's tuple-at-a-time access method or
> implement a completely new logic language that handles sets. 
> 
> On the other hand, if Prolog's set predicates were modified slightly, 
> then we would have standard Prolog coupled with a standard relational
> database system in an elegant and efficient way. 
> 
> The modifications are transparent to the Prolog programmer - findall, bagof
> and setof will not change their behaviour. 
> The set predicates must be changed in such way that they are able to tell 
> whether a fact that is searched for is in the internal Prolog workspace or
> not. If it is, the set predicate is evaluated as usual. If it isn't, then
> a database query is generated and transmitted to the database system.
> In either case the list of instantiated terms in the set predicates 
> contains the data we were looking for.
> 
> Does such an approach make sense? Where are the problems that I have
> overseen?

First, accessing a commercial DBMS of some enterprise may entail tables 
containing tens of thousands of tuples.  Imagine the table CustInfo of the
phone company or the U.S library of congress BooksOnHand.  To attempt to 
retrieve and instantiate the solution set per se is begging to overflow
available memory.

Second, there is a real time/space cost to each solution set so retrieved 
and the higher level logic (as in a browser) may well need very few tuples
prior to aborting the query.  The cost per useful tuple can be extream.

For this and other reasons, the Quintus Prolog Database Interface defines
relational predicates as the specification of:

The db/3 facts define a specific relational interface.

     db(TableName, DbName, Predname)

and

As an example, the following db/3 facts define Prolog relations item/7,
customer/7, and order/3.
 
     db('ITEM', tutorial,
             item(   'Serial_Number':integer ,
                     'Model_Number':integer,
                     'Manufacturer_ID':integer,
                     'Acquisition_Date':integer,
                     'Sales_Price':integer,
                     'Order_Number':integer,
                     'Purchase_Price':integer
             )).

     db('Customer', tutorial,
             customer('Customer_Number':integer,
                     'Name':string,
                     'Address':string,
                     'City':string,
                     'State':string,
                     'Zip_Code':string,
                     'Phone_Number':string
             )).

     db('orders', tutorial,
             order(  'Order_Number':integer,
                     'Date_Ordered':integer,
                     'Customer_Number':integer
             )).



when a db_connect(DbName) is encountered, the connection is made, the 
schema retrieved for each db/3 and the predicate implied
(item/7,customer/7, and order/3) are built.

When such a relational predicate is called, eg orders(Onum,Odate,CuNum).
the requisite SQL is generated and the first projection of 
orders(Onum,Odate,CuNum) is instantiated.  The normal Prolog backtacking
mechanics will provide additional members of the solution set until
no more are available, which returns an order/3 fail.

With such a primative, Prolog conjuctions can be transformed into SQL JOINs,
with the work being performed by the external DBMS rather than in Prolog.
eg: (read _* as anonymous variable of dis-interest)

	orders(Onum,Odate,CuNum), 
	item(_Serial,_Model,_Mfg,_Ad,Price,Onum,WholeSale).

will produce a join of 'ITEM' to 'orders' on field 'Order_Number' and
the projected results of Onum,Odate,CuNum,Price,WholeSale.