Make sure we've got all the docs, etc.

This commit is contained in:
Simon Forman 2018-07-15 20:43:26 -07:00
parent cf12b9ce17
commit 230134e6c2
15 changed files with 1750 additions and 21 deletions

View File

@ -12215,11 +12215,7 @@ expressions grow each derivation.</p>
<div class="prompt input_prompt">In&nbsp;[11]:</div>
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython2"><pre><span></span><span class="c1"># This is the straightforward version with no &quot;compaction&quot;.</span>
<span class="c1"># It works fine, but does waaaay too much work because the</span>
<span class="c1"># expressions grow each derivation.</span>
<span class="k">def</span> <span class="nf">D</span><span class="p">(</span><span class="n">symbol</span><span class="p">):</span>
<div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">D</span><span class="p">(</span><span class="n">symbol</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">derv</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>

View File

@ -232,10 +232,6 @@ expressions grow each derivation.
```python
# This is the straightforward version with no "compaction".
# It works fine, but does waaaay too much work because the
# expressions grow each derivation.
def D(symbol):
def derv(R):

View File

@ -266,10 +266,6 @@ derivation.
.. code:: ipython2
# This is the straightforward version with no "compaction".
# It works fine, but does waaaay too much work because the
# expressions grow each derivation.
def D(symbol):
def derv(R):

View File

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
-->
<!-- Title: finite_state_machine Pages: 1 -->
<svg width="534pt" height="270pt"
viewBox="0.00 0.00 534.00 270.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 266)">
<title>finite_state_machine</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-266 530,-266 530,4 -4,4"/>
<!-- i -->
<g id="node1" class="node"><title>i</title>
<ellipse fill="none" stroke="black" cx="338" cy="-146" rx="18" ry="18"/>
<ellipse fill="none" stroke="black" cx="338" cy="-146" rx="22" ry="22"/>
<text text-anchor="middle" x="338" y="-142.3" font-family="Times,serif" font-size="14.00">i</text>
</g>
<!-- i&#45;&gt;i -->
<g id="edge17" class="edge"><title>i&#45;&gt;i</title>
<path fill="none" stroke="black" d="M330.317,-166.991C329.369,-177.087 331.93,-186 338,-186 341.889,-186 344.337,-182.342 345.346,-177.059"/>
<polygon fill="black" stroke="black" points="348.846,-177.102 345.683,-166.991 341.85,-176.868 348.846,-177.102"/>
<text text-anchor="middle" x="338" y="-189.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- j -->
<g id="node10" class="node"><title>j</title>
<ellipse fill="none" stroke="black" cx="421" cy="-136" rx="18" ry="18"/>
<text text-anchor="middle" x="421" y="-132.3" font-family="Times,serif" font-size="14.00">j</text>
</g>
<!-- i&#45;&gt;j -->
<g id="edge18" class="edge"><title>i&#45;&gt;j</title>
<path fill="none" stroke="black" d="M357.466,-135.495C363.775,-132.451 371.008,-129.536 378,-128 383.213,-126.855 388.811,-126.984 394.167,-127.763"/>
<polygon fill="black" stroke="black" points="393.487,-131.197 404.002,-129.894 394.97,-124.355 393.487,-131.197"/>
<text text-anchor="middle" x="381.5" y="-131.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- h -->
<g id="node2" class="node"><title>h</title>
<ellipse fill="none" stroke="black" cx="504" cy="-85" rx="18" ry="18"/>
<ellipse fill="none" stroke="black" cx="504" cy="-85" rx="22" ry="22"/>
<text text-anchor="middle" x="504" y="-81.3" font-family="Times,serif" font-size="14.00">h</text>
</g>
<!-- h&#45;&gt;i -->
<g id="edge15" class="edge"><title>h&#45;&gt;i</title>
<path fill="none" stroke="black" d="M481.868,-83.4025C461.033,-82.62 428.676,-83.5645 403,-94 387.267,-100.394 372.373,-112.028 360.918,-122.673"/>
<polygon fill="black" stroke="black" points="358.306,-120.33 353.569,-129.807 363.182,-125.353 358.306,-120.33"/>
<text text-anchor="middle" x="421" y="-97.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- h&#45;&gt;h -->
<g id="edge16" class="edge"><title>h&#45;&gt;h</title>
<path fill="none" stroke="black" d="M496.317,-105.991C495.369,-116.087 497.93,-125 504,-125 507.889,-125 510.337,-121.342 511.346,-116.059"/>
<polygon fill="black" stroke="black" points="514.846,-116.102 511.683,-105.991 507.85,-115.868 514.846,-116.102"/>
<text text-anchor="middle" x="504" y="-128.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- a -->
<g id="node3" class="node"><title>a</title>
<ellipse fill="none" stroke="black" cx="18" cy="-128" rx="18" ry="18"/>
<text text-anchor="middle" x="18" y="-124.3" font-family="Times,serif" font-size="14.00">a</text>
</g>
<!-- b -->
<g id="node4" class="node"><title>b</title>
<ellipse fill="none" stroke="black" cx="255" cy="-113" rx="18" ry="18"/>
<text text-anchor="middle" x="255" y="-109.3" font-family="Times,serif" font-size="14.00">b</text>
</g>
<!-- a&#45;&gt;b -->
<g id="edge1" class="edge"><title>a&#45;&gt;b</title>
<path fill="none" stroke="black" d="M36.2801,-126.897C76.7816,-124.312 178.091,-117.845 226.89,-114.73"/>
<polygon fill="black" stroke="black" points="227.255,-118.214 237.011,-114.084 226.809,-111.229 227.255,-118.214"/>
<text text-anchor="middle" x="136.5" y="-123.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- c -->
<g id="node5" class="node"><title>c</title>
<ellipse fill="none" stroke="black" cx="97" cy="-155" rx="18" ry="18"/>
<text text-anchor="middle" x="97" y="-151.3" font-family="Times,serif" font-size="14.00">c</text>
</g>
<!-- a&#45;&gt;c -->
<g id="edge2" class="edge"><title>a&#45;&gt;c</title>
<path fill="none" stroke="black" d="M35.3297,-133.726C45.4364,-137.27 58.635,-141.898 70.1398,-145.932"/>
<polygon fill="black" stroke="black" points="69.099,-149.276 79.6938,-149.282 71.4153,-142.67 69.099,-149.276"/>
<text text-anchor="middle" x="57.5" y="-145.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- b&#45;&gt;b -->
<g id="edge3" class="edge"><title>b&#45;&gt;b</title>
<path fill="none" stroke="black" d="M248.266,-130.037C246.892,-139.858 249.137,-149 255,-149 258.665,-149 260.916,-145.429 261.753,-140.353"/>
<polygon fill="black" stroke="black" points="265.252,-140.031 261.734,-130.037 258.252,-140.044 265.252,-140.031"/>
<text text-anchor="middle" x="255" y="-152.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- d -->
<g id="node6" class="node"><title>d</title>
<ellipse fill="none" stroke="black" cx="338" cy="-79" rx="18" ry="18"/>
<text text-anchor="middle" x="338" y="-75.3" font-family="Times,serif" font-size="14.00">d</text>
</g>
<!-- b&#45;&gt;d -->
<g id="edge4" class="edge"><title>b&#45;&gt;d</title>
<path fill="none" stroke="black" d="M272.003,-106.283C283.319,-101.533 298.722,-95.0674 311.693,-89.6227"/>
<polygon fill="black" stroke="black" points="313.164,-92.801 321.03,-85.7034 310.455,-86.3466 313.164,-92.801"/>
<text text-anchor="middle" x="294.5" y="-101.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- c&#45;&gt;b -->
<g id="edge5" class="edge"><title>c&#45;&gt;b</title>
<path fill="none" stroke="black" d="M114.862,-150.653C138.269,-144.593 181.917,-133.2 219,-123 221.799,-122.23 224.721,-121.414 227.631,-120.594"/>
<polygon fill="black" stroke="black" points="228.623,-123.951 237.284,-117.849 226.708,-117.218 228.623,-123.951"/>
<text text-anchor="middle" x="176" y="-142.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- e -->
<g id="node7" class="node"><title>e</title>
<ellipse fill="none" stroke="black" cx="176" cy="-206" rx="18" ry="18"/>
<text text-anchor="middle" x="176" y="-202.3" font-family="Times,serif" font-size="14.00">e</text>
</g>
<!-- c&#45;&gt;e -->
<g id="edge6" class="edge"><title>c&#45;&gt;e</title>
<path fill="none" stroke="black" d="M112.483,-164.593C123.668,-172.001 139.356,-182.392 152.219,-190.911"/>
<polygon fill="black" stroke="black" points="150.312,-193.846 160.582,-196.45 154.177,-188.01 150.312,-193.846"/>
<text text-anchor="middle" x="136.5" y="-185.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- d&#45;&gt;b -->
<g id="edge7" class="edge"><title>d&#45;&gt;b</title>
<path fill="none" stroke="black" d="M320.205,-74.8763C311.208,-73.4911 300.131,-73.1424 291,-77 284.094,-79.9175 277.879,-84.9376 272.669,-90.3183"/>
<polygon fill="black" stroke="black" points="269.694,-88.4067 265.791,-98.2568 274.985,-92.9902 269.694,-88.4067"/>
<text text-anchor="middle" x="294.5" y="-80.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- f -->
<g id="node8" class="node"><title>f</title>
<ellipse fill="none" stroke="black" cx="176" cy="-46" rx="18" ry="18"/>
<text text-anchor="middle" x="176" y="-42.3" font-family="Times,serif" font-size="14.00">f</text>
</g>
<!-- d&#45;&gt;f -->
<g id="edge8" class="edge"><title>d&#45;&gt;f</title>
<path fill="none" stroke="black" d="M319.923,-75.478C292.098,-69.7389 236.768,-58.3271 203.708,-51.5086"/>
<polygon fill="black" stroke="black" points="204.321,-48.0614 193.82,-49.4692 202.907,-54.9171 204.321,-48.0614"/>
<text text-anchor="middle" x="255" y="-69.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- e&#45;&gt;b -->
<g id="edge9" class="edge"><title>e&#45;&gt;b</title>
<path fill="none" stroke="black" d="M190.241,-194.796C198.908,-187.136 210.212,-176.503 219,-166 226.507,-157.028 233.803,-146.389 239.774,-137.007"/>
<polygon fill="black" stroke="black" points="242.759,-138.834 245.056,-128.491 236.81,-135.144 242.759,-138.834"/>
<text text-anchor="middle" x="215.5" y="-176.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- g -->
<g id="node9" class="node"><title>g</title>
<ellipse fill="none" stroke="black" cx="255" cy="-211" rx="18" ry="18"/>
<text text-anchor="middle" x="255" y="-207.3" font-family="Times,serif" font-size="14.00">g</text>
</g>
<!-- e&#45;&gt;g -->
<g id="edge10" class="edge"><title>e&#45;&gt;g</title>
<path fill="none" stroke="black" d="M194.089,-207.11C203.659,-207.731 215.817,-208.521 226.677,-209.226"/>
<polygon fill="black" stroke="black" points="226.753,-212.738 236.959,-209.893 227.207,-205.753 226.753,-212.738"/>
<text text-anchor="middle" x="215.5" y="-211.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- f&#45;&gt;h -->
<g id="edge12" class="edge"><title>f&#45;&gt;h</title>
<path fill="none" stroke="black" d="M189.02,-33.1864C203.151,-19.5754 227.995,-0 254,-0 254,-0 254,-0 422,-0 453.632,-0 476.677,-31.2311 489.924,-55.8314"/>
<polygon fill="black" stroke="black" points="486.862,-57.5325 494.518,-64.8562 493.1,-54.3566 486.862,-57.5325"/>
<text text-anchor="middle" x="338" y="-3.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- f&#45;&gt;b -->
<g id="edge11" class="edge"><title>f&#45;&gt;b</title>
<path fill="none" stroke="black" d="M190.834,-56.7689C199.13,-63.3319 209.817,-71.9742 219,-80 224.034,-84.4001 229.343,-89.2757 234.262,-93.899"/>
<polygon fill="black" stroke="black" points="231.917,-96.4985 241.576,-100.852 236.74,-91.4252 231.917,-96.4985"/>
<text text-anchor="middle" x="215.5" y="-83.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- g&#45;&gt;i -->
<g id="edge13" class="edge"><title>g&#45;&gt;i</title>
<path fill="none" stroke="black" d="M269.741,-199.974C281.437,-190.587 298.524,-176.876 312.548,-165.622"/>
<polygon fill="black" stroke="black" points="314.778,-168.32 320.387,-159.331 310.397,-162.86 314.778,-168.32"/>
<text text-anchor="middle" x="294.5" y="-185.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- g&#45;&gt;g -->
<g id="edge14" class="edge"><title>g&#45;&gt;g</title>
<path fill="none" stroke="black" d="M248.266,-228.037C246.892,-237.858 249.137,-247 255,-247 258.665,-247 260.916,-243.429 261.753,-238.353"/>
<polygon fill="black" stroke="black" points="265.252,-238.031 261.734,-228.037 258.252,-238.044 265.252,-238.031"/>
<text text-anchor="middle" x="255" y="-250.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- j&#45;&gt;i -->
<g id="edge19" class="edge"><title>j&#45;&gt;i</title>
<path fill="none" stroke="black" d="M403.34,-139.8C397.561,-140.993 391.021,-142.205 385,-143 380.321,-143.618 375.357,-144.11 370.488,-144.502"/>
<polygon fill="black" stroke="black" points="369.864,-141.036 360.126,-145.209 370.341,-148.02 369.864,-141.036"/>
<text text-anchor="middle" x="381.5" y="-146.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- j&#45;&gt;h -->
<g id="edge20" class="edge"><title>j&#45;&gt;h</title>
<path fill="none" stroke="black" d="M436.857,-126.646C447.841,-119.73 463.1,-110.122 476.194,-101.878"/>
<polygon fill="black" stroke="black" points="478.237,-104.727 484.835,-96.4375 474.507,-98.8038 478.237,-104.727"/>
<text text-anchor="middle" x="460.5" y="-116.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -473,6 +473,8 @@
<li><a href="pretty.html#joy.utils.pretty_print.TracePrinter">TracePrinter (class in joy.utils.pretty_print)</a>
</li>
<li><a href="library.html#joy.utils.generated_library.tuck">tuck() (in module joy.utils.generated_library)</a>
</li>
<li><a href="types.html#joy.utils.polytypes.type_check">type_check() (in module joy.utils.polytypes)</a>
</li>
</ul></td>
</tr></table>

View File

@ -147,8 +147,11 @@ interesting aspects. Its quite a treasure trove.</p>
<li class="toctree-l2"><a class="reference internal" href="notebooks/Newton-Raphson.html">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="notebooks/Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="notebooks/Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="notebooks/TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="notebooks/NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="notebooks/Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="notebooks/The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="notebooks/Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>

View File

@ -0,0 +1,923 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>∂RE &#8212; Thun 0.2.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="re">
<h1>∂RE<a class="headerlink" href="#re" title="Permalink to this headline"></a></h1>
<div class="section" id="brzozowski-s-derivatives-of-regular-expressions">
<h2>Brzozowskis Derivatives of Regular Expressions<a class="headerlink" href="#brzozowski-s-derivatives-of-regular-expressions" title="Permalink to this headline"></a></h2>
<p>Legend:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>∧ intersection
union
∘ concatenation (see below)
¬ complement
ϕ empty set (aka ∅)
λ singleton set containing just the empty string
I set of all letters in alphabet
</pre></div>
</div>
<p>Derivative of a set <code class="docutils literal notranslate"><span class="pre">R</span></code> of strings and a string <code class="docutils literal notranslate"><span class="pre">a</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>∂a(R)
∂a(a) → λ
∂a(λ) → ϕ
∂a(ϕ) → ϕ
∂a(¬a) → ϕ
∂a(R*) → ∂a(R)∘R*
∂a(¬R) → ¬∂a(R)
∂a(R∘S) → ∂a(R)∘S δ(R)∘∂a(S)
∂a(R ∧ S) → ∂a(R) ∧ ∂a(S)
∂a(R S) → ∂a(R) ∂a(S)
∂ab(R) = ∂b(∂a(R))
</pre></div>
</div>
<p>Auxiliary predicate function <code class="docutils literal notranslate"><span class="pre">δ</span></code> (I call it <code class="docutils literal notranslate"><span class="pre">nully</span></code>) returns either
<code class="docutils literal notranslate"><span class="pre">λ</span></code> if <code class="docutils literal notranslate"><span class="pre">λ</span> <span class="pre"></span> <span class="pre">R</span></code> or <code class="docutils literal notranslate"><span class="pre">ϕ</span></code> otherwise:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>δ(a) → ϕ
δ(λ) → λ
δ(ϕ) → ϕ
δ(R*) → λ
δ(¬R) δ(R)≟ϕ → λ
δ(¬R) δ(R)≟λ → ϕ
δ(R∘S) → δ(R) ∧ δ(S)
δ(R ∧ S) → δ(R) ∧ δ(S)
δ(R S) → δ(R) δ(S)
</pre></div>
</div>
<p>Some rules we will use later for “compaction”:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>R ∧ ϕ = ϕ ∧ R = ϕ
R ∧ I = I ∧ R = R
R ϕ = ϕ R = R
R I = I R = I
R∘ϕ = ϕ∘R = ϕ
R∘λ = λ∘R = R
</pre></div>
</div>
<p>Concatination of sets: for two sets A and B the set A∘B is defined as:</p>
<p>{a∘b for a in A for b in B}</p>
<p>E.g.:</p>
<p>{a, b}∘{c, d} → {ac, ad, bc, bd}</p>
</div>
<div class="section" id="implementation">
<h2>Implementation<a class="headerlink" href="#implementation" title="Permalink to this headline"></a></h2>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">functools</span> <span class="k">import</span> <span class="n">partial</span> <span class="k">as</span> <span class="n">curry</span>
<span class="kn">from</span> <span class="nn">itertools</span> <span class="k">import</span> <span class="n">product</span>
</pre></div>
</div>
<div class="section" id="and">
<h3><code class="docutils literal notranslate"><span class="pre">ϕ</span></code> and <code class="docutils literal notranslate"><span class="pre">λ</span></code><a class="headerlink" href="#and" title="Permalink to this headline"></a></h3>
<p>The empty set and the set of just the empty string.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">phi</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">()</span> <span class="c1"># ϕ</span>
<span class="n">y</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">&#39;&#39;</span><span class="p">})</span> <span class="c1"># λ</span>
</pre></div>
</div>
</div>
<div class="section" id="two-letter-alphabet">
<h3>Two-letter Alphabet<a class="headerlink" href="#two-letter-alphabet" title="Permalink to this headline"></a></h3>
<p>Im only going to use two symbols (at first) becaase this is enough to
illustrate the algorithm and because you can represent any other
alphabet with two symbols (if you had to.)</p>
<p>I chose the names <code class="docutils literal notranslate"><span class="pre">O</span></code> and <code class="docutils literal notranslate"><span class="pre">l</span></code> (uppercase “o” and lowercase “L”) to
look like <code class="docutils literal notranslate"><span class="pre">0</span></code> and <code class="docutils literal notranslate"><span class="pre">1</span></code> (zero and one) respectively.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">syms</span> <span class="o">=</span> <span class="n">O</span><span class="p">,</span> <span class="n">l</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">&#39;0&#39;</span><span class="p">}),</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">&#39;1&#39;</span><span class="p">})</span>
</pre></div>
</div>
</div>
<div class="section" id="representing-regular-expressions">
<h3>Representing Regular Expressions<a class="headerlink" href="#representing-regular-expressions" title="Permalink to this headline"></a></h3>
<p>To represent REs in Python Im going to use tagged tuples. A <em>regular
expression</em> is one of:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">O</span>
<span class="n">l</span>
<span class="p">(</span><span class="n">KSTAR</span><span class="p">,</span> <span class="n">R</span><span class="p">)</span>
<span class="p">(</span><span class="n">NOT</span><span class="p">,</span> <span class="n">R</span><span class="p">)</span>
<span class="p">(</span><span class="n">AND</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="n">S</span><span class="p">)</span>
<span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="n">S</span><span class="p">)</span>
<span class="p">(</span><span class="n">OR</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="n">S</span><span class="p">)</span>
</pre></div>
</div>
<p>Where <code class="docutils literal notranslate"><span class="pre">R</span></code> and <code class="docutils literal notranslate"><span class="pre">S</span></code> stand for <em>regular expressions</em>.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">AND</span><span class="p">,</span> <span class="n">CONS</span><span class="p">,</span> <span class="n">KSTAR</span><span class="p">,</span> <span class="n">NOT</span><span class="p">,</span> <span class="n">OR</span> <span class="o">=</span> <span class="s1">&#39;and cons * not or&#39;</span><span class="o">.</span><span class="n">split</span><span class="p">()</span> <span class="c1"># Tags are just strings.</span>
</pre></div>
</div>
<p>Because they are formed of <code class="docutils literal notranslate"><span class="pre">frozenset</span></code>, <code class="docutils literal notranslate"><span class="pre">tuple</span></code> and <code class="docutils literal notranslate"><span class="pre">str</span></code> objects
only, these datastructures are immutable.</p>
</div>
<div class="section" id="string-representation-of-re-datastructures">
<h3>String Representation of RE Datastructures<a class="headerlink" href="#string-representation-of-re-datastructures" title="Permalink to this headline"></a></h3>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">stringy</span><span class="p">(</span><span class="n">re</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return a nice string repr for a regular expression datastructure.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">re</span> <span class="o">==</span> <span class="n">I</span><span class="p">:</span> <span class="k">return</span> <span class="s1">&#39;.&#39;</span>
<span class="k">if</span> <span class="n">re</span> <span class="ow">in</span> <span class="n">syms</span><span class="p">:</span> <span class="k">return</span> <span class="nb">next</span><span class="p">(</span><span class="nb">iter</span><span class="p">(</span><span class="n">re</span><span class="p">))</span>
<span class="k">if</span> <span class="n">re</span> <span class="o">==</span> <span class="n">y</span><span class="p">:</span> <span class="k">return</span> <span class="s1">&#39;^&#39;</span>
<span class="k">if</span> <span class="n">re</span> <span class="o">==</span> <span class="n">phi</span><span class="p">:</span> <span class="k">return</span> <span class="s1">&#39;X&#39;</span>
<span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">re</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">),</span> <span class="nb">repr</span><span class="p">(</span><span class="n">re</span><span class="p">)</span>
<span class="n">tag</span> <span class="o">=</span> <span class="n">re</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">if</span> <span class="n">tag</span> <span class="o">==</span> <span class="n">KSTAR</span><span class="p">:</span>
<span class="n">body</span> <span class="o">=</span> <span class="n">stringy</span><span class="p">(</span><span class="n">re</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">body</span><span class="p">:</span> <span class="k">return</span> <span class="n">body</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">body</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span> <span class="k">return</span> <span class="s1">&#39;(&#39;</span> <span class="o">+</span> <span class="n">body</span> <span class="o">+</span> <span class="s2">&quot;)*&quot;</span>
<span class="k">return</span> <span class="n">body</span> <span class="o">+</span> <span class="s1">&#39;*&#39;</span>
<span class="k">if</span> <span class="n">tag</span> <span class="o">==</span> <span class="n">NOT</span><span class="p">:</span>
<span class="n">body</span> <span class="o">=</span> <span class="n">stringy</span><span class="p">(</span><span class="n">re</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">body</span><span class="p">:</span> <span class="k">return</span> <span class="n">body</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">body</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span> <span class="k">return</span> <span class="s1">&#39;(&#39;</span> <span class="o">+</span> <span class="n">body</span> <span class="o">+</span> <span class="s2">&quot;)&#39;&quot;</span>
<span class="k">return</span> <span class="n">body</span> <span class="o">+</span> <span class="s2">&quot;&#39;&quot;</span>
<span class="n">r</span><span class="p">,</span> <span class="n">s</span> <span class="o">=</span> <span class="n">stringy</span><span class="p">(</span><span class="n">re</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">stringy</span><span class="p">(</span><span class="n">re</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
<span class="k">if</span> <span class="n">tag</span> <span class="o">==</span> <span class="n">CONS</span><span class="p">:</span> <span class="k">return</span> <span class="n">r</span> <span class="o">+</span> <span class="n">s</span>
<span class="k">if</span> <span class="n">tag</span> <span class="o">==</span> <span class="n">OR</span><span class="p">:</span> <span class="k">return</span> <span class="s1">&#39;</span><span class="si">%s</span><span class="s1"> | </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
<span class="k">if</span> <span class="n">tag</span> <span class="o">==</span> <span class="n">AND</span><span class="p">:</span> <span class="k">return</span> <span class="s1">&#39;(</span><span class="si">%s</span><span class="s1">) &amp; (</span><span class="si">%s</span><span class="s1">)&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">r</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
<span class="k">raise</span> <span class="ne">ValueError</span>
</pre></div>
</div>
</div>
<div class="section" id="i">
<h3><code class="docutils literal notranslate"><span class="pre">I</span></code><a class="headerlink" href="#i" title="Permalink to this headline"></a></h3>
<p>Match anything. Often spelled “.”</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">I</span> <span class="o">=</span> <span class="p">(</span><span class="mi">0</span><span class="o">|</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">I</span> <span class="o">=</span> <span class="p">(</span><span class="n">KSTAR</span><span class="p">,</span> <span class="p">(</span><span class="n">OR</span><span class="p">,</span> <span class="n">O</span><span class="p">,</span> <span class="n">l</span><span class="p">))</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">stringy</span><span class="p">(</span><span class="n">I</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">.</span>
</pre></div>
</div>
</div>
<div class="section" id="id1">
<h3><code class="docutils literal notranslate"><span class="pre">(.111.)</span> <span class="pre">&amp;</span> <span class="pre">(.01</span> <span class="pre">+</span> <span class="pre">11*)'</span></code><a class="headerlink" href="#id1" title="Permalink to this headline"></a></h3>
<p>The example expression from Brzozowski:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">.</span><span class="mf">111.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">(</span><span class="o">.</span><span class="mi">01</span> <span class="o">+</span> <span class="mi">11</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;</span>
<span class="n">a</span> <span class="o">&amp;</span> <span class="p">(</span><span class="n">b</span> <span class="o">+</span> <span class="n">c</span><span class="p">)</span><span class="s1">&#39;</span>
</pre></div>
</div>
<p>Note that it contains one of everything.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="n">I</span><span class="p">))))</span>
<span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">O</span><span class="p">,</span> <span class="n">l</span><span class="p">))</span>
<span class="n">c</span> <span class="o">=</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="p">(</span><span class="n">KSTAR</span><span class="p">,</span> <span class="n">l</span><span class="p">))</span>
<span class="n">it</span> <span class="o">=</span> <span class="p">(</span><span class="n">AND</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">NOT</span><span class="p">,</span> <span class="p">(</span><span class="n">OR</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">)))</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">stringy</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">.</span><span class="mf">111.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">11</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;)</span>
</pre></div>
</div>
</div>
<div class="section" id="nully">
<h3><code class="docutils literal notranslate"><span class="pre">nully()</span></code><a class="headerlink" href="#nully" title="Permalink to this headline"></a></h3>
<p>Lets get that auxiliary predicate function <code class="docutils literal notranslate"><span class="pre">δ</span></code> out of the way.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">nully</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> δ - Return λ if λ ⊆ R otherwise ϕ.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="c1"># δ(a) → ϕ</span>
<span class="c1"># δ(ϕ) → ϕ</span>
<span class="k">if</span> <span class="n">R</span> <span class="ow">in</span> <span class="n">syms</span> <span class="ow">or</span> <span class="n">R</span> <span class="o">==</span> <span class="n">phi</span><span class="p">:</span>
<span class="k">return</span> <span class="n">phi</span>
<span class="c1"># δ(λ) → λ</span>
<span class="k">if</span> <span class="n">R</span> <span class="o">==</span> <span class="n">y</span><span class="p">:</span>
<span class="k">return</span> <span class="n">y</span>
<span class="n">tag</span> <span class="o">=</span> <span class="n">R</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="c1"># δ(R*) → λ</span>
<span class="k">if</span> <span class="n">tag</span> <span class="o">==</span> <span class="n">KSTAR</span><span class="p">:</span>
<span class="k">return</span> <span class="n">y</span>
<span class="c1"># δ(¬R) δ(R)≟ϕ → λ</span>
<span class="c1"># δ(¬R) δ(R)≟λ → ϕ</span>
<span class="k">if</span> <span class="n">tag</span> <span class="o">==</span> <span class="n">NOT</span><span class="p">:</span>
<span class="k">return</span> <span class="n">phi</span> <span class="k">if</span> <span class="n">nully</span><span class="p">(</span><span class="n">R</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="k">else</span> <span class="n">y</span>
<span class="c1"># δ(R∘S) → δ(R) ∧ δ(S)</span>
<span class="c1"># δ(R ∧ S) → δ(R) ∧ δ(S)</span>
<span class="c1"># δ(R S) → δ(R) δ(S)</span>
<span class="n">r</span><span class="p">,</span> <span class="n">s</span> <span class="o">=</span> <span class="n">nully</span><span class="p">(</span><span class="n">R</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">nully</span><span class="p">(</span><span class="n">R</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
<span class="k">return</span> <span class="n">r</span> <span class="o">&amp;</span> <span class="n">s</span> <span class="k">if</span> <span class="n">tag</span> <span class="ow">in</span> <span class="p">{</span><span class="n">AND</span><span class="p">,</span> <span class="n">CONS</span><span class="p">}</span> <span class="k">else</span> <span class="n">r</span> <span class="o">|</span> <span class="n">s</span>
</pre></div>
</div>
</div>
<div class="section" id="no-compaction">
<h3>No “Compaction”<a class="headerlink" href="#no-compaction" title="Permalink to this headline"></a></h3>
<p>This is the straightforward version with no “compaction”. It works fine,
but does waaaay too much work because the expressions grow each
derivation.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">D</span><span class="p">(</span><span class="n">symbol</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">derv</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
<span class="c1"># ∂a(a) → λ</span>
<span class="k">if</span> <span class="n">R</span> <span class="o">==</span> <span class="p">{</span><span class="n">symbol</span><span class="p">}:</span>
<span class="k">return</span> <span class="n">y</span>
<span class="c1"># ∂a(λ) → ϕ</span>
<span class="c1"># ∂a(ϕ) → ϕ</span>
<span class="c1"># ∂a(¬a) → ϕ</span>
<span class="k">if</span> <span class="n">R</span> <span class="o">==</span> <span class="n">y</span> <span class="ow">or</span> <span class="n">R</span> <span class="o">==</span> <span class="n">phi</span> <span class="ow">or</span> <span class="n">R</span> <span class="ow">in</span> <span class="n">syms</span><span class="p">:</span>
<span class="k">return</span> <span class="n">phi</span>
<span class="n">tag</span> <span class="o">=</span> <span class="n">R</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="c1"># ∂a(R*) → ∂a(R)∘R*</span>
<span class="k">if</span> <span class="n">tag</span> <span class="o">==</span> <span class="n">KSTAR</span><span class="p">:</span>
<span class="k">return</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">derv</span><span class="p">(</span><span class="n">R</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">R</span><span class="p">)</span>
<span class="c1"># ∂a(¬R) → ¬∂a(R)</span>
<span class="k">if</span> <span class="n">tag</span> <span class="o">==</span> <span class="n">NOT</span><span class="p">:</span>
<span class="k">return</span> <span class="p">(</span><span class="n">NOT</span><span class="p">,</span> <span class="n">derv</span><span class="p">(</span><span class="n">R</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span>
<span class="n">r</span><span class="p">,</span> <span class="n">s</span> <span class="o">=</span> <span class="n">R</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="c1"># ∂a(R∘S) → ∂a(R)∘S δ(R)∘∂a(S)</span>
<span class="k">if</span> <span class="n">tag</span> <span class="o">==</span> <span class="n">CONS</span><span class="p">:</span>
<span class="n">A</span> <span class="o">=</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">derv</span><span class="p">(</span><span class="n">r</span><span class="p">),</span> <span class="n">s</span><span class="p">)</span> <span class="c1"># A = ∂a(R)∘S</span>
<span class="c1"># A δ(R) ∘ ∂a(S)</span>
<span class="c1"># A λ ∘ ∂a(S) → A ∂a(S)</span>
<span class="c1"># A ϕ ∘ ∂a(S) → A ϕ → A</span>
<span class="k">return</span> <span class="p">(</span><span class="n">OR</span><span class="p">,</span> <span class="n">A</span><span class="p">,</span> <span class="n">derv</span><span class="p">(</span><span class="n">s</span><span class="p">))</span> <span class="k">if</span> <span class="n">nully</span><span class="p">(</span><span class="n">r</span><span class="p">)</span> <span class="k">else</span> <span class="n">A</span>
<span class="c1"># ∂a(R ∧ S) → ∂a(R) ∧ ∂a(S)</span>
<span class="c1"># ∂a(R S) → ∂a(R) ∂a(S)</span>
<span class="k">return</span> <span class="p">(</span><span class="n">tag</span><span class="p">,</span> <span class="n">derv</span><span class="p">(</span><span class="n">r</span><span class="p">),</span> <span class="n">derv</span><span class="p">(</span><span class="n">s</span><span class="p">))</span>
<span class="k">return</span> <span class="n">derv</span>
</pre></div>
</div>
</div>
<div class="section" id="compaction-rules">
<h3>Compaction Rules<a class="headerlink" href="#compaction-rules" title="Permalink to this headline"></a></h3>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">_compaction_rule</span><span class="p">(</span><span class="n">relation</span><span class="p">,</span> <span class="n">one</span><span class="p">,</span> <span class="n">zero</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span>
<span class="n">b</span> <span class="k">if</span> <span class="n">a</span> <span class="o">==</span> <span class="n">one</span> <span class="k">else</span> <span class="c1"># R*1 = 1*R = R</span>
<span class="n">a</span> <span class="k">if</span> <span class="n">b</span> <span class="o">==</span> <span class="n">one</span> <span class="k">else</span>
<span class="n">zero</span> <span class="k">if</span> <span class="n">a</span> <span class="o">==</span> <span class="n">zero</span> <span class="ow">or</span> <span class="n">b</span> <span class="o">==</span> <span class="n">zero</span> <span class="k">else</span> <span class="c1"># R*0 = 0*R = 0</span>
<span class="p">(</span><span class="n">relation</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
<span class="p">)</span>
</pre></div>
</div>
<p>An elegant symmetry.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># R ∧ I = I ∧ R = R</span>
<span class="c1"># R ∧ ϕ = ϕ ∧ R = ϕ</span>
<span class="n">_and</span> <span class="o">=</span> <span class="n">curry</span><span class="p">(</span><span class="n">_compaction_rule</span><span class="p">,</span> <span class="n">AND</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="n">phi</span><span class="p">)</span>
<span class="c1"># R ϕ = ϕ R = R</span>
<span class="c1"># R I = I R = I</span>
<span class="n">_or</span> <span class="o">=</span> <span class="n">curry</span><span class="p">(</span><span class="n">_compaction_rule</span><span class="p">,</span> <span class="n">OR</span><span class="p">,</span> <span class="n">phi</span><span class="p">,</span> <span class="n">I</span><span class="p">)</span>
<span class="c1"># R∘λ = λ∘R = R</span>
<span class="c1"># R∘ϕ = ϕ∘R = ϕ</span>
<span class="n">_cons</span> <span class="o">=</span> <span class="n">curry</span><span class="p">(</span><span class="n">_compaction_rule</span><span class="p">,</span> <span class="n">CONS</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">phi</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="memoizing">
<h3>Memoizing<a class="headerlink" href="#memoizing" title="Permalink to this headline"></a></h3>
<p>We can save re-processing by remembering results we have already
computed. RE datastructures are immutable and the <code class="docutils literal notranslate"><span class="pre">derv()</span></code> functions
are <em>pure</em> so this is fine.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Memo</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">f</span> <span class="o">=</span> <span class="n">f</span>
<span class="bp">self</span><span class="o">.</span><span class="n">calls</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">hits</span> <span class="o">=</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mem</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">calls</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mem</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">hits</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mem</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">f</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<span class="k">return</span> <span class="n">result</span>
</pre></div>
</div>
</div>
<div class="section" id="with-compaction">
<h3>With “Compaction”<a class="headerlink" href="#with-compaction" title="Permalink to this headline"></a></h3>
<p>This version uses the rules above to perform compaction. It keeps the
expressions from growing too large.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">D_compaction</span><span class="p">(</span><span class="n">symbol</span><span class="p">):</span>
<span class="nd">@Memo</span>
<span class="k">def</span> <span class="nf">derv</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
<span class="c1"># ∂a(a) → λ</span>
<span class="k">if</span> <span class="n">R</span> <span class="o">==</span> <span class="p">{</span><span class="n">symbol</span><span class="p">}:</span>
<span class="k">return</span> <span class="n">y</span>
<span class="c1"># ∂a(λ) → ϕ</span>
<span class="c1"># ∂a(ϕ) → ϕ</span>
<span class="c1"># ∂a(¬a) → ϕ</span>
<span class="k">if</span> <span class="n">R</span> <span class="o">==</span> <span class="n">y</span> <span class="ow">or</span> <span class="n">R</span> <span class="o">==</span> <span class="n">phi</span> <span class="ow">or</span> <span class="n">R</span> <span class="ow">in</span> <span class="n">syms</span><span class="p">:</span>
<span class="k">return</span> <span class="n">phi</span>
<span class="n">tag</span> <span class="o">=</span> <span class="n">R</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="c1"># ∂a(R*) → ∂a(R)∘R*</span>
<span class="k">if</span> <span class="n">tag</span> <span class="o">==</span> <span class="n">KSTAR</span><span class="p">:</span>
<span class="k">return</span> <span class="n">_cons</span><span class="p">(</span><span class="n">derv</span><span class="p">(</span><span class="n">R</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">R</span><span class="p">)</span>
<span class="c1"># ∂a(¬R) → ¬∂a(R)</span>
<span class="k">if</span> <span class="n">tag</span> <span class="o">==</span> <span class="n">NOT</span><span class="p">:</span>
<span class="k">return</span> <span class="p">(</span><span class="n">NOT</span><span class="p">,</span> <span class="n">derv</span><span class="p">(</span><span class="n">R</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span>
<span class="n">r</span><span class="p">,</span> <span class="n">s</span> <span class="o">=</span> <span class="n">R</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="c1"># ∂a(R∘S) → ∂a(R)∘S δ(R)∘∂a(S)</span>
<span class="k">if</span> <span class="n">tag</span> <span class="o">==</span> <span class="n">CONS</span><span class="p">:</span>
<span class="n">A</span> <span class="o">=</span> <span class="n">_cons</span><span class="p">(</span><span class="n">derv</span><span class="p">(</span><span class="n">r</span><span class="p">),</span> <span class="n">s</span><span class="p">)</span> <span class="c1"># A = ∂a(r)∘s</span>
<span class="c1"># A δ(R) ∘ ∂a(S)</span>
<span class="c1"># A λ ∘ ∂a(S) → A ∂a(S)</span>
<span class="c1"># A ϕ ∘ ∂a(S) → A ϕ → A</span>
<span class="k">return</span> <span class="n">_or</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="n">derv</span><span class="p">(</span><span class="n">s</span><span class="p">))</span> <span class="k">if</span> <span class="n">nully</span><span class="p">(</span><span class="n">r</span><span class="p">)</span> <span class="k">else</span> <span class="n">A</span>
<span class="c1"># ∂a(R ∧ S) → ∂a(R) ∧ ∂a(S)</span>
<span class="c1"># ∂a(R S) → ∂a(R) ∂a(S)</span>
<span class="n">dr</span><span class="p">,</span> <span class="n">ds</span> <span class="o">=</span> <span class="n">derv</span><span class="p">(</span><span class="n">r</span><span class="p">),</span> <span class="n">derv</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="k">return</span> <span class="n">_and</span><span class="p">(</span><span class="n">dr</span><span class="p">,</span> <span class="n">ds</span><span class="p">)</span> <span class="k">if</span> <span class="n">tag</span> <span class="o">==</span> <span class="n">AND</span> <span class="k">else</span> <span class="n">_or</span><span class="p">(</span><span class="n">dr</span><span class="p">,</span> <span class="n">ds</span><span class="p">)</span>
<span class="k">return</span> <span class="n">derv</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="let-s-try-it-out">
<h2>Lets try it out…<a class="headerlink" href="#let-s-try-it-out" title="Permalink to this headline"></a></h2>
<p>(FIXME: redo.)</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">o</span><span class="p">,</span> <span class="n">z</span> <span class="o">=</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">&#39;0&#39;</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">&#39;1&#39;</span><span class="p">)</span>
<span class="n">REs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="n">N</span> <span class="o">=</span> <span class="mi">5</span>
<span class="n">names</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">product</span><span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="n">N</span> <span class="o">*</span> <span class="p">[(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)])))</span>
<span class="n">dervs</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">product</span><span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="n">N</span> <span class="o">*</span> <span class="p">[(</span><span class="n">o</span><span class="p">,</span> <span class="n">z</span><span class="p">)])))</span>
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">ds</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">names</span><span class="p">,</span> <span class="n">dervs</span><span class="p">):</span>
<span class="n">R</span> <span class="o">=</span> <span class="n">it</span>
<span class="n">ds</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">ds</span><span class="p">)</span>
<span class="k">while</span> <span class="n">ds</span><span class="p">:</span>
<span class="n">R</span> <span class="o">=</span> <span class="n">ds</span><span class="o">.</span><span class="n">pop</span><span class="p">()(</span><span class="n">R</span><span class="p">)</span>
<span class="k">if</span> <span class="n">R</span> <span class="o">==</span> <span class="n">phi</span> <span class="ow">or</span> <span class="n">R</span> <span class="o">==</span> <span class="n">I</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">REs</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">R</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">stringy</span><span class="p">(</span><span class="n">it</span><span class="p">)</span> <span class="p">;</span> <span class="nb">print</span>
<span class="nb">print</span> <span class="n">o</span><span class="o">.</span><span class="n">hits</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="n">o</span><span class="o">.</span><span class="n">calls</span>
<span class="nb">print</span> <span class="n">z</span><span class="o">.</span><span class="n">hits</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="n">z</span><span class="o">.</span><span class="n">calls</span>
<span class="nb">print</span>
<span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">stringy</span><span class="p">,</span> <span class="n">REs</span><span class="p">),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">n</span><span class="p">),</span> <span class="n">n</span><span class="p">)):</span>
<span class="nb">print</span> <span class="n">s</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">.</span><span class="mf">111.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">11</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;)</span>
<span class="mi">92</span> <span class="o">/</span> <span class="mi">122</span>
<span class="mi">92</span> <span class="o">/</span> <span class="mi">122</span>
<span class="p">(</span><span class="o">.</span><span class="mi">01</span><span class="p">)</span><span class="s1">&#39;</span>
<span class="p">(</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span><span class="p">)</span><span class="s1">&#39;</span>
<span class="p">(</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="o">^</span><span class="p">)</span><span class="s1">&#39;</span>
<span class="p">(</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;</span>
<span class="p">(</span><span class="o">.</span><span class="mf">111.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span><span class="p">)</span><span class="s1">&#39;)</span>
<span class="p">(</span><span class="o">.</span><span class="mf">111.</span> <span class="o">|</span> <span class="mf">11.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="o">^</span><span class="p">)</span><span class="s1">&#39;)</span>
<span class="p">(</span><span class="o">.</span><span class="mf">111.</span> <span class="o">|</span> <span class="mf">11.</span> <span class="o">|</span> <span class="mf">1.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span><span class="p">)</span><span class="s1">&#39;)</span>
<span class="p">(</span><span class="o">.</span><span class="mf">111.</span> <span class="o">|</span> <span class="mf">11.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;)</span>
<span class="p">(</span><span class="o">.</span><span class="mf">111.</span> <span class="o">|</span> <span class="mf">11.</span> <span class="o">|</span> <span class="mf">1.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;)</span>
</pre></div>
</div>
<p>Should match:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">.</span><span class="mf">111.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">11</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;)</span>
<span class="mi">92</span> <span class="o">/</span> <span class="mi">122</span>
<span class="mi">92</span> <span class="o">/</span> <span class="mi">122</span>
<span class="p">(</span><span class="o">.</span><span class="mi">01</span> <span class="p">)</span><span class="s1">&#39;</span>
<span class="p">(</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span> <span class="p">)</span><span class="s1">&#39;</span>
<span class="p">(</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="o">^</span> <span class="p">)</span><span class="s1">&#39;</span>
<span class="p">(</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;</span>
<span class="p">(</span><span class="o">.</span><span class="mf">111.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span> <span class="p">)</span><span class="s1">&#39;)</span>
<span class="p">(</span><span class="o">.</span><span class="mf">111.</span> <span class="o">|</span> <span class="mf">11.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="o">^</span> <span class="p">)</span><span class="s1">&#39;)</span>
<span class="p">(</span><span class="o">.</span><span class="mf">111.</span> <span class="o">|</span> <span class="mf">11.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;)</span>
<span class="p">(</span><span class="o">.</span><span class="mf">111.</span> <span class="o">|</span> <span class="mf">11.</span> <span class="o">|</span> <span class="mf">1.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="p">)</span><span class="s1">&#39;)</span>
<span class="p">(</span><span class="o">.</span><span class="mf">111.</span> <span class="o">|</span> <span class="mf">11.</span> <span class="o">|</span> <span class="mf">1.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;)</span>
</pre></div>
</div>
</div>
<div class="section" id="larger-alphabets">
<h2>Larger Alphabets<a class="headerlink" href="#larger-alphabets" title="Permalink to this headline"></a></h2>
<p>We could parse larger alphabets by defining patterns for e.g. each byte
of the ASCII code. Or we can generalize this code. If you study the code
above youll see that we never use the “set-ness” of the symbols <code class="docutils literal notranslate"><span class="pre">O</span></code>
and <code class="docutils literal notranslate"><span class="pre">l</span></code>. The only time Python set operators (<code class="docutils literal notranslate"><span class="pre">&amp;</span></code> and <code class="docutils literal notranslate"><span class="pre">|</span></code>) appear
is in the <code class="docutils literal notranslate"><span class="pre">nully()</span></code> function, and there they operate on (recursively
computed) outputs of that function, never <code class="docutils literal notranslate"><span class="pre">O</span></code> and <code class="docutils literal notranslate"><span class="pre">l</span></code>.</p>
<p>What if we try:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>(OR, O, l)
∂1((OR, O, l))
∂a(R S) → ∂a(R) ∂a(S)
∂1(O) ∂1(l)
∂a(¬a) → ϕ
ϕ ∂1(l)
∂a(a) → λ
ϕ λ
ϕ R = R
λ
</pre></div>
</div>
<p>And compare it to:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>{&#39;0&#39;, &#39;1&#39;)
∂1({&#39;0&#39;, &#39;1&#39;))
∂a(R S) → ∂a(R) ∂a(S)
∂1({&#39;0&#39;)) ∂1({&#39;1&#39;))
∂a(¬a) → ϕ
ϕ ∂1({&#39;1&#39;))
∂a(a) → λ
ϕ λ
ϕ R = R
λ
</pre></div>
</div>
<p>This suggests that we should be able to alter the functions above to
detect sets and deal with them appropriately. Exercise for the Reader
for now.</p>
</div>
<div class="section" id="state-machine">
<h2>State Machine<a class="headerlink" href="#state-machine" title="Permalink to this headline"></a></h2>
<p>We can drive the regular expressions to flesh out the underlying state
machine transition table.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">.</span><span class="mf">111.</span> <span class="o">&amp;</span> <span class="p">(</span><span class="o">.</span><span class="mi">01</span> <span class="o">+</span> <span class="mi">11</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;</span>
</pre></div>
</div>
<p>Says, “Three or more 1s and not ending in 01 nor composed of all 1s.”</p>
<div class="figure">
<img alt="State Machine Diagram" src="../_images/omg.svg" /></div>
<p>Start at <code class="docutils literal notranslate"><span class="pre">a</span></code> and follow the transition arrows according to their
labels. Accepting states have a double outline. (Graphic generated with
<a class="reference external" href="http://www.graphviz.org/">Dot from Graphviz</a>.) Youll see that only
paths that lead to one of the accepting states will match the regular
expression. All other paths will terminate at one of the non-accepting
states.</p>
<p>Theres a happy path to <code class="docutils literal notranslate"><span class="pre">g</span></code> along 111:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>a→c→e→g
</pre></div>
</div>
<p>After you reach <code class="docutils literal notranslate"><span class="pre">g</span></code> youre stuck there eating 1s until you see a 0,
which takes you to the <code class="docutils literal notranslate"><span class="pre">i→j→i|i→j→h→i</span></code> “trap”. You cant reach any
other states from those two loops.</p>
<p>If you see a 0 before you see 111 you will reach <code class="docutils literal notranslate"><span class="pre">b</span></code>, which forms
another “trap” with <code class="docutils literal notranslate"><span class="pre">d</span></code> and <code class="docutils literal notranslate"><span class="pre">f</span></code>. The only way out is another happy
path along 111 to <code class="docutils literal notranslate"><span class="pre">h</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>b→d→f→h
</pre></div>
</div>
<p>Once you have reached <code class="docutils literal notranslate"><span class="pre">h</span></code> you can see as many 1s or as many 0 in a
row and still be either still at <code class="docutils literal notranslate"><span class="pre">h</span></code> (for 1s) or move to <code class="docutils literal notranslate"><span class="pre">i</span></code> (for
0s). If you find yourself at <code class="docutils literal notranslate"><span class="pre">i</span></code> you can see as many 0s, or
repetitions of 10, as there are, but if you see just a 1 you move to
<code class="docutils literal notranslate"><span class="pre">j</span></code>.</p>
<div class="section" id="re-to-fsm">
<h3>RE to FSM<a class="headerlink" href="#re-to-fsm" title="Permalink to this headline"></a></h3>
<p>So how do we get the state machine from the regular expression?</p>
<p>It turns out that each RE is effectively a state, and each arrow points
to the derivative RE in respect to the arrows symbol.</p>
<p>If we label the initial RE <code class="docutils literal notranslate"><span class="pre">a</span></code>, we can say:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>a --0--&gt; ∂0(a)
a --1--&gt; ∂1(a)
</pre></div>
</div>
<p>And so on, each new unique RE is a new state in the FSM table.</p>
<p>Here are the derived REs at each state:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="o">.</span><span class="mf">111.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">11</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;)</span>
<span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="o">.</span><span class="mf">111.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span><span class="p">)</span><span class="s1">&#39;)</span>
<span class="n">c</span> <span class="o">=</span> <span class="p">(</span><span class="o">.</span><span class="mf">111.</span> <span class="o">|</span> <span class="mf">11.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;)</span>
<span class="n">d</span> <span class="o">=</span> <span class="p">(</span><span class="o">.</span><span class="mf">111.</span> <span class="o">|</span> <span class="mf">11.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="o">^</span><span class="p">)</span><span class="s1">&#39;)</span>
<span class="n">e</span> <span class="o">=</span> <span class="p">(</span><span class="o">.</span><span class="mf">111.</span> <span class="o">|</span> <span class="mf">11.</span> <span class="o">|</span> <span class="mf">1.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;)</span>
<span class="n">f</span> <span class="o">=</span> <span class="p">(</span><span class="o">.</span><span class="mf">111.</span> <span class="o">|</span> <span class="mf">11.</span> <span class="o">|</span> <span class="mf">1.</span><span class="p">)</span> <span class="o">&amp;</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span><span class="p">)</span><span class="s1">&#39;)</span>
<span class="n">g</span> <span class="o">=</span> <span class="p">(</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span><span class="o">*</span><span class="p">)</span><span class="s1">&#39;</span>
<span class="n">h</span> <span class="o">=</span> <span class="p">(</span><span class="o">.</span><span class="mi">01</span><span class="p">)</span><span class="s1">&#39;</span>
<span class="n">i</span> <span class="o">=</span> <span class="p">(</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">1</span><span class="p">)</span><span class="s1">&#39;</span>
<span class="n">j</span> <span class="o">=</span> <span class="p">(</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="o">^</span><span class="p">)</span><span class="s1">&#39;</span>
</pre></div>
</div>
<p>You can see the one-way nature of the <code class="docutils literal notranslate"><span class="pre">g</span></code> state and the <code class="docutils literal notranslate"><span class="pre">hij</span></code> “trap”
in the way that the <code class="docutils literal notranslate"><span class="pre">.111.</span></code> on the left-hand side of the <code class="docutils literal notranslate"><span class="pre">&amp;</span></code>
disappears once it has been matched.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="k">import</span> <span class="n">defaultdict</span>
<span class="kn">from</span> <span class="nn">pprint</span> <span class="k">import</span> <span class="n">pprint</span>
<span class="kn">from</span> <span class="nn">string</span> <span class="k">import</span> <span class="n">ascii_lowercase</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">d0</span><span class="p">,</span> <span class="n">d1</span> <span class="o">=</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">&#39;0&#39;</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">&#39;1&#39;</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="explore">
<h3><code class="docutils literal notranslate"><span class="pre">explore()</span></code><a class="headerlink" href="#explore" title="Permalink to this headline"></a></h3>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">explore</span><span class="p">(</span><span class="n">re</span><span class="p">):</span>
<span class="c1"># Don&#39;t have more than 26 states...</span>
<span class="n">names</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">iter</span><span class="p">(</span><span class="n">ascii_lowercase</span><span class="p">)</span><span class="o">.</span><span class="n">next</span><span class="p">)</span>
<span class="n">table</span><span class="p">,</span> <span class="n">accepting</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(),</span> <span class="nb">set</span><span class="p">()</span>
<span class="n">to_check</span> <span class="o">=</span> <span class="p">{</span><span class="n">re</span><span class="p">}</span>
<span class="k">while</span> <span class="n">to_check</span><span class="p">:</span>
<span class="n">re</span> <span class="o">=</span> <span class="n">to_check</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="n">state_name</span> <span class="o">=</span> <span class="n">names</span><span class="p">[</span><span class="n">re</span><span class="p">]</span>
<span class="k">if</span> <span class="p">(</span><span class="n">state_name</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">in</span> <span class="n">table</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">nully</span><span class="p">(</span><span class="n">re</span><span class="p">):</span>
<span class="n">accepting</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">state_name</span><span class="p">)</span>
<span class="n">o</span><span class="p">,</span> <span class="n">i</span> <span class="o">=</span> <span class="n">d0</span><span class="p">(</span><span class="n">re</span><span class="p">),</span> <span class="n">d1</span><span class="p">(</span><span class="n">re</span><span class="p">)</span>
<span class="n">table</span><span class="p">[</span><span class="n">state_name</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">names</span><span class="p">[</span><span class="n">o</span><span class="p">]</span> <span class="p">;</span> <span class="n">to_check</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">o</span><span class="p">)</span>
<span class="n">table</span><span class="p">[</span><span class="n">state_name</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">names</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="p">;</span> <span class="n">to_check</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="k">return</span> <span class="n">table</span><span class="p">,</span> <span class="n">accepting</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">table</span><span class="p">,</span> <span class="n">accepting</span> <span class="o">=</span> <span class="n">explore</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
<span class="n">table</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{(</span><span class="s1">&#39;a&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span> <span class="s1">&#39;b&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;a&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span> <span class="s1">&#39;c&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;b&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span> <span class="s1">&#39;b&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;b&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span> <span class="s1">&#39;d&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;c&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span> <span class="s1">&#39;b&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;c&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span> <span class="s1">&#39;e&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;d&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span> <span class="s1">&#39;b&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;d&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span> <span class="s1">&#39;f&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;e&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span> <span class="s1">&#39;b&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;e&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span> <span class="s1">&#39;g&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;f&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span> <span class="s1">&#39;b&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;f&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span> <span class="s1">&#39;h&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;g&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span> <span class="s1">&#39;i&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;g&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span> <span class="s1">&#39;g&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;h&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span> <span class="s1">&#39;i&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;h&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span> <span class="s1">&#39;h&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;i&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span> <span class="s1">&#39;i&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;i&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span> <span class="s1">&#39;j&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;j&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span> <span class="s1">&#39;i&#39;</span><span class="p">,</span>
<span class="p">(</span><span class="s1">&#39;j&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span> <span class="s1">&#39;h&#39;</span><span class="p">}</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">accepting</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="s1">&#39;h&#39;</span><span class="p">,</span> <span class="s1">&#39;i&#39;</span><span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="generate-diagram">
<h3>Generate Diagram<a class="headerlink" href="#generate-diagram" title="Permalink to this headline"></a></h3>
<p>Once we have the FSM table and the set of accepting states we can
generate the diagram above.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">_template</span> <span class="o">=</span> <span class="s1">&#39;&#39;&#39;</span><span class="se">\</span>
<span class="s1">digraph finite_state_machine {</span>
<span class="s1"> rankdir=LR;</span>
<span class="s1"> size=&quot;8,5&quot;</span>
<span class="s1"> node [shape = doublecircle]; </span><span class="si">%s</span><span class="s1">;</span>
<span class="s1"> node [shape = circle];</span>
<span class="si">%s</span><span class="s1"></span>
<span class="s1">}</span>
<span class="s1">&#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">link</span><span class="p">(</span><span class="n">fr</span><span class="p">,</span> <span class="n">nm</span><span class="p">,</span> <span class="n">label</span><span class="p">):</span>
<span class="k">return</span> <span class="s1">&#39; </span><span class="si">%s</span><span class="s1"> -&gt; </span><span class="si">%s</span><span class="s1"> [ label = &quot;</span><span class="si">%s</span><span class="s1">&quot; ];&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">fr</span><span class="p">,</span> <span class="n">nm</span><span class="p">,</span> <span class="n">label</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">make_graph</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">accepting</span><span class="p">):</span>
<span class="k">return</span> <span class="n">_template</span> <span class="o">%</span> <span class="p">(</span>
<span class="s1">&#39; &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">accepting</span><span class="p">),</span>
<span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
<span class="n">link</span><span class="p">(</span><span class="n">from_</span><span class="p">,</span> <span class="n">to</span><span class="p">,</span> <span class="n">char</span><span class="p">)</span>
<span class="k">for</span> <span class="p">(</span><span class="n">from_</span><span class="p">,</span> <span class="n">char</span><span class="p">),</span> <span class="p">(</span><span class="n">to</span><span class="p">)</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">table</span><span class="o">.</span><span class="n">iteritems</span><span class="p">())</span>
<span class="p">)</span>
<span class="p">)</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">make_graph</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">accepting</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">digraph</span> <span class="n">finite_state_machine</span> <span class="p">{</span>
<span class="n">rankdir</span><span class="o">=</span><span class="n">LR</span><span class="p">;</span>
<span class="n">size</span><span class="o">=</span><span class="s2">&quot;8,5&quot;</span>
<span class="n">node</span> <span class="p">[</span><span class="n">shape</span> <span class="o">=</span> <span class="n">doublecircle</span><span class="p">];</span> <span class="n">i</span> <span class="n">h</span><span class="p">;</span>
<span class="n">node</span> <span class="p">[</span><span class="n">shape</span> <span class="o">=</span> <span class="n">circle</span><span class="p">];</span>
<span class="n">a</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;0&quot;</span> <span class="p">];</span>
<span class="n">a</span> <span class="o">-&gt;</span> <span class="n">c</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;1&quot;</span> <span class="p">];</span>
<span class="n">b</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;0&quot;</span> <span class="p">];</span>
<span class="n">b</span> <span class="o">-&gt;</span> <span class="n">d</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;1&quot;</span> <span class="p">];</span>
<span class="n">c</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;0&quot;</span> <span class="p">];</span>
<span class="n">c</span> <span class="o">-&gt;</span> <span class="n">e</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;1&quot;</span> <span class="p">];</span>
<span class="n">d</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;0&quot;</span> <span class="p">];</span>
<span class="n">d</span> <span class="o">-&gt;</span> <span class="n">f</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;1&quot;</span> <span class="p">];</span>
<span class="n">e</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;0&quot;</span> <span class="p">];</span>
<span class="n">e</span> <span class="o">-&gt;</span> <span class="n">g</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;1&quot;</span> <span class="p">];</span>
<span class="n">f</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;0&quot;</span> <span class="p">];</span>
<span class="n">f</span> <span class="o">-&gt;</span> <span class="n">h</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;1&quot;</span> <span class="p">];</span>
<span class="n">g</span> <span class="o">-&gt;</span> <span class="n">i</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;0&quot;</span> <span class="p">];</span>
<span class="n">g</span> <span class="o">-&gt;</span> <span class="n">g</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;1&quot;</span> <span class="p">];</span>
<span class="n">h</span> <span class="o">-&gt;</span> <span class="n">i</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;0&quot;</span> <span class="p">];</span>
<span class="n">h</span> <span class="o">-&gt;</span> <span class="n">h</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;1&quot;</span> <span class="p">];</span>
<span class="n">i</span> <span class="o">-&gt;</span> <span class="n">i</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;0&quot;</span> <span class="p">];</span>
<span class="n">i</span> <span class="o">-&gt;</span> <span class="n">j</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;1&quot;</span> <span class="p">];</span>
<span class="n">j</span> <span class="o">-&gt;</span> <span class="n">i</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;0&quot;</span> <span class="p">];</span>
<span class="n">j</span> <span class="o">-&gt;</span> <span class="n">h</span> <span class="p">[</span> <span class="n">label</span> <span class="o">=</span> <span class="s2">&quot;1&quot;</span> <span class="p">];</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="drive-a-fsm">
<h3>Drive a FSM<a class="headerlink" href="#drive-a-fsm" title="Permalink to this headline"></a></h3>
<p>There are <em>lots</em> of FSM libraries already. Once you have the state
transition table they should all be straightforward to use. State
Machine code is very simple. Just for fun, here is an implementation in
Python that imitates what “compiled” FSM code might look like in an
“unrolled” form. Most FSM code uses a little driver loop and a table
datastructure, the code below instead acts like JMP instructions
(“jump”, or GOTO in higher-level-but-still-low-level languages) to
hard-code the information in the table into a little patch of branches.</p>
<div class="section" id="trampoline-function">
<h4>Trampoline Function<a class="headerlink" href="#trampoline-function" title="Permalink to this headline"></a></h4>
<p>Python has no GOTO statement but we can fake it with a “trampoline”
function.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">trampoline</span><span class="p">(</span><span class="n">input_</span><span class="p">,</span> <span class="n">jump_from</span><span class="p">,</span> <span class="n">accepting</span><span class="p">):</span>
<span class="n">I</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">input_</span><span class="p">)</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">bounce_to</span> <span class="o">=</span> <span class="n">jump_from</span><span class="p">(</span><span class="n">I</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">StopIteration</span><span class="p">:</span>
<span class="k">return</span> <span class="n">jump_from</span> <span class="ow">in</span> <span class="n">accepting</span>
<span class="n">jump_from</span> <span class="o">=</span> <span class="n">bounce_to</span>
</pre></div>
</div>
</div>
<div class="section" id="stream-functions">
<h4>Stream Functions<a class="headerlink" href="#stream-functions" title="Permalink to this headline"></a></h4>
<p>Little helpers to process the iterator of our data (a “stream” of “1”
and “0” characters, not bits.)</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">getch</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="nb">int</span><span class="p">(</span><span class="nb">next</span><span class="p">(</span><span class="n">I</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_1</span><span class="p">(</span><span class="n">I</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Loop on ones.&#39;&#39;&#39;</span>
<span class="k">while</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">):</span> <span class="k">pass</span>
<span class="k">def</span> <span class="nf">_0</span><span class="p">(</span><span class="n">I</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Loop on zeros.&#39;&#39;&#39;</span>
<span class="k">while</span> <span class="ow">not</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">):</span> <span class="k">pass</span>
</pre></div>
</div>
</div>
<div class="section" id="a-finite-state-machine">
<h4>A Finite State Machine<a class="headerlink" href="#a-finite-state-machine" title="Permalink to this headline"></a></h4>
<p>With those preliminaries out of the way, from the state table of
<code class="docutils literal notranslate"><span class="pre">.111.</span> <span class="pre">&amp;</span> <span class="pre">(.01</span> <span class="pre">+</span> <span class="pre">11*)'</span></code> we can immediately write down state machine
code. (You have to imagine that these are GOTO statements in C or
branches in assembly and that the state names are branch destination
labels.)</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">c</span> <span class="k">if</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="k">else</span> <span class="n">b</span>
<span class="n">b</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">_0</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="ow">or</span> <span class="n">d</span>
<span class="n">c</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">e</span> <span class="k">if</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="k">else</span> <span class="n">b</span>
<span class="n">d</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">f</span> <span class="k">if</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="k">else</span> <span class="n">b</span>
<span class="n">e</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">g</span> <span class="k">if</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="k">else</span> <span class="n">b</span>
<span class="n">f</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">h</span> <span class="k">if</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="k">else</span> <span class="n">b</span>
<span class="n">g</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">_1</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="ow">or</span> <span class="n">i</span>
<span class="n">h</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">_1</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="ow">or</span> <span class="n">i</span>
<span class="n">i</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">_0</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="ow">or</span> <span class="n">j</span>
<span class="n">j</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">h</span> <span class="k">if</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="k">else</span> <span class="n">i</span>
</pre></div>
</div>
<p>Note that the implementations of <code class="docutils literal notranslate"><span class="pre">h</span></code> and <code class="docutils literal notranslate"><span class="pre">g</span></code> are identical ergo
<code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">=</span> <span class="pre">g</span></code> and we could eliminate one in the code but <code class="docutils literal notranslate"><span class="pre">h</span></code> is an
accepting state and <code class="docutils literal notranslate"><span class="pre">g</span></code> isnt.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">acceptable</span><span class="p">(</span><span class="n">input_</span><span class="p">):</span>
<span class="k">return</span> <span class="n">trampoline</span><span class="p">(</span><span class="n">input_</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="p">{</span><span class="n">h</span><span class="p">,</span> <span class="n">i</span><span class="p">})</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">5</span><span class="p">):</span>
<span class="n">s</span> <span class="o">=</span> <span class="nb">bin</span><span class="p">(</span><span class="n">n</span><span class="p">)[</span><span class="mi">2</span><span class="p">:]</span>
<span class="nb">print</span> <span class="s1">&#39;</span><span class="si">%05s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">s</span><span class="p">,</span> <span class="n">acceptable</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="mi">0</span> <span class="kc">False</span>
<span class="mi">1</span> <span class="kc">False</span>
<span class="mi">10</span> <span class="kc">False</span>
<span class="mi">11</span> <span class="kc">False</span>
<span class="mi">100</span> <span class="kc">False</span>
<span class="mi">101</span> <span class="kc">False</span>
<span class="mi">110</span> <span class="kc">False</span>
<span class="mi">111</span> <span class="kc">False</span>
<span class="mi">1000</span> <span class="kc">False</span>
<span class="mi">1001</span> <span class="kc">False</span>
<span class="mi">1010</span> <span class="kc">False</span>
<span class="mi">1011</span> <span class="kc">False</span>
<span class="mi">1100</span> <span class="kc">False</span>
<span class="mi">1101</span> <span class="kc">False</span>
<span class="mi">1110</span> <span class="kc">True</span>
<span class="mi">1111</span> <span class="kc">False</span>
<span class="mi">10000</span> <span class="kc">False</span>
<span class="mi">10001</span> <span class="kc">False</span>
<span class="mi">10010</span> <span class="kc">False</span>
<span class="mi">10011</span> <span class="kc">False</span>
<span class="mi">10100</span> <span class="kc">False</span>
<span class="mi">10101</span> <span class="kc">False</span>
<span class="mi">10110</span> <span class="kc">False</span>
<span class="mi">10111</span> <span class="kc">True</span>
<span class="mi">11000</span> <span class="kc">False</span>
<span class="mi">11001</span> <span class="kc">False</span>
<span class="mi">11010</span> <span class="kc">False</span>
<span class="mi">11011</span> <span class="kc">False</span>
<span class="mi">11100</span> <span class="kc">True</span>
<span class="mi">11101</span> <span class="kc">False</span>
<span class="mi">11110</span> <span class="kc">True</span>
<span class="mi">11111</span> <span class="kc">False</span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="section" id="reversing-the-derivatives-to-generate-matching-strings">
<h2>Reversing the Derivatives to Generate Matching Strings<a class="headerlink" href="#reversing-the-derivatives-to-generate-matching-strings" title="Permalink to this headline"></a></h2>
<p>(UNFINISHED) Brzozowski also shewed how to go from the state machine to
strings and expressions…</p>
<p>Each of these states is just a name for a Brzozowskian RE, and so, other
than the initial state <code class="docutils literal notranslate"><span class="pre">a</span></code>, they can can be described in terms of the
derivative-with-respect-to-N of some other state/RE:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">c</span> <span class="o">=</span> <span class="n">d1</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">d0</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">d0</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
<span class="o">...</span>
<span class="n">i</span> <span class="o">=</span> <span class="n">d0</span><span class="p">(</span><span class="n">j</span><span class="p">)</span>
<span class="n">j</span> <span class="o">=</span> <span class="n">d1</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
</pre></div>
</div>
<p>Consider:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">c</span> <span class="o">=</span> <span class="n">d1</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">d0</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
</pre></div>
</div>
<p>Substituting:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="n">d0</span><span class="p">(</span><span class="n">d1</span><span class="p">(</span><span class="n">a</span><span class="p">))</span>
</pre></div>
</div>
<p>Unwrapping:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="n">d10</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</pre></div>
</div>
<p></p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">j</span> <span class="o">=</span> <span class="n">d1</span><span class="p">(</span><span class="n">d0</span><span class="p">(</span><span class="n">j</span><span class="p">))</span>
</pre></div>
</div>
<p>Unwrapping:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">j</span> <span class="o">=</span> <span class="n">d1</span><span class="p">(</span><span class="n">d0</span><span class="p">(</span><span class="n">j</span><span class="p">))</span> <span class="o">=</span> <span class="n">d01</span><span class="p">(</span><span class="n">j</span><span class="p">)</span>
</pre></div>
</div>
<p>We have a loop or “fixed point”.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">j</span> <span class="o">=</span> <span class="n">d01</span><span class="p">(</span><span class="n">j</span><span class="p">)</span> <span class="o">=</span> <span class="n">d0101</span><span class="p">(</span><span class="n">j</span><span class="p">)</span> <span class="o">=</span> <span class="n">d010101</span><span class="p">(</span><span class="n">j</span><span class="p">)</span> <span class="o">=</span> <span class="o">...</span>
</pre></div>
</div>
<p>hmm…</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">j</span> <span class="o">=</span> <span class="p">(</span><span class="mi">01</span><span class="p">)</span><span class="o">*</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">∂RE</a><ul>
<li><a class="reference internal" href="#brzozowski-s-derivatives-of-regular-expressions">Brzozowskis Derivatives of Regular Expressions</a></li>
<li><a class="reference internal" href="#implementation">Implementation</a><ul>
<li><a class="reference internal" href="#and"><code class="docutils literal notranslate"><span class="pre">ϕ</span></code> and <code class="docutils literal notranslate"><span class="pre">λ</span></code></a></li>
<li><a class="reference internal" href="#two-letter-alphabet">Two-letter Alphabet</a></li>
<li><a class="reference internal" href="#representing-regular-expressions">Representing Regular Expressions</a></li>
<li><a class="reference internal" href="#string-representation-of-re-datastructures">String Representation of RE Datastructures</a></li>
<li><a class="reference internal" href="#i"><code class="docutils literal notranslate"><span class="pre">I</span></code></a></li>
<li><a class="reference internal" href="#id1"><code class="docutils literal notranslate"><span class="pre">(.111.)</span> <span class="pre">&amp;</span> <span class="pre">(.01</span> <span class="pre">+</span> <span class="pre">11*)'</span></code></a></li>
<li><a class="reference internal" href="#nully"><code class="docutils literal notranslate"><span class="pre">nully()</span></code></a></li>
<li><a class="reference internal" href="#no-compaction">No “Compaction”</a></li>
<li><a class="reference internal" href="#compaction-rules">Compaction Rules</a></li>
<li><a class="reference internal" href="#memoizing">Memoizing</a></li>
<li><a class="reference internal" href="#with-compaction">With “Compaction”</a></li>
</ul>
</li>
<li><a class="reference internal" href="#let-s-try-it-out">Lets try it out…</a></li>
<li><a class="reference internal" href="#larger-alphabets">Larger Alphabets</a></li>
<li><a class="reference internal" href="#state-machine">State Machine</a><ul>
<li><a class="reference internal" href="#re-to-fsm">RE to FSM</a></li>
<li><a class="reference internal" href="#explore"><code class="docutils literal notranslate"><span class="pre">explore()</span></code></a></li>
<li><a class="reference internal" href="#generate-diagram">Generate Diagram</a></li>
<li><a class="reference internal" href="#drive-a-fsm">Drive a FSM</a><ul>
<li><a class="reference internal" href="#trampoline-function">Trampoline Function</a></li>
<li><a class="reference internal" href="#stream-functions">Stream Functions</a></li>
<li><a class="reference internal" href="#a-finite-state-machine">A Finite State Machine</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#reversing-the-derivatives-to-generate-matching-strings">Reversing the Derivatives to Generate Matching Strings</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Derivatives_of_Regular_Expressions.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer" role="contentinfo">
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
<img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" />
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
</html>

View File

@ -0,0 +1,391 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The Four Fundamental Operations of Definite Action &#8212; Thun 0.2.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="the-four-fundamental-operations-of-definite-action">
<h1>The Four Fundamental Operations of Definite Action<a class="headerlink" href="#the-four-fundamental-operations-of-definite-action" title="Permalink to this headline"></a></h1>
<p>All definite actions (computer program) can be defined by four
fundamental patterns of combination:</p>
<ol class="arabic simple">
<li>Sequence</li>
<li>Branch</li>
<li>Loop</li>
<li>Parallel</li>
</ol>
<div class="section" id="sequence">
<h2>Sequence<a class="headerlink" href="#sequence" title="Permalink to this headline"></a></h2>
<p>Do one thing after another. In joy this is represented by putting two
symbols together, juxtaposition:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">foo</span> <span class="n">bar</span>
</pre></div>
</div>
<p>Operations have inputs and outputs. The outputs of <code class="docutils literal notranslate"><span class="pre">foo</span></code> must be
compatible in “arity”, type, and shape with the inputs of <code class="docutils literal notranslate"><span class="pre">bar</span></code>.</p>
</div>
<div class="section" id="branch">
<h2>Branch<a class="headerlink" href="#branch" title="Permalink to this headline"></a></h2>
<p>Do one thing or another.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">boolean</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="n">branch</span>
<span class="n">t</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="n">branch</span>
<span class="o">----------------------</span>
<span class="n">T</span>
<span class="n">f</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="n">branch</span>
<span class="o">----------------------</span>
<span class="n">F</span>
<span class="n">branch</span> <span class="o">==</span> <span class="n">unit</span> <span class="n">cons</span> <span class="n">swap</span> <span class="n">pick</span> <span class="n">i</span>
<span class="n">boolean</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="n">branch</span>
<span class="n">boolean</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="n">unit</span> <span class="n">cons</span> <span class="n">swap</span> <span class="n">pick</span> <span class="n">i</span>
<span class="n">boolean</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="p">[[</span><span class="n">T</span><span class="p">]]</span> <span class="n">cons</span> <span class="n">swap</span> <span class="n">pick</span> <span class="n">i</span>
<span class="n">boolean</span> <span class="p">[[</span><span class="n">F</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]]</span> <span class="n">swap</span> <span class="n">pick</span> <span class="n">i</span>
<span class="p">[[</span><span class="n">F</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]]</span> <span class="n">boolean</span> <span class="n">pick</span> <span class="n">i</span>
<span class="p">[</span><span class="n">F</span><span class="o">-</span><span class="ow">or</span><span class="o">-</span><span class="n">T</span><span class="p">]</span> <span class="n">i</span>
</pre></div>
</div>
<p>Given some branch function <code class="docutils literal notranslate"><span class="pre">G</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">G</span> <span class="o">==</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="n">branch</span>
</pre></div>
</div>
<p>Used in a sequence like so:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">foo</span> <span class="n">G</span> <span class="n">bar</span>
</pre></div>
</div>
<p>The inputs and outputs of <code class="docutils literal notranslate"><span class="pre">F</span></code> and <code class="docutils literal notranslate"><span class="pre">T</span></code> must be compatible with the
outputs for <code class="docutils literal notranslate"><span class="pre">foo</span></code> and the inputs of <code class="docutils literal notranslate"><span class="pre">bar</span></code>, respectively.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">foo</span> <span class="n">F</span> <span class="n">bar</span>
<span class="n">foo</span> <span class="n">T</span> <span class="n">bar</span>
</pre></div>
</div>
<div class="section" id="ifte">
<h3><code class="docutils literal notranslate"><span class="pre">ifte</span></code><a class="headerlink" href="#ifte" title="Permalink to this headline"></a></h3>
<p>Often it will be easier on the programmer to write branching code with
the predicate specified in a quote. The <code class="docutils literal notranslate"><span class="pre">ifte</span></code> combinator provides
this (<code class="docutils literal notranslate"><span class="pre">T</span></code> for “then” and <code class="docutils literal notranslate"><span class="pre">E</span></code> for “else”):</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></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">ifte</span>
</pre></div>
</div>
<p>Defined in terms of <code class="docutils literal notranslate"><span class="pre">branch</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ifte</span> <span class="o">==</span> <span class="p">[</span><span class="n">nullary</span> <span class="ow">not</span><span class="p">]</span> <span class="n">dip</span> <span class="n">branch</span>
</pre></div>
</div>
<p>In this case, <code class="docutils literal notranslate"><span class="pre">P</span></code> must be compatible with the stack and return a
Boolean value, and <code class="docutils literal notranslate"><span class="pre">T</span></code> and <code class="docutils literal notranslate"><span class="pre">E</span></code> both must be compatible with the
preceeding and following functions, as described above for <code class="docutils literal notranslate"><span class="pre">F</span></code> and
<code class="docutils literal notranslate"><span class="pre">T</span></code>. (Note that in the current implementation we are depending on
Python for the underlying semantics, so the Boolean value doesnt <em>have</em>
to be Boolean because Pythons rules for “truthiness” will be used to
evaluate it. I reflect this in the structure of the stack effect comment
of <code class="docutils literal notranslate"><span class="pre">branch</span></code>, it will only accept Boolean values, and in the definition
of <code class="docutils literal notranslate"><span class="pre">ifte</span></code> above by including <code class="docutils literal notranslate"><span class="pre">not</span></code> in the quote, which also has the
effect that the subject quotes are in the proper order for <code class="docutils literal notranslate"><span class="pre">branch</span></code>.)</p>
</div>
</div>
<div class="section" id="loop">
<h2>Loop<a class="headerlink" href="#loop" title="Permalink to this headline"></a></h2>
<p>Do one thing zero or more times.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">boolean</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">loop</span>
<span class="n">t</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">loop</span>
<span class="o">----------------</span>
<span class="n">Q</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">loop</span>
<span class="o">...</span> <span class="n">f</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">loop</span>
<span class="o">--------------------</span>
<span class="o">...</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">loop</span></code> combinator generates a copy of itself in the true branch.
This is the hallmark of recursive defintions. In Thun there is no
equivalent to conventional loops. (There is, however, the <code class="docutils literal notranslate"><span class="pre">x</span></code>
combinator, defined as <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">dup</span> <span class="pre">i</span></code>, which permits recursive
constructs that do not need to be directly self-referential, unlike
<code class="docutils literal notranslate"><span class="pre">loop</span></code> and <code class="docutils literal notranslate"><span class="pre">genrec</span></code>.)</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">loop</span> <span class="o">==</span> <span class="p">[]</span> <span class="n">swap</span> <span class="p">[</span><span class="n">dup</span> <span class="n">dip</span> <span class="n">loop</span><span class="p">]</span> <span class="n">cons</span> <span class="n">branch</span>
<span class="n">boolean</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">loop</span>
<span class="n">boolean</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="p">[]</span> <span class="n">swap</span> <span class="p">[</span><span class="n">dup</span> <span class="n">dip</span> <span class="n">loop</span><span class="p">]</span> <span class="n">cons</span> <span class="n">branch</span>
<span class="n">boolean</span> <span class="p">[]</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="p">[</span><span class="n">dup</span> <span class="n">dip</span> <span class="n">loop</span><span class="p">]</span> <span class="n">cons</span> <span class="n">branch</span>
<span class="n">boolean</span> <span class="p">[]</span> <span class="p">[[</span><span class="n">Q</span><span class="p">]</span> <span class="n">dup</span> <span class="n">dip</span> <span class="n">loop</span><span class="p">]</span> <span class="n">branch</span>
</pre></div>
</div>
<p>In action the false branch does nothing while the true branch does:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">t</span> <span class="p">[]</span> <span class="p">[[</span><span class="n">Q</span><span class="p">]</span> <span class="n">dup</span> <span class="n">dip</span> <span class="n">loop</span><span class="p">]</span> <span class="n">branch</span>
<span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">dup</span> <span class="n">dip</span> <span class="n">loop</span>
<span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">dip</span> <span class="n">loop</span>
<span class="n">Q</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">loop</span>
</pre></div>
</div>
<p>Because <code class="docutils literal notranslate"><span class="pre">loop</span></code> expects and consumes a Boolean value, the <code class="docutils literal notranslate"><span class="pre">Q</span></code>
function must be compatible with the previous stack <em>and itself</em> with a
boolean flag for the next iteration:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Q</span> <span class="o">==</span> <span class="n">G</span> <span class="n">b</span>
<span class="n">Q</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">loop</span>
<span class="n">G</span> <span class="n">b</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">loop</span>
<span class="n">G</span> <span class="n">Q</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">loop</span>
<span class="n">G</span> <span class="n">G</span> <span class="n">b</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">loop</span>
<span class="n">G</span> <span class="n">G</span> <span class="n">Q</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">loop</span>
<span class="n">G</span> <span class="n">G</span> <span class="n">G</span> <span class="n">b</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">loop</span>
<span class="n">G</span> <span class="n">G</span> <span class="n">G</span>
</pre></div>
</div>
<div class="section" id="while">
<h3><code class="docutils literal notranslate"><span class="pre">while</span></code><a class="headerlink" href="#while" title="Permalink to this headline"></a></h3>
<p>Keep doing <code class="docutils literal notranslate"><span class="pre">B</span></code> <em>while</em> some predicate <code class="docutils literal notranslate"><span class="pre">P</span></code> is true. This is
convenient as the predicate function is made nullary automatically and
the body function can be designed without regard to leaving a Boolean
flag for the next iteration:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">B</span><span class="p">]</span> <span class="k">while</span>
<span class="o">--------------------------------------</span>
<span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="n">nullary</span> <span class="p">[</span><span class="n">B</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="n">nullary</span><span class="p">]</span> <span class="n">loop</span>
<span class="k">while</span> <span class="o">==</span> <span class="n">swap</span> <span class="p">[</span><span class="n">nullary</span><span class="p">]</span> <span class="n">cons</span> <span class="n">dup</span> <span class="n">dipd</span> <span class="n">concat</span> <span class="n">loop</span>
<span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">B</span><span class="p">]</span> <span class="k">while</span>
<span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">B</span><span class="p">]</span> <span class="n">swap</span> <span class="p">[</span><span class="n">nullary</span><span class="p">]</span> <span class="n">cons</span> <span class="n">dup</span> <span class="n">dipd</span> <span class="n">concat</span> <span class="n">loop</span>
<span class="p">[</span><span class="n">B</span><span class="p">]</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">nullary</span><span class="p">]</span> <span class="n">cons</span> <span class="n">dup</span> <span class="n">dipd</span> <span class="n">concat</span> <span class="n">loop</span>
<span class="p">[</span><span class="n">B</span><span class="p">]</span> <span class="p">[[</span><span class="n">P</span><span class="p">]</span> <span class="n">nullary</span><span class="p">]</span> <span class="n">dup</span> <span class="n">dipd</span> <span class="n">concat</span> <span class="n">loop</span>
<span class="p">[</span><span class="n">B</span><span class="p">]</span> <span class="p">[[</span><span class="n">P</span><span class="p">]</span> <span class="n">nullary</span><span class="p">]</span> <span class="p">[[</span><span class="n">P</span><span class="p">]</span> <span class="n">nullary</span><span class="p">]</span> <span class="n">dipd</span> <span class="n">concat</span> <span class="n">loop</span>
<span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="n">nullary</span> <span class="p">[</span><span class="n">B</span><span class="p">]</span> <span class="p">[[</span><span class="n">P</span><span class="p">]</span> <span class="n">nullary</span><span class="p">]</span> <span class="n">concat</span> <span class="n">loop</span>
<span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="n">nullary</span> <span class="p">[</span><span class="n">B</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="n">nullary</span><span class="p">]</span> <span class="n">loop</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="parallel">
<h2>Parallel<a class="headerlink" href="#parallel" title="Permalink to this headline"></a></h2>
<p>The <em>parallel</em> operation indicates that two (or more) functions <em>do not
interfere</em> with each other and so can run in parallel. The main
difficulty in this sort of thing is orchestrating the recombining
(“join” or “wait”) of the results of the functions after they finish.</p>
<p>The current implementaions and the following definitions <em>are not
actually parallel</em> (yet), but there is no reason they couldnt be
reimplemented in terms of e.g. Python threads. I am not concerned with
performance of the system just yet, only the elegance of the code it
allows us to write.</p>
<div class="section" id="cleave">
<h3><code class="docutils literal notranslate"><span class="pre">cleave</span></code><a class="headerlink" href="#cleave" title="Permalink to this headline"></a></h3>
<p>Joy has a few parallel combinators, the main one being <code class="docutils literal notranslate"><span class="pre">cleave</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">...</span> <span class="n">x</span> <span class="p">[</span><span class="n">A</span><span class="p">]</span> <span class="p">[</span><span class="n">B</span><span class="p">]</span> <span class="n">cleave</span>
<span class="o">---------------------------------------------------------</span>
<span class="o">...</span> <span class="p">[</span><span class="n">x</span> <span class="o">...</span><span class="p">]</span> <span class="p">[</span><span class="n">A</span><span class="p">]</span> <span class="n">infra</span> <span class="n">first</span> <span class="p">[</span><span class="n">x</span> <span class="o">...</span><span class="p">]</span> <span class="p">[</span><span class="n">B</span><span class="p">]</span> <span class="n">infra</span> <span class="n">first</span>
<span class="o">---------------------------------------------------------</span>
<span class="o">...</span> <span class="n">a</span> <span class="n">b</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">cleave</span></code> combinator expects a value and two quotes and it executes
each quote in “separate universes” such that neither can affect the
other, then it takes the first item from the stack in each universe and
replaces the value and quotes with their respective results.</p>
<p>(I think this corresponds to the “fork” operator, the little
upward-pointed triangle, that takes two functions <code class="docutils literal notranslate"><span class="pre">A</span> <span class="pre">::</span> <span class="pre">x</span> <span class="pre">-&gt;</span> <span class="pre">a</span></code> and
<code class="docutils literal notranslate"><span class="pre">B</span> <span class="pre">::</span> <span class="pre">x</span> <span class="pre">-&gt;</span> <span class="pre">b</span></code> and returns a function <code class="docutils literal notranslate"><span class="pre">F</span> <span class="pre">::</span> <span class="pre">x</span> <span class="pre">-&gt;</span> <span class="pre">(a,</span> <span class="pre">b)</span></code>, in Conal
Elliotts “Compiling to Categories” paper, et. al.)</p>
<p>Just a thought, if you <code class="docutils literal notranslate"><span class="pre">cleave</span></code> two jobs and one requires more time to
finish than the other youd like to be able to assign resources
accordingly so that they both finish at the same time.</p>
</div>
<div class="section" id="apply-functions">
<h3>“Apply” Functions<a class="headerlink" href="#apply-functions" title="Permalink to this headline"></a></h3>
<p>There are also <code class="docutils literal notranslate"><span class="pre">app2</span></code> and <code class="docutils literal notranslate"><span class="pre">app3</span></code> which run a single quote on more
than one value:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">...</span> <span class="n">y</span> <span class="n">x</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">app2</span>
<span class="o">---------------------------------------------------------</span>
<span class="o">...</span> <span class="p">[</span><span class="n">y</span> <span class="o">...</span><span class="p">]</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">infra</span> <span class="n">first</span> <span class="p">[</span><span class="n">x</span> <span class="o">...</span><span class="p">]</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">infra</span> <span class="n">first</span>
<span class="o">...</span> <span class="n">z</span> <span class="n">y</span> <span class="n">x</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">app3</span>
<span class="o">---------------------------------</span>
<span class="o">...</span> <span class="p">[</span><span class="n">z</span> <span class="o">...</span><span class="p">]</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">infra</span> <span class="n">first</span>
<span class="p">[</span><span class="n">y</span> <span class="o">...</span><span class="p">]</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">infra</span> <span class="n">first</span>
<span class="p">[</span><span class="n">x</span> <span class="o">...</span><span class="p">]</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">infra</span> <span class="n">first</span>
</pre></div>
</div>
<p>Because the quoted program can be <code class="docutils literal notranslate"><span class="pre">i</span></code> we can define <code class="docutils literal notranslate"><span class="pre">cleave</span></code> in
terms of <code class="docutils literal notranslate"><span class="pre">app2</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cleave</span> <span class="o">==</span> <span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="n">app2</span> <span class="p">[</span><span class="n">popd</span><span class="p">]</span> <span class="n">dip</span>
</pre></div>
</div>
<p>(Im not sure why <code class="docutils literal notranslate"><span class="pre">cleave</span></code> was specified to take that value, I may
make a combinator that does the same thing but without expecting a
value.)</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">clv</span> <span class="o">==</span> <span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="n">app2</span>
<span class="p">[</span><span class="n">A</span><span class="p">]</span> <span class="p">[</span><span class="n">B</span><span class="p">]</span> <span class="n">clv</span>
<span class="o">------------------</span>
<span class="n">a</span> <span class="n">b</span>
</pre></div>
</div>
</div>
<div class="section" id="map">
<h3><code class="docutils literal notranslate"><span class="pre">map</span></code><a class="headerlink" href="#map" title="Permalink to this headline"></a></h3>
<p>The common <code class="docutils literal notranslate"><span class="pre">map</span></code> function in Joy should also be though of as a
<em>parallel</em> operator:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">...</span><span class="p">]</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="nb">map</span>
</pre></div>
</div>
<p>There is no reason why the implementation of <code class="docutils literal notranslate"><span class="pre">map</span></code> couldnt distribute
the <code class="docutils literal notranslate"><span class="pre">Q</span></code> function over e.g. a pool of worker CPUs.</p>
</div>
<div class="section" id="pam">
<h3><code class="docutils literal notranslate"><span class="pre">pam</span></code><a class="headerlink" href="#pam" title="Permalink to this headline"></a></h3>
<p>One of my favorite combinators, the <code class="docutils literal notranslate"><span class="pre">pam</span></code> combinator is just:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pam</span> <span class="o">==</span> <span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="nb">map</span>
</pre></div>
</div>
<p>This can be used to run any number of programs separately on the current
stack and combine their (first) outputs in a result list.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">[[</span><span class="n">A</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">C</span><span class="p">]</span> <span class="o">...</span><span class="p">]</span> <span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="nb">map</span>
<span class="o">-------------------------------</span>
<span class="p">[</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">...</span><span class="p">]</span>
</pre></div>
</div>
</div>
<div class="section" id="handling-other-kinds-of-join">
<h3>Handling Other Kinds of Join<a class="headerlink" href="#handling-other-kinds-of-join" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">cleave</span></code> operators and others all have pretty brutal join
semantics: everything works and we always wait for every
sub-computation. We can imagine a few different potentially useful
patterns of “joining” results from parallel combinators.</p>
<div class="section" id="first-to-finish">
<h4>first-to-finish<a class="headerlink" href="#first-to-finish" title="Permalink to this headline"></a></h4>
<p>Thinking about variations of <code class="docutils literal notranslate"><span class="pre">pam</span></code> there could be one that only
returns the first result of the first-to-finish sub-program, or the
stack could be replaced by its output stack.</p>
<p>The other sub-programs would be cancelled.</p>
</div>
<div class="section" id="fulminators">
<h4>“Fulminators”<a class="headerlink" href="#fulminators" title="Permalink to this headline"></a></h4>
<p>Also known as “Futures” or “Promises” (by <em>everybody</em> else. “Fulinators”
is what I was going to call them when I was thinking about implementing
them in Thun.)</p>
<p>The runtime could be amended to permit “thunks” representing the results
of in-progress computations to be left on the stack and picked up by
subsequent functions. These would themselves be able to leave behind
more “thunks”, the values of which depend on the eventual resolution of
the values of the previous thunks.</p>
<p>In this way you can create “chains” (and more complex shapes) out of
normal-looking code that consist of a kind of call-graph interspersed
with “asyncronous” … events?</p>
<p>In any case, until I can find a rigorous theory that shows that this
sort of thing works perfectly in Joy code Im not going to worry about
it. (And I think the Categories can deal with it anyhow? Incremental
evaluation, yeah?)</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">The Four Fundamental Operations of Definite Action</a><ul>
<li><a class="reference internal" href="#sequence">Sequence</a></li>
<li><a class="reference internal" href="#branch">Branch</a><ul>
<li><a class="reference internal" href="#ifte"><code class="docutils literal notranslate"><span class="pre">ifte</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#loop">Loop</a><ul>
<li><a class="reference internal" href="#while"><code class="docutils literal notranslate"><span class="pre">while</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#parallel">Parallel</a><ul>
<li><a class="reference internal" href="#cleave"><code class="docutils literal notranslate"><span class="pre">cleave</span></code></a></li>
<li><a class="reference internal" href="#apply-functions">“Apply” Functions</a></li>
<li><a class="reference internal" href="#map"><code class="docutils literal notranslate"><span class="pre">map</span></code></a></li>
<li><a class="reference internal" href="#pam"><code class="docutils literal notranslate"><span class="pre">pam</span></code></a></li>
<li><a class="reference internal" href="#handling-other-kinds-of-join">Handling Other Kinds of Join</a><ul>
<li><a class="reference internal" href="#first-to-finish">first-to-finish</a></li>
<li><a class="reference internal" href="#fulminators">“Fulminators”</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/The_Four_Operations.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer" role="contentinfo">
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
<img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" />
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
</html>

View File

@ -0,0 +1,209 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Type Checking &#8212; Thun 0.2.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="type-checking">
<h1>Type Checking<a class="headerlink" href="#type-checking" title="Permalink to this headline"></a></h1>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">sys</span>
<span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span>
<span class="nb">format</span><span class="o">=</span><span class="s1">&#39;</span><span class="si">%(message)s</span><span class="s1">&#39;</span><span class="p">,</span>
<span class="n">stream</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="p">,</span>
<span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.utils.polytypes</span> <span class="k">import</span> <span class="p">(</span>
<span class="n">doc_from_stack_effect</span><span class="p">,</span>
<span class="n">infer</span><span class="p">,</span>
<span class="n">reify</span><span class="p">,</span>
<span class="n">unify</span><span class="p">,</span>
<span class="n">FUNCTIONS</span><span class="p">,</span>
<span class="n">JoyTypeError</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">D</span> <span class="o">=</span> <span class="n">FUNCTIONS</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="k">del</span> <span class="n">D</span><span class="p">[</span><span class="s1">&#39;product&#39;</span><span class="p">]</span>
<span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">D</span><span class="p">)</span>
</pre></div>
</div>
<div class="section" id="an-example">
<h2>An Example<a class="headerlink" href="#an-example" title="Permalink to this headline"></a></h2>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rrest</span><span class="p">,</span> <span class="n">ccons</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>25 (--) ∘ pop swap rolldown rrest ccons
28 (a1 --) ∘ swap rolldown rrest ccons
31 (a3 a2 a1 -- a2 a3) ∘ rolldown rrest ccons
34 (a4 a3 a2 a1 -- a2 a3 a4) ∘ rrest ccons
37 ([a4 a5 ...1] a3 a2 a1 -- a2 a3 [...1]) ∘ ccons
40 ([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1]) ∘
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a4</span> <span class="n">a5</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="p">[</span><span class="n">a2</span> <span class="n">a3</span> <span class="o">...</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.parser</span> <span class="k">import</span> <span class="n">text_to_expression</span>
<span class="kn">from</span> <span class="nn">joy.utils.stack</span> <span class="k">import</span> <span class="n">stack_to_string</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;0 1 2 [3 4]&#39;</span><span class="p">)</span> <span class="c1"># reverse order</span>
<span class="nb">print</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">4</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fi</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">u</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="n">a2</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="n">a3</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="n">a4</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="n">a5</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(),</span> <span class="n">s1</span><span class="p">:</span> <span class="p">()}</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">))</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">g</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">...</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="p">]</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span> <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">2</span> <span class="p">])</span>
</pre></div>
</div>
</div>
<div class="section" id="unification-works-in-reverse">
<h2>Unification Works “in Reverse”<a class="headerlink" href="#unification-works-in-reverse" title="Permalink to this headline"></a></h2>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;[2 3]&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fo</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># output side, not input side</span>
<span class="n">u</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">a2</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="n">a3</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(),</span> <span class="n">s1</span><span class="p">:</span> <span class="p">()}</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">))</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">g</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">...</span> <span class="p">[</span><span class="n">a4</span> <span class="n">a5</span> <span class="p">]</span> <span class="mi">3</span> <span class="mi">2</span> <span class="n">a1</span> <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">3</span> <span class="p">])</span>
</pre></div>
</div>
</div>
<div class="section" id="failing-a-check">
<h2>Failing a Check<a class="headerlink" href="#failing-a-check" title="Permalink to this headline"></a></h2>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>25 (--) ∘ dup mul
28 (a1 -- a1 a1) ∘ mul
31 (f1 -- f2) ∘
31 (i1 -- i2) ∘
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;&quot;two&quot;&#39;</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">&#39;two&#39;</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fi</span><span class="p">)</span>
<span class="k">except</span> <span class="n">JoyTypeError</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span>
<span class="nb">print</span> <span class="n">err</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Cannot</span> <span class="n">unify</span> <span class="s1">&#39;two&#39;</span> <span class="ow">and</span> <span class="n">f1</span><span class="o">.</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Type Checking</a><ul>
<li><a class="reference internal" href="#an-example">An Example</a></li>
<li><a class="reference internal" href="#unification-works-in-reverse">Unification Works “in Reverse”</a></li>
<li><a class="reference internal" href="#failing-a-check">Failing a Check</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/TypeChecking.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer" role="contentinfo">
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
<img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" />
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
</html>

View File

@ -130,8 +130,30 @@
<li class="toctree-l2"><a class="reference internal" href="Types.html#appendix-joy-in-the-logical-paradigm">Appendix: Joy in the Logical Paradigm</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="TypeChecking.html">Type Checking</a><ul>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html#an-example">An Example</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html#unification-works-in-reverse">Unification Works “in Reverse”</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html#failing-a-check">Failing a Check</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l1"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l1"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a><ul>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html#sequence">Sequence</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html#branch">Branch</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html#loop">Loop</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html#parallel">Parallel</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#brzozowski-s-derivatives-of-regular-expressions">Brzozowskis Derivatives of Regular Expressions</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#implementation">Implementation</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#let-s-try-it-out">Lets try it out…</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#larger-alphabets">Larger Alphabets</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#state-machine">State Machine</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#reversing-the-derivatives-to-generate-matching-strings">Reversing the Derivatives to Generate Matching Strings</a></li>
</ul>
</li>
</ul>
</div>
</div>

File diff suppressed because one or more lines are too long

View File

@ -291,7 +291,7 @@ guard against being used on invalid types.</p>
<dl class="data">
<dt id="joy.utils.polytypes.FUNCTIONS">
<code class="descclassname">joy.utils.polytypes.</code><code class="descname">FUNCTIONS</code><em class="property"> = {'_Tree_add_Ee': _Tree_add_Ee, '_Tree_delete_R0': _Tree_delete_R0, '_Tree_delete_clear_stuff': _Tree_delete_clear_stuff, '_Tree_get_E': _Tree_get_E, 'add': add, 'and': and, 'b': b, 'bool': bool, 'branch': branch, 'ccons': ccons, 'clear': clear, 'concat_': concat_, 'cons': cons, 'dip': dip, 'dipd': dipd, 'dipdd': dipdd, 'div': div, 'divmod': divmod, 'dup': dup, 'dupd': dupd, 'dupdd': dupdd, 'dupdip': dupdip, 'eq': eq, 'first': first, 'first_two': first_two, 'floordiv': floordiv, 'fourth': fourth, 'ge': ge, 'gt': gt, 'i': i, 'infra': infra, 'le': le, 'loop': loop, 'lshift': lshift, 'lt': lt, 'modulus': modulus, 'mul': mul, 'ne': ne, 'neg': neg, 'not': not, 'nullary': nullary, 'over': over, 'pm': pm, 'pop': pop, 'popd': popd, 'popdd': popdd, 'popop': popop, 'popopd': popopd, 'popopdd': popopdd, 'pow': pow, 'pred': pred, 'product': product, 'rest': rest, 'rolldown': rolldown, 'rollup': rollup, 'rrest': rrest, 'rshift': rshift, 'second': second, 'sqrt': sqrt, 'stack': stack, 'stuncons': stuncons, 'stununcons': stununcons, 'sub': sub, 'succ': succ, 'sum': sum, 'swaack': swaack, 'swap': swap, 'swons': swons, 'third': third, 'truediv': truediv, 'tuck': tuck, 'uncons': uncons, 'unit': unit, 'unswons': unswons, 'x': x}</em><a class="headerlink" href="#joy.utils.polytypes.FUNCTIONS" title="Permalink to this definition"></a></dt>
<code class="descclassname">joy.utils.polytypes.</code><code class="descname">FUNCTIONS</code><em class="property"> = {'!=': ne, '&amp;': and, '*': mul, '+': add, '++': succ, '-': sub, '--': pred, '/': truediv, '&lt;': lt, '&lt;&lt;': lshift, '&lt;=': le, '&lt;&gt;': ne, '=': eq, '&gt;': gt, '&gt;=': ge, '&gt;&gt;': rshift, '_Tree_add_Ee': _Tree_add_Ee, '_Tree_delete_R0': _Tree_delete_R0, '_Tree_delete_clear_stuff': _Tree_delete_clear_stuff, '_Tree_get_E': _Tree_get_E, 'add': add, 'and': and, 'b': b, 'bool': bool, 'branch': branch, 'ccons': ccons, 'clear': clear, 'concat_': concat_, 'cons': cons, 'dip': dip, 'dipd': dipd, 'dipdd': dipdd, 'div': div, 'divmod': divmod, 'dup': dup, 'dupd': dupd, 'dupdd': dupdd, 'dupdip': dupdip, 'eq': eq, 'first': first, 'first_two': first_two, 'floordiv': floordiv, 'fourth': fourth, 'ge': ge, 'gt': gt, 'i': i, 'infra': infra, 'le': le, 'loop': loop, 'lshift': lshift, 'lt': lt, 'modulus': modulus, 'mul': mul, 'ne': ne, 'neg': neg, 'not': not, 'nullary': nullary, 'over': over, 'pop': pop, 'popd': popd, 'popdd': popdd, 'popop': popop, 'popopd': popopd, 'popopdd': popopdd, 'pow': pow, 'pred': pred, 'product': product, 'rest': rest, 'roll&lt;': rolldown, 'roll&gt;': rollup, 'rolldown': rolldown, 'rollup': rollup, 'rrest': rrest, 'rshift': rshift, 'second': second, 'sqrt': sqrt, 'stack': stack, 'stuncons': stuncons, 'stununcons': stununcons, 'sub': sub, 'succ': succ, 'sum': sum, 'swaack': swaack, 'swap': swap, 'swons': swons, 'third': third, 'truediv': truediv, 'truthy': bool, 'tuck': tuck, 'uncons': uncons, 'unit': unit, 'unswons': unswons, 'x': x}</em><a class="headerlink" href="#joy.utils.polytypes.FUNCTIONS" title="Permalink to this definition"></a></dt>
<dd><p>Docstring for functions in Sphinx?</p>
</dd></dl>
@ -372,6 +372,14 @@ expression is carried along and updated and yielded.</p>
effects. An expression is carried along and updated and yielded.</p>
</dd></dl>
<dl class="function">
<dt id="joy.utils.polytypes.type_check">
<code class="descclassname">joy.utils.polytypes.</code><code class="descname">type_check</code><span class="sig-paren">(</span><em>name</em>, <em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/polytypes.html#type_check"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.polytypes.type_check" title="Permalink to this definition"></a></dt>
<dd><p>Trinary predicate. True if named function type-checks, False if it
fails, None if its indeterminate (because I havent entered it into
the FUNCTIONS dict yet.)</p>
</dd></dl>
</div>
</div>

View File

@ -266,10 +266,6 @@ derivation.
.. code:: ipython2
# This is the straightforward version with no "compaction".
# It works fine, but does waaaay too much work because the
# expressions grow each derivation.
def D(symbol):
def derv(R):
@ -539,9 +535,8 @@ machine transition table.
Says, "Three or more 1's and not ending in 01 nor composed of all 1's."
.. figure:: omg.svg
:alt: omg.svg
:alt: State Machine Diagram
omg.svg
Start at ``a`` and follow the transition arrows according to their
labels. Accepting states have a double outline. (Graphic generated with

View File

@ -18,6 +18,9 @@ These essays are adapted from Jupyter notebooks. I hope to have those hosted so
Newton-Raphson
Zipper
Types
TypeChecking
NoUpdates
Categorical
The_Four_Operations
Derivatives_of_Regular_Expressions