CS 342 Lecture -*-Outline-*- ** Abstraction in general def: abstraction is a many to one mapping, suppression of inessential detail *** Abstraction Techniques **** parameterization abstraction of variables or constants e.g., summing an array, sum(a), sum[T](a) abstraction of algorithmic parts e.g., mapcar **** specification an abstraction of a procedure implementation (its effect) e.g., a sort routine gives a permutation that's ordered abstraction of data structure and operations e.g., integers, integer subrange e.g., sets vs. lists with no duplicates *** Kinds of abstractions (give examples) **** procedural (lambda) e.g., sum of array abstracts effect of sequence of stmts (algorithm) pre+post conditions used for spec **** data e.g., ints, lists, sets, complex numbers, arrays abstracts representation and algorithms of data structure abstract values + descriptions of ops used for spec **** control e.g., if-then-else, goto iteration abstraction e.g., int$from_to, set[array[int]]$elements abstracts generation of a sequence (of elements) used in a loop specified by giving sequence yielded *** examples ------------------ ; in LISP (set the-empty-tree '(tree)) (define tree-make (left node right) ; : tree, s-exp, tree -> tree (cons 'tree (cons left (cons node (cons right '()))))) (define leaf-make (node) ; : s-exp -> tree (tree-make the-empty-tree node the-empty-tree)) (define post-order2 (tree) (if (null? (cdr tree)) '() (append (post-order2 (cadr tree)) (append (post-order2 (caddr tree)) (cons (caddr (cdr tree)) '()))))) (define tree-empty? (tree) (null? (cdr tree))) (define tree-left (tree) (car (cdr tree))) (define tree-root (tree) (cadr (cdr tree))) (define tree-right (tree) (caddr (cdr tree))) (define append3 (l1 l2 l3) (append l1 (append l2 l3))) (define post-order (tree) (if (tree-empty? tree) '() (append3 (post-order (tree-left tree)) (post-order (tree-right tree)) (list1 (tree-root tree))))) ------------------ Go through the correctness argument for post-order2 first, then the argument for post-order, be sure to show how the lemmas for the subroutines help. Note: both data abstraction and procedural abstraction Efficiency: can transform (or have compiler transform) post-order into post-order2. The punch line: what happens if we change the definition of trees? ------------------ (set the-empty-tree '()) (define tree-make (left node right) ; : tree, s-exp, tree -> tree (cons left (cons node (cons right '())))) (define leaf-make (node) ; : s-exp -> tree (tree-make the-empty-tree node the-empty-tree)) (define tree-empty? (tree) (null? tree)) (define tree-left (tree) (car tree)) (define tree-root (tree) (cadr tree)) (define tree-right (tree) (caddr tree)) ------------------ note that leaf-make is the same! Our post-order still works correctly, but post-order2 does not. Abstraction is also a key to efficiency, most efficiency gains come from changing the data structure... above example was a small gain in efficiency could also do things like implementing arrays with binary trees to make average access O(log n) instead of O(n), where n is size of array ---------------------- ; in CLU (Kamin's version) (cluster Tree ; Export: make, empty, empty?, ; left, right, root (rep lst) ; if lst is empty, tree is empty ; else (List$car lst) is left subtree, ; (List$car (List$cdr lst)) is root, ; (List$car (List$cdr (List$cdr lst))) ; is right subtree (define empty () ; -> Tree (Tree (List$nil))) (define make (left node right) ; : Tree, object, Tree -> Tree (Tree (List$cons left (List$cons node (List$cons right (List$nil)))))) (define empty? (tree) (List$null? (lst tree))) (define left (tree) (List$car (lst tree))) (define root (tree) (List$car (List$cdr (lst tree)))) (define right (tree) (List$car (List$cdr (List$cdr (lst tree))))) ) (define leaf-make (node) ; : Object -> Tree (tree$make (Tree$empty) node (Tree$empty))) (load libraray.clu) (define append (x y) (if (List$null? x) y (List$cons (List$car x) (append (List$cdr x) y)))) (define append3 (l1 l2 l3) (append l1 (append l2 l3))) (define post-order (tree) (if (Tree$empty? tree) (List$nil) (append3 (post-order (Tree$left tree)) (post-order (Tree$right tree)) (list1 (Tree$root tree))))) ---------------------- Note List$nil has to be invoked, no constants. can change the representation of trees here too: ---------------------- (cluster Tree ; Export: make, empty, empty?, ; left, right, root (rep defined l n r) ; if defined = 0, tree is empty ; otw, defined = 1 and l is left subtree ; n is value of the root node, ; r is right subtree (define empty () ; -> Tree (Tree 0 0 0 0)) (define make (left node right) ; : Tree, object, Tree -> Tree (Tree 1 left node right)) (define empty? (tree) (= 0 (defined tree))) (define left (tree) (l tree)) (define root (tree) (n tree)) (define right (tree) (r tree)) ) ---------------------- other programs work exactly as before.