/* TEACH TEACHNUMS Aaron Sloman 10 Aug 2009 This is a DRAFT teach file. Comments and suggestions welcome. It may be too difficult for some younger children, though some of the early ideas could be presented by a teacher using a computer, with pupils being asked to make suggestions about how things should work. More advanced learners (especially potential mathematical high fliers) could work through this file themselves, trying out the suggested procedure definitions then exploring alternatives, and finally trying to meet the challenges presented at the end, e.g. extending these ideas to negative numbers, and other extensions. Regarding negative numbers, teachers may find it useful to read: Pamela Liebeck, Scores and Forfeits: An Intuitive Model for Integer Arithmetic, Educational Studies in Mathematics, Vol 21, No 3, June, 1990, pp. 221--239, [Available via JSTOR to subscribing institutions] CONTENTS - (Use g to access required sections) -- Introduction -- A myth about computers -- Using bit-patterns in two-element links chained to form lists -- Doing arithmetic on lists of x's. -- First procedure: a number recognizer -- A procedure for adding two nums -- A procedure to subtract a number from another -- Another version, subnums2 using the pattern matcher -- Multiplication as repeated addition -- Some predicates for comparing numbers -- -- samenum checks whether two numbers are the same -- -- bigger checks whether a number is bigger than another -- -- between checks whether a number is between two others -- A procedure to divide one number into another -- A hard problem: how to represent and operate on negative numbers -- Another hard problem: how to divide 4 by 7 and produce a fraction -- Introducing 'place' notation to compress number representations -- Can you use numbers for counting? -- -- Try problem (a) -- -- Try problem (b) -- Introducing numerals -- How about using place notation with number names? -- More information -- Introduction In this teach file we introduce the idea of representing numbers as lists of 'x's and operations on numbers such as addition, subtraction and multiplication as operations on lists. The file gets to the point where new puzzles arise regarding how to deal with negative numbers. Working out how to do that is left as an exercise (for teachers and learners). There is no one right answer: learners should explore different types of solution. -- A myth about computers --------------------------------------------- It is often said that computers operate primarily on numbers and that everything else computers do is built on top of those operations. This is not correct. Computers operate on 'bit-patterns', i.e. patterns made of collections of switches that can be on or off. These can be represented by strings made up of '1's and '0's, e.g. 000111000111000111 000010011000111001101111 The fact that we use '0' and '1', is misleading. We could have used 'X' and 'Y', e.g. XXXYYYXXXYYYXXXYYY XXXXYXXYYXXXYYYXXYYXYYYY Any two symbols can be used in bit-patterns. One of many things that can be done using bit patterns is representing locations in memory in the computer, and also representing printable symbols. For now the details are not important. -- Using bit-patterns in two-element links chained to form lists ------ It is very often useful to store information in structures that are all built out of elementary structures containing only two adjacent locations in memory. These are called 'pairs' in Pop-11. The first location of a pair may store some bit pattern that represents a letter for example 'x' or 'y', or a word, e.g. 'the' or 'cat', or anything else (e.g. a number 3769). The second location can store a bit pattern that specifies the location of another pair. When several pairs are 'joined up' in a series to form a chain, because each pair points to the next pair, then they are sometimes referred to as 'links', making up a chain, or list. For example the list of words [how now brown cow] could be represented as chained links, as follows, where each asterisk '*' represents a bit-pattern that specifies the location of the next link, and 'NIL' at the end means there is not another link: .---. .---.---. .---.---. .-----.---. .---.---. | *---->|how| *---->|now| *---->|brown| *---->|cow|NIL| .---. .---.---. .---.---. .-----.---. .---.---. The first asterisk represents a bit-pattern that could be stored in various places, specifying where to find this list. This diagram suggests that the links are all stored close together, and in the order shown, but that is not required for the system to work. There are many more details concerning how lists are represented in computers, but we shall ignore them as we want to explore ways of using lists to represent numbers. Anyone wanting to know more about what lists are, how they are implemented in Pop-11, and which notations and commands are available to construct and operate on them, can look at TEACH LISTS TEACH WAL TEACH MATCHES and many 'teach' files that use lists and the pattern matcher, e.g. TEACH RIVER TEACH RESPOND Below we introduce the idea of using a list of 'x's to represent a number. We then have to define arithmetical operations, like addition, multiplication, subtraction and division using operations on lists. This file assumes that you have already had some practice writing simple Pop-11 programs and know, for example, that if L is a list, then hd(L) is the first element of L (its 'head') and tl(L) is a list (the 'tail' of L) containing everything in L except the first element. So hd([how now brown cow]) is the word "how" tl([how now brown cow]) is the list [now brown cow] The operator "<>" can be used to join two lists together, or more precisely to produce a new list that starts with the elements of the first list and then has a tail containing the second list. For example: [how now] <> [brown cow] produces [how now brown cow] -- Doing arithmetic on lists of x's. ---------------------------------- In what follows we present some pop-11 procedures that can operate on lists of x's in order to perform arithmetic operations. You will find each procedure presented with some documentation preceding it, saying what its name is, what inputs it takes, what output it takes, what it is for and giving some test examples. The tests can be run after the procedures are compiled. If you change any of the procedure definitions you should run the tests again. The procedure headers are produced using a command in the poplog editor Ved, namely ENTER procheader, whose use is explained in HELP * VED_PROCHEADER the procedures defined below are define isnum(item) -> boole; check whether item is a number and return true or false define addnums(num1, num2) -> sum; check whether num1 and num2 are numbers and if so return a new number which is their sum, otherwise mishap define subnums(num1, num2) -> diff; if num1 and num2 are numbers return a number that is their difference define subnums2(num1, num2) -> diff; another way of defining subnums define mult(num1, num2) -> product; if num1 and num2 are numbers return a number that is the result of multiplying num1 by num2 The next three are predicates for testing a relation between two or three numbers. They all return a boolean value, i.e. true or false. define samenum(num1, num2) -> boole; true if the numbers are the same define bigger(num1, num2) -> boole; true if num1 is bigger than num2 define between(num1, num2, num3) -> boole; true if num1 is between num2 and num3 Returning to arithmetical operators: define divide(num1, num2) -> (remainder, quotient); divide num1 by num2 and return the remainder and the quotient (num1 is the dividend, num2 the divisor) The file ends with a challenge to extend these ideas to negative numbers and some other challenges. -- First procedure: a number recognizer ------------------------------- We need a number recognizer, which will be used in many other procedures to check that they have been given a list, and failing that to produce an error message (or MISHAP message in Pop-11). We can define a number recognizer procedure as follows. It checks that it is given a list, and that the list contains only occurrences of the word "x". It returns the boolean true or the boolean false, depending on what it finds. A first problem is whether the empty list should be used to represent a number. An obvious answer is that it should represent the number 0. We shall take that option below, but you could consider whether the program could be changed so as not to allow the empty list. */ /* PROCEDURE: isnum (item) -> boole INPUTS : item is anything OUTPUTS : boole is a truth-value (boolean) USED IN : Many procedures below. CREATED : 30 May 2009 PURPOSE : Recognize a numeral in the form of a list that is either empty, i.e. [] or contains only occurrences of the word "x", e.g. [x] [x x x] ;;; specify some tests that will be used to check that the procedure ;;; works TESTS: isnum([x x x]) => ** isnum([]) => ** isnum([y y y]) => ** isnum([xx]) => ** isnum(99) => ** */ define isnum(item) -> boole; lvars L; ;;; if the list is empty if islist(item) and item matches [] ;;; or the list starts with "x" followed by a number list or (islist(item) and item matches ![x ??L:isnum]) then true else false endif -> boole; enddefine; /* -- A procedure for adding two nums ------------------------------------ */ /* PROCEDURE: addnums (num1, num2) -> sum INPUTS : num1, num2 Where : num1 is a num num2 is a num OUTPUTS : sum is a num USED IN : several procedures below CREATED : 30 May 2009 PURPOSE : add two numbers (as lists) returning the sum (as a list). It should produce a mishap if given non-numbers. TESTS: addnums([], []) => ** [] addnums([x], []) => ** [x] addnums([], [x]) => ** [x] addnums([x x], [x x x]) => ** [x x x x x] addnums([x x], [y y]) => ;;; MISHAP - Nums needed for addnums ;;; INVOLVING: [y y] ;;; FILE : /home/axs/popd/teachnums.p ;;; DOING : addnums runproc ;;; this should also produce a mishap (why?) addnums([xx], [xxx]) => ;;; MISHAP - Nums needed for addnums ;;; INVOLVING: [xx] ;;; FILE : /home/axs/popd/teachnums.p ;;; DOING : addnums runproc */ define addnums(num1, num2) -> sum; ;;; first check that num1 and num2 satisfy isnum unless isnum(num1) then mishap('Nums needed for addnums', [^num1]); endunless; unless isnum(num2) then mishap('Nums needed for addnums', [^num2]); endunless; ;;; now we know they are both nums, so we can add them ;;; if either num1 or num2 is empty use the other as the result if num1 matches [] then num2 -> sum elseif num2 matches [] then num1 -> sum else ;;; add an "x" to num1 and reduce one from num2 ;;; and add the two resulting lists addnums([ x ^^num1], tl(num2)) -> sum endif enddefine; ;;; exercise: try defining a version of this using the Pop-11 concatenator ;;; operator <> /* -- A procedure to subtract a number from another ---------------------- */ /* PROCEDURE: subnums (num1, num2) -> diff INPUTS : num1, num2 Where : num1 is a number num2 is a number OUTPUTS : diff is a number USED IN : ??? CREATED : 21 Jun 2009 PURPOSE : ??? if num1 is bigger than or equal to num2 then return a number which when added to num2 gives num1 TESTS: subnums( [], [] ) => ** [] subnums( [x], [] ) => ** [x] subnums( [], [x] ) => ;;; MISHAP - subnums cannot subtract from zero ;;; INVOLVING: [] [x] ;;; FILE : /home/axs/popd/teachnums.p ;;; DOING : subnums runproc subnums( [x x x], [x x x x] ) => ;;; MISHAP - subnums cannot subtract from zero ;;; INVOLVING: [] [x] ;;; FILE : /home/axs/popd/teachnums.p ;;; DOING : subnums(*4) runproc subnums( [x x x x], [x x x x] ) => ** [] */ define subnums(num1, num2) -> diff; if isnum(num1) and isnum(num2) then if num2 matches [] then num1 -> diff elseif num1 matches [] then mishap('subnums cannot subtract from zero', [^num1 ^num2]); else ;;; subtract an "x" from both and return the difference subnums(tl(num1), tl(num2)) -> diff endif else mishap('Nums needed for subnums', [^num1 ^num2]); endif; enddefine; /* -- Another version, subnums2 using the pattern matcher ---------------- */ /* PROCEDURE: subnums2 (num1, num2) -> diff INPUTS : num1, num2 Where : num1 is a number num2 is a number OUTPUTS : diff is a number USED IN : ??? CREATED : 21 Jun 2009 PURPOSE : ??? if num1 is bigger than or equal to num2 then return a number which when added to num2 gives num1 TESTS: subnums2( [], [] ) => ** [] subnums2( [x], [] ) => ** [x] subnums2( [], [x] ) => ;;; MISHAP - Cannot subtract bigger number from smaller ;;; INVOLVING: [] [x] ;;; FILE : /home/axs/popd/teachnums.p ;;; DOING : subnums2 runproc subnums2( [x x x], [x] ) => ** [x x] subnums2( [x x x], [x x x x] ) => ;;; MISHAP - Cannot subtract bigger number from smaller ;;; INVOLVING: [x x x] [x x x x] ;;; FILE : /home/axs/popd/teachnums.p ;;; DOING : subnums2 runproc subnums2( [x x x x], [x x x x] ) => ** [] subnums2( [x x x x x x x x], [x x x x] ) => ** [x x x x] */ define subnums2(num1, num2) -> diff; if isnum(num1) and isnum(num2) then if num1 matches ![??diff ^^num2] then ;;; nothing else to do else mishap('Cannot subtract bigger number from smaller', [^num1 ^num2]) endif else mishap('Nums needed for subnums', [^num1 ^num2]); endif; enddefine; /* -- Multiplication as repeated addition -------------------------------- */ /* PROCEDURE: mult (num1, num2) -> product INPUTS : num1, num2 Where : num1 is a num num2 is a num OUTPUTS : product is a num USED IN : ??? CREATED : 30 May 2009 PURPOSE : multiply two numbers (as lists) returning the product TESTS: mult([], []) => ** [] mult([], [x x x x]) => ** [] mult([x x x x], []) => ** [] mult([x x x x], [x]) => ** [x x x x] mult([x], [x x x x]) => ** [x x x x] mult([x x], [x x x x]) => ** [x x x x x x x x] */ define mult(num1, num2) -> product; if isnum(num1) and isnum(num2) then if num1 matches [] then [] -> product elseif num2 matches [] then [] -> product else [] -> product; until num2 matches [] do addnums(num1, product) -> product; tl(num2) -> num2; enduntil; endif else mishap('Nums needed for product', [^num1 ^num2]); endif; enddefine; ;;; NOTE: ;;; A substantial chunk of the code in this procedure is redundant ;;; and can be removed, because of unobvious duplication. ;;; Which lines can be removed without changing the behaviour? ;;; Explain why? /* -- Some predicates for comparing numbers ------------------------------ -- -- samenum checks whether two numbers are the same */ /* PROCEDURE: samenum (num1, num2) -> boole INPUTS : num1, num2 Where : num1 is a number num2 is a number OUTPUTS : boole is a boolean USED IN : divide CREATED : 10 Aug 2009 PURPOSE : Testing numbers for equality true if the numbers are the same TESTS: samenum([], []) => ** samenum([x], [x]) => ** samenum([xx], [xx]) => ;;; MISHAP - Nums needed for samenum ;;; INVOLVING: [xx] [xx] ;;; FILE : /home/axs/popd/teachnums.p ;;; DOING : samenum runproc samenum([x x], [x x]) => ** samenum([x x x], [x]) => ** samenum([], [x x]) => ** */ define samenum(num1, num2) -> boole; if isnum(num1) and isnum(num2) then num1 matches num2 -> boole else mishap('Nums needed for samenum', [^num1 ^num2]); endif enddefine; /* -- -- bigger checks whether a number is bigger than another */ /* PROCEDURE: bigger (num1, num2) -> boole INPUTS : num1, num2 Where : num1 is a num num2 is a num OUTPUTS : boole is a boolean USED IN : divide CREATED : 30 May 2009 PURPOSE : determine whether num1 is bigger than num2 TESTS: bigger([], []) => ** bigger([x], []) => ** bigger([], [x]) => ** bigger([x x], [x x]) => ** bigger([x x x], [x x]) => ** bigger([x x x x x], [x x]) => ** bigger([x x], [x x x x]) => ** bigger([xx], [xxxx]) => ;;; MISHAP - Nums needed for samenum ;;; INVOLVING: [xx] [xxxx] ;;; FILE : /home/axs/popd/teachnums.p ;;; DOING : samenum bigger runproc */ define bigger(num1, num2) -> boole; ;;; note: we don't need to test that num1 and num2 are ;;; numbers, ad samenum does that if samenum(num1, num2) then false -> boole elseif num1 matches [] then false -> boole elseif num2 matches [] then true -> boole else bigger(tl(num1), tl(num2)) -> boole endif enddefine; /* -- -- between checks whether a number is between two others */ /* PROCEDURE: between (num1, num2, num3) -> boole INPUTS : num1, num2, num3 Where : num1 is a number num2 is a number num3 is a number OUTPUTS : boole is a boolean USED IN : CREATED : 21 Jun 2009 PURPOSE : Check whether num1 is between num2 and num3 in ascending or descending order TESTS: between([x], [x], [x]) => ** between([x x], [x], []) => ** between([x], [x x], []) => ** between([x x], [x], [x x x]) => ** between([x x], [x x], [x x x]) => ** */ define between(num1, num2, num3) -> boole; (bigger(num3, num1) and bigger(num1, num2)) or (bigger(num2, num1) and bigger(num1, num3)) -> boole enddefine; /* -- A procedure to divide one number into another ---------------------- */ /* PROCEDURE: divide (num1, num2) -> (remainder, quotient); INPUTS : num1, num2 Where : num1 is a number (the dividend) num2 is a number (the divisor) OUTPUTS : remainder, quotient Where : remainder is a number quotient is a number USED IN : ??? CREATED : 21 Jun 2009 PURPOSE : given two numbers num1, num2, divide num1 by num2 and return quotient and remainder quotient is the number of times num2 goes into num1 remainder is the remainder after dividing num2 into num1 (The remainder should be less than num2). TESTS: divide([], []) => ;;; MISHAP - Cannot divide [] into [] ;;; FILE : /home/axs/popd/teachnums.p ;;; DOING : divide runproc ;;; do the next two give reasonable answers? divide([], [x]) => ** [] [] divide([], [x x]) => ** [] [] divide([x], []) => ;;; MISHAP - Cannot divide [] into [x] ;;; FILE : /home/axs/popd/teachnums.p ;;; DOING : divide runproc divide([x], [x]) => ** [] [x] divide([x x x x], [x x x x]) => ** [] [x] divide([x x x x], [x x]) => ** [] [x x] divide([x x x x x x x], [x x x]) => ** [x] [x x] divide([x x x x x x x x x], [x x x]) => ** [] [x x x] */ define divide(num1, num2) -> (remainder, quotient); ;;; we don't need to check that they are numbers as ;;; bigger and samenum will do that if num2 == [] then mishap('Cannot divide [] into ' >< num1, []); elseif bigger(num2, num1) then [] -> quotient; num1 -> remainder elseif samenum(num1, num2) then [x] -> quotient; [] -> remainder else divide(subnums(num1, num2), num2) -> (remainder, quotient); addnums([x], quotient) -> quotient; endif; enddefine; /* -- A hard problem: how to represent and operate on negative numbers --- */ /* What should subnums do if the second number is larger than the first? subnums([x x], [x x x]) => At present it gives this mysterious error message (which could be modified of course): ;;; MISHAP - subnums cannot subtract from zero ;;; INVOLVING: [] [x] ;;; FILE : /home/axs/popd/teachnums.p ;;; DOING : subnums(*3) runproc You have been taught that the result of subtracting 3 from 2 should be a negative number. But what is a negative number? How can you represent negative numbers using lists? How should they be added, subtracted or multiplied? Why should multiplying two negative numbers give a positive number? Try to find ways of extending this package that are not totally arbitrary and give a sensible interpretation of negative numbers. If you come up with a suggestion please write to me about it (email address at end of this file). THERE IS NO UNIQUE RIGHT ANSWER If you find an answer feel free to email me about it (address at bottom of file), or post it on the comp.lang.pop forum. You may find this paper by Pamela Liebeck relevant, if you can get hold of it. Pamela Liebeck, Scores and Forfeits: An Intuitive Model for Integer Arithmetic, Educational Studies in Mathematics, Vol 21, No 3, June, 1990, pp. 221--239, Available on JSTOR here from subscribing academic institutions: http://links.jstor.org/sici?sici=0013-1954%28199006%2921%3A3%3C221%3ASAFAIM%3E2.0.CO%3B2-N */ /* -- Another hard problem: how to divide 4 by 7 and produce a fraction -- */ /* At present dividing a number by another number using the procedure divide, defined above, gives a remainder and a quotient, as in these examples: divide([x x x x x x x x], [x x x])=> ** [x x] [x x] divide([x x x x x x x x], [x x x x])=> ** [] [x x] divide([x x x x x x x x], [x x x x x])=> ** [x x x] [x] divide([x x], [x x x])=> ** [x x] [] divide([x x x], [x x x x x])=> ** [x x x] [] Can you think of a way of changing the procedure divide(num1, num2), so that instead of producing two numbers as its result it produces a single object that can be thought of as a ratio (num1/num2). The way you represent ratios should have the property that if you divide num1 by num2 to get a ratio, then if you multiply that ratio by num2 you should get back to num1. Can you make this work with negative as well as positive numbers. The key idea is to think of a good way to represent ratios so that they preserve all the required information, but have no redundant information. If you come up with a suggestion please write to me about it (email address at end of this file). THERE IS NO UNIQUE RIGHT ANSWER If you find an answer feel free to email me about it (address at bottom of file), or post it on the comp.lang.pop forum. */ /* -- Introducing 'place' notation to compress number representations ---- */ /* If you use the notation developed here to represent numbers you will soon realise that it is analogous to representing numbers by sequences of strokes: | || ||| |||| ||||| |||||| In principle any number, no matter how large, could be represented either as a sequence of strokes, or as a list of x's. However this can get very unwieldy for very large numbers. E.g. this is how the number 217 could look (with the list 'folded' to fit within a reasonable width: [x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x] And this is how it could look using the stroke notation without spaces: ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||| Compare that with the brevity of using three digits in "217". This works because the numbers are interpreted as keep the right most number add 10 times the number next left add 100 times the number next left ..... giving 7 + 10x1 + 100x2, or, if you prefer 2x100 + 10x1 + 7 Try working out a way to get a comparable compression using lists of x's so that instead of a number like 217 being represented by one long list of x's it is represented by three much shorter lists. If you can develop such a notation try designing and testing some procedures to convert between the above simple-minded list notation and a place-based notation. Also modify the procedures for adding, subtracting, multiplying and dividing so that they can handle numbers represented in the new way. THERE IS NO UNIQUE RIGHT ANSWER If you find an answer feel free to email me about it (address at bottom of file), or post it on the comp.lang.pop forum. */ /* -- Can you use numbers for counting? ---------------------------------- */ /* (a) If I give you a list of words, and ask you how many there are, you can point at them in turn as you recite number names, and when you get to the end you can announce the final name as the answer to the 'how many' question. (b) Alternatively if I give you a list of words and ask you to give me a list containing the first three words, or the first nine words, you can count along the list until you get to the number specified, and make a list of all the words you have counted. */ /* -- -- Try problem (a) */ /* Can you define a procedure how_many that performs the first task? It is useful to use the fact that in Pop-11, code run in brackets like this will create a list of the values produced in the code: [% .... %] That construct could be used in a how_many procedure: */ define how_many(list) -> number; lvars item; ;;; go through the list and create a new one representing a number ;;; of the types used above. [% for item in list do ;;;; what exactly ??? endfor %] -> number; enddefine; /* ;;; Test it thus (and define some more tests of your own) how_many([ the hat ]) => ;;; should produce ** [x x] whereas how_many([the man with a hat is blind as a bat ]) => ;;; should produce ** [x x x x x x x x x x] ;;; What should this do? how_many([ ]) => */ /* -- -- Try problem (b) */ /* Can you define a procedure count_out that performs the second task, namely to produce a specified number of elements from a list. */ define count_out(items, number) -> list; ;;; what should go in here? ;;; you need a look to generate the numbers, one at a time, ;;; and as you do that you save an item from the list items. ;;; when you generate the target number given, the program can stop ;;; counting and return the list of saved items. enddefine; /* ;;; Test it thus (and define some more tests of your own) ;;; save a list of words for re-use vars words = [the man with a hat is blind as a bat]; count_out(words, [x x]) => should produce ** [the man] count_out(words, [x x x x x]) => should produce ** [the man with a hat] What should this do ? count_out(words, []) => */ /* -- Introducing numerals ----------------------------------------------- */ /* There are many things we use numbers for which would be very clumsy if we were to use lists of 'x's as names. So it would be useful to have Pop-11 words as names, providing a short hand notation. E.g. "one" could be a name for [ x ] "two" could be a name for [ x x ] "three" could be a name for [ x x x] "four" could be a name for [ x x x x ] and so on. Can you find a way of setting up a mapping between the words and the numbers, where the numbers are represented as lists of 'x's? If you do that, how could you modify the previous two definitions so that how_many([ the hat ]) => produces ** two and count_out(words, "five") => produces ** [the man with a hat] */ /* -- How about using place notation with number names? ------------------ */ /* Could you produce a program that understands the words nought one two .... nine and then can interpret lists of those words as representing numbers in the usual decimal way, e.g. what_number([three]) => should produce [x x x] what_number([three five]) => should produce a list of 35 'x's [x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x] what_number([three five nine]) => should produce a list of 359 'x's, and so on. What should these produce what_number([three five nought]) => what_number([three nought five]) => what_number([nought three five]) => what_number([nought nought three five]) => */ /* -- More information --------------------------------------------------- For more information on poplog see http://www.cs.bham.ac.uk/research/projects/poplog/freepoplog.html There is a section on teaching using Pop-11 http://www.cs.bham.ac.uk/research/projects/poplog/freepoplog.html#teaching There is a Pop-11 primer here: http://www.cs.bham.ac.uk/research/projects/poplog/primer/ ======== Aaron Sloman Email: A.Sloman@cs.bham.ac.uk http://www.cs.bham.ac.uk/~axs --- ?????/teachnums.p --- Copyright University of Birmingham 2009. All rights reserved. --- See http://www.cs.bham.ac.uk/research/projects/poplog/copyright.html */