Editing Trees; implemented BTree-Delete.
This commit is contained in:
+552
-37
@@ -133,11 +133,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from notebook_preamble import J, V, define"
|
||||
"from notebook_preamble import D, J, V, define, DefinitionWrapper"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -906,7 +906,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 30,
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@@ -917,6 +917,22 @@
|
||||
"\n",
|
||||
"@FunctionWrapper\n",
|
||||
"def cmp_(stack, expression, dictionary):\n",
|
||||
" '''\n",
|
||||
" cmp takes two values and three quoted programs on the stack and runs\n",
|
||||
" one of the three depending on the results of comparing the two values:\n",
|
||||
"\n",
|
||||
" a b [G] [E] [L] cmp\n",
|
||||
" ------------------------- a > b\n",
|
||||
" G\n",
|
||||
"\n",
|
||||
" a b [G] [E] [L] cmp\n",
|
||||
" ------------------------- a = b\n",
|
||||
" E\n",
|
||||
"\n",
|
||||
" a b [G] [E] [L] cmp\n",
|
||||
" ------------------------- a < b\n",
|
||||
" L\n",
|
||||
" '''\n",
|
||||
" L, (E, (G, (b, (a, stack)))) = stack\n",
|
||||
" expression = pushback(G if a > b else L if a < b else E, expression)\n",
|
||||
" return stack, expression, dictionary\n",
|
||||
@@ -925,6 +941,55 @@
|
||||
"D['cmp'] = cmp_"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from joy.library import FunctionWrapper, S_ifte\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"@FunctionWrapper\n",
|
||||
"def cond(stack, expression, dictionary):\n",
|
||||
" '''\n",
|
||||
" like a case statement; works by rewriting into a chain of ifte.\n",
|
||||
"\n",
|
||||
" [..[[Bi] Ti]..[D]] -> ...\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" [[[B0] T0] [[B1] T1] [D]] cond\n",
|
||||
" -----------------------------------------\n",
|
||||
" [B0] [T0] [[B1] [T1] [D] ifte] ifte\n",
|
||||
"\n",
|
||||
" '''\n",
|
||||
" conditions, stack = stack\n",
|
||||
" if conditions:\n",
|
||||
" expression = _cond(conditions, expression)\n",
|
||||
" try:\n",
|
||||
" # Attempt to preload the args to first ifte.\n",
|
||||
" (P, (T, (E, expression))) = expression\n",
|
||||
" except ValueError:\n",
|
||||
" # If, for any reason, the argument to cond should happen to contain\n",
|
||||
" # only the default clause then this optimization will fail.\n",
|
||||
" pass\n",
|
||||
" else:\n",
|
||||
" stack = (E, (T, (P, stack)))\n",
|
||||
" return stack, expression, dictionary\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def _cond(conditions, expression):\n",
|
||||
" (clause, rest) = conditions\n",
|
||||
" if not rest: # clause is [D]\n",
|
||||
" return clause\n",
|
||||
" P, T = clause\n",
|
||||
" return (P, (T, (_cond(rest, ()), (S_ifte, expression))))\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"D['cond'] = cond"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 31,
|
||||
@@ -1415,17 +1480,16 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# TODO: BTree-delete\n",
|
||||
"# BTree-delete\n",
|
||||
"\n",
|
||||
"Then, once we have add, get, and delete we can see about abstracting them.\n",
|
||||
"\n",
|
||||
" tree key [E] BTree-delete\n",
|
||||
" ---------------------------- key in tree\n",
|
||||
" tree key [Er] BTree-delete\n",
|
||||
" -------------------------------- key in tree\n",
|
||||
" tree\n",
|
||||
"\n",
|
||||
" tree key [E] BTree-delete\n",
|
||||
" ---------------------------- key not in tree\n",
|
||||
" tree key E"
|
||||
" tree key [Er] BTree-delete\n",
|
||||
" ---------------------- ------ key not in tree\n",
|
||||
" tree key Er"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1434,26 +1498,16 @@
|
||||
"source": [
|
||||
"So:\n",
|
||||
"\n",
|
||||
" BTree-delete == [pop not] [] [R0] [R1] genrec\n",
|
||||
"\n",
|
||||
"And:\n",
|
||||
"\n",
|
||||
" [n_key n_value left right] key R0 [BTree-get] R1\n",
|
||||
" [n_key n_value left right] key [dup first] dip [BTree-get] R1\n",
|
||||
" [n_key n_value left right] n_key key [BTree-get] R1\n",
|
||||
" [n_key n_value left right] n_key key [BTree-get] roll> [T>] [E] [T<] cmp\n",
|
||||
" [n_key n_value left right] [BTree-get] n_key key [T>] [E] [T<] cmp\n",
|
||||
"\n",
|
||||
" BTree-delete == [pop not] swap [[dup first] dip] [roll> [T>] [E] [T<] cmp] genrec"
|
||||
" BTree-Delete == [pop not] swap [R0] [R1] genrec\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
" [n_key n_value left right] [BTree-get] T>\n",
|
||||
" [n_key n_value left right] [BTree-get] E\n",
|
||||
" [n_key n_value left right] [BTree-get] T<"
|
||||
" [Er] BTree-delete\n",
|
||||
" -------------------------------------\n",
|
||||
" [pop not] [Er] [R0] [R1] genrec"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1466,32 +1520,493 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
"source": [
|
||||
"Now we get to figure out the recursive case:\n",
|
||||
"\n",
|
||||
" w/ D == [pop not] [Er] [R0] [R1] genrec\n",
|
||||
"\n",
|
||||
" [node_key node_value left right] key R0 [D] R1\n",
|
||||
" [node_key node_value left right] key over first swap dup [D] R1\n",
|
||||
" [node_key node_value left right] node_key key key [D] R1\n",
|
||||
"\n",
|
||||
"And then:\n",
|
||||
"\n",
|
||||
" [node_key node_value left right] node_key key key [D] R1\n",
|
||||
" [node_key node_value left right] node_key key key [D] cons roll> [T>] [E] [T<] cmp\n",
|
||||
" [node_key node_value left right] node_key key [key D] roll> [T>] [E] [T<] cmp\n",
|
||||
" [node_key node_value left right] [key D] node_key key [T>] [E] [T<] cmp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Now this:;\n",
|
||||
"\n",
|
||||
" [node_key node_value left right] [key D] node_key key [T>] [E] [T<] cmp\n",
|
||||
"\n",
|
||||
"Becomes one of these three:;\n",
|
||||
"\n",
|
||||
" [node_key node_value left right] [key D] T>\n",
|
||||
" [node_key node_value left right] [key D] E\n",
|
||||
" [node_key node_value left right] [key D] T<"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Greater than case and less than case\n",
|
||||
"\n",
|
||||
" [node_key node_value left right] [key D] T>\n",
|
||||
" -------------------------------------------------\n",
|
||||
" [node_key node_value left key D right]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"First:\n",
|
||||
"\n",
|
||||
" right left node_value node_key [key D] dipd\n",
|
||||
" right left key D node_value node_key\n",
|
||||
" right left' node_value node_key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Ergo:\n",
|
||||
"\n",
|
||||
" [node_key node_value left right] [key D] [dipd] cons infra"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"So:\n",
|
||||
"\n",
|
||||
" T> == [dipd] cons infra\n",
|
||||
" T< == [dipdd] cons infra"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### The else case\n",
|
||||
"\n",
|
||||
" [node_key node_value left right] [key D] E\n",
|
||||
"\n",
|
||||
"We have to handle three cases, so let's use `cond`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The first two cases are symmetrical, if we only have one non-empty child node return it.\n",
|
||||
"\n",
|
||||
" E == [\n",
|
||||
" [[pop third not] pop fourth]\n",
|
||||
" [[pop fourth not] pop third]\n",
|
||||
" [default]\n",
|
||||
" ] cond"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"(If both child nodes are empty return an empty node.)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The initial structure of the default function:\n",
|
||||
"\n",
|
||||
" default == [E'] cons infra\n",
|
||||
"\n",
|
||||
" [node_key node_value left right] [key D] default\n",
|
||||
" [node_key node_value left right] [key D] [E'] cons infra\n",
|
||||
" [node_key node_value left right] [[key D] E'] infra\n",
|
||||
"\n",
|
||||
" right left node_value node_key [key D] E'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If both child nodes are non-empty, we find the highest node in our lower sub-tree, take its key and value to replace (delete) our own, then get rid of it by recursively calling delete() on our lower sub-node with our new key.\n",
|
||||
"\n",
|
||||
"(We could also find the lowest node in our higher sub-tree and take its key and value and delete it. I only implemented one of these two symmetrical options. Over a lot of deletions this might make the tree more unbalanced. Oh well.)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"First things first, we no longer need this node's key and value:\n",
|
||||
"\n",
|
||||
" right left node_value node_key [key D] roll> popop E''\n",
|
||||
" right left [key D] node_value node_key popop E''\n",
|
||||
" right left [key D] E''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Then we have to we find the highest (right-most) node in our lower (left) sub-tree:\n",
|
||||
"\n",
|
||||
" right left [key D] E''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Ditch the key:\n",
|
||||
"\n",
|
||||
" right left [key D] rest E'''\n",
|
||||
" right left [D] E'''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Find the right-most node:\n",
|
||||
"\n",
|
||||
" right left [D] [dup W] dip E''''\n",
|
||||
" right left dup W [D] E''''\n",
|
||||
" right left left W [D] E''''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Consider:\n",
|
||||
"\n",
|
||||
" left W"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We know left is not empty:\n",
|
||||
"\n",
|
||||
" [L_key L_value L_left L_right] W"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We want to keep extracting the right node as long as it is not empty:\n",
|
||||
"\n",
|
||||
" left [P] [B] while W'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The predicate:\n",
|
||||
"\n",
|
||||
" [L_key L_value L_left L_right] P\n",
|
||||
" [L_key L_value L_left L_right] fourth\n",
|
||||
" L_right\n",
|
||||
" \n",
|
||||
"(This has a bug, can run on `[]` so must be guarded:\n",
|
||||
"\n",
|
||||
" if_not_empty == [] swap [] ifte\n",
|
||||
" ?fourth == [fourth] if_not_empty\n",
|
||||
" W.rightmost == [?fourth] [fourth] while"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"The body is also `fourth`:\n",
|
||||
"\n",
|
||||
" left [fourth] [fourth] while W'\n",
|
||||
" rightest W'"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We know rightest is not empty:\n",
|
||||
"\n",
|
||||
" [R_key R_value R_left R_right] W'\n",
|
||||
" [R_key R_value R_left R_right] uncons uncons pop\n",
|
||||
" R_key [R_value R_left R_right] uncons pop\n",
|
||||
" R_key R_value [R_left R_right] pop\n",
|
||||
" R_key R_value"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"So:\n",
|
||||
"\n",
|
||||
" W == [fourth] [fourth] while uncons uncons pop"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"And:\n",
|
||||
"\n",
|
||||
" right left left W [D] E''''\n",
|
||||
" right left R_key R_value [D] E''''"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Final stretch. We want to end up with something like:\n",
|
||||
"\n",
|
||||
" right left [R_key D] i R_value R_key\n",
|
||||
" right left R_key D R_value R_key\n",
|
||||
" right left' R_value R_key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"If we adjust our definition of `W` to include `over` at the end:\n",
|
||||
"\n",
|
||||
" W == [fourth] [fourth] while uncons uncons pop over"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"That will give us:\n",
|
||||
"\n",
|
||||
" right left R_key R_value R_key [D] E''''\n",
|
||||
"\n",
|
||||
" right left R_key R_value R_key [D] cons dipdd E'''''\n",
|
||||
" right left R_key R_value [R_key D] dipdd E'''''\n",
|
||||
" right left R_key D R_key R_value E'''''\n",
|
||||
" right left' R_key R_value E'''''\n",
|
||||
" right left' R_key R_value swap\n",
|
||||
" right left' R_value R_key"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"So:\n",
|
||||
"\n",
|
||||
" E' == roll> popop E''\n",
|
||||
"\n",
|
||||
" E'' == rest E'''\n",
|
||||
"\n",
|
||||
" E''' == [dup W] dip E''''\n",
|
||||
"\n",
|
||||
" E'''' == cons dipdd swap"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Substituting:\n",
|
||||
"\n",
|
||||
" W == [fourth] [fourth] while uncons uncons pop over\n",
|
||||
" E' == roll> popop rest [dup W] dip cons dipdd swap\n",
|
||||
" E == [\n",
|
||||
" [[pop third not] pop fourth]\n",
|
||||
" [[pop fourth not] pop third]\n",
|
||||
" [[E'] cons infra]\n",
|
||||
" ] cond"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Minor rearrangement:\n",
|
||||
"\n",
|
||||
" W == dup [fourth] [fourth] while uncons uncons pop over\n",
|
||||
" E' == roll> popop rest [W] dip cons dipdd swap\n",
|
||||
" E == [\n",
|
||||
" [[pop third not] pop fourth]\n",
|
||||
" [[pop fourth not] pop third]\n",
|
||||
" [[E'] cons infra]\n",
|
||||
" ] cond"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Refactoring\n",
|
||||
"\n",
|
||||
" W.rightmost == [fourth] [fourth] while\n",
|
||||
" W.unpack == uncons uncons pop\n",
|
||||
" E.clear_stuff == roll> popop rest\n",
|
||||
" E.delete == cons dipdd\n",
|
||||
" W == dup W.rightmost W.unpack over\n",
|
||||
" E.0 == E.clear_stuff [W] dip E.delete swap\n",
|
||||
" E == [\n",
|
||||
" [[pop third not] pop fourth]\n",
|
||||
" [[pop fourth not] pop third]\n",
|
||||
" [[E.0] cons infra]\n",
|
||||
" ] cond\n",
|
||||
" T> == [dipd] cons infra\n",
|
||||
" T< == [dipdd] cons infra\n",
|
||||
" R0 == over first swap dup\n",
|
||||
" R1 == cons roll> [T>] [E] [T<] cmp\n",
|
||||
" BTree-Delete == [pop not] swap [R0] [R1] genrec\n",
|
||||
"\n",
|
||||
"By the standards of the code I've written so far, this is a *huge* Joy program."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 20,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
"source": [
|
||||
"DefinitionWrapper.add_definitions('''\n",
|
||||
"first_two == uncons uncons pop\n",
|
||||
"fourth == rest rest rest first\n",
|
||||
"?fourth == [] [fourth] [] ifte\n",
|
||||
"W.rightmost == [?fourth] [fourth] while\n",
|
||||
"E.clear_stuff == roll> popop rest\n",
|
||||
"E.delete == cons dipdd\n",
|
||||
"W == dup W.rightmost first_two over\n",
|
||||
"E.0 == E.clear_stuff [W] dip E.delete swap\n",
|
||||
"E == [[[pop third not] pop fourth] [[pop fourth not] pop third] [[E.0] cons infra]] cond\n",
|
||||
"T> == [dipd] cons infra\n",
|
||||
"T< == [dipdd] cons infra\n",
|
||||
"R0 == over first swap dup\n",
|
||||
"R1 == cons roll> [T>] [E] [T<] cmp\n",
|
||||
"BTree-Delete == [pop not] swap [R0] [R1] genrec''', D)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 23,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"['a' 23 [] ['b' 88 [] []]]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"J(\"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'c' ['Er'] BTree-Delete \")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 24,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"['a' 23 [] ['c' 44 [] []]]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"J(\"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'b' ['Er'] BTree-Delete \")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"['b' 88 [] ['c' 44 [] []]]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"J(\"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'a' ['Er'] BTree-Delete \")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 26,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"['a' 23 [] ['b' 88 [] ['c' 44 [] 'Er' 'der' []]]]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"J(\"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'der' ['Er'] BTree-Delete \")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 30,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"J(\"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'der' [pop] BTree-Delete \")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"One bug, I forgot to put `not` in the first two clauses of the `cond`.\n",
|
||||
"\n",
|
||||
"The behavior of the `[Er]` function should maybe be different: either just silently fail, or maybe implement some sort of function that can grab the pending expression up to a sentinel value or something, allowing for a kind of \"except\"-ish control-flow?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Then, once we have add, get, and delete we can see about abstracting them.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
@@ -2161,7 +2676,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython2",
|
||||
"version": "2.7.13"
|
||||
"version": "2.7.12"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
Reference in New Issue
Block a user