# Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Introduction to Computer Science I Topic 3: Recursive.

## Presentation on theme: "Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Introduction to Computer Science I Topic 3: Recursive."— Presentation transcript:

Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Introduction to Computer Science I Topic 3: Recursive Data Types and Structural Recursion Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Lists Structures are useful for storing data objects that contain a fixed number of elements However, in many cases we do not know how many elements a data structure consists of –or the structure of the data is recursive Using recursive data types, we can store data objects of arbitrary size in a structured way Idea: One element of the data structure stores (directly or indirectly) another instance of the data structure –This is what we call a recursive data structure –A recursion anchor is needed for a finite data structure –To build this recursion anchor, we use the method for heterogeneous data from our last lecture 2

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Building Recursive Data Types A list lst is either –the empty list, the-emptylst, or –(make-lst s r), where s is a value and r is a list 3

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Lists Building lists with structures 4 (define-struct lst (first rest)) (define-struct emptylst ()) (define the-emptylst (make-emptylst)) ;; a list with 0 elements (define list0 the-emptylst) ;; a list with 1 element (define list1 (make-lst 'a the-emptylst)) ;; a list with 2 elements (define list2 (make-lst 'a (make-lst 'b the-emptylst))) ;; get the 2nd element from list2 (lst-first (lst-rest list2)) 'b

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Lists Lists are an important data type and therefore there is a built-in data type for them –(also because of historical reasons) –Constructor with 2 arguments: cons (for cons truct) equivalent to make-lst from previous slide –The empty list: empty equivalent to the-emptylst –Selectors: first for the first element, rest for the second element equivalent to lst-first, lst-rest historical names for first and rest: car and cdr –Predicates: list?, empty? equivalent to lst?, emptylst? 5

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Lists Example 6 ;; a list with 0 elements ;; (define list1 the-emptylst) (define list0 empty) ;; a list with 1 element ;; (define list1 (make-lst 'a the-emptylst)) (define list1 (cons 'a empty) ;; a list with 2 elements ;; (define list2 (make-lst 'a ;; (make-lst 'b ;; the-emptylst))) (define list2 (cons 'a (cons 'b empty)) ;; get the 2nd element from list2 ;; (lst-first (lst-rest list2)) 'b (first (rest list2)) 'b

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Lists The only difference between make-lst and cons: –cons expects empty or (cons … ) as second argument –E.g. (cons 1 2) throws an error, (make-lst 1 2) doesnt –Thus, cons prevents incorrect use however, this check is missing in other versions of Scheme A better emulation would look like this: –But this can not guarantee that the user does not use make-lst directly 7 (define-struct lst (first rest)) (define-struct emptylst ()) (define the-emptylst (make-emptylst)) (define (our-cons a-value a-list) (cond [(emptylst? a-list) (make-lst a-value a-list)] [(lst? a-list) (make-lst a-value a-list)] [else (error 'our-cons "list as second argument expected")]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Lists 8

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Lists In general, a list does not have to contain values of one kind, but may contain arbitrary values 9 (cons 0 (cons 1 (cons 2 (cons 3 (cons 4 (cons 5 (cons 6 (cons 7 (cons 8 (cons 9 empty)))))))))) (cons 'RobbyRound (cons 3 (cons true empty)))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 The Closure Property An operation for combining data objects satisfies the closure property if the results of combining things with that operation can themselves be combined using the same operation –Example: cons Such combination operators permit us to create hierarchical data structures. 10

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 The Closure Property 11 Question: Have we seen the closure property before?

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 The Closure Property Origin of the word closure –Abstract algebra: A set of elements is said to be closed under an operation, if applying the operation to elements in the set produces an element that is again an element of the set 12

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 The Closure Property The thought that an instrument of combination satisfies the closure property is very intuitive Unfortunately, the combination operators of many languages do not satisfy closure –We can combine elements by storing them in an array –However, in some languages one cannot build arrays of arrays or not use them as parameter/return types –Lack of a built-in general-purpose glue that makes it easy to manipulate compound data in a uniform way 13

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 The list Constructor Creating longer lists with cons is somewhat tedious Therefore there is a constructor called list –accepts any number of arguments –creates a list with all arguments as elements –e.g. (list 1 2 3) instead of (cons 1 (cons 2 (cons 3 empty))) –e.g. (list (list a 1) (list b 2)) In general (list exp-1 … exp-n) is equivalent to (cons exp-1 (cons … (cons exp-n empty ) … )) 14

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 The / quote Constructor Lists and symbols can be abbreviated even more by using the quote constructor ' –'(1 2 3) is short for (list 1 2 3) –'((1 2) (3 4) (5 6)) stands for (list (list 1 2) (list 3 4) (list 5 6)) –'(a b c) stands for (list 'a 'b 'c) Dont confuse this with (list a b c) – list evaluates all arguments, quote does not –In general, '(exp-1 … exp-n) is equivalent to (list 'exp-1 … 'exp-n ), where 'exp-i = exp-i for all self-evaluating values (numbers, booleans) Note that this rule is recursive! To use list and quote, –please use the level Beginning Student with List Abbreviations in DrScheme from now on! 15

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Handling recursive data types How do we handle instances of recursive data types? –Answer: We use our design method for heterogeneous data –Example: Does a special symbol occur in a list of symbols? 1 st Step: Definition of the contract, Header etc. –Note the convention list-of-XXX to document in the contract what kind of data is expected as list elements 16 ;; contains-doll? : list-of-symbols -> boolean ;; to determine whether the symbol 'doll occurs ;; on a-list-of-symbols (define (contains-doll? a-list-of-symbols)...)

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Handling recursive data types Creating templates –Write a cond -branch for each data type; indicate selectors First Case (empty list) is trivial 17 (define (contains-doll? a-list-of-symbols) (cond [(empty? a-list-of-symbols)...] [(cons? a-list-of-symbols)... (first a-list-of-symbols)...... (rest a-list-of-symbols)...])) (define (contains-doll? a-list-of-symbols) (cond [(empty? a-list-of-symbols) false] [(cons? a-list-of-symbols)... (first a-list-of-symbols)...... (rest a-list-of-symbols)...]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Handling recursive data types We can already test the first element of the list with the available data What do we do with the rest of the list? –We need an auxiliary procedure, which tests if the (rest of the) list contains the symbol –This auxiliary procedure is contains-doll? itself! 18 (define (contains-doll? a-list-of-symbols) (cond [(empty? a-list-of-symbols) false] [(cons? a-list-of-symbols) (cond [(symbol=? (first a-list-of-symbols) 'doll) true]... (rest a-list-of-symbols)...]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Handling recursive data types Solution : 19 (define (contains-doll? a-list-of-symbols) (cond [(empty? a-list-of-symbols) false] [(cons? a-list-of-symbols) (cond [(symbol=? (first a-list-of-symbols) 'doll) true] [else (contains-doll? (rest a-list-of-symbols))]) ]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Handling recursive data types Why is it this solution well-defined? –Here, well-defined means that the evaluation of the procedure terminates Not every recursive definition leads to a well-defined function! –e.g. (define (f a-bool) (f (not a-bool))) Our recursive definition is an example of structural recursion –The structure of the procedure follows the (recursive) structure of the data –Such recursive definitions are always well defined, because the nesting depth of the data is reduced after each recursive call 20 (define (contains-doll? a-list-of-symbols) (cond [(empty? a-list-of-symbols) false] [(cons? a-list-of-symbols) (cond [(symbol=? (first a-list-of-symbols) 'doll) true] [else (contains-doll? (rest a-list-of-symbols))]) ]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Design of procedures for recursive data How does our design concept change? –Data analysis and design If the problem description involves information of arbitrary size, we need a recursive data structure The definition of this data structure needs at least two cases, at least one of which must not (directly or indirectly) refer back to the definition –Contract and procedure header: no changes –Examples: no changes –Template: Indicate the recursive call in the recursive branches –Procedure body First, implement the basic (non-recursive) branches, then the recursive branches. For the recursive calls, assume that the procedure already works as desired –Test: no changes 21

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Creating recursive data Procedures that process recursive data according to our design method usually combine the result of recursive call(s) with the non-recursive data This combination often consists of the construction of new data which has the same structure as the input 22 (define (sum a-list-of-nums) (cond [(empty? a-list-of-nums) 0] [else (+ (first a-list-of-nums) (sum (rest a-list-of-nums)))]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Creating recursive data Computation of the wage –of a person or multiple people 23 ;; wage : number -> number ;; to compute the total wage (at \$12 per hour) ;; of someone who worked for h hours (define (wage h) (* 12 h)) ;; hours->wages : list-of-numbers -> list-of-numbers ;; to create a list of weekly wages from ;; a list of weekly hours (alon) (define (hours->wages alon) (cond [(empty? alon) empty] [else (cons (wage (first alon)) (hours->wages (rest alon)))]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Structures that contain Structures Structures (and lists) do not necessarily have to contain atomic data –They can e.g. contain instances of their own structure as elements (as in the list structure) –They may also contain any other types of structures/lists e.g. list of points, list of lists of points Example: –A inventory record is a structure (make-ir s n), s being a symbol and n a (positive) number: (define-struct ir (name price)) –An inventory-list is either 1.empty, or 2.(cons ir inv), ir being an inventory record and inv an inventory-list 24

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 The Structure of Natural Numbers Often, natural numbers are described by means of an enumeration: 0,1,2, etc. –However, we cannot program etc. Using a recursive definition, we can get rid of etc.: –0 is a natural number –If n is a natural number, then so is the successor of n (succ n) –This definition generates: 0, (succ 0), (succ (succ 0)) etc. –Cf. the Peano-Axioms from mathematics This is analogous to the construction of lists –cons is equivalent to succ –rest is equivalent to pred –empty? is equivalent to zero? Therefore, functions that operate on natural numbers and functions that operate on lists can be structured in the same way! 25

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 The Structure of Natural Numbers Example 1 Example 2 26 ;; hellos : N -> list-of-symbols ;; to create a list of n copies of 'hello (define (hellos n) (cond [(zero? n) empty] [else (cons 'hello (hellos (pred n)))])) ;; ! : N -> N ;; computes the faculty function (define (! n) (cond [(zero? n) 1] [else (* n (! (pred n)))]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Intermezzo Design of auxiliary procedures revisited 27

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Design of auxiliary procedures: wish lists Larger programs are made up of many different (auxiliary) procedures Suggested method: Creation and maintenance of a wish list of auxiliary procedures –A list of procedures that are missing to complete a program The procedures of the wish list can be implemented stepwise by means of our design method The wish list will often change during implementation –e.g. one discovers that new auxiliary procedures are needed 28

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Design of auxiliary procedures: wish lists The order of processing the wish list is important –Bottom-Up-approach: First implement the procedures that do not depend on any other procedure of the wish list Advantage: We can test immediately and at any time Disadvantage: At the beginning it is often difficult to see which procedures are needed on the lowest level; one might lose track of the big picture –Top-Down- approach: First implement the main procedure, then those called by the main procedure, and so on Advantage : Incremental refinement of the program structure Disadvantage : Testing can only be done late; sometimes you discover way down that there is a conceptual error higher up –Often a mix of Top-Down and Bottom-Up makes sense 29

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Design of auxiliary procedures: wish lists Example: Sorting a list of numbers –First, we follow our design method… 30 ;; sort : list-of-numbers -> list-of-numbers ;; to create a sorted list of numbers from all ;; the numbers in alon ;; Examples: ;; (sort empty) empty ;; (sort (cons 1297.04 (cons 20000.00 (cons -505.25 empty)))) ;; (cons -505.25 (cons 1297.04 (cons 20000.00 empty))) (define (sort alon) (cond [(empty? alon)...] [else... (first alon)... (sort (rest alon))...]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Design of auxiliary procedures: wish lists First case (empty list) is trivial The call (sort (rest alon)) returns a sorted list in the recursive case (first alon) has to be sorted into this list The procedure for doing this is added to our wish list; for now we can complete the sort-procedure 31 ;; insert : number list-of-numbers -> list-of-numbers ;; to create a list of numbers from n and the numbers ;; on alon that is sorted in descending order; alon is ;; already sorted (define (insert n alon)...) (define (sort alon) (cond [(empty? alon) empty] [else (insert (first alon) (sort (rest alon)))]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Design of auxiliary procedures: wish lists The insert-procedure can now be implemented independently of sort –important: detailed analysis of the different cases –This type of sorting is known as Insertion-Sort 32 ;; insert : number list-of-numbers (sorted) ;; -> list-of-numbers (sorted) ;; to create a list of numbers from n and the numbers on ;; alon that is sorted in descending order; alon is sorted (define (insert n alon) (cond [(empty? alon) (cons n empty)] [else (cond [(<= n (first alon)) (cons n alon)] [(> n (first alon)) (cons (first alon) (insert n (rest alon)))])]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Design of auxiliary procedures: Generalization of Problems A more general problem is often easier to solve than the actual problem Approach: The auxiliary procedure solves the generalized problem, the main procedure specializes the auxiliary procedure to solve the actual problem Example: Changing coins –In how may different ways can we make change of 1, given coins of 1, 2, 5, 10, 20 and 50 Cent? –Generalization: In how may different ways can we change amount a using the first n types of coins from 1, 2, 5, 10, 20 and 50 Cent? –Specialization: n = 6 33

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Design of auxiliary procedures: Generalization of Problems Counting ways to change: Straightforward formulation of the generalized problem as recursive procedure: –The number of ways to change amount a using n kinds of coins equals: 1 if a = 0 0 if a<0 or n = 0 otherwise: –the number of ways to change amount a using all but the last kind of coin, plus –the number of ways to change amount a-d using all n kinds of coins, where d is the denomination of the last kind of coin. 34

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Design of auxiliary procedures: Generalization of Problems 35 (define (count-change amount) (cc amount 6)) (define (cc amount kinds-of-coins) (cond [(= amount 0) 1] [(or (< amount 0) (= kinds-of-coins 0)) 0] [else (+ (cc amount (- kinds-of-coins 1)) (cc (- amount (denomination kinds-of-coins)) kinds-of-coins))])) (define (denomination coin-number) (cond ((= coin-number 1) 1) ((= coin-number 2) 2) ((= coin-number 3) 5) ((= coin-number 4) 10) ((= coin-number 5) 20) ((= coin-number 6) 50)))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Design of auxiliary procedures: Generalization of Problems Comments on the count-change procedure: –This kind of recursion is different from structural recursion, which you have seen before More on this later –This procedure needs a lot of computing A lot of time may be needed for amounts >100 The time required increases exponentially with the size of the amount More on this later 36

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Trees 37

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Trees Trees are one of the most important data structures in computer science –representation of hierarchical relations Example: family trees 38

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Trees Data modeling, 1st attempt: Problem: It is impossible to create an instance of this data structure –The basic case is missing (termination of the recursion) –We failed to apply our rule for designing recursive data structures The definition of a recursive data structure needs at least two cases, at least one of which must not be recursive 39 A child is a structure (make-child father mother name date eyes), where father and mother are child-structures ; name and eyes are symbols, date is a number

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Trees Data modeling, 2nd attempt : This definition conforms to our design rule; it can represent a family tree 40 A family tree node (ftn) is either 1. empty, or 2. (make-child father mother name year eyes) where father and mother are ftn; name and eyes are symbols, year is a number

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Trees Carl: (make-child empty empty Carl 1926 green) Adam: (make-child (make-child empty empty Carl 1926 green) (make-child empty empty Bettina 1926 green) Adam 1950 yellow) 41 redundancy!

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Trees Avoid redundancy by binding to names 42 ;; Oldest Generation: (define Carl (make-child empty empty 'Carl 1926 'green)) (define Bettina (make-child empty empty 'Bettina 1926 'green)) ;; Middle Generation: (define Adam (make-child Carl Bettina 'Adam 1950 'yellow)) (define Dave (make-child Carl Bettina 'Dave 1955 'black)) (define Eva (make-child Carl Bettina 'Eva 1965 'blue)) (define Fred (make-child empty empty 'Fred 1966 'pink)) ;; Youngest Generation: (define Gustav (make-child Fred Eva 'Gustav 1988 'brown))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Trees Design of functions on trees –The method is the same, but it leads to more than one recursive call General template 43 ;; fun-for-ftn : ftn -> ??? (define (fun-for-ftn a-ftree) (cond [(empty? a-ftree)...] [else... (fun-for-ftn (child-father a-ftree))...... (fun-for-ftn (child-mother a-ftree))...... (child-name a-ftree)...... (child-date a-ftree)...... (child-eyes a-ftree)...]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Trees Example: blue-eyed-ancestor? 44 ;; blue-eyed-ancestor? : ftn -> boolean ;; to determine whether a-ftree contains a child ;; structure with 'blue in the eyes field (define (blue-eyed-ancestor? a-ftree) (cond [(empty? a-ftree) false] [else (or (symbol=? (child-eyes a-ftree) 'blue) (or (blue-eyed-ancestor? (child-father a-ftree)) (blue-eyed-ancestor? (child-mother a-ftree))))]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Mutually Recursive Structures Inverted example: Children instead of ancestors 45 Important difference for modeling: A person can have any number of children, but only two ancestors (parents) We need a list to store the children

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Mutually Recursive Structures We need two separate data structures: –A parent is a structure (make-parent loc name date eyes), where loc is a list of children, name and eyes symbols, and date is a number. –A list of children is either 1.empty, or 2.(cons p loc), whereas p is a parent and loc is a list of children Each of these definitions is useless when looked at separately, because it refers to another data structure which has not yet been defined –Such data structures are called mutually recursive –Mutually recursive data structures should always be defined together 46

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Mutually Recursive Structures Representation of the family tree 47 ;; Youngest Generation: (define Gustav (make-parent empty 'Gustav 1988 'brown)) (define Fred&Eva (list Gustav)) ;; Middle Generation: (define Adam (make-parent empty 'Adam 1950 'yellow)) (define Dave (make-parent empty 'Dave 1955 'black)) (define Eva (make-parent Fred&Eva 'Eva 1965 'blue)) (define Fred (make-parent Fred&Eva 'Fred 1966 'pink)) (define Carl&Bettina (list Adam Dave Eva)) ;; Oldest Generation: (define Carl (make-parent Carl&Bettina 'Carl 1926 'green)) (define Bettina (make-parent Carl&Bettina 'Bettina 1926 'green))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Mutually Recursive Structures How do we create the procedure blue-eyed- descendant? Contract, description, header, examples : 48 ;; blue-eyed-descendant? : parent -> boolean ;; to determine whether a-parent or any of its descendants ;;(children, grandchildren, and so on) have 'blue in the ;; eyes field (define (blue-eyed-descendant? a-parent)...) ;; Here are three simple examples, formulated as tests: (boolean=? (blue-eyed-descendant? Gustav) false) (boolean=? (blue-eyed-descendant? Eva) true) (boolean=? (blue-eyed-descendant? Bettina) true)

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Mutually Recursive Structures Template: Current person can be checked immediately 49 (define (blue-eyed-descendant? a-parent)... (parent-children a-parent)...... (parent-name a-parent)...... (parent-date a-parent)...... (parent-eyes a-parent)... ) (define (blue-eyed-descendant? a-parent) (cond [(symbol=? (parent-eyes a-parent) 'blue) true] [else... (parent-children a-parent)...... (parent-name a-parent)...... (parent-date a-parent)...])) Name and date of birth are unimportant for this task

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Mutually Recursive Structures We need a procedure which browses a list of children in search of blue-eyed descendants Following our guideline for complex procedures, we add such a procedure to our wish list: Now we can finish blue-eyed-descendant? : 50 ;; blue-eyed-children? : list-of-children -> boolean ;; to determine whether any of the structures ;; on aloc is blue-eyed or has any blue-eyed descendant (define (blue-eyed-children? aloc)...) (define (blue-eyed-descendant? a-parent) (cond [(symbol=? (parent-eyes a-parent) 'blue) true] [else (blue-eyed-children? (parent-children a-parent))]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Mutually Recursive Structures Processing the wish list: –Creation of blue-eyed-children? Standard template for lists: List is empty trivial Result of the recursive call needs only be linked with or, to check if the first element of the list has a blue-eyed descendant We just need a procedure which computes if a descendant has blue eyes, given a parent structure –This procedure is blue-eyed-descendant? 51 (define (blue-eyed-children? aloc) (cond [(empty? aloc)...] [else... (first aloc)...... (blue-eyed-children? (rest aloc))...]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Mutually Recursive Structures Final result 52 ;; blue-eyed-children? : list-of-children -> boolean ;; to determine whether any of the structures in aloc ;; is blue-eyed or has any blue-eyed descendant (define (blue-eyed-children? aloc) (cond [(empty? aloc) false] [else (or (blue-eyed-descendant? (first aloc)) (blue-eyed-children? (rest aloc)))]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Mutually Recursive Structures Lesson learned: –Reason: The structure of the procedure should always follow the structure of the data! –Mutually recursive data should always be treated as a single unit, since they only make sense that way –Implement procedures on mutually recursive data by using the wish list approach Due to the mutual dependencies, strict bottom-up or top-down implementation is not possible! 53 Procedures operating on mutually recursive data structures are mutually recursive themselves!

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Intermezzo Iterative refinement of programs 54

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Iterative refinement of programs While we are programming, we create a model of a small part of the real world –When we start, it is often not clear which aspects/information should be included in the model Because of this, we should proceed iteratively, i.e. improve the program and data concept stepwise –Start with a very simple model –Add details step by step Our example: Iterative refinement of a data model for file systems 55

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Iterative refinement of programs Example of a file system structure 56

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Iterative refinement of programs Model 1: –Files are represented by the name of the file (symbol); –A directory is a list made up of files and directories Data model: 57 A file is a symbol A directory (short: dir) is either empty, or (cons f d) where f is a file and d is a directory; or (cons d1 d2) where d1 and d2 are dirs.

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Iterative refinement of programs Model 2: –A directory has a name and other attributes which we want to model Improved Data model: – (define-struct dir (name content) –Both data structures are mutually recursive! 58 A directory (short: dir) is a structure (make-dir n c), where n is a symbol and c is a list of files and directories A list of files and directories (LOFD) is either 1.empty 2.(cons f d) where f is a file and d is a LOFD 3.(cons d1 d2) whereas d1 is a dir and d2 is a LOFD

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Iterative refinement of programs Model 3: –We also want to model the attributes of files (size, content) –We want to be able to distinguish between files and directories Improved Data model : – (define-struct file (name size content)) 59 A list of files (LOF) is either 1.empty 2.(cons f lof) where f is a file and lof is a LOF A file is a structure (make-file name size content), where name is a symbol, size is a number and content is a string

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Iterative refinement of programs Model 3:… Improved Data model, continued: – (define-struct dir (name dirs files)) 60 A directory (short: dir) is a structure (make-dir name dirs files), where name is a symbol, dirs is a LOD and files is a LOF A list of directories (LOD) is either 1.empty 2.(cons d lod) where d is a dir and lod is a LOD

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Procedures with many complex arguments 61

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Procedures with many complex arguments Up to now we have only seen procedures that accept one complex argument –complex means: The data type of the argument is defined recursively For two or more complex arguments, there are three cases to consider: 1.One of the arguments can be treated as atomic for the purpose of the procedure 2.All arguments are processed synchronously 3.All possible cases of the input arguments must be treated separately We will now look at one example for each of these cases 62

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Procedures with many complex arguments First example: One argument is treated as atomic –Recursion happens only for first argument 63 ;; append : list list -> list ;; to construct a new list by replacing empty ;; in alon1 with alon2 (define (append alon1 alon2) (cond ((empty? alon1) alon2) (else (cons (first alon1) (append (rest alon1) alon2)))))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Procedures with many complex arguments Second example: All arguments are processed synchronously 64 ;; addlist : ;; list-of-numbers list-of-numbers -> list-of-numbers ;; to construct a new list of numbers where the i-th number ;; is the sum of the i-th number of alon1 and the i-th ;; number of alon2 ;; ;; Example: (addlist (list 1 2) (list 7 8 9)) (list 8 10) (define (addlist alon1 alon2) (cond [(or (empty? alon1) (empty? alon2)) empty] [else (cons (+ (first alon1) (first alon2)) (addlist (rest alon1) (rest alon2)))]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Procedures with many complex arguments Third Example: All possible cases of the input arguments must be treated separately Examples: 65 ;; list-pick : list-of-symbols N[>= 1] -> symbol ;; to determine the nth symbol from alos, counting from 1; ;; signals an error if there is no n-th item (define (list-pick alos n)...) (list-pick empty 1) ;; expected behavior: (error 'list-pick "...") (list-pick (cons 'a empty) 1) ;; expected value: 'a (list-pick empty 3) ;; expected behavior: (error 'list-pick "...") (list-pick (cons 'a empty) 3) ;; expected behavior: (error 'list-pick "...")

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Procedures with many complex arguments Third example: All possible cases of the input arguments must be treated separately Obviously, there are four interesting cases: 66 (empty? alos)(cons? alos) (= n 1) (and (= n 1) (empty? alos)) (and (= n 1) (cons? alos)) (> n 1) (and (> n 1) (empty? alos)) (and (> n 1) (cons? alos))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Procedures with many complex arguments Transferring the different cases to the procedure design Now, each case can be implemented individually 67 define (list-pick alos n) (cond [(and (= n 1) (empty? alos))...] [(and (> n 1) (empty? alos))... (sub1 n)...] [(and (= n 1) (cons? alos))... (first alos)... (rest alos)...] [(and (> n 1) (cons? alos))... (sub1 n)... (first alos)... (rest alos)...]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Procedures with many complex arguments Complete implementation –Works, but the procedure can be simplified! –Next step for such procedures Analyze the cases and look for possible simplifications 68 ;; list-pick : list-of-symbols N[>= 1] -> symbol ;; to determine the nth symbol from alos, counting from 1; ;; signals an error if there is no nth item (define (list-pick alos n) (cond [(and (= n 1) (empty? alos)) (error 'list-pick "list too short")] [(and (> n 1) (empty? alos)) (error 'list-pick "list too short")] [(and (= n 1) (cons? alos)) (first alos)] [(and (> n 1) (cons? alos)) (list-pick (rest alos) (sub1 n))]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Procedures with many complex arguments Cases 1 and 2 have the same implementation Simplified implementation: 69 (define (list-pick alos n) (cond [(and (= n 1) (empty? alos)) (error 'list-pick "list too short")] [(and (> n 1) (empty? alos)) (error 'list-pick "list too short")] [(and (= n 1) (cons? alos)) (first alos)] [(and (> n 1) (cons? alos)) (list-pick (rest alos) (pred n))])) (define (list-pick alos n) (cond [(or (and (= n 1) (empty? alos)) (and (> n 1) (empty? alos))) (error 'list-pick "list too short")] [(and (= n 1) (cons? alos)) (first alos)] [(and (> n 1) (cons? alos)) (list-pick (rest alos) (pred n))]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Procedures with many complex arguments A close look (rules of logic) at the code reveals that the first condition can be reduced to (empty? alos) –As a result, we can omit the cons-condition from cases 2 and 3 Final version: 70 (define (list-pick alos n) (cond [(empty? alos) (error 'list-pick "list too short")] [(= n 1) (first alos)] [(> n 1) (list-pick (rest alos) (sub1 n))])) (define (list-pick alos n) (cond [(or (and (= n 1) (empty? alos)) (and (> n 1) (empty? alos))) (error 'list-pick "list too short")] [(and (= n 1) (cons? alos)) (first alos)] [(and (> n 1) (cons? alos)) (list-pick (rest alos) (sub1 n))]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Analyzing arithmetic expressions In the following, we look at a larger example, which illustrates the methods learned in this lecture At the same time, this program is the first step towards a Scheme interpreter written in Scheme –making the evaluation rules more concrete! Task: –representation and computation of any nested arithmetic expression consisting of multiplication and addition Input: deep list of symbols and numbers –For example, '(+ 3 (* (+ 3 5) (* 1 2)))) = (list '+ 3 (list '* (list '+ 3 5) (list '* 1 2))) = (cons '+ (cons 3 (cons (cons '* (cons (cons '+ (cons 3 (cons 5 empty))) (cons (cons '* (cons 1 (cons 2 empty))) empty))) empty))) Output: value representing the arithmetic expression 71

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Analyzing arithmetic expressions First step: data analysis Design of a data structure for arithmetic expressions –In principle, we could work directly with the deep lists of symbols/numbers (so-called s-expressions) –This gets complex very quickly, because s-expressions are too general e.g., we just want to consider double-digit operators, but there are only lists for s-expressions –Furthermore, we must always be prepared for wrong inputs Therefore, we will define our own data structure for storing arithmetic data, and convert the s-expressions to this structure –This is called parsing 72

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Analyzing arithmetic expressions Definition of the data type aexp: 73 ;; Data definition: ;; An arithmetic expression aexp is either ;; 1. a number ;; 2. (make-add l r) where l and r are aexp ;; 3. (make-mul l r) where l and r are aexp (define-struct add (left right)) (define-struct mul (left right))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Analyzing arithmetic expressions Definition of the parser 74 ;; parse :: deep-list-of symbol -> aexp ;; converts a deep list of symbols into a corresponding ;; aexp, if possible ;; ;; Example: ;; (parse '(+ 3 (* (+ 3 5) (* 1 2)))) ;; = (make-add 3 (make-mul (make-add 3 5) (make-mul 1 2))) (define (parse sexp) (cond [(number? sexp) sexp] [(cons? sexp) (cond [(symbol=? (first sexp) '+) (make-add (parse (second sexp)) (parse (third sexp)))] [(symbol=? (first sexp) '*) (make-mul (parse (second sexp)) (parse (third sexp)))])]))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Analyzing arithmetic expressions Definition of the evaluation Procedure 75 ;; calc :: aexp -> number ;; ;; calculates the number represented by ;; the arithmetic expression exp ;; ;; Example: ;; (calc (make-add 3 (make-mul (make-add 3 5) (make-mul 1 2)))) ;; = 19 (define (calc exp) (cond ((number? exp) exp) ((add? exp) (+ (calc (add-left exp)) (calc (add-right exp)))) ((mul? exp) (* (calc (mul-left exp)) (calc (mul-right exp))))))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Analyzing arithmetic expressions Usage of the interpreter: –e.g. (calc (parse (+ 5 (* 7 3)))) 26 What is this program good for? –Good example of recursive data structures and recursive functions that operate on them –We have just implemented a (primitive) interpreter it interprets the language of the arithmetic expression –It models how Scheme itself interprets arithmetic expressions –The basic structure of this mini-interpreter is already the same as the structure of a full-grown interpreter for a language like Scheme Parser, recursively defined data structure, recursively defined evaluation procedure –Later, we will extend the interpreter so that it can interpret the substantial parts of the language Scheme! 76

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Analyzing arithmetic expressions Take a look at the code from the Software Engineering point of view: –How extensible is it? Two important dimensions for extensibility: –Adding new data types (e.g. Div, Sub) –Adding new operations (e.g. scale) Adding new operations is easy: –No existing code must be changed! 77

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Analyzing arithmetic expressions Adding a new operation 78 ;; swap+* :: aexp -> aexp ;; ;; generates new aexp within which ;; every addition is replaced by multiplication ;; and vice versa ;; ;; Example: ;; (swap+* (make-add 3 (make-mul 5 7))) ;; = (make-mul 3 (make-add 5 7)) (define (swap+* exp) (cond ((number? exp) exp) ((add? exp) (make-mul (swap+* (add-left exp)) (swap+* (add-right exp)))) ((mul? exp) (make-add (swap+* (mul-left exp)) (swap+* (mul-right exp))))))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Analyzing arithmetic expressions Take a look at the code from the Software Engineering point of view: –How extensible is it? Two important dimensions for extensibility: –Adding new data types (e.g. Div, Sub) –Adding new operations (e.g. scale) Adding new operations is easy: –No existing code must be changed! But adding new data types is hard: –the cond-statements of all operations must be extended by one case for each new data type 79

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Analyzing arithmetic expressions Adding a new data type 80 ;; Data definition: ;; An arithmetic expression aexp is either ;; 1. a number ;; 2. (make-add l r) where l and r are aexp ;; 3. (make-mul l r) where l and r are aexp ;; 4. (make-sub l r) where l and r are aexp (define-struct add (left right)) (define-struct mul (left right)) (define-struct sub (left right))

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Analyzing arithmetic expressions Adding a new data type 81 ;; calc :: aexp -> number ;; … (define (calc exp) (cond ((number? exp) exp) ((add? exp) (+ (calc (add-left exp)) (calc (add-right exp)))) ((sub? exp) (- (calc (add-left exp)) (calc (add-right exp)))) ((mul? exp) (* (calc (mul-left exp)) (calc (mul-right exp)))))) Existing code must be changed. Analogous: other operations such as swap+*

Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Introduction to Computer Science I: T3 Analyzing arithmetic expressions Take a look at the code from the Software Engineering point of view: –How extensible is it? Two important dimensions for extensibility: –Adding new data types (e.g. Div, Sub) –Adding new operations (e.g. scale) Adding new operations is easy: –No existing code must be changed! But adding new data types is hard: –the cond-statements of all operations must be extended by one case for each new data type –Existing code must be changed; this is bad, in particular if the different parts of the code should be developed independently from each other Later, we will see that the situation in object-oriented languages is exactly inverted! This problem is sometimes called the extensibility problem 82