tweaks
authorjim <jim@web>
Sat, 25 Apr 2015 02:28:28 +0000 (22:28 -0400)
committerLinux User <ikiwiki@localhost.members.linode.com>
Sat, 25 Apr 2015 02:28:28 +0000 (22:28 -0400)
topics/week12_list_and_tree_zippers.mdwn

index b9e030c..c59a87d 100644 (file)
@@ -36,7 +36,7 @@ Here's an idea. What if we had some way of representing a list as "broken" at a
 
        [10; 20; 30; 40; 50; 60; 70; 80; 90]
 
-we might imagine the list "broken" at position 3 like this (positions are numbered starting from 0):
+we might imagine the list "broken" at position 3 like this (we follow the dominant convention of counting list positions from the left starting at 0):
 
                    40;
                30;     50;
@@ -64,7 +64,7 @@ The kind of data structure we're looking for here is called a **list zipper**. T
                                    80;
                                        90]
 
-would be represented as `([30; 20; 10], [40; 50; 60; 70; 80; 90])`. To move forward in the base list, we pop the head element `40` off of the head element of the second list in the zipper, and push it onto the first list, getting `([40; 30; 20; 10], [50; 60; 70; 80; 90])`. To move backwards again, we pop off of the first list, and push it onto the second. To reconstruct the base list, we just "move backwards" until the first list is empty. (This is supposed to evoke the image of zipping up a zipper; hence the data structure's name.)
+would be represented as `([30; 20; 10], [40; 50; 60; 70; 80; 90])`. To move forward in the base list, we pop the head element `40` off of the head element of the second list in the zipper, and push it onto the first list, getting `([40; 30; 20; 10], [50; 60; 70; 80; 90])`. To move backwards again, we pop off of the first list, and push it onto the second. To reconstruct the base list, we just "moved backwards" until the first list is empty. (This is supposed to evoke the image of zipping up a zipper; hence the data structure's name.)
 
 Last time we gave the class, we had some discussion of what's the right way to apply the "zipper" metaphor. I suggest it's best to think of the tab of the zipper being here:
 
@@ -86,18 +86,18 @@ However you understand the "zipper" metaphor, this is a very handy data structur
 
     [10; 20; 30; *; 50; 60; 70; 80; 90], * filled by 40
 
-would represent a list zipper where the break is at position 3 (we follow the dominant convention of counting list positions from the left starting at 0), and the element occupying that position is `40`. For a list zipper, this might be implemented using the pairs-of-lists structure described above.
+would represent a list zipper where the break is at position 3, and the element occupying that position is `40`. For a list zipper, this could be implemented using the pairs-of-lists structure described above.
 
 Alternatively, we could present it in a form more like we used in the seminar for tree zippers:
 
-    in_focus = 40, context = ([30; 20; 10], [50; 60; 70; 80; 90])
+    in_focus = 40, context = (before = [30; 20; 10], after = [50; 60; 70; 80; 90])
 
 
 ##Tree Zippers##
 
 Now how could we translate a zipper-like structure over to trees? What we're aiming for is a way to keep track of where we are in a tree, in the same way that the "broken" lists let us keep track of where we are in the base list.
 
-It's important to set some ground rules for what will follow. If you don't understand these ground rules you will get confused. First off, for many uses of trees one wants some of the nodes or leaves in the tree to be *labeled* with additional information. It's important not to conflate the label with the node itself. Numerically one and the same piece of information---for example, the same `int`---could label two nodes of the tree without those nodes thereby being identical, as here:
+It's important to set some ground rules for what will follow. If you don't understand these ground rules you will get confused. First off, for many uses of trees one wants some of the nodes or leaves in the tree to be *labeled* with additional information. It's important not to conflate the label with the node itself. Numerically one and the same piece of information --- for example, the same `int` --- could label two nodes of the tree without those nodes thereby being identical, as here:
 
                root
                / \
@@ -117,7 +117,7 @@ The leftmost leaf and the rightmost leaf have the same label; but they are diffe
 
 Here I haven't drawn what the labels are. The leftmost leaf, the node tagged "3" in this diagram, doesn't have the label `3`. It has the label `10`, as we said before. I just haven't put that into the diagram. The node tagged "2" doesn't have the label `2`. It doesn't have any label. The tree in this example only has information labeling its leaves, not any of its inner nodes. The identity of its inner nodes is exhausted by their position in the tree.
 
-That is a second thing to note. In what follows, we'll only be working with *leaf-labeled* trees. In some uses of trees, one also wants labels on inner nodes. But we won't be discussing any such trees now. Our trees only have labels on their leaves. The diagrams below will tag all of the nodes, as in the second diagram above, and won't display what the leaves' labels are.
+That is a second thing to note. In what follows, we'll only be working with *leaf-labeled* trees. In some uses of trees, one also (or sometimes, only) wants labels on inner nodes. But we won't be discussing any such trees now. Our trees only have labels on their leaves. The diagrams below will tag all of the nodes, as in the second diagram above, and won't display what the leaves' labels are.
 
 Final introductory comment: in particular applications, you may only need to work with binary trees---trees where internal nodes always have exactly two subtrees. That is what we'll work with in the homework, for example. But to get the guiding idea of how tree zippers work, it's helpful first to think about trees that permit nodes to have many subtrees. So that's how we'll start.
 
@@ -161,7 +161,7 @@ And the parent of that context should intuitively be a context centered on `node
 
        Root
 
-Fully spelled out, then, our tree focused on `node 50` would look like this. (For brevity, I'll write `siblings = [foo | bar]` instead of `left_siblings = [foo]; right_siblings = [bar]`.)
+Fully spelled out, then, our tree focused on `node 50` would look like this:
 
     in_focus = subtree 50,
     context = (up = (up = Root,
@@ -195,7 +195,7 @@ How would we move upward in a tree? Well, to move up from the focused tree just
         /        |      \
        leaf 1  leaf 2  leaf 3
 
-Call the unfocused tree just specified `subtree 20'`. The result of moving upward from our previous focused tree, focused on `leaf 1`, would be a tree focused on the subtree just described, with the context being the outermost `up` element of the previous focused tree (what's written above as `(up = ..., siblings = [*; subtree 50; subtree 80])`. That is:
+Call the unfocused tree just specified `subtree 20'`. (It's the same as `subtree 20` was before. We just give it a different name because `subtree 20` wasn't a component we could extract from the previous zipper. We had to rebuild it from the information the previous zipper encoded.) The result of moving upward from our previous focused tree, focused on `leaf 1`, would be a tree focused on the subtree just described, with the context being the outermost `up` element of the previous focused tree (what's written above as `(up = ..., siblings = [*; subtree 50; subtree 80])`. That is:
 
     up = ...,
     siblings = [*; subtree 50; subtree 80],
@@ -214,12 +214,12 @@ Moving upwards yet again would get us:
     context = (up = Root,
                siblings = [*; subtree 920; subtree 950])
 
-where `subtree 500'` refers to a tree built from a root node whose children are given by the list `[*; subtree 50; subtree 80]`, with `subtree 20'` inserted into the `*` position. Moving upwards yet again would get us:
+where `subtree 500'` refers to a subtree built from a root node whose children are given by the list `[*; subtree 50; subtree 80]`, with `subtree 20'` inserted into the `*` position. Moving upwards yet again would get us:
 
     in_focus = subtree 9200',
     context = Root
 
-where the focused element is the root of our base tree. Like the "moving backward" operation for the list zipper, this "moving upward" operation is supposed to be reminiscent of closing a zipper, and that's why these data structures are called zippers.
+where the focused node is exactly the root of our complete tree. Like the "moving backward" operation for the list zipper, this "moving upward" operation is supposed to be reminiscent of closing a zipper, and that's why these data structures are called zippers.
 
 We haven't given you an executable implementation of the tree zipper, but only a suggestive notation. We have however told you enough that you should be able to implement it yourself. Or if you're lazy, you can read: