Before attempting these exercises, some readers may find it helpful to read the next chapter.
1. Modify the above examples to define a procedure called rooms_with_length which instead of being given the name of a room is given a length, i.e. a number. It should print out the name of every room with that length.
You could model the definition of rooms_with_length on the definition of findroom. It would use a similar looping structure, but instead of testing whether the first element of each room is the required name, it would test whether the second element is the required length. And instead of stopping (using return) it would then print the name and continue round the loop.
2. The procedure find_and_show_all could be very inefficient. For each room name it initiates a new search down the list, using find_and_show. If the list of room data is very long, this could be very wasteful.
Try defining a new version of find_and_show_all which is essentially like findroom, but modified to take a list of names instead of just one name. Further it would not have a output local variable, since it would print relevant information instead of producing a result. Two further modifications of findroom will be needed. The call of mishap at the end should be removed, and the conditional
if data(1) = name then return(); ;;; i.e. stop the procedure endif;will need to be replaced by something equivalent to the following, (which is not Pop-11):
if data(1) is a member of the list of names then display_room(data) endif;There is a procedure called `member' in the Poplog system which takes an item and a list and produces the result TRUE if the item is in the list, false otherwise. So
member("room4", [room2 room4 room17])would be an expression denoting the object true, whereas
member("room5", [room2 room4 room17])would denote the object false. You could use a conditional starting something like:
if member(data(1), namelist) thenIf the procedure called `member' did not already exist in Pop-11 you could define it using concepts already illustrated. Try defining a procedure called `iselement' which takes an object and a list of objects, and searches down the list using "=" to see if the given object is the same as an element of the list. If so stop searching and produce the result TRUE, using the imperatives:
true -> result; return();If you get to the end of the list without finding the given object then the last action would be
false -> result;The search process could use the `for ... endfor' syntax. When tested your procedure should behave like this:
iselement("cat", [mouse cat dog]) => ** <true> iselement("pig", [mouse cat dog]) => ** <false> iselement(4, [a 1 b 2 c 3 d 4 e 5]) => ** <true> islement(99, []) => ** <false>A procedure like iselement that returns a boolean (i.e. true or false result) is called a "predicate". Pop-11 has many built in predicates for testing individual objects (e.g. isinteger, islist, isword, isstring, isprocedure, and many more) and also `binary' predicates for testing relations between things, including the arithmetical relations `<', `>', member(item, list), issubstring(string1, string2), and many more. The most commonly used binary predicates are "=" for testing equality of structures, and "==" for testing strict identity of objects. Two structures with the same components can pass the "=" test and fail the "==" test, for example two strings with the same characters:
'the cat' = 'the cat' => ** <true> ;;; the following returns false because they are two distinct strings 'the cat' == 'the cat' => ** <false>