Minor docs edits.
This commit is contained in:
parent
37c34fc54f
commit
22f7c6da00
|
|
@ -11775,7 +11775,7 @@ div#notebook {
|
||||||
</div>
|
</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="text_cell_render border-box-sizing rendered_html">
|
<div class="text_cell_render border-box-sizing rendered_html">
|
||||||
<h1 id="Treating-Trees-I">Treating Trees I<a class="anchor-link" href="#Treating-Trees-I">¶</a></h1><p>Although any expression in Joy can be considered to describe a <a href="https://en.wikipedia.org/wiki/Tree_structure">tree</a> with the quotes as compound nodes and the non-quote values as leaf nodes, in this page I want to talk about <a href="https://en.wikipedia.org/wiki/Binary_search_tree">ordered binary trees</a> and how to make and use them.</p>
|
<h1 id="Treating-Trees-I:-Ordered-Binary-Trees">Treating Trees I: Ordered Binary Trees<a class="anchor-link" href="#Treating-Trees-I:-Ordered-Binary-Trees">¶</a></h1><p>Although any expression in Joy can be considered to describe a <a href="https://en.wikipedia.org/wiki/Tree_structure">tree</a> with the quotes as compound nodes and the non-quote values as leaf nodes, in this page I want to talk about <a href="https://en.wikipedia.org/wiki/Binary_search_tree">ordered binary trees</a> and how to make and use them.</p>
|
||||||
<p>The basic structure, in a <a href="https://en.wikipedia.org/wiki/Algebraic_data_type">crude type notation</a>, is:</p>
|
<p>The basic structure, in a <a href="https://en.wikipedia.org/wiki/Algebraic_data_type">crude type notation</a>, is:</p>
|
||||||
|
|
||||||
<pre><code>Tree :: [] | [key value Tree Tree]
|
<pre><code>Tree :: [] | [key value Tree Tree]
|
||||||
|
|
@ -11886,6 +11886,24 @@ key [value [] []] cons
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="output_wrapper">
|
||||||
|
<div class="output">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="output_area">
|
||||||
|
|
||||||
|
<div class="prompt"></div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="output_subarea output_stream output_stdout output_text">
|
||||||
|
<pre>['k' 'v' [] []]
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -12498,7 +12516,7 @@ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec</code></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="text_cell_render border-box-sizing rendered_html">
|
<div class="text_cell_render border-box-sizing rendered_html">
|
||||||
<h2 id="Interlude:-cmp-combinator">Interlude: <code>cmp</code> combinator<a class="anchor-link" href="#Interlude:-cmp-combinator">¶</a></h2><p>Instead of mucking about with nested <code>ifte</code> combinators let's just go whole hog and define <code>cmp</code> which takes two values and three quoted programs on the stack and runs one of the three depending on the results of comparing the two values:</p>
|
<h2 id="Interlude:-cmp-combinator">Interlude: <code>cmp</code> combinator<a class="anchor-link" href="#Interlude:-cmp-combinator">¶</a></h2><p>Instead of mucking about with nested <code>ifte</code> combinators let's use <code>cmp</code> which takes two values and three quoted programs on the stack and runs one of the three depending on the results of comparing the two values:</p>
|
||||||
|
|
||||||
<pre><code> a b [G] [E] [L] cmp
|
<pre><code> a b [G] [E] [L] cmp
|
||||||
------------------------- a > b
|
------------------------- a > b
|
||||||
|
|
@ -12518,47 +12536,6 @@ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec</code></pre>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [20]:</div>
|
<div class="prompt input_prompt">In [20]:</div>
|
||||||
<div class="inner_cell">
|
|
||||||
<div class="input_area">
|
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">joy.library</span> <span class="kn">import</span> <span class="n">FunctionWrapper</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">joy.utils.stack</span> <span class="kn">import</span> <span class="n">pushback</span>
|
|
||||||
<span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span>
|
|
||||||
|
|
||||||
|
|
||||||
<span class="nd">@FunctionWrapper</span>
|
|
||||||
<span class="k">def</span> <span class="nf">cmp_</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
|
|
||||||
<span class="sd">'''</span>
|
|
||||||
<span class="sd"> cmp takes two values and three quoted programs on the stack and runs</span>
|
|
||||||
<span class="sd"> one of the three depending on the results of comparing the two values:</span>
|
|
||||||
|
|
||||||
<span class="sd"> a b [G] [E] [L] cmp</span>
|
|
||||||
<span class="sd"> ------------------------- a > b</span>
|
|
||||||
<span class="sd"> G</span>
|
|
||||||
|
|
||||||
<span class="sd"> a b [G] [E] [L] cmp</span>
|
|
||||||
<span class="sd"> ------------------------- a = b</span>
|
|
||||||
<span class="sd"> E</span>
|
|
||||||
|
|
||||||
<span class="sd"> a b [G] [E] [L] cmp</span>
|
|
||||||
<span class="sd"> ------------------------- a < b</span>
|
|
||||||
<span class="sd"> L</span>
|
|
||||||
<span class="sd"> '''</span>
|
|
||||||
<span class="n">L</span><span class="p">,</span> <span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="p">(</span><span class="n">G</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
|
|
||||||
<span class="n">expression</span> <span class="o">=</span> <span class="n">pushback</span><span class="p">(</span><span class="n">G</span> <span class="k">if</span> <span class="n">a</span> <span class="o">></span> <span class="n">b</span> <span class="k">else</span> <span class="n">L</span> <span class="k">if</span> <span class="n">a</span> <span class="o"><</span> <span class="n">b</span> <span class="k">else</span> <span class="n">E</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span>
|
|
||||||
<span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span>
|
|
||||||
|
|
||||||
|
|
||||||
<span class="n">D</span><span class="p">[</span><span class="s1">'cmp'</span><span class="p">]</span> <span class="o">=</span> <span class="n">cmp_</span>
|
|
||||||
</pre></div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
|
||||||
<div class="input">
|
|
||||||
<div class="prompt input_prompt">In [21]:</div>
|
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 0 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 0 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
|
||||||
|
|
@ -12589,7 +12566,7 @@ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec</code></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [22]:</div>
|
<div class="prompt input_prompt">In [21]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
|
||||||
|
|
@ -12620,7 +12597,7 @@ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec</code></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [23]:</div>
|
<div class="prompt input_prompt">In [22]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"0 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"0 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
|
||||||
|
|
@ -12706,7 +12683,7 @@ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec</code></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [24]:</div>
|
<div class="prompt input_prompt">In [23]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == over [popop popop first] nullary'</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == over [popop popop first] nullary'</span><span class="p">)</span>
|
||||||
|
|
@ -12755,7 +12732,7 @@ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec</code></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [25]:</div>
|
<div class="prompt input_prompt">In [24]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec'</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec'</span><span class="p">)</span>
|
||||||
|
|
@ -12768,7 +12745,7 @@ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec</code></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [26]:</div>
|
<div class="prompt input_prompt">In [25]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Still works.</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Still works.</span>
|
||||||
|
|
@ -12938,7 +12915,7 @@ key left-keys right-keys
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [27]:</div>
|
<div class="prompt input_prompt">In [26]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec'</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec'</span><span class="p">)</span>
|
||||||
|
|
@ -12959,7 +12936,7 @@ key left-keys right-keys
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [28]:</div>
|
<div class="prompt input_prompt">In [27]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [foo] Tree-iter'</span><span class="p">)</span> <span class="c1"># It doesn't matter what F is as it won't be used.</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [foo] Tree-iter'</span><span class="p">)</span> <span class="c1"># It doesn't matter what F is as it won't be used.</span>
|
||||||
|
|
@ -12990,7 +12967,7 @@ key left-keys right-keys
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [29]:</div>
|
<div class="prompt input_prompt">In [28]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [first] Tree-iter"</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [first] Tree-iter"</span><span class="p">)</span>
|
||||||
|
|
@ -13021,7 +12998,7 @@ key left-keys right-keys
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [30]:</div>
|
<div class="prompt input_prompt">In [29]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [second] Tree-iter"</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [second] Tree-iter"</span><span class="p">)</span>
|
||||||
|
|
@ -13061,7 +13038,7 @@ key left-keys right-keys
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [31]:</div>
|
<div class="prompt input_prompt">In [30]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [3 9 5 2 8 6 7 8 4] [0 swap Tree-add] step'</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [3 9 5 2 8 6 7 8 4] [0 swap Tree-add] step'</span><span class="p">)</span>
|
||||||
|
|
@ -13092,7 +13069,7 @@ key left-keys right-keys
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [32]:</div>
|
<div class="prompt input_prompt">In [31]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'to_set == [] swap [0 swap Tree-add] step'</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'to_set == [] swap [0 swap Tree-add] step'</span><span class="p">)</span>
|
||||||
|
|
@ -13105,7 +13082,7 @@ key left-keys right-keys
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [33]:</div>
|
<div class="prompt input_prompt">In [32]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set'</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set'</span><span class="p">)</span>
|
||||||
|
|
@ -13145,7 +13122,7 @@ key left-keys right-keys
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [34]:</div>
|
<div class="prompt input_prompt">In [33]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'unique == [to_set [first] Tree-iter] cons run'</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'unique == [to_set [first] Tree-iter] cons run'</span><span class="p">)</span>
|
||||||
|
|
@ -13158,7 +13135,7 @@ key left-keys right-keys
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [35]:</div>
|
<div class="prompt input_prompt">In [34]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique'</span><span class="p">)</span> <span class="c1"># Filter duplicate items.</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique'</span><span class="p">)</span> <span class="c1"># Filter duplicate items.</span>
|
||||||
|
|
@ -13302,7 +13279,7 @@ Tree-iter-order == [not] [pop] [dup third] [proc_left proc_current proc_right] g
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [36]:</div>
|
<div class="prompt input_prompt">In [35]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1">#define('Tree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec')</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1">#define('Tree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec')</span>
|
||||||
|
|
@ -13328,7 +13305,7 @@ Tree-iter-order == [not] [pop] [dup third] [proc_left proc_current proc_right] g
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [37]:</div>
|
<div class="prompt input_prompt">In [36]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order'</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order'</span><span class="p">)</span>
|
||||||
|
|
@ -13361,7 +13338,7 @@ Tree-iter-order == [not] [pop] [dup third] [proc_left proc_current proc_right] g
|
||||||
</div>
|
</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="text_cell_render border-box-sizing rendered_html">
|
<div class="text_cell_render border-box-sizing rendered_html">
|
||||||
<p>Parameterizing the <code>[F]</code> function is left as an exercise for the reader (for now.)</p>
|
<p>Parameterizing the <code>[F]</code> function is left as an exercise for the reader.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -13528,7 +13505,7 @@ Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec</code></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [38]:</div>
|
<div class="prompt input_prompt">In [37]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># I don't want to deal with name conflicts with the above so I'm inlining everything here.</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># I don't want to deal with name conflicts with the above so I'm inlining everything here.</span>
|
||||||
|
|
@ -13555,7 +13532,7 @@ Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec</code></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [39]:</div>
|
<div class="prompt input_prompt">In [38]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "mike" [popd " not in tree" +] Tree-get'</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "mike" [popd " not in tree" +] Tree-get'</span><span class="p">)</span>
|
||||||
|
|
@ -13586,7 +13563,7 @@ Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec</code></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [40]:</div>
|
<div class="prompt input_prompt">In [39]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "gary" [popop "err"] Tree-get'</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "gary" [popop "err"] Tree-get'</span><span class="p">)</span>
|
||||||
|
|
@ -13617,7 +13594,7 @@ Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec</code></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [41]:</div>
|
<div class="prompt input_prompt">In [40]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
|
||||||
|
|
@ -13654,7 +13631,7 @@ Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec</code></pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [52]:</div>
|
<div class="prompt input_prompt">In [41]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
|
||||||
|
|
@ -13847,59 +13824,6 @@ T< == [dipdd] cons infra</code></pre>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
|
||||||
<div class="input">
|
|
||||||
<div class="prompt input_prompt">In [42]:</div>
|
|
||||||
<div class="inner_cell">
|
|
||||||
<div class="input_area">
|
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">joy.library</span> <span class="kn">import</span> <span class="n">FunctionWrapper</span><span class="p">,</span> <span class="n">S_ifte</span>
|
|
||||||
|
|
||||||
|
|
||||||
<span class="nd">@FunctionWrapper</span>
|
|
||||||
<span class="k">def</span> <span class="nf">cond</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
|
|
||||||
<span class="sd">'''</span>
|
|
||||||
<span class="sd"> like a case statement; works by rewriting into a chain of ifte.</span>
|
|
||||||
|
|
||||||
<span class="sd"> [..[[Bi] Ti]..[D]] -> ...</span>
|
|
||||||
|
|
||||||
|
|
||||||
<span class="sd"> [[[B0] T0] [[B1] T1] [D]] cond</span>
|
|
||||||
<span class="sd"> -----------------------------------------</span>
|
|
||||||
<span class="sd"> [B0] [T0] [[B1] [T1] [D] ifte] ifte</span>
|
|
||||||
|
|
||||||
<span class="sd"> '''</span>
|
|
||||||
<span class="n">conditions</span><span class="p">,</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
|
|
||||||
<span class="k">if</span> <span class="n">conditions</span><span class="p">:</span>
|
|
||||||
<span class="n">expression</span> <span class="o">=</span> <span class="n">_cond</span><span class="p">(</span><span class="n">conditions</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span>
|
|
||||||
<span class="k">try</span><span class="p">:</span>
|
|
||||||
<span class="c1"># Attempt to preload the args to first ifte.</span>
|
|
||||||
<span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="p">(</span><span class="n">T</span><span class="p">,</span> <span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">expression</span><span class="p">)))</span> <span class="o">=</span> <span class="n">expression</span>
|
|
||||||
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
|
||||||
<span class="c1"># If, for any reason, the argument to cond should happen to contain</span>
|
|
||||||
<span class="c1"># only the default clause then this optimization will fail.</span>
|
|
||||||
<span class="k">pass</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="n">stack</span> <span class="o">=</span> <span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="p">(</span><span class="n">T</span><span class="p">,</span> <span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span>
|
|
||||||
<span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span>
|
|
||||||
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="nf">_cond</span><span class="p">(</span><span class="n">conditions</span><span class="p">,</span> <span class="n">expression</span><span class="p">):</span>
|
|
||||||
<span class="p">(</span><span class="n">clause</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span> <span class="o">=</span> <span class="n">conditions</span>
|
|
||||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">rest</span><span class="p">:</span> <span class="c1"># clause is [D]</span>
|
|
||||||
<span class="k">return</span> <span class="n">clause</span>
|
|
||||||
<span class="n">P</span><span class="p">,</span> <span class="n">T</span> <span class="o">=</span> <span class="n">clause</span>
|
|
||||||
<span class="k">return</span> <span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="p">(</span><span class="n">T</span><span class="p">,</span> <span class="p">(</span><span class="n">_cond</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="p">()),</span> <span class="p">(</span><span class="n">S_ifte</span><span class="p">,</span> <span class="n">expression</span><span class="p">))))</span>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<span class="n">D</span><span class="p">[</span><span class="s1">'cond'</span><span class="p">]</span> <span class="o">=</span> <span class="n">cond</span>
|
|
||||||
</pre></div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -14198,7 +14122,7 @@ E == [
|
||||||
</div>
|
</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="text_cell_render border-box-sizing rendered_html">
|
<div class="text_cell_render border-box-sizing rendered_html">
|
||||||
<p>Minor rearrangement:</p>
|
<p>Minor rearrangement, move <code>dup</code> into <code>W</code>:</p>
|
||||||
|
|
||||||
<pre><code>W == dup [fourth] [fourth] while uncons uncons pop over
|
<pre><code>W == dup [fourth] [fourth] while uncons uncons pop over
|
||||||
E′ == roll> popop rest [W] dip cons dipd swap
|
E′ == roll> popop rest [W] dip cons dipd swap
|
||||||
|
|
@ -14218,9 +14142,9 @@ E == [
|
||||||
<h3 id="Refactoring">Refactoring<a class="anchor-link" href="#Refactoring">¶</a></h3>
|
<h3 id="Refactoring">Refactoring<a class="anchor-link" href="#Refactoring">¶</a></h3>
|
||||||
<pre><code>W.rightmost == [fourth] [fourth] while
|
<pre><code>W.rightmost == [fourth] [fourth] while
|
||||||
W.unpack == uncons uncons pop
|
W.unpack == uncons uncons pop
|
||||||
|
W == dup W.rightmost W.unpack over
|
||||||
E.clear_stuff == roll> popop rest
|
E.clear_stuff == roll> popop rest
|
||||||
E.delete == cons dipd
|
E.delete == cons dipd
|
||||||
W == dup W.rightmost W.unpack over
|
|
||||||
E.0 == E.clear_stuff [W] dip E.delete swap
|
E.0 == E.clear_stuff [W] dip E.delete swap
|
||||||
E == [
|
E == [
|
||||||
[[pop third not] pop fourth]
|
[[pop third not] pop fourth]
|
||||||
|
|
@ -14241,7 +14165,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [43]:</div>
|
<div class="prompt input_prompt">In [42]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
|
||||||
|
|
@ -14258,7 +14182,8 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
|
||||||
<span class="s1">T< == [dipdd] cons infra</span>
|
<span class="s1">T< == [dipdd] cons infra</span>
|
||||||
<span class="s1">R0 == over first swap dup</span>
|
<span class="s1">R0 == over first swap dup</span>
|
||||||
<span class="s1">R1 == cons roll> [T>] [E] [T<] cmp</span>
|
<span class="s1">R1 == cons roll> [T>] [E] [T<] cmp</span>
|
||||||
<span class="s1">Tree-Delete == [pop not] [pop] [R0] [R1] genrec'''</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
|
<span class="s1">Tree-Delete == [pop not] [pop] [R0] [R1] genrec</span>
|
||||||
|
<span class="s1">'''</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -14268,7 +14193,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [44]:</div>
|
<div class="prompt input_prompt">In [43]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'c' Tree-Delete "</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'c' Tree-Delete "</span><span class="p">)</span>
|
||||||
|
|
@ -14299,7 +14224,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [45]:</div>
|
<div class="prompt input_prompt">In [44]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'b' Tree-Delete "</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'b' Tree-Delete "</span><span class="p">)</span>
|
||||||
|
|
@ -14330,7 +14255,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [46]:</div>
|
<div class="prompt input_prompt">In [45]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'a' Tree-Delete "</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'a' Tree-Delete "</span><span class="p">)</span>
|
||||||
|
|
@ -14361,7 +14286,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [47]:</div>
|
<div class="prompt input_prompt">In [46]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'der' Tree-Delete "</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'der' Tree-Delete "</span><span class="p">)</span>
|
||||||
|
|
@ -14392,7 +14317,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [48]:</div>
|
<div class="prompt input_prompt">In [47]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [4 2 3 1 6 7 5 ] [0 swap Tree-add] step'</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [4 2 3 1 6 7 5 ] [0 swap Tree-add] step'</span><span class="p">)</span>
|
||||||
|
|
@ -14423,7 +14348,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [49]:</div>
|
<div class="prompt input_prompt">In [48]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 3 Tree-Delete "</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 3 Tree-Delete "</span><span class="p">)</span>
|
||||||
|
|
@ -14454,7 +14379,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
|
||||||
</div>
|
</div>
|
||||||
<div class="cell border-box-sizing code_cell rendered">
|
<div class="cell border-box-sizing code_cell rendered">
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<div class="prompt input_prompt">In [50]:</div>
|
<div class="prompt input_prompt">In [49]:</div>
|
||||||
<div class="inner_cell">
|
<div class="inner_cell">
|
||||||
<div class="input_area">
|
<div class="input_area">
|
||||||
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 4 Tree-Delete "</span><span class="p">)</span>
|
<div class=" highlight hl-ipython2"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 4 Tree-Delete "</span><span class="p">)</span>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# Treating Trees I\n",
|
"# Treating Trees I: Ordered Binary Trees\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Although any expression in Joy can be considered to describe a [tree](https://en.wikipedia.org/wiki/Tree_structure) with the quotes as compound nodes and the non-quote values as leaf nodes, in this page I want to talk about [ordered binary trees](https://en.wikipedia.org/wiki/Binary_search_tree) and how to make and use them.\n",
|
"Although any expression in Joy can be considered to describe a [tree](https://en.wikipedia.org/wiki/Tree_structure) with the quotes as compound nodes and the non-quote values as leaf nodes, in this page I want to talk about [ordered binary trees](https://en.wikipedia.org/wiki/Binary_search_tree) and how to make and use them.\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
|
@ -92,7 +92,15 @@
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 3,
|
"execution_count": 3,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"['k' 'v' [] []]\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"J('\"v\" \"k\" Tree-new')"
|
"J('\"v\" \"k\" Tree-new')"
|
||||||
]
|
]
|
||||||
|
|
@ -521,7 +529,7 @@
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Interlude: `cmp` combinator\n",
|
"## Interlude: `cmp` combinator\n",
|
||||||
"Instead of mucking about with nested `ifte` combinators let's just go whole hog and define `cmp` which takes two values and three quoted programs on the stack and runs one of the three depending on the results of comparing the two values:\n",
|
"Instead of mucking about with nested `ifte` combinators let's use `cmp` which takes two values and three quoted programs on the stack and runs one of the three depending on the results of comparing the two values:\n",
|
||||||
"\n",
|
"\n",
|
||||||
" a b [G] [E] [L] cmp\n",
|
" a b [G] [E] [L] cmp\n",
|
||||||
" ------------------------- a > b\n",
|
" ------------------------- a > b\n",
|
||||||
|
|
@ -540,43 +548,6 @@
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 20,
|
"execution_count": 20,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"from joy.library import FunctionWrapper\n",
|
|
||||||
"from joy.utils.stack import pushback\n",
|
|
||||||
"from notebook_preamble import D\n",
|
|
||||||
"\n",
|
|
||||||
"\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",
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"D['cmp'] = cmp_"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 21,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
|
|
@ -592,7 +563,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 22,
|
"execution_count": 21,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -609,7 +580,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 23,
|
"execution_count": 22,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -674,7 +645,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 24,
|
"execution_count": 23,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|
@ -713,7 +684,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 25,
|
"execution_count": 24,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|
@ -722,7 +693,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 26,
|
"execution_count": 25,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"scrolled": false
|
"scrolled": false
|
||||||
},
|
},
|
||||||
|
|
@ -865,7 +836,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 27,
|
"execution_count": 26,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|
@ -881,7 +852,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 28,
|
"execution_count": 27,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -898,7 +869,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 29,
|
"execution_count": 28,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -915,7 +886,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 30,
|
"execution_count": 29,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -940,7 +911,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 31,
|
"execution_count": 30,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -957,7 +928,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 32,
|
"execution_count": 31,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|
@ -966,7 +937,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 33,
|
"execution_count": 32,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -990,7 +961,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 34,
|
"execution_count": 33,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|
@ -999,7 +970,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 35,
|
"execution_count": 34,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"scrolled": true
|
"scrolled": true
|
||||||
},
|
},
|
||||||
|
|
@ -1117,7 +1088,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 36,
|
"execution_count": 35,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|
@ -1141,7 +1112,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 37,
|
"execution_count": 36,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -1160,7 +1131,7 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Parameterizing the `[F]` function is left as an exercise for the reader (for now.)"
|
"Parameterizing the `[F]` function is left as an exercise for the reader."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -1310,7 +1281,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 38,
|
"execution_count": 37,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|
@ -1333,7 +1304,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 39,
|
"execution_count": 38,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -1350,7 +1321,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 40,
|
"execution_count": 39,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -1367,7 +1338,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 41,
|
"execution_count": 40,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -1390,7 +1361,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 52,
|
"execution_count": 41,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -1552,55 +1523,6 @@
|
||||||
"We have to handle three cases, so let's use `cond`."
|
"We have to handle three cases, so let's use `cond`."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 42,
|
|
||||||
"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": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
|
|
@ -1860,7 +1782,7 @@
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Minor rearrangement:\n",
|
"Minor rearrangement, move `dup` into `W`:\n",
|
||||||
"\n",
|
"\n",
|
||||||
" W == dup [fourth] [fourth] while uncons uncons pop over\n",
|
" W == dup [fourth] [fourth] while uncons uncons pop over\n",
|
||||||
" E′ == roll> popop rest [W] dip cons dipd swap\n",
|
" E′ == roll> popop rest [W] dip cons dipd swap\n",
|
||||||
|
|
@ -1879,9 +1801,9 @@
|
||||||
"\n",
|
"\n",
|
||||||
" W.rightmost == [fourth] [fourth] while\n",
|
" W.rightmost == [fourth] [fourth] while\n",
|
||||||
" W.unpack == uncons uncons pop\n",
|
" W.unpack == uncons uncons pop\n",
|
||||||
|
" W == dup W.rightmost W.unpack over\n",
|
||||||
" E.clear_stuff == roll> popop rest\n",
|
" E.clear_stuff == roll> popop rest\n",
|
||||||
" E.delete == cons dipd\n",
|
" E.delete == cons dipd\n",
|
||||||
" W == dup W.rightmost W.unpack over\n",
|
|
||||||
" E.0 == E.clear_stuff [W] dip E.delete swap\n",
|
" E.0 == E.clear_stuff [W] dip E.delete swap\n",
|
||||||
" E == [\n",
|
" E == [\n",
|
||||||
" [[pop third not] pop fourth]\n",
|
" [[pop third not] pop fourth]\n",
|
||||||
|
|
@ -1899,7 +1821,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 43,
|
"execution_count": 42,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
|
@ -1917,12 +1839,13 @@
|
||||||
"T< == [dipdd] cons infra\n",
|
"T< == [dipdd] cons infra\n",
|
||||||
"R0 == over first swap dup\n",
|
"R0 == over first swap dup\n",
|
||||||
"R1 == cons roll> [T>] [E] [T<] cmp\n",
|
"R1 == cons roll> [T>] [E] [T<] cmp\n",
|
||||||
"Tree-Delete == [pop not] [pop] [R0] [R1] genrec''', D)"
|
"Tree-Delete == [pop not] [pop] [R0] [R1] genrec\n",
|
||||||
|
"''', D)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 44,
|
"execution_count": 43,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -1939,7 +1862,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 45,
|
"execution_count": 44,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -1956,7 +1879,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 46,
|
"execution_count": 45,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -1973,7 +1896,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 47,
|
"execution_count": 46,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -1990,7 +1913,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 48,
|
"execution_count": 47,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -2007,7 +1930,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 49,
|
"execution_count": 48,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
|
|
@ -2024,7 +1947,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 50,
|
"execution_count": 49,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"scrolled": true
|
"scrolled": true
|
||||||
},
|
},
|
||||||
|
|
@ -2099,11 +2022,6 @@
|
||||||
" Tree-delete == [pop not] [pop] [_Tree_delete_R0] [_Tree_delete_R1] genrec\n",
|
" Tree-delete == [pop not] [pop] [_Tree_delete_R0] [_Tree_delete_R1] genrec\n",
|
||||||
"\n"
|
"\n"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": []
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
# Treating Trees I
|
# Treating Trees I: Ordered Binary Trees
|
||||||
|
|
||||||
Although any expression in Joy can be considered to describe a [tree](https://en.wikipedia.org/wiki/Tree_structure) with the quotes as compound nodes and the non-quote values as leaf nodes, in this page I want to talk about [ordered binary trees](https://en.wikipedia.org/wiki/Binary_search_tree) and how to make and use them.
|
Although any expression in Joy can be considered to describe a [tree](https://en.wikipedia.org/wiki/Tree_structure) with the quotes as compound nodes and the non-quote values as leaf nodes, in this page I want to talk about [ordered binary trees](https://en.wikipedia.org/wiki/Binary_search_tree) and how to make and use them.
|
||||||
|
|
||||||
|
|
@ -64,6 +64,9 @@ define('Tree-new == swap [[] []] cons cons')
|
||||||
J('"v" "k" Tree-new')
|
J('"v" "k" Tree-new')
|
||||||
```
|
```
|
||||||
|
|
||||||
|
['k' 'v' [] []]
|
||||||
|
|
||||||
|
|
||||||
(As an implementation detail, the `[[] []]` literal used in the definition of `Tree-new` will be reused to supply the *constant* tail for *all* new nodes produced by it. This is one of those cases where you get amortized storage "for free" by using [persistent datastructures](https://en.wikipedia.org/wiki/Persistent_data_structure). Because the tail, which is `((), ((), ()))` in Python, is immutable and embedded in the definition body for `Tree-new`, all new nodes can reuse it as their own tail without fear that some other code somewhere will change it.)
|
(As an implementation detail, the `[[] []]` literal used in the definition of `Tree-new` will be reused to supply the *constant* tail for *all* new nodes produced by it. This is one of those cases where you get amortized storage "for free" by using [persistent datastructures](https://en.wikipedia.org/wiki/Persistent_data_structure). Because the tail, which is `((), ((), ()))` in Python, is immutable and embedded in the definition body for `Tree-new`, all new nodes can reuse it as their own tail without fear that some other code somewhere will change it.)
|
||||||
|
|
||||||
### Adding to a non-empty node.
|
### Adding to a non-empty node.
|
||||||
|
|
@ -302,7 +305,7 @@ J('[] [[23 "b"] [88 "a"] [44 "c"]] [i Tree-add] step')
|
||||||
|
|
||||||
|
|
||||||
## Interlude: `cmp` combinator
|
## Interlude: `cmp` combinator
|
||||||
Instead of mucking about with nested `ifte` combinators let's just go whole hog and define `cmp` which takes two values and three quoted programs on the stack and runs one of the three depending on the results of comparing the two values:
|
Instead of mucking about with nested `ifte` combinators let's use `cmp` which takes two values and three quoted programs on the stack and runs one of the three depending on the results of comparing the two values:
|
||||||
|
|
||||||
a b [G] [E] [L] cmp
|
a b [G] [E] [L] cmp
|
||||||
------------------------- a > b
|
------------------------- a > b
|
||||||
|
|
@ -317,39 +320,6 @@ Instead of mucking about with nested `ifte` combinators let's just go whole hog
|
||||||
L
|
L
|
||||||
|
|
||||||
|
|
||||||
```python
|
|
||||||
from joy.library import FunctionWrapper
|
|
||||||
from joy.utils.stack import pushback
|
|
||||||
from notebook_preamble import D
|
|
||||||
|
|
||||||
|
|
||||||
@FunctionWrapper
|
|
||||||
def cmp_(stack, expression, dictionary):
|
|
||||||
'''
|
|
||||||
cmp takes two values and three quoted programs on the stack and runs
|
|
||||||
one of the three depending on the results of comparing the two values:
|
|
||||||
|
|
||||||
a b [G] [E] [L] cmp
|
|
||||||
------------------------- a > b
|
|
||||||
G
|
|
||||||
|
|
||||||
a b [G] [E] [L] cmp
|
|
||||||
------------------------- a = b
|
|
||||||
E
|
|
||||||
|
|
||||||
a b [G] [E] [L] cmp
|
|
||||||
------------------------- a < b
|
|
||||||
L
|
|
||||||
'''
|
|
||||||
L, (E, (G, (b, (a, stack)))) = stack
|
|
||||||
expression = pushback(G if a > b else L if a < b else E, expression)
|
|
||||||
return stack, expression, dictionary
|
|
||||||
|
|
||||||
|
|
||||||
D['cmp'] = cmp_
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
J("1 0 ['G'] ['E'] ['L'] cmp")
|
J("1 0 ['G'] ['E'] ['L'] cmp")
|
||||||
```
|
```
|
||||||
|
|
@ -681,7 +651,7 @@ J('[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order')
|
||||||
2 3 4 5 6 7 8 9
|
2 3 4 5 6 7 8 9
|
||||||
|
|
||||||
|
|
||||||
Parameterizing the `[F]` function is left as an exercise for the reader (for now.)
|
Parameterizing the `[F]` function is left as an exercise for the reader.
|
||||||
|
|
||||||
## Getting values by key
|
## Getting values by key
|
||||||
Let's derive a function that accepts a tree and a key and returns the value associated with that key.
|
Let's derive a function that accepts a tree and a key and returns the value associated with that key.
|
||||||
|
|
@ -937,51 +907,6 @@ We have found the node in the tree where `key` equals `node_key`. We need to re
|
||||||
|
|
||||||
We have to handle three cases, so let's use `cond`.
|
We have to handle three cases, so let's use `cond`.
|
||||||
|
|
||||||
|
|
||||||
```python
|
|
||||||
from joy.library import FunctionWrapper, S_ifte
|
|
||||||
|
|
||||||
|
|
||||||
@FunctionWrapper
|
|
||||||
def cond(stack, expression, dictionary):
|
|
||||||
'''
|
|
||||||
like a case statement; works by rewriting into a chain of ifte.
|
|
||||||
|
|
||||||
[..[[Bi] Ti]..[D]] -> ...
|
|
||||||
|
|
||||||
|
|
||||||
[[[B0] T0] [[B1] T1] [D]] cond
|
|
||||||
-----------------------------------------
|
|
||||||
[B0] [T0] [[B1] [T1] [D] ifte] ifte
|
|
||||||
|
|
||||||
'''
|
|
||||||
conditions, stack = stack
|
|
||||||
if conditions:
|
|
||||||
expression = _cond(conditions, expression)
|
|
||||||
try:
|
|
||||||
# Attempt to preload the args to first ifte.
|
|
||||||
(P, (T, (E, expression))) = expression
|
|
||||||
except ValueError:
|
|
||||||
# If, for any reason, the argument to cond should happen to contain
|
|
||||||
# only the default clause then this optimization will fail.
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
stack = (E, (T, (P, stack)))
|
|
||||||
return stack, expression, dictionary
|
|
||||||
|
|
||||||
|
|
||||||
def _cond(conditions, expression):
|
|
||||||
(clause, rest) = conditions
|
|
||||||
if not rest: # clause is [D]
|
|
||||||
return clause
|
|
||||||
P, T = clause
|
|
||||||
return (P, (T, (_cond(rest, ()), (S_ifte, expression))))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
D['cond'] = cond
|
|
||||||
```
|
|
||||||
|
|
||||||
#### One or more child nodes are `[]`
|
#### One or more child nodes are `[]`
|
||||||
The first two cases are symmetrical: if we only have one non-empty child node return it. If both child nodes are empty return an empty node.
|
The first two cases are symmetrical: if we only have one non-empty child node return it. If both child nodes are empty return an empty node.
|
||||||
|
|
||||||
|
|
@ -1127,7 +1052,7 @@ Substituting:
|
||||||
[[E′] cons infra]
|
[[E′] cons infra]
|
||||||
] cond
|
] cond
|
||||||
|
|
||||||
Minor rearrangement:
|
Minor rearrangement, move `dup` into `W`:
|
||||||
|
|
||||||
W == dup [fourth] [fourth] while uncons uncons pop over
|
W == dup [fourth] [fourth] while uncons uncons pop over
|
||||||
E′ == roll> popop rest [W] dip cons dipd swap
|
E′ == roll> popop rest [W] dip cons dipd swap
|
||||||
|
|
@ -1141,9 +1066,9 @@ Minor rearrangement:
|
||||||
|
|
||||||
W.rightmost == [fourth] [fourth] while
|
W.rightmost == [fourth] [fourth] while
|
||||||
W.unpack == uncons uncons pop
|
W.unpack == uncons uncons pop
|
||||||
|
W == dup W.rightmost W.unpack over
|
||||||
E.clear_stuff == roll> popop rest
|
E.clear_stuff == roll> popop rest
|
||||||
E.delete == cons dipd
|
E.delete == cons dipd
|
||||||
W == dup W.rightmost W.unpack over
|
|
||||||
E.0 == E.clear_stuff [W] dip E.delete swap
|
E.0 == E.clear_stuff [W] dip E.delete swap
|
||||||
E == [
|
E == [
|
||||||
[[pop third not] pop fourth]
|
[[pop third not] pop fourth]
|
||||||
|
|
@ -1174,7 +1099,8 @@ T> == [dipd] cons infra
|
||||||
T< == [dipdd] cons infra
|
T< == [dipdd] cons infra
|
||||||
R0 == over first swap dup
|
R0 == over first swap dup
|
||||||
R1 == cons roll> [T>] [E] [T<] cmp
|
R1 == cons roll> [T>] [E] [T<] cmp
|
||||||
Tree-Delete == [pop not] [pop] [R0] [R1] genrec''', D)
|
Tree-Delete == [pop not] [pop] [R0] [R1] genrec
|
||||||
|
''', D)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
Treating Trees I
|
Treating Trees I: Ordered Binary Trees
|
||||||
================
|
======================================
|
||||||
|
|
||||||
Although any expression in Joy can be considered to describe a
|
Although any expression in Joy can be considered to describe a
|
||||||
`tree <https://en.wikipedia.org/wiki/Tree_structure>`__ with the quotes
|
`tree <https://en.wikipedia.org/wiki/Tree_structure>`__ with the quotes
|
||||||
|
|
@ -96,6 +96,12 @@ Definition:
|
||||||
|
|
||||||
J('"v" "k" Tree-new')
|
J('"v" "k" Tree-new')
|
||||||
|
|
||||||
|
|
||||||
|
.. parsed-literal::
|
||||||
|
|
||||||
|
['k' 'v' [] []]
|
||||||
|
|
||||||
|
|
||||||
(As an implementation detail, the ``[[] []]`` literal used in the
|
(As an implementation detail, the ``[[] []]`` literal used in the
|
||||||
definition of ``Tree-new`` will be reused to supply the *constant* tail
|
definition of ``Tree-new`` will be reused to supply the *constant* tail
|
||||||
for *all* new nodes produced by it. This is one of those cases where you
|
for *all* new nodes produced by it. This is one of those cases where you
|
||||||
|
|
@ -420,10 +426,10 @@ Examples
|
||||||
Interlude: ``cmp`` combinator
|
Interlude: ``cmp`` combinator
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
Instead of mucking about with nested ``ifte`` combinators let's just go
|
Instead of mucking about with nested ``ifte`` combinators let's use
|
||||||
whole hog and define ``cmp`` which takes two values and three quoted
|
``cmp`` which takes two values and three quoted programs on the stack
|
||||||
programs on the stack and runs one of the three depending on the results
|
and runs one of the three depending on the results of comparing the two
|
||||||
of comparing the two values:
|
values:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|
@ -439,38 +445,6 @@ of comparing the two values:
|
||||||
------------------------- a < b
|
------------------------- a < b
|
||||||
L
|
L
|
||||||
|
|
||||||
.. code:: ipython2
|
|
||||||
|
|
||||||
from joy.library import FunctionWrapper
|
|
||||||
from joy.utils.stack import pushback
|
|
||||||
from notebook_preamble import D
|
|
||||||
|
|
||||||
|
|
||||||
@FunctionWrapper
|
|
||||||
def cmp_(stack, expression, dictionary):
|
|
||||||
'''
|
|
||||||
cmp takes two values and three quoted programs on the stack and runs
|
|
||||||
one of the three depending on the results of comparing the two values:
|
|
||||||
|
|
||||||
a b [G] [E] [L] cmp
|
|
||||||
------------------------- a > b
|
|
||||||
G
|
|
||||||
|
|
||||||
a b [G] [E] [L] cmp
|
|
||||||
------------------------- a = b
|
|
||||||
E
|
|
||||||
|
|
||||||
a b [G] [E] [L] cmp
|
|
||||||
------------------------- a < b
|
|
||||||
L
|
|
||||||
'''
|
|
||||||
L, (E, (G, (b, (a, stack)))) = stack
|
|
||||||
expression = pushback(G if a > b else L if a < b else E, expression)
|
|
||||||
return stack, expression, dictionary
|
|
||||||
|
|
||||||
|
|
||||||
D['cmp'] = cmp_
|
|
||||||
|
|
||||||
.. code:: ipython2
|
.. code:: ipython2
|
||||||
|
|
||||||
J("1 0 ['G'] ['E'] ['L'] cmp")
|
J("1 0 ['G'] ['E'] ['L'] cmp")
|
||||||
|
|
@ -930,7 +904,7 @@ Now we can sort sequences.
|
||||||
|
|
||||||
|
|
||||||
Parameterizing the ``[F]`` function is left as an exercise for the
|
Parameterizing the ``[F]`` function is left as an exercise for the
|
||||||
reader (for now.)
|
reader.
|
||||||
|
|
||||||
Getting values by key
|
Getting values by key
|
||||||
---------------------
|
---------------------
|
||||||
|
|
@ -1291,50 +1265,6 @@ need to replace the current node with something
|
||||||
|
|
||||||
We have to handle three cases, so let's use ``cond``.
|
We have to handle three cases, so let's use ``cond``.
|
||||||
|
|
||||||
.. code:: ipython2
|
|
||||||
|
|
||||||
from joy.library import FunctionWrapper, S_ifte
|
|
||||||
|
|
||||||
|
|
||||||
@FunctionWrapper
|
|
||||||
def cond(stack, expression, dictionary):
|
|
||||||
'''
|
|
||||||
like a case statement; works by rewriting into a chain of ifte.
|
|
||||||
|
|
||||||
[..[[Bi] Ti]..[D]] -> ...
|
|
||||||
|
|
||||||
|
|
||||||
[[[B0] T0] [[B1] T1] [D]] cond
|
|
||||||
-----------------------------------------
|
|
||||||
[B0] [T0] [[B1] [T1] [D] ifte] ifte
|
|
||||||
|
|
||||||
'''
|
|
||||||
conditions, stack = stack
|
|
||||||
if conditions:
|
|
||||||
expression = _cond(conditions, expression)
|
|
||||||
try:
|
|
||||||
# Attempt to preload the args to first ifte.
|
|
||||||
(P, (T, (E, expression))) = expression
|
|
||||||
except ValueError:
|
|
||||||
# If, for any reason, the argument to cond should happen to contain
|
|
||||||
# only the default clause then this optimization will fail.
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
stack = (E, (T, (P, stack)))
|
|
||||||
return stack, expression, dictionary
|
|
||||||
|
|
||||||
|
|
||||||
def _cond(conditions, expression):
|
|
||||||
(clause, rest) = conditions
|
|
||||||
if not rest: # clause is [D]
|
|
||||||
return clause
|
|
||||||
P, T = clause
|
|
||||||
return (P, (T, (_cond(rest, ()), (S_ifte, expression))))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
D['cond'] = cond
|
|
||||||
|
|
||||||
One or more child nodes are ``[]``
|
One or more child nodes are ``[]``
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
@ -1534,7 +1464,7 @@ Substituting:
|
||||||
[[E′] cons infra]
|
[[E′] cons infra]
|
||||||
] cond
|
] cond
|
||||||
|
|
||||||
Minor rearrangement:
|
Minor rearrangement, move ``dup`` into ``W``:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|
@ -1553,9 +1483,9 @@ Refactoring
|
||||||
|
|
||||||
W.rightmost == [fourth] [fourth] while
|
W.rightmost == [fourth] [fourth] while
|
||||||
W.unpack == uncons uncons pop
|
W.unpack == uncons uncons pop
|
||||||
|
W == dup W.rightmost W.unpack over
|
||||||
E.clear_stuff == roll> popop rest
|
E.clear_stuff == roll> popop rest
|
||||||
E.delete == cons dipd
|
E.delete == cons dipd
|
||||||
W == dup W.rightmost W.unpack over
|
|
||||||
E.0 == E.clear_stuff [W] dip E.delete swap
|
E.0 == E.clear_stuff [W] dip E.delete swap
|
||||||
E == [
|
E == [
|
||||||
[[pop third not] pop fourth]
|
[[pop third not] pop fourth]
|
||||||
|
|
@ -1587,7 +1517,8 @@ program.
|
||||||
T< == [dipdd] cons infra
|
T< == [dipdd] cons infra
|
||||||
R0 == over first swap dup
|
R0 == over first swap dup
|
||||||
R1 == cons roll> [T>] [E] [T<] cmp
|
R1 == cons roll> [T>] [E] [T<] cmp
|
||||||
Tree-Delete == [pop not] [pop] [R0] [R1] genrec''', D)
|
Tree-Delete == [pop not] [pop] [R0] [R1] genrec
|
||||||
|
''', D)
|
||||||
|
|
||||||
.. code:: ipython2
|
.. code:: ipython2
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue