{"id":1184,"date":"2020-12-25T00:12:58","date_gmt":"2020-12-25T05:12:58","guid":{"rendered":"https:\/\/stacyprowell.com\/blog\/?p=1184"},"modified":"2020-12-25T00:20:48","modified_gmt":"2020-12-25T05:20:48","slug":"turing-complete","status":"publish","type":"post","link":"https:\/\/stacyprowell.com\/blog\/2020\/12\/25\/turing-complete\/","title":{"rendered":"Turing Complete"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"405\" src=\"https:\/\/stacyprowell.com\/blog\/wp-content\/uploads\/2020\/12\/SKK-1-1024x405.png\" alt=\"SKK = I\" class=\"wp-image-1193\" srcset=\"https:\/\/stacyprowell.com\/blog\/wp-content\/uploads\/2020\/12\/SKK-1-1024x405.png 1024w, https:\/\/stacyprowell.com\/blog\/wp-content\/uploads\/2020\/12\/SKK-1-300x119.png 300w, https:\/\/stacyprowell.com\/blog\/wp-content\/uploads\/2020\/12\/SKK-1-768x304.png 768w, https:\/\/stacyprowell.com\/blog\/wp-content\/uploads\/2020\/12\/SKK-1.png 1137w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption>SKK = I<\/figcaption><\/figure>\n\n\n\n<p>The Relision system is now Turing complete.  This is a good thing, but there is a crazy amount of work left to do.  Right now only the simplest matching is performed to allow somewhat trivial lambda expressions to work.<\/p>\n\n\n\n<p>The screenshot is probably not that impressive.  What is going on?<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2>SKI Calculus<\/h2>\n\n\n\n<p>The SKI calculus consists of three operators.<\/p>\n\n\n\n<ul><li>The <em>identity<\/em>: for any term <span class=\"katex-eq\" data-katex-display=\"false\">x<\/span>; <span class=\"katex-eq\" data-katex-display=\"false\">Ix = x<\/span>.<\/li><li>The <em>constant function generator<\/em>: for any terms <span class=\"katex-eq\" data-katex-display=\"false\">x,y<\/span>; <span class=\"katex-eq\" data-katex-display=\"false\">Kxy = x<\/span><\/li><li>The <em>substitution<\/em>: for any terms <span class=\"katex-eq\" data-katex-display=\"false\">x,y,z<\/span>; <span class=\"katex-eq\" data-katex-display=\"false\">Sxyz = (xz)(yz)<\/span><\/li><\/ul>\n\n\n\n<p>The SKI calculus is useful because it is relatively simple (it only has the above three rules) and because it is <em>Turing complete<\/em>.  Thus any system that is powerful enough to implement the SKI calculus is also Turing complete.<\/p>\n\n\n\n<p>Implementing the SKI calculus in Relision is (relatively) straightforward using single-argument lambdas.<\/p>\n\n\n\n<ul><li>The identity: <code>$x -&gt; $x<\/code><\/li><li>The constant function generator: <code>$x -&gt; $y -&gt; $x<\/code><\/li><li>The substitution operator: <code>$x -&gt; $y -&gt; $z -&gt; (($x.$z).($y.$z))<\/code><\/li><\/ul>\n\n\n\n<p>The Relision language provides lambdas that consist of two parts: a <em>pattern<\/em> and  a <em>body<\/em>, joined by a lambda map symbol <code>-&gt;<\/code>.  When a lambda is <em>applied<\/em> to an argument (using the <em>applicative dot<\/em>), the pattern is matched against the argument, yielding (potentially) a set of bindings.  These bindings are then applied to the lambda&#8217;s body, yielding the final result.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">$x -> $x . 15\n\/\/ Match $x against 15; the match succeeds with {bind $x=>15}.\n\/\/ Apply this binding to the lambda body.\n--> {bind $x=>15} . $x\n--> 15<\/pre>\n\n\n\n<p>The lambda map is right-associative, so the constant function generator is really <code>$x -&gt; ($y -&gt; $x)<\/code>.  Here&#8217;s an example of how it creates constant functions.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">$x -> $y -> $x . 21\n\/\/ Match $x against 21; the match succeeds with {bind $x=>21}.\n\/\/ Apply this binding to the lambda body.  Note that $x is not\n\/\/ bound in the second lambda.\n--> {bind $x=>21} . ($y -> $x)\n--> $y -> 21\n\n\/\/ This is a constant function; it always evaluates to 21.\n$y -> 21 . 9\n--> {bind $y=>9} . 21\n--> 21<\/pre>\n\n\n\n<p>It turns out that in the SKI calculus <span class=\"katex-eq\" data-katex-display=\"false\">SKK = I<\/span>.  We should be able to show that in Relision.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ SKK\n\/\/ S = $x -> $y -> $z -> (($x.$z).($y.$z))\n\/\/ K = $x -> $y -> $x\n(($x -> $y -> $z -> (($x.$z).($y.$z))) . ($x -> $y -> $x)) . ($x -> $y -> $x)\n\/\/&lt;------------- S ----------------->|   |&lt;----- K ---->|    |&lt;----- K ---->|\n--> $z -> $z<\/pre>\n\n\n\n<p>If you look at the screenshot at the start of this post, you&#8217;ll see that Relision correctly handles this case.  In fact, it handles many more; read up on the SKI calculus if you are interested.<\/p>\n\n\n\n<h2>Under the Hood<\/h2>\n\n\n\n<p>Variables that appear in a lambda pattern are rewritten to have a lambda index, and the lambda index of terms is computed based on this.  It isn&#8217;t the same as a DeBruijn index, but it is really close and works well.  Variables are no longer rewritten by name, per se, but by a UID that is computed for each variable name and lambda index.  This makes matching during rewriting a constant time operation, whereas string comparison was not (necessarily).<\/p>\n\n\n\n<p>One of the challenges of working in Rust is that you have to think very carefully about when and what data should be modifiable, who owns it, and how the compiler or runtime can know when to de-allocate it.  The benefits are two: no garbage collection, and a cleaner and more deliberate design.  Still, this puts a lot of cognitive burden on the programmer compared to, say, Python.  Still, after I struggle through a particular part of the implementation I end up in a better place with a cleaner and simpler design.  In short, I think the design of Relision is superior to the older Elision in many ways&#8230; and of course <em>faster<\/em>.<\/p>\n\n\n\n<p>There is a roadmap to the first public release (1.0.0), and shockingly I am making really good progress on it.  The only real challenge is getting access to my computer (I use my own computer for all development; my work computer is on the other side of the room and for <em>paying work<\/em>).  My son has re-discovered the game &#8220;Slime Rancher.&#8221;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>P = computability is the cornerstone of P<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[11,12],"_links":{"self":[{"href":"https:\/\/stacyprowell.com\/blog\/wp-json\/wp\/v2\/posts\/1184"}],"collection":[{"href":"https:\/\/stacyprowell.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/stacyprowell.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/stacyprowell.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/stacyprowell.com\/blog\/wp-json\/wp\/v2\/comments?post=1184"}],"version-history":[{"count":11,"href":"https:\/\/stacyprowell.com\/blog\/wp-json\/wp\/v2\/posts\/1184\/revisions"}],"predecessor-version":[{"id":1198,"href":"https:\/\/stacyprowell.com\/blog\/wp-json\/wp\/v2\/posts\/1184\/revisions\/1198"}],"wp:attachment":[{"href":"https:\/\/stacyprowell.com\/blog\/wp-json\/wp\/v2\/media?parent=1184"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/stacyprowell.com\/blog\/wp-json\/wp\/v2\/categories?post=1184"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/stacyprowell.com\/blog\/wp-json\/wp\/v2\/tags?post=1184"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}