For Programmers: Free Programming Magazines  


Home > Archive > Prolog > May 2004 > [newbie] Usefulness of cut (!) ? As opposed to "fail" ?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author [newbie] Usefulness of cut (!) ? As opposed to "fail" ?
Dirk Mittler

2004-05-12, 9:20 pm

I'm using SWI-Prolog, and learning as I go. I haven't bought a book about
Prolog yet, but intend to. Meanwhile, I'm absorbing as much as I can from
the manual, and from general reading. And from experimenting all day.

One question I have in mind, and maybe somebody can explain this to me, is
why in a list of conditions, it's useful to have a cut operator (!) . One
situation would be, to avoid dangling pointers. Another situation could be,
if it was followed by a semicolon (or). But under what circumstances would
code want to issue a cut (!), not followed by a "fail", and not followed by
a ";" ?

Dirk


Martin Sondergaard

2004-05-12, 9:20 pm

"Dirk Mittler" <mdirk@sympatico.ca> wrote in message
news:vHdnc.105040$ZJ5.2400429@news20.bellglobal.com...
> I'm using SWI-Prolog, and learning as I go. I haven't bought a book about
> Prolog yet, but intend to. Meanwhile, I'm absorbing as much as I can from
> the manual, and from general reading. And from experimenting all day.
>
> One question I have in mind, and maybe somebody can explain this to me, is
> why in a list of conditions, it's useful to have a cut operator (!) . One
> situation would be, to avoid dangling pointers. Another situation could

be,
> if it was followed by a semicolon (or). But under what circumstances would
> code want to issue a cut (!), not followed by a "fail", and not followed

by
> a ";" ?
>
> Dirk
>
>


Its easier with a good book.
I recommend Ivan Bratko's book, "Prolog Programming for Artificial
Intelligence".

You may like to print out this message, to make it easier to read,
its a bit long.

When you write a rule with two or more clauses,
you will often want use only one clause to succeed.

Suppose you have some code like this :
myrule :- myrule2, myrule3, fail.

If you write a rule called "myrule2", you can put a "!" at the end
of one of its clauses, to prevent it going on to the next clauses.

Here is an example of a rule called "what_is" which wrongly goes on to the
last clause,
which is not desireable.
I also show a rule called "what_is2", which is the same except that it uses
two "!" operators,
which make it behave better.


% Here are some facts used by the rules.

verb(run).
verb(jump).
verb(telephone).

noun(box).
noun(man).
noun(telephone).


% Here are two rules, "what_is" and "what_is2".

what_is(X) :-
verb(X),
write( 'It is a verb.' ).

what_is(X) :-
noun(X),
write( 'It is a noun.' ).

what_is(X) :-
write( 'I dont know what it is.' ).


% This version uses a "!" to stop it going on to the last clause
% if clause 1 or clause 2 succeded.

what_is2(X) :-
verb(X),
write( 'It is a verb.' ),
!.

what_is2(X) :-
noun(X),
write( 'It is a noun.' ),
!.

what_is2( _ ) :-
write( 'I dont know what it is.' ).


Here I show how the behaviour of the two rules differs.
This is a prolog session, this is what I did to test the two rules :

?- what_is(jump).
It is a verb.


?- what_is(run).
It is a verb.

Yes
?- what_is(france).
I dont know what it is.

Yes
?- what_is(run), write( ' ok. ' ), fail.
It is a verb. ok. I dont know what it is. ok.

No
?- what_is(box), write( ' ok. ' ), fail.
It is a noun. ok. I dont know what it is. ok.

No
?- what_is(telephone), write( ' ok. ' ), fail.
It is a verb. ok. It is a noun. ok. I dont know what it is. ok.

No
?-
% The word "telephone" is both a verb and a noun,
% so it was correct to say "It is a verb. It is a noun".

% But I don't want it to say "I dont know what it is"
% if it has said "It is a verb" or "It is a noun".

% Now here is the version with cuts.

Yes
?- what_is2(run).
It is a verb.

Yes
?- what_is2(run), write( ' ok. ' ), fail.
It is a verb. ok.

No
?- what_is2(box), write( ' ok. ' ), fail.
It is a noun. ok.

No
?- what_is2(telephone), write( ' ok. ' ), fail.
It is a verb. ok.

No
?- what_is2(france).
I dont know what it is.

Yes
?-


--
Martin Sondergaard.



Christopher Browne

2004-05-12, 9:20 pm

The world rejoiced as "Dirk Mittler" <mdirk@sympatico.ca> wrote:
> I'm using SWI-Prolog, and learning as I go. I haven't bought a book about
> Prolog yet, but intend to. Meanwhile, I'm absorbing as much as I can from
> the manual, and from general reading. And from experimenting all day.
>
> One question I have in mind, and maybe somebody can explain this to me, is
> why in a list of conditions, it's useful to have a cut operator (!) . One
> situation would be, to avoid dangling pointers. Another situation could be,
> if it was followed by a semicolon (or). But under what circumstances would
> code want to issue a cut (!), not followed by a "fail", and not followed by
> a ";" ?


Cut essentially tells the system not to re-explore adjacent paths.

It's somewhat akin to a database COMMIT.

For instance, here are a set of predicates that evaluate what the
"base" for taxation is on a Canadian "Schedule 1" tax form.

line(TAXPAYER, 'Schedule 1', 3, BASE) :-
line(TAXPAYER, 'Schedule 1', 2, AMT),
AMT < 32184,
!,
BASE is 0.

line(TAXPAYER, 'Schedule 1', 3, BASE) :-
line(TAXPAYER, 'Schedule 1', 2, AMT),
AMT < 64369,
32183 < AMT,
!,
BASE is 32183.

line(TAXPAYER, 'Schedule 1', 3, BASE) :-
line(TAXPAYER, 'Schedule 1', 2, AMT),
64368 < AMT,
AMT < 104649,
!,
BASE is 64368.

line(TAXPAYER, 'Schedule 1', 3, BASE) :-
line(TAXPAYER, 'Schedule 1', 2, AMT),
104648 < AMT,
!,
BASE is 104648.

In each case, if the evaluation reaches the ! point, then there will
_never_ be a need to re-evaluate the predicate. One of those 4 cases
will turn out to be true, and the cut means that failures down the
road do NOT lead to any backtracking on this particular predicate.

If something else fails, then we DON'T bother checking to see if one
of the above alternatives could have succeeded, because we know it
wouldn't have.

CUT essentially represents a "hack" to allow you to give the system
hints as to what paths not to bother with. To some degree, it's an
"optimization" that isn't strictly necessary; it just makes it faster
to evaluate complex predicates. On the other hand, if there are any
side-effects in some predicates, it is an error NOT to do a CUT when
you reach certain points.
--
(format nil "~S@~S" "cbbrowne" "acm.org")
http://www.ntlug.org/~cbbrowne/finances.html
Perhaps there should be a new 'quantum' datatype; you would be able to
take its address or value, but not both simultaneously.
-- Michael Shields
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com