Download presentation
Presentation is loading. Please wait.
Published byMelina Williams Modified over 9 years ago
1
Flow of Control Chapter 5
2
Flow of Control n What order computer uses to get answers –sub-goal ordering –clause ordering n Prolog flow-of-control –sequence + backtracking standard –ways to modify that n Today –disjunction, cut, (& negation)
3
Disjunction n Prolog uses comma for AND n It uses semi-colon for OR person(X) :- parent(X, _) ; parent(_, X). No comma here – it’s not an AND Semi-colon usually alone on its own line X is a person if they’re someone’s parent OR someone’s child
4
Control Using Disjunction n Prolog gives all answers for first part before starting answers for second part –then gives all answers for second part person(X) :- parent(X, _) ; parent(_, X). People will be returned in this order: pam, tom, tom [sic], bob, bob, pat bob, bob, liz, ann, pat, jim Tom and Bob are parents of two Bob also has two parents
5
AND and OR n Semi-colon splits rule into two parts –commas group together on either side man(X) :- parent(X, _), male(X); parent(_, X), male(X). First find all the parents that are male Then find all the children that are male
6
AND and OR II n Use parentheses to group differently man(X) :- ( parent(X, _) ; parent(_, X) ),male(X). First find the parents Then find the children But make sure they’re male in either case
7
OR versus Clauses n Putting a semi-colon in is marginally more efficient than using two clauses –but it means the same thing man(X) :- parent(X, _), male(X); parent(_, X), male(X). man(X) :- parent(X, _), male(X). man(X) :- parent(_, X), male(X).
8
Exercise n Rewrite the following predicate without the semi-colon notation: translate(Number, Word) :- Number = 1, Word = one ; Number = 2, Word = two ; Number = 3, Word = three.
9
Preventing Backtracking n Backtracking is automatic n Sometimes we don’t want it –first answer is only correct one –know there aren’t any more answers n Block backtracking by using a “cut” –predicate is !/0
10
Example Problem n Grocery shopping –have a list –store has some items (not all) –visit store, buy what you can… –…calculate total price… –…and what’s left to buy (at another store) ?- costToBuy([ham, eggs, nails], Cost, Rest). Cost = 4, Rest = [nails] This store doesn’t sell nails
11
Grocery Lists n Write the costToBuy/3 predicate n If nothing on list –price is 0 –nothing left to buy n If there is an item H –if it has a price, you can buy it –otherwise, you can’t buy it Base case Recursive case #1 Recursive case #2
12
Recursive Cases n You can buy it –get its price –get the price of the rest of the stuff –add them together to get the total n You can’t buy it –it is (or should be) on the list of can’t-buys –get the price of everything else
13
Does It Have a Price? n If it has a price, Prolog will find it n So ask for the price –if there is a price, you’ll get it & carry on –if there is no price, Prolog fails (= says no) n And what if it fails? –Prolog will back up and try something else –the something else should be add it to the list of stuff you can’t get
14
costToBuy/3 % costToBuy(+L, ?P, ?R) costToBuy([], 0, []).% nothing on list costToBuy([H|T], P, R) :-% can buy H price(H, PH),% (H has a price) costToBuy(T, PT, R), P is PH + PT. costToBuy([H|T], P, [H|R]) :-% couldn’t buy H costToBuy(T, P, R).% (H had no price)
15
At the Store price(milk, 5). price(eggs, 1). price(ham, 3). price(bread, 1). price(tomato, 2). price(fish, 3). costToBuy([], 0, []). costToBuy([H|T], P, R) :- price(H, PH), costToBuy(T, PT, R), P is PH + PT. costToBuy([H|T], P, [H|R]) :- costToBuy(T, P, R).
16
Buying Stuff Example ?- costToBuy([ham, eggs, nails], Cost, Rest). Cost = 4 Rest = [nails] Yes ?- costToBuy([milk, fish, bread], P, R). P = 9 R = [] Yes
17
Further Solutions ?- costToBuy([ham, eggs, nails], Price, Rest). Price = 4 Rest = [nails] ; Price = 3 Rest = [eggs, nails] ; Price = 1 Rest = [ham, nails] ; Price = 0 Rest = [ham, eggs, nails]
18
costToBuy and Backtracking n The predicate gives the correct answer first –adds up prices of things with prices –adds un-priced objects to the can’t-buy list n Backtracking gives more answers –objects with prices get added to can’t-buy list n Good Thing / Bad Thing –drop items you can’t afford –not precisely what we said it should be
19
Avoiding Backtracking n We’d like to commit to the first rule (second clause) once we find H has a price –don’t want it to go back and try more rules n We can tell Prolog to commit to a rule –called “cutting” a predicate –predicate is called “cut” –predicate is !/0
20
costToBuy/3 With Cut costToBuy([], 0, []).% nothing on list costToBuy([H|T], P, R) :-% can buy H price(H, PH),% (H has a price) !,% commit to this rule costToBuy(T, PT, R), P is PH + PT. costToBuy([H|T], P, [H|R]) :-% couldn’t buy H costToBuy(T, P, R).% (H had no price)
21
Going Shopping Again ?- costToBuy([ham, eggs, nails], P, R). P = 4 R = [nails] ; No n Now matches what we said –total price of things we can buy –list of things not available to buy –no “extra” solutions
22
What Cut Does n Cut commits you to the current rule –can’t backtrack to other rules for this predicate, on this call –if this predicate is going to succeed, it’s going to succeed in this rule –if this rule fails, the predicate fails –commitment occurs when you hit the ! –can still use other rules if didn’t get to the !
23
Loaves and Fishes Looking at eggs price(eggs, P) %makes P = 1 !, %commit here costToBuy(…), & cetera Looking at nails price(nails, P) %fails Look for another rule nails gets added to R Even if you backtrack, you won’t get to the last rule for eggs Last rule is available for nails Didn’t get to the !
24
Application of Cut n Cut applies to this call to this predicate –no more rules will be considered right now –this question is gonna be answered right here! n All rules available for other calls –recursive calls start with all options open –new calls ditto
25
New Calls ?- costToBuy([bread, nails], P, R). P = 1, R = [nails] ?- costToBuy([bread], P1, R1), costToBuy([nails], P2, R2). costToBuy([nails], P2, R2). P1 = 1, R1 = [], P2 = 0, R2 = [nails] ?- member(X, [bread, nails]), costToBuy([X], P, R). X = bread, P = 1, R = [] ; X = nails, P = 0, R = [nails] recursion new question backtracking restarts question
26
Cut Blocks Backtracking n Backtracking goes normally… n …unless we backtrack to a ! –that means “done for this predicate” sillyPrices(X, Y, Z) :- X = yes, !, member(Y, [nails, ham, eggs]), price(Y, Z). sillyPrices(X, Y, Z) :- price(Y, Z). backtracking OK here
27
Limited Backtracking ?- sillyPrices(yes, What, HowMuch). What = ham HowMuch = 3 ; What = eggs HowMuch = 1 ; No ?- sillyPrices(no, bread, HowMuch). HowMuch = 1
28
Red Green n “Red” cuts chop off answers –as above – some answers are not desired –without cut, Prolog would generate them n “Green” cuts prevent useless backtracking –wouldn’t have got any answers anyway –but Prolog would have looked – takes time –“efficiency” cut
29
Green Cut % max(+X, +Y, –Max) max(X, Y, X) :- X >= Y, !.% green cut max(X, Y, Y) :- X < Y. n max(5, 3, X) sets X to 5, no more answers –but without the cut Prolog would try the second clause as well – even tho’ it can’t work
30
Exercise n Write a predicate admission/2 to give the admission price to a club function –club members pay $2 –non-members pay $5 n Use club_member/1 to tell if someone is a member or not n Name known, price to be returned
31
Solution % admission(+Person, –Price) admission(Member, 2) :- club_member(Member),!. admission(NonMember, 5).
32
The Price of Admission admission(M, 2) :- club_member(M), !. admission(M, 5). club_member(bob). ?- admission(bob, P). P = 2 ; No ?- admission(bob, 5). Yes “The only price of admission for bob is 2” “Yes, the price of admission for bob is 5” Huh?
33
What Happened? admission(M, 2) :- club_member(M), !. ?- admission(bob, 5). 2 does not unify with 5 this rule is not considered the ! is never reached go on to the next rule admission(M, 5). M = bob
34
Making Exceptions n Fix by making rule head more general admission(M, P) :- club_member(M), !, P = 2. admission(M, 5). club_member(bob). ?- admission(bob, P). P = 2 ; No ?- admission(bob, 5). No “The only price of admission for bob is 2” “The price of admission for bob is not 5”
35
Now It Works admission(M, P) :- club_member(M), !, P = 2. ?- admission(bob, 5). M = bob, P = 5 club_member(bob) succeeds ! commits us to this rule 5 does not unify with 2 ! blocks backtracking No
36
Exceptions n Second clause states general rule –admission is $5 n First rule captures exception –for members, only $2 n Can combine two rules into one admission(M, P) :- club_member(M), !, P = 2 ; P = 5.
37
Capturing Exceptions n Admission to a movie: –$2.00 for kids (under 12) –$5.00 for youth (12 – 17) –$8.00 for adults (18 – 64) –$5.00 for seniors (65+) n Code it up as it stands –one rule using ! and ;
38
Movie Admissions admission(Age, Amount) :- Age < 12, !, Amount = 2 ; Age < 18, !, Amount = 5 ; Age < 65, !, Amount = 8 ; Amount = 5. n All cases combined in one rule n Has four sub-rules n ! blocks backtracking n Only the ! you get to, tho’
39
Tracing Execution n Suppose start with age 15 –rule head matches –Age < 12 fails – go to next sub-rule (;) –Age < 18 succeeds – ! commits us –Amount = 5 succeeds n Ask for another answer –Amount = 5 has no more solutions –can’t go back past !, so no more answers
40
Prolog “Else if” Statement n That form (multiple cuts and semi-colons) functions like a big if-then-elsif construct if (age < 12) amount 2; else if (age < 18) amount 5; else if (age < 65) amount 8; else amount 5; n Common way to write for multiple cases
41
Elsif and Relationships n The style above only works if you are calculating a price based on an age –Age is a known quantity –Price is an unknown (or dubious) quantity –IOW: admission(+Age, ?Price) n If you want to generate ages from prices, you need to avoid the !
42
Admission Relationship admission(Age, 2) :- between(0, 11, Age). admission(Age, 5) :- between(12, 17, Age). admission(Age, 8) :- between(18, 64, Age). admission(Age, 5) :- between(65, 120, Age). n between/3 succeeds if 3 rd argument between 1 st and 2 nd (inclusive) –generates 3 rd argument if necessary n Note that over 120 not admitted anymore….
43
Full Exceptions n Above fine if every category has an answer n But sometimes a category may be missing –Mary likes all animals except snakes likes(mary, X) :- snake(X), !, fail ;animal(X).snake(sammy). fail/0 always fails ?- likes(mary, sammy). No
44
Fuller Exceptions n Harry likes everything except snakes likes(harry, X) :- snake(X), !, fail ;true.snake(sammy). n Here there are no further conditions on X –but still need to say rule succeeds true/0 always succeeds ?- likes(harry, opera). Yes
45
Exercise n Write a clause of likes/2 for Michele –Michele likes animals –except spiders and snakes –except she likes Sammy (who is a snake) likes(michele, X) :- …
46
Stating Negative Conditions n Sometimes you want to say that some condition does not hold n Prolog allows this –not/1this is a predicate –\+/1this is a prefix operator n \+ is the preferred way to go n not is the traditional way to go
47
Non-Members n a is not a member of [q, w, e, r, t, y] ?- \+ member(a, [q,w,e,r,t,y]). Yes n Admission prices revised admission(Member, 2) :- club_member(Member). admission(NonMember, 5) :- \+ club_member(NonMember).
48
How Not Works n “Negation by failure” –not tries to prove its argument –if the argument fails, not succeeds n \+ club_member(mark). –tries to prove club_member(mark). –if club_member(mark) succeeds, \+ fails –if club_member(mark) fails, \+ succeeds
49
Not versus Cut n Not is generally less efficient than cut –club_member called twice for non-members n Not is more logical than cut –can rearrange clauses so not-clause comes first n Exercise: rewrite costToBuy/3 using \+ instead of !
50
Variables Under the Not n Handled by the predicate call ?- \+ parent(jim, X). X = _G301 Yes n Tried to find an X that jim was parent of –that failed –\+ succeeded –X remains unbound (OK – no child of jim)
51
Variables Under the Not n Failure results in no variable bindings ?- \+ parent(bob, X). No n Tried to find an X that bob was parent of –that succeeded (X = ann) –so \+ failed –answer was No, so no bindings printed
52
Not Never Binds Variables n No bindings printed for \+ questions –success means no values were found –failure means no bindings survive n Can’t use \+ or not to generate counter- examples –can’t say “find an X such that bob is not the parent of X”
53
Finding Bob’s Non-Children n Need to make X into someone first person(X) :- parent(X, _). person(X) :- parent(_, X). nonparent(X, Y) :- person(X), person(Y), \+ parent(X, Y). n Now can find nonparents ?- nonparent(bob, X). X = pam
54
Not Does Not Commute n \+’s variables should be as instantiated as necessary when called –otherwise it may prevent solutions being found ?- \+ parent(X, Y), X = jim, Y = bob. No ?- X = jim, Y = bob, \+ parent(X, Y). X = jim, Y = bob Yes
55
Next Time n Input and Output –Chapter 6
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.