[comp.lang.prolog] multiple copies of a clause in the DB

tim@linc.cis.upenn.edu (Tim Finin) (08/07/87)

I'm studying various ways to extend Prolog's simple model of the
database (e.g. a flat, global collections of clauses) to a richer
hierarchical one with inheritance.  I am trying to decide whether to
allow multiple instances of a clause in a resulting database view.

Most Prolog implementations, at least those descendant from DEC-10
Prolog, do allow the database to contain two identical clauses.  Most
of the non-Prolog logic programming languages that I am familiar with
do not.  I am interested in discovering what use, if any, people have
made of the ability to assert multiple copies of a clause into the
database.  

I, for one, have never found a use for this in practice.  In fact, it
has only effected my life by being a source of bugs.  It is easy
enough to accidentally get multiple copies of a clause in the database
by consulting a file instead of reconsulting it or by defining the
same predicate in two different files.  This can easily mess up your
program unless you use a rather pure logic programming style which
doen't depend on the order in which the clauses are stored in the
database.

Has anyone out there found a good use for this Prolog "feature"?

Tim

debray@arizona.edu (Saumya Debray) (08/08/87)

In article <1696@super.upenn.edu>, tim@linc.cis.upenn.edu (Tim Finin) writes:

> Most Prolog implementations allow the database to contain two
> identical clauses. [...] I have never found a use for this in practice.
> In fact, it has only effected my life by being a source of bugs.  It
> is easy enough to accidentally get multiple copies of a clause in the
> database by consulting a file instead of reconsulting it or by defining
> the same predicate in two different files.  This can easily mess up
> your program ...

In my view, in this case the underlying implementation should provide
something that focuses on efficiency, without taking away from the user
the flexibility of imposing additional constraints if he so desires.
If I don't care about the presence of duplicate clauses, I shouldn't have
to pay the price of checking for duplicates; on the other hand, if I do
care about duplicates, it's easy enough to extend "assert" to take care of
this, e.g.:

   my_assert((H :- B)) :- clause(H,B) -> true ; assert((H :- B)).
   my_assert(Fact) :- clause(Fact,true) -> true ; assert(Fact).

Since "consult" is basically a read-assert loop, the analogous extension
of "consult" to "my_consult" is straightforward.

Such an approach is flexible enough to handle stronger notions of what
constitutes "redundancy" in the database as well, e.g. if I wanted to
ensure that only those facts were asserted that were not provable from
what's already in the database, I'd write something like

   my_assert(X) :- not(X), assert(X).   [*]

Of course, with this "my_assert" is no longer guaranteed to terminate,
but that's the user's problem.

[* This only works for ground facts, of course, but you see what I'm
getting at.]

In summary: language constructs should be designed so that (i) users
don't have to pay for features they don't use; and (ii) users should
have the flexibility of extending the basic language features to do
what they want without undue suffering.
-- 
Saumya Debray		CS Department, University of Arizona, Tucson

     internet:   debray@arizona.edu
     uucp:       {allegra, cmcl2, ihnp4} !arizona!debray