{"id":191,"date":"2006-10-20T14:07:31","date_gmt":"2006-10-20T14:07:31","guid":{"rendered":"http:\/\/scientopia.org\/blogs\/goodmath\/2006\/10\/20\/a-metalanguage-for-pathological-programming-cellular-automata-in-alpaca\/"},"modified":"2006-10-20T14:07:31","modified_gmt":"2006-10-20T14:07:31","slug":"a-metalanguage-for-pathological-programming-cellular-automata-in-alpaca","status":"publish","type":"post","link":"http:\/\/www.goodmath.org\/blog\/2006\/10\/20\/a-metalanguage-for-pathological-programming-cellular-automata-in-alpaca\/","title":{"rendered":"A Metalanguage for Pathological Programming: Cellular Automata in Alpaca"},"content":{"rendered":"<p>Todays entry isn&#8217;t so much a pathological language itself as it is a delightful toy which can be used to *produce* pathological languages. I&#8217;m looking at Chris Pressey&#8217;s wonderful language [ALPACA](http:\/\/catseye.mine.nu:8080\/projects\/alpaca\/), which is a meta-language for describing different kinds of cellular automata.<br \/>\nFrankly, I&#8217;m very jealous of Alpaca. I started writing a cellular automata language something like this on my own; I spent about two weeks of my free time working on it, and got it roughly 90% finished before I found out that he&#8217;d already done it, the bastard!<br \/>\nAlpaca definitely qualifies as a real language, in that it is capable of generating turing complete automatons. We can show this in two different ways. First, Conway&#8217;s life is a trivial program in Alpaca, and you can build a turing machine simulator using life. And second, Alpaca includes an implementation of a Brainfuck clone as a cellular automaton.<br \/>\nAlpaca&#8217;s a very simple language, but it lets you define pretty much any cellular automaton that works in a two-dimensional rectangular grid. And it comes with some very fun, and some very pathological examples.<\/p>\n<p><!--more--><br \/>\nIn case you&#8217;re non familiar with cellular automatons, here&#8217;s a very quick explanation.<br \/>\nIn a cellular automaton, you&#8217;ve got a grid made up of something almost like a collection of identical finite state machines, which are called a *cell*. A cell can be in any one of some finite list of *states*. Each time you step time forwards, the cell gets to modify its state by looking at its own current state, and the states of its immediate neighbors. The entire grid steps simultaneously.<br \/>\nIt&#8217;s a very simple idea, but a remarkably powerful. Some incredibly complicated and fascinating behaviors can be produced by simple cellular automata.  Alpaca lets you define pretty much any two-dimensional rectangular grid based cellular automaton.<br \/>\nFor example, the most famous cellular automaton is Conway&#8217;s &#8220;Game of Life&#8221;. In life, each cell can have one of two states: live, or dead. Each step, if a cell is dead and it has three neighbors that are alive, it switches to alive, otherwise it stays dead. If it&#8217;s alive, and it has 4 or more life neighbors, it dies (overcrowding); if it has less that two neighbors, it dies (loneliness), and if it has three or four neighbors, it stays alive. That&#8217;s it &#8211; that&#8217;s enough to [simulate a turing machine!](http:\/\/www.cs.ualberta.ca\/~bulitko\/F02\/papers\/tm_words.pdf)<br \/>\nLife is trivial in Alpaca:<br \/>\nstate Dead  &#8221; &#8221; to Alive when 3 Alive and 5 Dead;<br \/>\nstate Alive &#8220;*&#8221; to Dead when 4 Alive or 7 Dead.<br \/>\nYou nawe the states, and the rules by which they&#8217;ll change states. The thing in quotes is<br \/>\nthe character that will be used in input files to represent a cell in that state.<br \/>\nHere&#8217;s an example of a very simple input file for the life automaton: it&#8217;s called a *glider*.<\/p>\n<pre>\n*\n* *\n**\n<\/pre>\n<p>If you run the glider, what you&#8217;ll get is basically that figure moving diagonally across the grid. Here&#8217;s a few steps:<br \/>\n<img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/homepage.mac.com\/markcc\/scooter.jpg?w=625\" \/><br \/>\nOr much cooler, here&#8217;s a pattern called the turbine:<\/p>\n<pre>\n****** **\n****** **\n**\n**     **\n**     **\n**     **\n**\n** ******\n** ******\n<\/pre>\n<p>If you run the turbine in life, it will go though a cycle of eight steps over and over again:<br \/>\n<img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"life-turbine-one.jpg\" src=\"https:\/\/i0.wp.com\/scientopia.org\/img-archive\/goodmath\/img_90.jpg?resize=302%2C310\" width=\"302\" height=\"310\" \/><br \/>\n<img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" alt=\"life-turbine-two.jpg\" src=\"https:\/\/i0.wp.com\/scientopia.org\/img-archive\/goodmath\/img_91.jpg?resize=304%2C314\" width=\"304\" height=\"314\" \/><br \/>\nAnother wonderful example of what you can do in Alpaca is wireworld. Wirewold is an amazing automaton which simulates digital circuits. I wrote a bit about wireworld back on the [old GM\/BM](http:\/\/goodmath.blogspot.com\/2006\/04\/wireworld.html).<br \/>\nIn wireworld, you have wires and sparks. Sparks are divided into two parts: the leading edge of a spark, and the trailing edge of a spark. So you end up with four states: empty, wire, spark, and tail. The rules for wireworld are:<br \/>\n1. If you&#8217;re the leading edge of a spark, next step, you turn to tail.<br \/>\n2. If you&#8217;re wire, and *one or two* of your neighbors is the leading edge of a spark, you turn into the leading edge of a spark.<br \/>\n3. If you&#8217;re the trailing edge of a spark, next step, you turn to wire.<br \/>\n4. Otherwise, just stay the way you are.<br \/>\nWritten in Alpaca, wireworld is:<br \/>\nstate Empty &#8221; &#8220;;<br \/>\nstate Spark &#8220;#&#8221; to Tail;<br \/>\nstate Tail &#8220;-&#8221; to Wire;<br \/>\nstate Wire &#8220;=&#8221; to Spark when 1 Spark and not 3 Spark.<br \/>\nAnd here&#8217;s an example of wireworld running, with empty cells as black, wire as gold, leading edge of a spark as green, and tail of a spark as red:<br \/>\n<img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/homepage.mac.com\/markcc\/wire-or.jpg?w=625\" \/><br \/>\nNow, it&#8217;s time to get *seriously* pathological. To demonstrate that this is turing complete, Chris implemented a bit-oriented brainfuck variant called Braktif as a cellular automaton. Here&#8217;s the alpaca program for it, documentation included:<br \/>\n\/*<br \/>\n* The Braktif Cellular Automaton<br \/>\n* June 2005, Chris Pressey<br \/>\n*<br \/>\n* Braktif is an esoteric programming language very similar to<br \/>\n* &#8216;Brainfuck F&#8217; and &#8216;Archway&#8217;, with a small but significant<br \/>\n* difference: Braktif is formulated as a 28-state cellular automaton.<br \/>\n*<br \/>\n* Braktif playfields are divided into a program on the right and<br \/>\n* a data storage area on the left.  (The data storage area can be<br \/>\n* considered to extend indefinately to the left.)  The program<br \/>\n* and data area are connected by a &#8216;bus&#8217;.  On the bus sit the<br \/>\n* instruction pointer, which rests underneath the part of the<br \/>\n* program which is currently executing, and the data pointer, which<br \/>\n* rests underneath the part of the storage which is currently being<br \/>\n* addressed.  The instruction pointer and data pointer communicate<br \/>\n* by means of signals (from the IP to the DP) and replies (from the<br \/>\n* DP to the IP) sent along the bus.<br \/>\n*<br \/>\n* The instructions of a Braktif program resemble those of Smallfuck<br \/>\n* or Brainfuck F:<br \/>\n*<br \/>\n*   *   flip current data bit<br \/>\n*   &gt;   advance DP one cell to the right<br \/>\n*   +]<br \/>\n*<br \/>\n* Braktif:<br \/>\n*                            WendCmd) or (&gt; SkipBack),<br \/>\nto SkipStart when ^&lt; SkipReply and ^ InstrMark,<br \/>\nto SkipFore when v&lt; SkipStart or  when &gt; is Signal,<br \/>\nto ^&gt; when ^&gt; is Signal,<br \/>\nto v&gt; when v&gt; is Signal,<br \/>\nto &lt; when &lt; is Reply,<br \/>\nto ^&lt; when ^&lt; is Reply,<br \/>\nto v&lt; when v LeftTool or &lt; RightTool,<br \/>\nto ContReply when &lt; ContTool,<br \/>\nto SkipReply when  InstrPtr and ^&gt; LeftCmd,<br \/>\nto RightSig when &gt; InstrPtr and ^&gt; RightCmd,<br \/>\nto FlipSig when &gt; InstrPtr and ^&gt; FlipCmd,<br \/>\nto QuerySig when &gt; InstrPtr and ^&gt; WhileCmd,<br \/>\nto InstrPtr when &lt; WakeMark or v&lt; WakeMark or ^&lt; Wakemark,<br \/>\nto InstrPtr when &lt; InstrPtr and ^ SkipBack,<br \/>\nto SkipStop when &lt; SkipFore,<br \/>\nto InstrPtr when  FlipSig,<br \/>\nto LeftTool when &gt; LeftSig,<br \/>\nto RightTool when &gt; RightSig,<br \/>\nto SkipTool when &gt; QuerySig and ^ OffBit,<br \/>\nto ContTool when &gt; QuerySig and ^ OnBit;<br \/>\nstate FlipTool\t&#8220;f&#8221;<br \/>\nto ContTool;<br \/>\nstate LeftTool\t&#8220;l&#8221;<br \/>\nto Bus;<br \/>\nstate RightTool\t&#8220;r&#8221;<br \/>\nto Bus;<br \/>\nstate ContTool  &#8220;c&#8221;<br \/>\nto DataPtr;<br \/>\nstate SkipTool\t&#8220;s&#8221;<br \/>\nto DataPtr;<br \/>\n\/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8211; Data Store: Tape Contents &#8212;&#8212;&#8212;&#8212;&#8212;&#8211; *\/<br \/>\nstate OnBit\t&#8220;1&#8221;<br \/>\nto OffBit when v FlipTool;<br \/>\nstate OffBit\t&#8220;0&#8221;<br \/>\nto OnBit when v FlipTool;<br \/>\n\/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8211; Program: Instruction Pointer &#8212;&#8212;&#8212;&#8212;&#8211; *\/<br \/>\nstate InstrPtr\t&#8220;i&#8221;<br \/>\nto Bus when ^ Space,<br \/>\nto InstrMark;<br \/>\nstate InstrMark\t&#8220;I&#8221;<br \/>\nto WakeMark when &lt; ContReply,<br \/>\nto Bus when &lt; SkipReply;<br \/>\nstate WakeMark\t&quot;W&quot;<br \/>\nto Bus;<br \/>\n\/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8211; Program: Instruction Skipper &#8212;&#8212;&#8212;&#8212;&#8211; *\/<br \/>\nstate SkipStart\t&quot;!&quot;<br \/>\nto Space;<br \/>\nstate SkipStop\t&quot;%&quot;<br \/>\nto Bus;<br \/>\nstate SkipFore\t&quot;}&quot;<br \/>\nto Space;<br \/>\nstate SkipBack\t&quot;{&quot;<br \/>\nto Space;<br \/>\n\/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; Program: Instructions &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- *\/<br \/>\nstate FlipCmd\t&quot;*&quot;;<br \/>\nstate LeftCmd\t&quot;&#8221;;<br \/>\nstate WhileCmd\t&#8220;[&#8220;;<br \/>\nstate WendCmd\t&#8220;]&#8221;.<br \/>\nI don&#8217;t know how to capture the execution of a braktif program for you to watch; I tried using a screen recorder, but it doesn&#8217;t interact well with the terminal where I can run the Alpaca Braktif interpreter. I definitely recommend downloading it and running the braktif example programs: it&#8217;s *fascinating* to watch. There&#8217;s a data bus connecting the program to the data tape, and as the program runs, you can watch data operations flow across the bus to move the data pointer and alter data on the tape. Fascinating, brilliant, and quite definitely, pathological.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Todays entry isn&#8217;t so much a pathological language itself as it is a delightful toy which can be used to *produce* pathological languages. I&#8217;m looking at Chris Pressey&#8217;s wonderful language [ALPACA](http:\/\/catseye.mine.nu:8080\/projects\/alpaca\/), which is a meta-language for describing different kinds of cellular automata. Frankly, I&#8217;m very jealous of Alpaca. I started writing a cellular automata language [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[92],"tags":[],"class_list":["post-191","post","type-post","status-publish","format-standard","hentry","category-pathological-programming"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p4lzZS-35","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/191","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/comments?post=191"}],"version-history":[{"count":0,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/posts\/191\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/media?parent=191"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/categories?post=191"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.goodmath.org\/blog\/wp-json\/wp\/v2\/tags?post=191"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}