@ -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 — 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 > Brzozowski’ s 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" > ' ' < / 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 > I’ m 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" > ' 0' < / span > < span class = "p" > }),< / span > < span class = "nb" > frozenset< / span > < span class = "p" > ({< / span > < span class = "s1" > ' 1' < / 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 I’ m 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" > ' and cons * not or' < / 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" > ' ' ' < / span >
< span class = "sd" > Return a nice string repr for a regular expression datastructure.< / span >
< span class = "sd" > ' ' ' < / 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" > ' .' < / 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" > ' ^' < / 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" > ' X' < / 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" > > < / span > < span class = "mi" > 1< / span > < span class = "p" > :< / span > < span class = "k" > return< / span > < span class = "s1" > ' (' < / span > < span class = "o" > +< / span > < span class = "n" > body< / span > < span class = "o" > +< / span > < span class = "s2" > " )*" < / span >
< span class = "k" > return< / span > < span class = "n" > body< / span > < span class = "o" > +< / span > < span class = "s1" > ' *' < / 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" > > < / span > < span class = "mi" > 1< / span > < span class = "p" > :< / span > < span class = "k" > return< / span > < span class = "s1" > ' (' < / span > < span class = "o" > +< / span > < span class = "n" > body< / span > < span class = "o" > +< / span > < span class = "s2" > " )' " < / span >
< span class = "k" > return< / span > < span class = "n" > body< / span > < span class = "o" > +< / span > < span class = "s2" > " ' " < / 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" > ' < / span > < span class = "si" > %s< / span > < span class = "s1" > | < / span > < span class = "si" > %s< / span > < span class = "s1" > ' < / 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" > ' (< / span > < span class = "si" > %s< / span > < span class = "s1" > ) & (< / span > < span class = "si" > %s< / span > < span class = "s1" > )' < / 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" > & < / 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" > & < / 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" > ' < / span >
< span class = "n" > a< / span > < span class = "o" > & < / 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" > ' < / 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" > & < / 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" > ' )< / 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 > Let’ s 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" > ' ' ' < / span >
< span class = "sd" > δ - Return λ if λ ⊆ R otherwise ϕ.< / span >
< span class = "sd" > ' ' ' < / 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" > & < / 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 > Let’ s 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" > ' 0' < / span > < span class = "p" > ),< / span > < span class = "n" > D_compaction< / span > < span class = "p" > (< / span > < span class = "s1" > ' 1' < / 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" > ' /' < / 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" > ' /' < / 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" > & < / 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" > ' )< / 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" > ' < / 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" > ' < / 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" > ' < / 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" > ' < / span >
< span class = "p" > (< / span > < span class = "o" > .< / span > < span class = "mf" > 111.< / span > < span class = "p" > )< / 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" > ' )< / 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" > & < / 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" > ' )< / 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" > & < / span > < span class = "p" > ((< / span > < span class = "o" > .< / span > < span class = "mi" > 01< / span > < span class = "p" > )< / span > < span class = "s1" > ' )< / 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" > & < / 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" > ' )< / 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" > & < / 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" > ' )< / 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" > & < / 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" > ' )< / 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" > ' < / 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" > ' < / 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" > ' < / 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" > ' < / span >
< span class = "p" > (< / span > < span class = "o" > .< / span > < span class = "mf" > 111.< / span > < span class = "p" > )< / 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" > ' )< / 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" > & < / 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" > ' )< / 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" > & < / 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" > ' )< / 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" > & < / span > < span class = "p" > ((< / span > < span class = "o" > .< / span > < span class = "mi" > 01< / span > < span class = "p" > )< / span > < span class = "s1" > ' )< / 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" > & < / 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" > ' )< / 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 you’ ll 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" > & < / 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 > {' 0' , ' 1' )
∂1({' 0' , ' 1' ))
∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
∂1({' 0' )) ∨ ∂1({' 1' ))
∂a(¬a) → ϕ
ϕ ∨ ∂1({' 1' ))
∂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" > & < / 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" > ' < / span >
< / pre > < / div >
< / div >
< p > Says, “Three or more 1’ s and not ending in 01 nor composed of all 1’ s.”< / 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 > .) You’ ll 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 > There’ s 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 > you’ re stuck there eating 1’ s 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 can’ t 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 1’ s 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 1’ s) or move to < code class = "docutils literal notranslate" > < span class = "pre" > i< / span > < / code > (for
0’ s). If you find yourself at < code class = "docutils literal notranslate" > < span class = "pre" > i< / span > < / code > you can see as many 0’ s, 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 arrow’ s 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--> ∂0(a)
a --1--> ∂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" > & < / 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" > ' )< / 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" > & < / 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" > ' )< / 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" > & < / 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" > ' )< / 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" > & < / 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" > ' )< / 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" > & < / 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" > ' )< / 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" > & < / span > < span class = "p" > ((< / span > < span class = "o" > .< / span > < span class = "mi" > 01< / span > < span class = "p" > )< / span > < span class = "s1" > ' )< / 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" > ' < / 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" > ' < / 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" > ' < / 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" > ' < / 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" > & < / 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" > ' 0' < / span > < span class = "p" > ),< / span > < span class = "n" > D_compaction< / span > < span class = "p" > (< / span > < span class = "s1" > ' 1' < / 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' 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" > ' a' < / span > < span class = "p" > ,< / span > < span class = "mi" > 0< / span > < span class = "p" > ):< / span > < span class = "s1" > ' b' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' a' < / span > < span class = "p" > ,< / span > < span class = "mi" > 1< / span > < span class = "p" > ):< / span > < span class = "s1" > ' c' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' b' < / span > < span class = "p" > ,< / span > < span class = "mi" > 0< / span > < span class = "p" > ):< / span > < span class = "s1" > ' b' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' b' < / span > < span class = "p" > ,< / span > < span class = "mi" > 1< / span > < span class = "p" > ):< / span > < span class = "s1" > ' d' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' c' < / span > < span class = "p" > ,< / span > < span class = "mi" > 0< / span > < span class = "p" > ):< / span > < span class = "s1" > ' b' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' c' < / span > < span class = "p" > ,< / span > < span class = "mi" > 1< / span > < span class = "p" > ):< / span > < span class = "s1" > ' e' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' d' < / span > < span class = "p" > ,< / span > < span class = "mi" > 0< / span > < span class = "p" > ):< / span > < span class = "s1" > ' b' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' d' < / span > < span class = "p" > ,< / span > < span class = "mi" > 1< / span > < span class = "p" > ):< / span > < span class = "s1" > ' f' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' e' < / span > < span class = "p" > ,< / span > < span class = "mi" > 0< / span > < span class = "p" > ):< / span > < span class = "s1" > ' b' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' e' < / span > < span class = "p" > ,< / span > < span class = "mi" > 1< / span > < span class = "p" > ):< / span > < span class = "s1" > ' g' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' f' < / span > < span class = "p" > ,< / span > < span class = "mi" > 0< / span > < span class = "p" > ):< / span > < span class = "s1" > ' b' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' f' < / span > < span class = "p" > ,< / span > < span class = "mi" > 1< / span > < span class = "p" > ):< / span > < span class = "s1" > ' h' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' g' < / span > < span class = "p" > ,< / span > < span class = "mi" > 0< / span > < span class = "p" > ):< / span > < span class = "s1" > ' i' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' g' < / span > < span class = "p" > ,< / span > < span class = "mi" > 1< / span > < span class = "p" > ):< / span > < span class = "s1" > ' g' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' h' < / span > < span class = "p" > ,< / span > < span class = "mi" > 0< / span > < span class = "p" > ):< / span > < span class = "s1" > ' i' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' h' < / span > < span class = "p" > ,< / span > < span class = "mi" > 1< / span > < span class = "p" > ):< / span > < span class = "s1" > ' h' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' i' < / span > < span class = "p" > ,< / span > < span class = "mi" > 0< / span > < span class = "p" > ):< / span > < span class = "s1" > ' i' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' i' < / span > < span class = "p" > ,< / span > < span class = "mi" > 1< / span > < span class = "p" > ):< / span > < span class = "s1" > ' j' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' j' < / span > < span class = "p" > ,< / span > < span class = "mi" > 0< / span > < span class = "p" > ):< / span > < span class = "s1" > ' i' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' j' < / span > < span class = "p" > ,< / span > < span class = "mi" > 1< / span > < span class = "p" > ):< / span > < span class = "s1" > ' h' < / 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" > ' h' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' i' < / 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" > ' ' ' < / span > < span class = "se" > \< / span >
< span class = "s1" > digraph finite_state_machine {< / span >
< span class = "s1" > rankdir=LR;< / span >
< span class = "s1" > size=" 8,5" < / 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" > ' ' ' < / 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" > ' < / span > < span class = "si" > %s< / span > < span class = "s1" > -> < / span > < span class = "si" > %s< / span > < span class = "s1" > [ label = " < / span > < span class = "si" > %s< / span > < span class = "s1" > " ];' < / 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" > ' ' < / 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" > ' < / span > < span class = "se" > \n< / span > < span class = "s1" > ' < / 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" > " 8,5" < / 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" > -> < / span > < span class = "n" > b< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 0" < / span > < span class = "p" > ];< / span >
< span class = "n" > a< / span > < span class = "o" > -> < / span > < span class = "n" > c< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 1" < / span > < span class = "p" > ];< / span >
< span class = "n" > b< / span > < span class = "o" > -> < / span > < span class = "n" > b< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 0" < / span > < span class = "p" > ];< / span >
< span class = "n" > b< / span > < span class = "o" > -> < / span > < span class = "n" > d< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 1" < / span > < span class = "p" > ];< / span >
< span class = "n" > c< / span > < span class = "o" > -> < / span > < span class = "n" > b< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 0" < / span > < span class = "p" > ];< / span >
< span class = "n" > c< / span > < span class = "o" > -> < / span > < span class = "n" > e< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 1" < / span > < span class = "p" > ];< / span >
< span class = "n" > d< / span > < span class = "o" > -> < / span > < span class = "n" > b< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 0" < / span > < span class = "p" > ];< / span >
< span class = "n" > d< / span > < span class = "o" > -> < / span > < span class = "n" > f< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 1" < / span > < span class = "p" > ];< / span >
< span class = "n" > e< / span > < span class = "o" > -> < / span > < span class = "n" > b< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 0" < / span > < span class = "p" > ];< / span >
< span class = "n" > e< / span > < span class = "o" > -> < / span > < span class = "n" > g< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 1" < / span > < span class = "p" > ];< / span >
< span class = "n" > f< / span > < span class = "o" > -> < / span > < span class = "n" > b< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 0" < / span > < span class = "p" > ];< / span >
< span class = "n" > f< / span > < span class = "o" > -> < / span > < span class = "n" > h< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 1" < / span > < span class = "p" > ];< / span >
< span class = "n" > g< / span > < span class = "o" > -> < / span > < span class = "n" > i< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 0" < / span > < span class = "p" > ];< / span >
< span class = "n" > g< / span > < span class = "o" > -> < / span > < span class = "n" > g< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 1" < / span > < span class = "p" > ];< / span >
< span class = "n" > h< / span > < span class = "o" > -> < / span > < span class = "n" > i< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 0" < / span > < span class = "p" > ];< / span >
< span class = "n" > h< / span > < span class = "o" > -> < / span > < span class = "n" > h< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 1" < / span > < span class = "p" > ];< / span >
< span class = "n" > i< / span > < span class = "o" > -> < / span > < span class = "n" > i< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 0" < / span > < span class = "p" > ];< / span >
< span class = "n" > i< / span > < span class = "o" > -> < / span > < span class = "n" > j< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 1" < / span > < span class = "p" > ];< / span >
< span class = "n" > j< / span > < span class = "o" > -> < / span > < span class = "n" > i< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 0" < / span > < span class = "p" > ];< / span >
< span class = "n" > j< / span > < span class = "o" > -> < / span > < span class = "n" > h< / span > < span class = "p" > [< / span > < span class = "n" > label< / span > < span class = "o" > =< / span > < span class = "s2" > " 1" < / 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" > ' ' ' Loop on ones.' ' ' < / 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" > ' ' ' Loop on zeros.' ' ' < / 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" > & < / 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 > isn’ t.< / 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" > ' < / span > < span class = "si" > %05s< / span > < span class = "s1" > ' < / 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" > Brzozowski’ s 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" > & < / 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" > Let’ s 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 >