Flow of Control Chapter 5 Flow of Control
- Slides: 55
Flow of Control Chapter 5
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 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 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 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 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 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 = 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 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 (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 – 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 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 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([], 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, 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 = 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 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 – 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 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([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 = [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 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 !, % 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 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, 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 – 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 = 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 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, 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 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).
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 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) : - 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. ? - 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 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) – $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 < 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 < 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 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 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, 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 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) : 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 – 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 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] ? - + 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 – 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 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). 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, 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 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) : - 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 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
- Data flow vs control flow
- Control flow and data flow computers
- Transaction flow graph
- Stock control e flow control
- Error control and flow control
- Magic box respiratory
- 15l to fio2
- High flow versus low flow oxygen
- Laminar flow meter
- External flow
- Ecological succession
- Flow of energy vs flow of matter
- Transform flow and transaction flow
- Transform flow and transaction flow
- Rotational and irrotational flow
- Internal flow and external flow
- Flow chart of cheese
- Variable orifice symbol
- Udp flow control
- Cmp 8086
- Exceptional control flow
- Repl capture/apply: memory
- Material flow control
- Control flow graph for bubble sort
- Check valve symbol
- Control flow graph examples with solutions
- Database security definition
- Control valve flow characteristics
- Blood flow control
- Control hijacking
- Control flow graph
- Dd path graph for triangle problem
- Flow divider valve symbol
- Flow control valve direction
- Pneumatic timer symbol
- Flow control functions in php
- Loop 8086
- Cash flow and cost control
- Quality control process flow chart
- Control flow graph python
- Flow control frame format
- Reset control refers to
- Tcp flow control
- Tcp flow control
- Outbound flows
- In sctp, only data chunks consume
- Interrupts execution flow
- Ics 312
- Empty statement in sequential block
- Control-flow graph
- Program flow of control without and with interrupts
- Flow control instructions in assembly language
- Control flow graph for bubble sort
- Flow control
- Structured programming
- Single acting and double acting cylinder