Flow of Control Chapter 5 Flow of Control

  • Slides: 55
Download presentation
Flow of Control Chapter 5

Flow of Control Chapter 5

Flow of Control n What order computer uses to get answers – sub-goal ordering

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)

Disjunction Prolog uses comma for AND n It uses semi-colon for OR n X

Disjunction Prolog uses comma for AND n It uses semi-colon for OR n X is a person if they’re someone’s parent OR someone’s child person(X) : parent(X, _) ; parent(_, X). No comma here – it’s not an AND Semi-colon usually alone on its own line

Control Using Disjunction n Prolog gives all answers for first part before starting answers

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) : People will be returned in this order: parent(X, _) pam, tom [sic], bob, pat ; parent(_, X). bob, liz, ann, pat, jim Tom and Bob are parents of two Bob also has two parents

AND and OR n Semi-colon splits rule into two parts – commas group together

AND and OR n Semi-colon splits rule into two parts – commas group together on either side man(X) : parent(X, _), First find all the parents that are male(X) ; parent(_, X), Then find all the children that are male(X).

AND and OR II n Use parentheses to group differently man(X) : ( First

AND and OR II n Use parentheses to group differently man(X) : ( First find the parents parent(X, _) ; parent(_, X) Then find the children ), male(X). But make sure they’re male in either case

OR versus Clauses n Putting a semi-colon in is marginally more efficient than using

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).

Exercise n Rewrite the following predicate without the semi-colon notation: translate(Number, Word) : Number

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.

Preventing Backtracking is automatic n Sometimes we don’t want it n – first answer

Preventing Backtracking is automatic n Sometimes we don’t want it n – first answer is only correct one – know there aren’t any more answers n Block backtracking by using a “cut” – predicate is !/0

Example Problem n Grocery shopping – have a list – store has some items

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) ? - cost. To. Buy([ham, eggs, nails], Cost, Rest). Cost = 4, Rest = [nails] This store doesn’t sell nails

Grocery Lists Write the cost. To. Buy/3 predicate n If nothing on list n

Grocery Lists Write the cost. To. Buy/3 predicate n If nothing on list n – price is 0 – nothing left to buy n Base case If there is an item H – if it has a price, you can buy it Recursive case #1 – otherwise, you can’t buy it Recursive case #2

Recursive Cases n You can buy it – get its price – get the

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

Does It Have a Price? If it has a price, Prolog will find it

Does It Have a Price? If it has a price, Prolog will find it n So ask for the price n – 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

cost. To. Buy/3 % cost. To. Buy(+L, ? P, ? R) cost. To. Buy([],

cost. To. Buy/3 % cost. To. Buy(+L, ? P, ? R) cost. To. Buy([], 0, []). % nothing on list cost. To. Buy([H|T], P, R) : % can buy H price(H, PH), % (H has a price) cost. To. Buy(T, PT, R), P is PH + PT. cost. To. Buy([H|T], P, [H|R]) : - % couldn’t buy H cost. To. Buy(T, P, R). % (H had no price)

At the Store price(milk, 5). price(eggs, 1). price(ham, 3). price(bread, 1). price(tomato, 2). price(fish,

At the Store price(milk, 5). price(eggs, 1). price(ham, 3). price(bread, 1). price(tomato, 2). price(fish, 3). cost. To. Buy([], 0, []). cost. To. Buy([H|T], P, R) : price(H, PH), cost. To. Buy(T, PT, R), P is PH + PT. cost. To. Buy([H|T], P, [H|R]) : cost. To. Buy(T, P, R).

Buying Stuff Example ? - cost. To. Buy([ham, eggs, nails], Cost, Rest). Cost =

Buying Stuff Example ? - cost. To. Buy([ham, eggs, nails], Cost, Rest). Cost = 4 Rest = [nails] Yes ? - cost. To. Buy([milk, fish, bread], P, R). P=9 R = [] Yes

Further Solutions ? - cost. To. Buy([ham, eggs, nails], Price, Rest). Price = 4

Further Solutions ? - cost. To. Buy([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]

cost. To. Buy and Backtracking n The predicate gives the correct answer first –

cost. To. Buy 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

Avoiding Backtracking n We’d like to commit to the first rule (second clause) once

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

cost. To. Buy/3 With Cut cost. To. Buy([], 0, []). % nothing on list

cost. To. Buy/3 With Cut cost. To. Buy([], 0, []). % nothing on list cost. To. Buy([H|T], P, R) : % can buy H price(H, PH), % (H has a price) !, % commit to this rule cost. To. Buy(T, PT, R), P is PH + PT. cost. To. Buy([H|T], P, [H|R]) : - % couldn’t buy H cost. To. Buy(T, P, R). % (H had no price)

Going Shopping Again ? - cost. To. Buy([ham, eggs, nails], P, R). P=4 R

Going Shopping Again ? - cost. To. Buy([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

What Cut Does n Cut commits you to the current rule – can’t backtrack

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 !

Loaves and Fishes Looking at eggs price(eggs, P) % makes P = 1 !,

Loaves and Fishes Looking at eggs price(eggs, P) % makes P = 1 !, % commit here cost. To. Buy(…), & cetera Even if you backtrack, you won’t get to the last rule for eggs Looking at nails price(nails, P) % fails Look for another rule nails gets added to R Last rule is available for nails Didn’t get to the !

Application of Cut n Cut applies to this call to this predicate – no

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

New Calls ? - cost. To. Buy([bread, nails], P, R). recursion P = 1,

New Calls ? - cost. To. Buy([bread, nails], P, R). recursion P = 1, R = [nails] ? - cost. To. Buy([bread], P 1, R 1), new question cost. To. Buy([nails], P 2, R 2). P 1 = 1, R 1 = [], P 2 = 0, R 2 = [nails] ? - member(X, [bread, nails]), cost. To. Buy([X], P, R). X = bread, P = 1, R = [] ; X = nails, P = 0, R = [nails] backtracking restarts question

Cut Blocks Backtracking goes normally… n …unless we backtrack to a ! n –

Cut Blocks Backtracking goes normally… n …unless we backtrack to a ! n – that means “done for this predicate” silly. Prices(X, Y, Z) : X = yes, !, member(Y, [nails, ham, eggs]), backtracking OK here price(Y, Z). silly. Prices(X, Y, Z) : - price(Y, Z).

Limited Backtracking ? - silly. Prices(yes, What, How. Much). What = ham How. Much

Limited Backtracking ? - silly. Prices(yes, What, How. Much). What = ham How. Much = 3 ; What = eggs How. Much = 1 ; No ? - silly. Prices(no, bread, How. Much). How. Much = 1

Red Green n “Red” cuts chop off answers – as above – some answers

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

Green Cut % max(+X, +Y, –Max) max(X, Y, X) : X >= Y, !.

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

Exercise n Write a predicate admission/2 to give the admission price to a club

Exercise n Write a predicate admission/2 to give the admission price to a club function – club members pay $2 – non-members pay $5 Use club_member/1 to tell if someone is a member or not n Name known, price to be returned n

Solution % admission(+Person, –Price) admission(Member, 2) : club_member(Member), !. admission(Non. Member, 5).

Solution % admission(+Person, –Price) admission(Member, 2) : club_member(Member), !. admission(Non. Member, 5).

The Price of Admission admission(M, 2) : - club_member(M), !. admission(M, 5). club_member(bob). ?

The Price of Admission admission(M, 2) : - club_member(M), !. admission(M, 5). club_member(bob). ? - admission(bob, P). P=2; “The only price of admission for bob is 2” No ? - admission(bob, 5). Yes “Yes, the price of admission for bob is 5” Huh?

What Happened? admission(M, 2) : - club_member(M), !. ? - admission(bob, 5). 2 does

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

Making Exceptions n Fix by making rule head more general admission(M, P) : -

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; “The only price of admission for bob is 2” No ? - admission(bob, 5). “The price of admission for bob is not 5” No

Now It Works admission(M, P) : - club_member(M), !, P = 2. ? -

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

Exceptions n Second clause states general rule – admission is $5 n First rule

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.

Capturing Exceptions n Admission to a movie: – $2. 00 for kids (under 12)

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 ;

Movie Admissions admission(Age, Amount) : Age < 12, !, Amount = 2 ; Age

Movie Admissions admission(Age, Amount) : Age < 12, !, Amount = 2 ; Age < 18, !, Amount = 5 ; Age < 65, !, Amount = 8 ; Amount = 5. n n All cases combined in one rule Has four sub-rules ! blocks backtracking Only the ! you get to, tho’

Tracing Execution n Suppose start with age 15 – rule head matches – Age

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

Prolog “Else if” Statement n That form (multiple cuts and semi-colons) functions like a

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

Elsif and Relationships n The style above only works if you are calculating a

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 !

Admission Relationship admission(Age, 2) : - between(0, 11, Age). admission(Age, 5) : - between(12,

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….

Full Exceptions Above fine if every category has an answer n But sometimes a

Full Exceptions Above fine if every category has an answer n But sometimes a category may be missing n – Mary likes all animals except snakes likes(mary, X) : snake(X), !, fail/0 always fails ; animal(X). ? - likes(mary, sammy). snake(sammy). No

Fuller Exceptions n Harry likes everything except snakes ? - likes(harry, opera). likes(harry, X)

Fuller Exceptions n Harry likes everything except snakes ? - likes(harry, opera). likes(harry, X) : Yes snake(X), !, fail ; true/0 always succeeds snake(sammy). n Here there are no further conditions on X – but still need to say rule succeeds

Exercise n Write a clause of likes/2 for Michele – Michele likes animals –

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) : …

Stating Negative Conditions Sometimes you want to say that some condition does not hold

Stating Negative Conditions Sometimes you want to say that some condition does not hold n Prolog allows this n – not/1 this is a predicate – +/1 this is a prefix operator + is the preferred way to go n not is the traditional way to go n

Non-Members n a is not a member of [q, w, e, r, t, y]

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(Non. Member, 5) : + club_member(Non. Member).

How Not Works n “Negation by failure” – not tries to prove its argument

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

Not versus Cut n Not is generally less efficient than cut – club_member called

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 cost. To. Buy/3 using + instead of !

Variables Under the Not Handled by the predicate call ? - + parent(jim, X).

Variables Under the Not Handled by the predicate call ? - + parent(jim, X). X = _G 301 Yes n Tried to find an X that jim was parent of n – that failed – + succeeded – X remains unbound (OK – no child of jim)

Variables Under the Not Failure results in no variable bindings ? - + parent(bob,

Variables Under the Not Failure results in no variable bindings ? - + parent(bob, X). No n Tried to find an X that bob was parent of n – that succeeded (X = ann) – so + failed – answer was No, so no bindings printed

Not Never Binds Variables n No bindings printed for + questions – success means

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 counterexamples – can’t say “find an X such that bob is not the parent of X”

Finding Bob’s Non-Children n Need to make X into someone first person(X) : -

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

Not Does Not Commute n +’s variables should be as instantiated as necessary when

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

Next Time n Input and Output – Chapter 6

Next Time n Input and Output – Chapter 6