Recursive Data Structures and Grammars Themes Recursive Description

  • Slides: 33
Download presentation
Recursive Data Structures and Grammars Themes Recursive Description of Data Structures Recursive Definitions of

Recursive Data Structures and Grammars Themes Recursive Description of Data Structures Recursive Definitions of Properties of Data Structures Recursive Algorithms for Manipulating and Traversing Data Structures Structural induction Examples Lists Trees Expressions and Expression Trees

List Processing Recursive Definition List : = nil | (cons All List) List<Type> :

List Processing Recursive Definition List : = nil | (cons All List) List<Type> : = nil (cons Type List<Type>) Process lists using these two cases and use recursion to recursively process lists in cons Use first and rest to access components of cons Size is the number of conses (generally number of constructors) Prove properties by inducting on size – assume 2 property holds for smaller size objects and

Member (defun member (x l) (cond ((equal l nil) ((equal x (first l)) t)

Member (defun member (x l) (cond ((equal l nil) ((equal x (first l)) t) ((member x (rest l))))) 3

Append (defun append (x y) (if (equal x nil) y (cons (first x) (append

Append (defun append (x y) (if (equal x nil) y (cons (first x) (append (rest x) y)))) Properties 1. 2. 3. (append x nil) = x (length (append x y)) = (+ (length x) (length y)) (append x (append y z)) = (append x y) z) 4

Structural Induction When using induction on recursively defined data structures like lists you can

Structural Induction When using induction on recursively defined data structures like lists you can induct on the size of the data structure = to the number of calls to the constructors. When trying to show a property for a data structure of a given size, you can assume that the property holds when making a recursive call on a smaller data structure. You must make sure that the property holds for all constructors including base cases. With lists (rest …) will return a smaller data structure (at least one fewer cons) Structural induction allows you to induct on the recursive data structure without being explicit about the size provided the IH is applied to smaller objects.

Proof of Property 1 Show (append x nil) = x using structural induction Base

Proof of Property 1 Show (append x nil) = x using structural induction Base case. x = nil. In this case, (append nil) returns nil = x. By induction assume recursive call satisfies the property [note (rest x) is smaller than x] I. E. (append (rest x) nil) = (rest x) Thus (append x nil) returns (cons (first x) (rest x)) = x

Proof of Property 2 Show (length (append x y) = (+ (length x) (length

Proof of Property 2 Show (length (append x y) = (+ (length x) (length y)) using structural induction on x Base case. x = nil. (append nil y) = y and (length y) = (+ (length nil) (length y)) By induction assume recursive call satisfies the property (length (append (rest x) y) = (+ (length (rest x)) (length y)) Thus (length (append x y)) = (length (cons (first x) (append (rest x) y)) = (+ 1 (length (rest x)) + (length y)) = (+ (length x) (length y))

Proof of Property 3 Show (append x (append y z)) = (append x y)

Proof of Property 3 Show (append x (append y z)) = (append x y) z) Base case. x = nil. (append nil (append y z)) = (append y z) = (append nil y) z) Assume property holds for (rest x) (append x y) z) (append (cons (first x) (append (rest x) y)) z) [by def] (cons (first x) (append (rest x) y) z)) [by def] (cons (first x) (append (rest x) (append y z))) [by IH] (append (cons (first x) (rest x)) (append y z)) [by def] (append x (append y z)) [by property of cons]

Reverse (defun reverse (l) (if (equal l nil) nil (append (reverse (rest l)) (cons

Reverse (defun reverse (l) (if (equal l nil) nil (append (reverse (rest l)) (cons (first l) nil)))) Properties (length (reverse x)) = (length x) (reverse (append x y)) = (append (reverse y) (reverse x)) = x 9

Proof of Property 2 Show (rev (append x y)) = (append (rev y) (rev

Proof of Property 2 Show (rev (append x y)) = (append (rev y) (rev x)) Base case. x = nil. (rev (append nil y)) = (rev y) = (append (rev y) nil) = (append (rev y) (rev nil)) Assume property holds for (rest x) (rev (append x y)) (rev (cons (first x) (append (rest x) y)) [def apppend] (append (rev (append (rest x) y)) (cons (first x) nil)) [def rev] (append (rev y) (rev (rest x))) (cons (first x) nil)) [IH] (append (rev y) (append (rev (rest x)) (cons (first x) nil))) [prop app] (append (rev y) (rev x)) [def of rev]

Proof of Property 3 Show (rev x)) = x Base case. x = nil.

Proof of Property 3 Show (rev x)) = x Base case. x = nil. (rev nil)) = (rev nil) = nil Assume property holds for (rest x) (rev x)) (rev (append (rev (rest x)) (cons (first x) nil))) [def rev] (append (rev (cons (first x) nil)) (rev (rest x)))) [property 2 of rev] (append (cons (first x) nil) (rev (rest x)))) [def of rev] (append (cons (first x) nil) (rest x)) [IH] (cons (first x) (append nil (rest x))) [def of app] (cons (first x) (rest x)) = x [def of app and prop of cons]

n-Trees Finite collection of nodes Each node has exactly one parent, but for the

n-Trees Finite collection of nodes Each node has exactly one parent, but for the root node Each node may have up to n children A leaf node has no children An interior node is a node that is not a leaf Each subtree is a tree rooted at a given node Tree : = nil | (All List<Tree>) E. G. (1 ((2 nil) (3 nil) (4 nil)))

Binary Trees A binary tree is a 2 -tree A binary tree is Empty,

Binary Trees A binary tree is a 2 -tree A binary tree is Empty, or Consists of a node with 3 attributes: value left, which is a binary tree right, which is a binary tree • Bin. Tree<Type> : = (Type Bin. Tree<Type>) E. G. (1 (2 nil) (3 (4 nil) (5 nil))) (Bin. Tree 1 (Bin. Tree 2 nil) (Bin. Tree 3 (Bin. Tree 4 nil) (Bin. Tree 5 nil)))

Number of Nodes of a Binary Trees Nnodes(T) = 0 if T is empty

Number of Nodes of a Binary Trees Nnodes(T) = 0 if T is empty Nnodes(T. left) + Nnodes(T. right) + 1 (defun Nnodes (BT) (if (equal BT nil) 0 (+ (Nnodes (left BT)) (Nnodes (right BT)) 1))) (defun left (BT) (second BT)) (defun right (BT) (third BT))

Height of Binary Trees Height of tree T, H(T), is the max length of

Height of Binary Trees Height of tree T, H(T), is the max length of the paths from the root all of the leaves H(T) = -1 if T is empty max( H(left(T)), H(right(T)) ) + 1 (defun Height (BT) (if (equal BT nil) -1 (+ (max (Height (left BT)) (Height (right BT))) 1)))

Correctness of Height Show (Height BT) = length of the longest path in BT

Correctness of Height Show (Height BT) = length of the longest path in BT Prove by structural induction Base case. -1 for nil is needed to obtain the correct height of a tree with a single node. Assume (Height (left BT)) and (Height (right BT)) compute the lengths of the longest paths in the left and right subtrees The longest path in BT is one more than the longest path in either the left or right subtrees which by induction is one more than the maximum of (Height (left BT)) and (Height (right BT))

Internal Path Length (IPL) The sum of the length of the paths from the

Internal Path Length (IPL) The sum of the length of the paths from the root to every node in the tree Recursively: IPL( T ) = 0 if T is empty IPL( T ) = IPL( left( T )) + IPL( right( T )) + num_nodes( T ) – 1 (defun IPL (BT) (if (equal BT nil) 0 (+ (IPL (left BT)) (IPL (right BT)) (- (Nnodes BT) 1))))

IPL Verification (check= (IPL nil) 0) (check= (let ((BT (cons. Bin. Tree 1 (cons.

IPL Verification (check= (IPL nil) 0) (check= (let ((BT (cons. Bin. Tree 1 (cons. Bin. Tree 2 nil) (cons. Bin. Tree 3 (cons. Bin. Tree 4 nil) (cons. Bin. Tree 5 nil))))) (IPL BT)) 6) 1 IPL = 6 = 0 + 2 + 4 3 2 4 5 Nnodes = 5 IPL((left BT)) = 0 IPL((right BT)) = 2

Correctness of IPL Show (ipl BT) = sum of the lengths of the paths

Correctness of IPL Show (ipl BT) = sum of the lengths of the paths from the root to all nodes in the tree. Prove by structural induction Base case. 0 is needed to get the proper value for a tree with a single node. Assume (ipl (left BT)) and (ipl (right BT)) compute the sum of the lengths of paths in the left and right subtrees The length of each path in BT is one more than the lengths of the paths in the left and right subtrees. Thus one has to be added for each node in the left and right subtrees and since there are (- (Nnodes BT) 1) such nodes this must be added to the sum of (ipl (left BT)) and (ipl (right BT))

Recurrence for the Number of Binary Trees Let Tn be the number of binary

Recurrence for the Number of Binary Trees Let Tn be the number of binary trees with n nodes. T 0 = 1, T 1 = 1, T 2 = 2, T 3 = 5

Expression Trees Basic arithmetic expressions can be represented by a binary tree Internal nodes

Expression Trees Basic arithmetic expressions can be represented by a binary tree Internal nodes are operators Leaf nodes are operands Consider 2 * ( 3 + 5 ) : * 2 + 3 5

Expression Tree Definition Exp. Tree : = (Number Integer) | (Add Expr. Tree) |

Expression Tree Definition Exp. Tree : = (Number Integer) | (Add Expr. Tree) | (Mult Expr. Tree) (defun Num. Node (val) (list 'Number val)) (defun Add. Node (E 1 E 2) (list 'Add E 1 E 2)) (defun Mult. Node (E 1 E 2) (list 'Mult E 1 E 2)) (Mult. Node (Num. Node 2) (Add. Node (Num. Node 3) (Num. Node 5)))

Expression Tree Evaluation Check each case in the recursive definition, recursively evaluate subexpressions and

Expression Tree Evaluation Check each case in the recursive definition, recursively evaluate subexpressions and apply appropriate operator (defun Eval. Expr (E) (cond ((is. Number E) (Val E)) ((is. Add E) (+ (Eval. Expr (Op 1 E)) (Eval. Expr (Op 2 E)))) ((is. Mult E) (* (Eval. Expr (Op 1 E)) (Eval. Expr (Op 2 E)))))) (check= (let ((E (Mult. Node (Num. Node 2) (Add. Node (Num. Node 3) (Num. Node 5))))) (Eval. Expr E)) 16)

Expression Trees with Variables What if we allow variables in expression trees? The value

Expression Trees with Variables What if we allow variables in expression trees? The value depends on the values of the variables Consider x * ( z + 5 ) When x = 2 & z = 5 the value is 20 When x = 0 & z =5 the value is 0 When x = 2 & z = -1 the value is 8 x … * + z 5

Environments Need to look up the values of all variables occurring in the expression

Environments Need to look up the values of all variables occurring in the expression Environment contains a list of bindings where a binding is a pair (name value) that binds a value to the name of the variable E. G. env = ((x 2) (z 5)) lookup returns the value associated with a given variable in an environment (lookup ‘x env) 2

Expression Tree Evaluation Modify Eval. Expr to include variables – need second argument containing

Expression Tree Evaluation Modify Eval. Expr to include variables – need second argument containing an environment and must handle variable case (defun Eval. Expr (E env) (cond ((is. Number E) (Val E)) ((is. Variable E) (lookup E env)) ((is. Add E) (+ (Eval. Expr (Op 1 E) env) (Eval. Expr (Op 2 E) env))) ((is. Mult E) (* (Eval. Expr (Op 1 E) env) (Eval. Expr (Op 2 E) env)))))

Binary Search Trees Binary Search Tree (BST) Binary Tree All elements in left(T) are

Binary Search Trees Binary Search Tree (BST) Binary Tree All elements in left(T) are < value(T) All elements in right(T) are value(T) Each subtree of a BST is a BST

Partially Ordered Trees Heap (binary) Complete binary tree So, height = Θ(lg n) Nodes

Partially Ordered Trees Heap (binary) Complete binary tree So, height = Θ(lg n) Nodes are assigned some measure, a priority No node has lower priority than its children

Inorder traversal Recursively visit nodes in T. left visit root Recursively visit nodes in

Inorder traversal Recursively visit nodes in T. left visit root Recursively visit nodes in T. right An in order traversal of a BST lists the elements in sorted order. Proof by induction.

Expression Trees Basic arithmetic expressions can be represented by a binary tree Internal nodes

Expression Trees Basic arithmetic expressions can be represented by a binary tree Internal nodes are operators Leaf nodes are operands Consider 2 * ( 3 + 5 ) : Note that parentheses don’t appear. Expression trees are not ambiguous, as infix expressions are (can be). * 2 + 3 5

Expression Tree – In-order Traversal An in-order traversal yields 2*3+5 We put parentheses around

Expression Tree – In-order Traversal An in-order traversal yields 2*3+5 We put parentheses around every operation to make this correct: (2 * ( 3 + 5 ) ) (not all are needed) * 2 + 3 5

Pre- and Post-Order Traversal Always go left-right Pre (me first): Visit node Traverse left

Pre- and Post-Order Traversal Always go left-right Pre (me first): Visit node Traverse left subtree Traverse right subtree Post (me last): Traverse left subtree Traverse right subtree Visit node

Expression Trees – Pre- and Post. Order Pre: * 2 + 3 5 Post:

Expression Trees – Pre- and Post. Order Pre: * 2 + 3 5 Post: 2 3 5 + * Note: Parentheses never needed * 2 + 3 5