a not operator that works... 
Author Message
 a not operator that works...

We're using Quintus Prolog Release 3.1.4, which doesn't seem to have a not/1
operator.  However, our textbook (Minimanual in Prolog) says not is defined
as:

not(X) :- X, !, fail.

This only changes 'yes' to 'no'.  It does not change 'no' to 'yes' which I
need as I'm testing to see whether a node in a tree is the root or not with
root(X) :- not(edge(_,X).  If there's no edge from anything to this node,
then it's a root.

Is there a better definition of 'not' that works both ways?  There's also
/== for not equal to, but I've tried edge(_,X) /== yes and edge(_,X) /==
true with no luck.  Is there a reserved word for 'yes' or 'true' that I
should be using?

Any hints appreciated!  I've done SQL and UniQuery for long enough to have
the concepts down, but I'm having trouble explaining to Prolog what I want
it to do.

--
Wendy in Chandler, AZ



Tue, 11 May 2004 03:17:52 GMT  
 a not operator that works...

Quote:
> We're using Quintus Prolog Release 3.1.4, which doesn't seem to have a
not/1
> operator.  However, our textbook (Minimanual in Prolog) says not is
defined
> as:

> not(X) :- X, !, fail.

<snipped>

If that's what your textbook says, take it outside and burn it.

Quintus' is-not-provable operator is written \+ X
e.g.

| ?- \+ true.

no

| ?- \+ fail.

yes

--
Regards

John Fletcher



Tue, 11 May 2004 03:43:32 GMT  
 a not operator that works...

Quote:
> > not(X) :- X, !, fail.
> If that's what your textbook says, take it outside and burn it.
> Quintus' is-not-provable operator is written \+ X

It does indeed say that... but I'll wait until after the final for the
bonfire, as it does have other useful information. Looks like I'd better
stick to the Quintus manual webpages rather than the textbook.

The \+ operator works perfectly.  What's _scary_ is that I emailed my
instructor with my problem and he said to use \==.    Which is how I ended
up here bothering you nice people. :)  Who knows what the rest of my
classmates are doing... I don't see them here, and the TA wasn't any help,
either!

--
Wendy in Chandler, AZ



Tue, 11 May 2004 04:01:07 GMT  
 a not operator that works...
: not(X) :- X, !, fail.
: This only changes 'yes' to 'no'.  It does not change 'no' to 'yes' which I

That is true, but did you read your textbook carefully ? Is this the
_complete_ definition of not/1 ? The ! in your body would make no sense
if this was the complete definition of not/1, would it ?

Remko



Tue, 11 May 2004 04:21:30 GMT  
 a not operator that works...

Quote:

>> : not(X) :- X, !, fail.
>> : This only changes 'yes' to 'no'.  It does not change 'no' to 'yes'
> That is true, but did you read your textbook carefully ? Is this the
> _complete_ definition of not/1 ? The ! in your body would make no sense
> if this was the complete definition of not/1, would it ?

That's the whole definition.  Page 65, Minimanuals in Scheme and Prolog.
I've already been advised to burn the book. :)

It actually says:
not(Whatever) :- Whatever,
                           !,
                           fail.
not(Whatever).

but when I include the last line in my .pl file, it complains about the
singleton variable.  I took that to mean that they were giving an example of
how to use not/1 once they had defined it.

Apparently, not/1 is built in to other Prologs, but not Quintus.  I suppose
I could define it:  not(X) :- \+ X. now that I know about the \+ operator.

--
Wendy in Chandler, AZ



Tue, 11 May 2004 04:36:34 GMT  
 a not operator that works...
: not(Whatever) :- Whatever,
:                           !,
:                           fail.
: not(Whatever).

: but when I include the last line in my .pl file, it complains about the
: singleton variable.  I took that to mean that they were giving an example of
: how to use not/1 once they had defined it.

Prolog doesn't complain, it 'warns'. Singleton variable means that your
variable is only used once in your clause, which usually indicates you
misspelled something.
In this case, 'Whatever' is only used once, yet your declaration is
correct. To ommit the message, you can usually start your singleton variable
with an _.

Coming back to your problem: try the above definition of not, and ignore
the warning generated on singleton variables. Does it do what you want
it to do ? And it's probably very interesting to find out why it does(n't) !

Remko

PS: Bart Demoen pointed out to me that it can make sense to have a cut
    in your last clause. Sorry for my mistake.



Tue, 11 May 2004 05:32:38 GMT  
 a not operator that works...

Quote:

> It actually says:
> not(Whatever) :- Whatever,
>                            !,
>                            fail.
> not(Whatever).

That's the correct definition. The second clause is there to succeed for
all values of Whatever such that Whatever is not provable.

Quote:

> but when I include the last line in my .pl file, it complains about the
> singleton variable.  I took that to mean that they were giving an example of
> how to use not/1 once they had defined it.

Some Prolog systems warn about singleton variables (as the Whatever in the
second clause above) in case the singleton is the result of a typo, as in
the following incorrect version of the first clause

not(Whatever) :- Whatnot, !, fail.

However, it should just be a warning. If the warning bothers you, rewrite
the second clause as

not(_Whatever).

Many Prolog systems allow singleton variables without warning if the first
character of the variable name is "_".

-- F



Tue, 11 May 2004 05:32:57 GMT  
 a not operator that works...

Quote:

> : not(Whatever) :- Whatever,
> :                           !,
> :                           fail.
> : not(Whatever).
> In this case, 'Whatever' is only used once, yet your declaration is
> correct. To ommit the message, you can usually start your singleton
variable
> with an _.

Ahhhh.... in some other languages, warnings like that mean it didn't
compile.  I didn't go any further until I got the message to stop happening.
So I guess the book is safe from the bonfire. :)

Back to understanding this implementation of not/1:  I understand the first
part-- if Whatever is in the factbase, even once, it fails.  (It works
without the cut, also, it's just less efficient that way.  I think.)

But the line I left out... it must always succeed.  I tried defining abc(X).
and it always succeeds, no matter what you put as the argument.  Looking at
the trace of it, I think when you call abc(z). it makes a fact, and then
finds that fact and succeeds.  Close?

sitting at the feet of the masters...
--
Wendy in Chandler, AZ



Tue, 11 May 2004 08:39:05 GMT  
 a not operator that works...
Quote:

> But the line I left out... it must always succeed.

It does. But if the value of Whatever was such that the call to Whatever
in the first clause succeeded, the cut (!) that follows the call to
Whatever commits Prolog to the first clause, and "fail" makes the clause
(and thus the not(Whatever) call) fail. Without the cut, the second clause
would always be tried, and so not(Whatever) would always succeed.

-- F



Tue, 11 May 2004 10:56:01 GMT  
 a not operator that works...

Quote:


> > But the line I left out... it must always succeed.
> It does. But if the value of Whatever was such that the call to Whatever
> in the first clause succeeded, the cut (!) that follows the call to
> Whatever commits Prolog to the first clause, and "fail" makes the clause
> (and thus the not(Whatever) call) fail. Without the cut, the second clause
> would always be tried, and so not(Whatever) would always succeed.

{tries it again with and without the cut} ... and of course, you're correct.

Help me trace the code:
bay(odie).
not(X) :- X, !, fail.
not(X).

So I call it with
not(bay(odie)).
It finds that X is in the factbase, sees the !, hits the 'fail.' and reports
'no.'.  If the ! keeps it from going farther, I don't understand how it gets
PAST the ! to the fail.

Paraphrasing what I've read, the ! is supposed to mean 'don't go past here
if you get here again.'  But I don't know how to apply that to tracing the
code.

--
Wendy in Chandler, AZ



Tue, 11 May 2004 11:28:11 GMT  
 a not operator that works...
G'day all.

Quote:

>Paraphrasing what I've read, the ! is supposed to mean 'don't go past here
>if you get here again.'

Kind of.

Two Prolog clauses are meant to mean logical disjunction.  So, for
example:

        foo(bar).
        foo(baz).

is equivalent to:

        foo(X) :- (X = bar ; X = baz).

Prolog implements disjunction by backtracking.  First it tries X = bar,
then later if you need another solution, it tries X = baz.

If Prolog were "pure" logic it wouldn't matter which one you tried first,
as they are both "correct".  Just so long as you tried them both when you
need another solution.  However, Prolog is not a pure language.  It says
that you try the first clause, then the second and so on.

Your definition of not/1:

        not(Whatever) :- Whatever, !, fail.
        not(_Whatever).

is the same as:

        not(Whatever) :- (Whatever, !, fail ; true).

What the cut '!' means is something more like "if you've gotten this
far, don't backtrack further in this predicate".  That is, it commits
to one possibility.  That way, when the first clause fails, the second
clause is not tried, as would happen if the cut were not there.

Your confusion is because the cut is not logical, and using it is not
pure "logic programming".  If it were, (Anything ; true) would always
succeed.  (Or possibly infinitely loop, but that's not important for
this discussion.)

If you want to avoid undue stress, avoid using the cut in your own
assignment-level programs.  The frustration you will get from trying to
understand what it does isn't worth it.

Cheers,
Andrew Bromage



Tue, 11 May 2004 12:36:59 GMT  
 a not operator that works...

Quote:

> Two Prolog clauses are meant to mean logical disjunction.  So, for
example:
> not(Whatever) :- Whatever, !, fail.
> not(_Whatever).
> is the same as:
> not(Whatever) :- (Whatever, !, fail ; true).

It makes much more sense to me in the second incarnation, thanks!  I'll
think of the ! as 'commit,' then, in the places I have to use it.

--
Wendy in Chandler, AZ



Tue, 11 May 2004 23:42:25 GMT  
 a not operator that works...

To perhaps state the obvious, be aware that to make sense as negation
the argument Whatever needs to be fully ground upon calling not(_) with the
standard definition given in two versions below

Consider for instance

    ?- not(X=1) , X=2.

that fails

while

    ?- X=2, not(X=1).

succeeds with X bound to 2 as it should

or

    ?- not(not(X=1)), X=2.

that succeeds with X bound to 2
while

    ?- X=2, not(not(X=1)).

fails
 as it should.

Quote:


>>Two Prolog clauses are meant to mean logical disjunction.  So, for

>example:

>>not(Whatever) :- Whatever, !, fail.
>>not(_Whatever).
>>is the same as:
>>not(Whatever) :- (Whatever, !, fail ; true).

>It makes much more sense to me in the second incarnation, thanks!  I'll
>think of the ! as 'commit,' then, in the places I have to use it.

>--
>Wendy in Chandler, AZ



Mon, 17 May 2004 19:27:26 GMT  
 a not operator that works...

Quote:

> To perhaps state the obvious, be aware that to make sense as negation
> the argument Whatever needs to be fully ground upon calling not(_) with the
> standard definition given in two versions below

> Consider for instance

>     ?- not(X=1) , X=2.

> that fails

> while

>     ?- X=2, not(X=1).

> succeeds with X bound to 2 as it should

Requiring groundness checking before a negated
goal is called, is safe, but too conservative.

I think it is OK to skip the groundness check when
the negated goal FAILS (like f(X)=1 does):

?- not(f(X)=1),X=2.
X=2

yes
?- X=2,not(f(X)=1).
X=2

This definition of negation is safe, while only testing
for groundess half of the time:

not(X):- \+ X,!.
not(X):-ground(X),!,fail.
not(X):-user_error('should be ground',not(X))->fail;abort.

The reasoning is that if a goal X fails (and its
negation succeeds), it would do just the same if it
were instantiated before (or after) X was called.

Paul Tarau



Wed, 19 May 2004 18:08:43 GMT  
 a not operator that works...
Assuming the following definition
user_error(X,Y) :- write(user_error(X,Y)),nl.

you still have non-logical behaviour such as this to deal with:

?- not(not(X=1)),X=2.                          
user_error(should be ground,not(_122=1))

X = 2 ? ;

Why present an answer that is clearly wrong (even though the error message
printed indicates that something is wrong, it can be hidden in lots of
output)?

I accept your reasoning if the last clause is

not(X):-write(user_error('should be ground',not(X))),nl, abort.

Quote:

>Requiring groundness checking before a negated
>goal is called, is safe, but too conservative.

>I think it is OK to skip the groundness check when
>the negated goal FAILS (like f(X)=1 does):

>?- not(f(X)=1),X=2.
>X=2

>yes
>?- X=2,not(f(X)=1).
>X=2

>This definition of negation is safe, while only testing
>for groundess half of the time:

>not(X):- \+ X,!.
>not(X):-ground(X),!,fail.
>not(X):-user_error('should be ground',not(X))->fail;abort.

>The reasoning is that if a goal X fails (and its
>negation succeeds), it would do just the same if it
>were instantiated before (or after) X was called.

>Paul Tarau



Thu, 20 May 2004 08:30:14 GMT  
 
 [ 17 post ]  Go to page: [1] [2]

 Relevant Pages 

1. GCL not working ( or operator error )

2. Does not work with TPS but works with DBF

3. 5.2 Network application works with 95, does not work with 98

4. Does the Autosave works in Excel , if not how to make it work in my program

5. Work library not same as current working library

6. REALdatabase not null and primary key not working

7. NOT Allow Inserts not working

8. Q: (IF WS-VAR NOT = SPACE) does not work in DBCS context

9. tcl/tk man pages use .HS, not .TH for title, so man -k does not work

10. How does the ?= operator work in Eiffel

11. fixpoint operator that works with functions of different numbers of arguments

12. Old tcl programs don't work - equality operator in tcl 8.3

 

 
Powered by phpBB® Forum Software