Article View: comp.lang.prolog
Article #571Re: Fun. vs. Logic
From: John Cleary
Date: Tue, 12 Dec 1989 04:28
Date: Tue, 12 Dec 1989 04:28
111 lines
5159 bytes
5159 bytes
In article <11500020@hpldola.HP.COM>, patch@hpldola.HP.COM (Pat Chkoreff) writes:
>
> Negation worries me. A language feature should either be essential for
> computation, or defined in terms of something that is. Negation is NOT
> essential for computation, so I HOPE that it can be defined in terms of pure
> Horn clauses, which are. Is there an effective procedure for removing
> negation from a first-order logic program, resulting in a pure Horn clause
> program? I wouldn't necessarily USE the procedure -- I just want to know if
> it exists. If not, then something stinks.
There is a simple translation of negation to first order logic that requires
a correct implementation of not equals. Given a predicate say p(X1,...) which
is called somewhere in the form not(p(Y1...)) then the call can be replaced
by a positive call np(Y1,...) where the definition of np can be derived
systematicly from that for p.
If p is defined as follows:
p(X1,...) :- a11(...), ..... a1n1(....)
p(X1,...) :- a21(...), ......a2n2(....)
...
p(X1,...) :- am1(...), ..... amnm(....)
then np is defined as
np(X1,...):- not(a11(...)), not(a21(...)), ... not(am1(...))
np(X1,...):- not(a11(...)), not(a21(...)), ... not(am2(...))
....
np(X1,...):- not(a1n1(...)), not(a21(...)), ... not(amnm(...))
where each of the not(aij(..)) can be further translated or if they
are of the form not(not(q(...)) replced by q(...).
Warning there can be a lot of these clauses: n1*n2*n3*...nm to be precise.
Also I have assumed the heads of teh clauses contain only free variables
so the aij(...) may be equality(=). To avoid a circular definition of not(_=_)
this needs to be done explicitly. Given a finite Herbrand Universe
there are only a finite (but possibly large) number of pairs of things that
are not equal so this too can be written down (it is however different for
each program).
I am not entirely sure of the theoretical status of this translation.
It assumes that the completion of the program is what you really meant
and gives the usual semantics for stratified programs as near as I can tell.
For nostratified programs, for example:
p:- not(p)
the translated program is:
p:- not_p
not_p:-p.
which would conclude that both p and not_p are false. So in there is no
guarantee that the result will be consistent in these cases.
The standard minimal meta-interpreter for Prolog can be extended to give this
type of behavior as follows. Assume that the program is represented by the
clauses(...) predicate which representes all the clauses for a particular
program as a single list of clauses. The positive call is given by call(...)
and the negative by neg(...).
call(true):- true.
call((A,B)):- call(A), call(B).
call(not(A)):- neg(A).
call(X=X):- true.
call(A):- clauses(List), scan(A,List).
scan(A,[(A:-B)|_]):- call(B).
scan(A,[_|Tail]):- scan(A,Tail).
neg((A,B)):- neg(A).
neg((A,B)):- neg(B).
neg(X=Y):- not_equals(X,Y).
neg(not(A)):- call(A).
neg(A):- clauses(List), neg_scan(A,List).
neg_scan(A,[(H:-B)|Tail]):- not_equals(A,H), neg_scan(A,Tail).
neg_scan(A,[(A:-B)|Tail]):- neg(B), neg_scan(A,Tail).
not_equals(...) %needs to be defined depending on the program
As you say you might not want to use this although depending on the
circumstances programs translated or interpreted this way can be efficient
and these techniques contain the essence of a number of the approaches
to negation that are available.
>
> I'll continue to use the eager Prolog that's available to me. I need to
> find out about NU-Prolog, even if I don't use it. At least it might give me
> a "meta-language" for documenting (and thinking about) the termination
> properties of my predicates.
>
My personal experience is that NU-Prolog is a wonderful language for
programming in. In fact the step up from Prolog to NU-Prolog was almost
as much fun as the step from imperative languages to Prolog.
You need many fewer cuts and can adopt a much freer and more expressive
programming style. Try it you'll love it.
As for efficiency it is not intrinsicly much less efficient than standard
Prologs and I am sure that if as much effort was put into its implementtion
as into other systems out there it would run just as fast (I have heard
figures of 10% to 15% slowdown over eager Prologs but this is surely
application dependent).
John G. Cleary
Department of Computer Science
University of Calgary
2500 University Drive
N.W. Calgary
Alberta T2N 1N4
Canada
cleary@cpsc.UCalgary.ca
Phone: (403)282-5711 or (403)220-6087
Technical Details
Message-ID:
<2221@cs-spool.calgary.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!attcan!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!zephyr.ens.tek.com!uw-beaver!ubc-cs!alberta!calgary!cpsc!clearyReferences:
<11500018@hpldola.HP.COM> <11500020@hpldola.HP.COM>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!zephyr.ens.tek.com!uw-beaver!ubc-cs!alberta!calgary!cpsc!cleary From: cleary@cpsc.ucalgary.ca (John Cleary) Newsgroups: comp.lang.prolog Subject: Re: Fun. vs. Logic Summary: translation of negation to horn cluases Message-ID: <2221@cs-spool.calgary.UUCP> Date: 12 Dec 89 04:28:11 GMT References: <11500018@hpldola.HP.COM> <11500020@hpldola.HP.COM> Sender: news@calgary.UUCP Lines: 111