Newsgroups: comp.lang.prolog
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!oitnews.harvard.edu!purdue!lerc.nasa.gov!magnus.acs.ohio-state.edu!math.ohio-state.edu!howland.reston.ans.net!newsfeed.internetmci.com!usenet.eel.ufl.edu!warwick!bsmail!miki!jwl
From: jwl@miki.cs.bris.ac.uk (John Lloyd)
Subject: Re: is there a sound/complete implementation of negation as failure?
Message-ID: <DEqtF3.Dzo@uns.bris.ac.uk>
Keywords: Constructive negation
Sender: jwl@miki (John Lloyd)
Nntp-Posting-Host: miki.cs.bris.ac.uk
Organization: Unviversity of Bristol, Dept of Computer Science
References:  <42q4gc$1vb@coopers.cs.ubc.ca>
Date: Mon, 11 Sep 1995 13:28:15 GMT
Lines: 129

In article <42q4gc$1vb@coopers.cs.ubc.ca>, poole@cs.ubc.ca (David Poole) writes:
|> I am looking for a version of a Prolog-like language that correctly
|> implements negation as failure, say according to Clark's semantics or
|> the stable model semantics or the well founded semantics (I am only
|> interested in acyclic programs, so I am not concerned about cases
|> where these semantics differ). I am not satisfied with a program that
|> delays negation as failure with free variables, and flounders on
|> programs that have free variables in the negation.
|> 
|> Here is the application:
|> I am constructing a list of terms of the form p(X,Y) and want to enforce
|> the constraint that p is functional (if the X's agree the Y's must agree).
|> 
|> Here is a specification of the program:
|> 
|> functional(L) :-
|>    \+ notfun(L).
|> notfun(L) :-
|>    member(p(X,Y1),L),
|>    member(P(X,Y2),L),
|>    Y1 \= Y2.
|> 
|> member(X,[X|_]).
|> member(X,[_|Z]) :-
|>    member(X,Z).
|> 
|> %  X \= Y is true of X and Y are not equal
|> X \= Y :-
|>    \+ X=Y.
|> 
|> 
|> I expect the following results (all of which follow from the above program
|> using Clark's completion, or the stable model semantics or ... )
|> 
|> ? functional([p(a,b),p(b,c),p(a,d)])
|> fails
|> 
|> ? functional([p(a,b),p(b,c),p(d,d)])
|> succeeds
|> 
|> ? functional([p(a,b),p(b,c),p(a,X)])
|> succeeds with X=b
|> 
|> ? functional([p(a,Y),p(b,c),p(a,X)])
|> succeeds with Y=X
|> 
|> ? functional([p(a,b),p(Z,c),p(c,d)])
|> succeeds with the costraint that Z \= a and Z \= c
|> 
|> ? functional([p(a,Y),p(Z,c),p(a,X)])
|> succeeds with two answers:
|>   X=Y & Z\=a
|>   Z=a X=Y=c
|> (or some other representation of the constraints on these)
|> 
|> Thanks for your help,
|> David


Here is the Escher solution to this nice little challenge.  I've edited 
the queries slightly (Escher doesn't have a clean user interface yet), 
but the answers are exactly as Escher prints them.  Note that the last 
answer is equivalent to the answer given by David Poole.

It would be interesting to hear about other LP systems which can handle
this kind of thing.

John Lloyd


((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((


MODULE    ConstructiveNegation.

IMPORT    Lists.

CONSTRUCT Item1/0, Item2/0.

FUNCTION  A, B, C, D : One -> Item1.

FUNCTION  P : Item1 * Item1 -> Item2.


FUNCTION  Functional : List(Item2) -> Boolean.

Functional(z) =>
    ~ SOME [x, y1, y2] (Member(P(x,y1), z) & Member(P(x,y2), z) & y1 ~= y2).


((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((


? Functional(Cons(P(A,B), Cons(P(B,C), Cons(P(A,D), Nil))))

False



? Functional(Cons(P(A,B), Cons(P(B,C), Cons(P(D,D), Nil))))

True



? Functional(Cons(P(A,B), Cons(P(B,C), Cons(P(A,x), Nil))))

x = B



? Functional(Cons(P(A,y), Cons(P(B,C), Cons(P(A,x), Nil))))

x = y



? Functional(Cons(P(A,B), Cons(P(z,C), Cons(P(C,D), Nil))))

(z ~= A) & (z ~= C)



? Functional(Cons(P(A,y), Cons(P(z,C), Cons(P(A,x), Nil))))"

((z ~= A) & (x = y)) \/
(((z ~= A) & ((x = C) & (y = C))) \/
((x = C) & (y = C)))

