EXERCISE SHEET 3 {This exercise is about tracing and lists. This exercise needs the file called "likes", which contains fragments of prolog for three different phases of the exercises.} {Now you can load it into prolog...} sicstus [likes]. {The first part of the file deals with my personal preferences with respect to certain animals. The predicate assess(X) succeeds if I like or dislike X, and fails if I have no preferences. There are some animals I dislike outright, and others I definitely like. For the rest, I try and think of an animal they are similar to, and assess whether I like that or not. Look at the program, and see if you get the gist. Then try it out on these few examples, to get the idea: (for this exercise we will use the cut operator to prevent sicstus from giving all solutions...)} assess(rabbits),!. assess(bears),!. assess(camels),!. {So far so good. See if you can work out why the next four come up with the answers they do:} assess(lions),!. assess(tigers),!. assess(geese),!. assess(pigeons),!. {OK, that's got the idea, the program seems to work reasonably well. Let's see if we can crash it:} assess(frogs),!. assess(koalas),!. {Oh dear! We'll have to find out what's wrong. You can look at the program and work it out for yourself, if you like, or take this opportunity to see the trace package in action. First, let's see what happens when we trace something we know works. At each step, just creep, ie. hit a return. When it gets to call ( 6) or so, give a g command to see what function calls are waiting for this predicate to succeed.} trace. assess(pigeons). {That may help you follow what goes on in this program. Let's try out the spy command:} notrace. spy(assess). {This time, answer each ? by l (I mean lower case L), to leap to the next spy-point. When you get to about call ( 22), hit a "g" to see what goals are pending. This may give you an idea what's happening if you haven't one already... Use the "a" command to abort the rest of the execution.} assess(koalas). {Now to stop spying on assess, and start spying on similar:} nospy(assess). spy(similar). {Creep through the following. See where you get a "+" in the first column.} assess(dingoes). {For this next one, answer each call with s for skip. Type return on Exit lines} assess(geese). {That's the end of the first part of the exercise sheet, now to continue tracing with the second part, the mystery function... Answer the M = blah type responses with a return rather than a ;.} f(2, M). f(3, M). f(4, M). {For this last one, answer the M = 89 question with a ; rather than return.} f(10, M). {Guess what the function does if you feel up to it... We'll use trace to look at it in more detail.} trace. {Now go through this creeping, but skipping some of the calls to f. You'll eventually get the M = 89 from last time. Hit a ; at it, and creep from there onwards. See what happens? If you don't, wait 'til you get to call 460 and give a g command. If you still don't see why it goes awry, ask someone...} f(10, M). {Now we leave tracing and get onto lists. Here are some unifications for you to try. Before you type the following in, try to guess what the outcome is. Don't just type in without thinking.} X = .(a, .(b, .(c, []))). X = .(D, .(e, [f, G])). X = .(a, b). {Be careful with that one!} {Did you manage to predict what had happened?} .(a, .(b, .(c, [d, e, f]))) = [X|Y]. X = [a|[1,2,3]]. [X|Y] = [[a, b, c], [d, e, f]]. [X|Y] = [[a, b], c, d]. [X|X] = [[a, b], C]. [X|X] = [[a, b], a, b]. .(X, Y) = [do,be,do,be,do]. {Only try this next one if you really don't know what will happen...} X = [V, W, X, Y, Z]. {There's a definition of member in the file likes, let's see it in action.} member(1, [0, 1, 2, 3]). member(1, [0, [1], 2]). member(1, [2, 4, 6]). {You don't have to instantiate both parameters in member, you can use it as a "generator". Answer the X = blah question with a ; and see what happens:} member(X, [the, cat, sat, on, the, mat]). {This can be quite useful. In the file "likes", I've defined a predicate, days, which contains a list of the days of the week. Answer the questions with ;.} days(X), member(M, X). {What use is it? Here's something to print them all out. Notice that there's a fail at the end. days(X), member(D, X), write(D), nl, fail. {See what it prints out? The no at the end is because eventually member runs out of days to pick up, and itself fails. This next one is going to make your eyes pop out. It's on 2 lines, the first one ends in a comma, not a dot.} X = [mon, tue, wed, thu, fri, sat, sun|X], member(D, X), write(D), nl, fail. {Using "fail" this way is quite common in Prolog. With your knowledge in lists, you should now be able to write a predicate which collects all the days in one list.} {The following is a special treat for those who would like a bit of challenge. You don't have to finish it in the class.} {Aliens from the planet Trd have only three swearwords, zrt, pfk and rrb. They use these all the time, and it gets on the nerves of their president, Jrk. Jrk orders that all text should be censored, so that swearwords are removed. Write a function censor(I, O), where I is a list of Trdish words, and O is the list with obsceneties removed. What would it produce for the following examples?} censor([plt,yrd,pfk,crl,rrb], L). censor([nsp,liq,krk,zrt,plb], L). censor([pwq,frg,prolog,rza,zrt,zrt,zrt,zrt,zrt,pfk], L). {President Jrk decides that merely removing words from sentences isn't enough, and decrees that all swearwords should be replaced by the word swk, which means "beep" in Trdish. Alter your program so that it conforms to the new requirements.}