|
|||
|
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 |
|
|
||||
|
||||
|
|
|
|||
|
"Dirk Mittler" <mdirk@sympatico.ca> wrote in message
news:vHdnc.105040$ZJ5.2400429@news20.bellglobal.co m... > 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. |
|
|||
|
I still plan to buy such book. But you've explained it extremely well,
thank you. Even without a book, I get the point. Dirk "Martin Sondergaard" <nobody@nowhere.com> wrote in message news:1084062608.30971.0@damia.uk.clara.net... > "Dirk Mittler" <mdirk@sympatico.ca> wrote in message > news:vHdnc.105040$ZJ5.2400429@news20.bellglobal.co m... [...] > > 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. > > > |
|
|||
|
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 |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|