Tutorials/slsparse

From LifeWiki
Revision as of 18:38, 11 October 2018 by Dvgrn (talk | contribs) (Raw material for an slsparse tutorial)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Overview

Adam P. Goucher's single-channel compiler program for sparse constellations of still lifes, slsparse, is a very powerful tool for helping to construct a large number of self-constructing Life circuitry designs. This walkthrough describes the current process for piecing together one of the simplest types of self-constructing spaceship, a Demonoid (diagonal Geminoid). Compiling a different self-constructing structure is mostly a matter of building a blueprint for it, and feeding the required still-life constellations into slsparse via an infile.mc or infile.rle.

Installation

This 'slsparse' walkthrough is written for running via Cygwin on Windows. Linux folks will probably be clever enough to adjust the instructions to leave out the Cygwin-related details that they don't need.

To get slsparse working, follow the initial setup instructions for apgmera -- https://gitlab.com/apgoucher/apgmera -- but then run this clone command instead:

git clone https://gitlab.com/apgoucher/slmake.git

cd slmake

Demonoid specifics

Let's assign names to the various widely separated parts of our planned Demonoid. (Need diagram here)

"Circuit A": a signal splitter consisting of a syringe plus a dependent Herschel-to-2-gliders converter. Glider in, two gliders out in different direction -- one to run the construction arm, and one to make a copy of the recipe stream and send it to Circuit B.

"Circuit B": a simple Snark reflector, which sends the recipe stream copy to a copy of Circuit A at the other end of the spaceship.

Each time the recipe glider stream goes through one of the universal constructors, it has to accomplish several tasks:

  1. Create a new child copy of the universal constructor at a (4096,-4096) offset (in Golly coordinates, not Cartesian coordinates -- inverted Y axis). This means starting with the existing elbow near the parent's Circuit B, and pushing an elbow 2048 cells out to build the child's Circuit A.
  2. The elbow is pushed out another 2048 cells to build the child's Circuit B.
  3. Make a 180-degree return glider on a lane 3hd from the single-channel lane, leaving an elbow block next to child Circuit B. The child U.C. will start construction from this elbow location.
  4. Wait until the return glider is passing Circuit A, then hit it with a glider in the channel to make a honeyfarm, then an additional 23-glider salvo to produce a clean new elbow block near Circuit A.
  5. Hit the new elbow block with a 22-glider "elbow duplicator" salvo to produce two elbows in series on the channel.
  6. Hit the nearer, southwest, duplicated elbow block with a stream of 17 gliders to produce a Snark-destroying return glider directly in the channel.
  7. Meet the Snark-destroying return glider with two more gliders to settle the resulting explosion and produce a clean single elbow block, lined up correctly with the glider channel *before* the turn that the Snark has been facilitating (until now).
  8. Use the new elbow block to move the northeast duplicated elbow block -- now a hand block -- into a position where a standard slmake recipe can use it to build a new temporary lossless elbow Snark at the child's Circuit A.

Note: Steps 5, 6, and 8 could be optimized somewhat. We really only need to produce one elbow, plus an extra "hand" block that doesn't have to be on the channel. In fact, instead of cleaning up any leftover junk from the collision in #4, we could use it as a starting target to build the Snark -- all we really need from that collision is a usable elbow block, or even better a single Snark-destroy return glider on the single-channel lane.

  1. Now we're back to something slmake can do! This time we just need to ask slmake to build a Snark reflector.
  2. Add the resulting slmake glider stream to the end of the single-channel recipe so far. Measure how far the first northeastward output glider is from where it needs to be, to strike our adjusted hand block and begin the Snark construction.
  3. Find a workable sequence of block-move recipes from pp.txt to correct for the measured distance, and patch this in just before the slmake Snark construction recipe.
  4. The result will be that a new temporary lossless elbow Snark will be created at a (4096, -4096) offset from the old one, so it will be ready for use immediately when the glider recipe stream arrives at the child constructor. [i]This has to be done as a separate step from #1, by the way, because the single-channel stream passes through this location during the construction of the rest of the U.C.[/i]
  5. Now the construction stage is complete. Again using block-move recipes from pp.txt, push the elbow block outward until it lines up with the Snark reflector from the previous (grandparent) universal constructor, and shoot it down with an LWSS.
  6. Push the elbow block outward until it lines up with the syringe and H-to-2G, and shoot it down with six more *WSSes.
  7. Now the destruction stage is complete. Send an elbow-destroy recipe to delete the elbow block, since it's no longer needed.

Where slsparse comes in

You can get help from slsparse at two points in this recipe -- Step 1 and Step 9.

Start out by setting up your infile.mc to do the Step 1 construction. There's a sample infile.mc in the slsparse package:

{your Cygwin install directory}\home\{your username}\repos\slmake\infile.mc

Open it in Golly and edit it until it matches what you want to build, and where you want to build it relative to the initial elbow block. The block-on-mango marks both the elbow location and the orientation of the input glider stream. Always save the file as infile.mc or infile.rle.

We're going to build a Demonoid with a long step size -- a long distance between reflectors -- so slsparse's long-distance compilation abilities will come in handy.

Here's the input RLE file. Captions to be added later...

x = 4188, y = 4069, rule = B3/S23 4177b2o$4177bobo$4179bo4b2o$4175b4ob2o2bo2bo$4175bo2bobobobob2o$4178bo bobobo$4179b2obobo$4183bo2$4169b2o$4170bo7b2o$4170bobo5b2o$4171b2o7$ 4181b2o$4181bo$4182b3o$4184bo2044$2146bo11b2o$2145bobo10b2o$2112b2o31b obo$2113bo25b2o2b3ob2o$2113bobo23bo2bo$2114b2o21bobo3b3ob2o$2137b2o6bo b2o7$2135b2o13b2o$2135b2o13b2o$2165b2o$2164bo2bo$2165b2obo$2168bo$ 2168b2o$2153b2o$2154bo$2126b2o23b3o$2126bo24bo$2127b3o$2120b2o7bo$ 2120bo$2121b3o$2123bo1970$2bo$bobob2o$o2bob2o$obo$bo! #C [[ THUMBSIZE 2 THEME 6 GRID GRIDMAJOR 0 SUPPRESS THUMBLAUNCH ]] #C [[ THEME 6 HEIGHT 1000 WIDTH 1000 ZOOM -12 ]]
Southwest to northeast:
block-on-mango marking start location for construction-arm elbow,
Circuit A (syringe and H-to-2G,
Circuit B (Snark)

(click above to open LifeViewer)

When you run slsparse, if the compilation process is successful, a single-channel recipe pattern is created in outfile.mc, with the outfile.txt listing the timing offsets between gliders.

The program currently appends lots of elbow block moves to the end of the recipe, to get the elbow back to where it started We don't want to go back that far, so we'll have to identify the exact point where the recipe produces a clean elbow block again after sending the final sideways glider. Remove all the gliders after that to get the useful part of the recipe.

You can do this by running the pattern until the first useless glider is about to hit the elbow. Then copy all the remaining useless recipe gliders, go back to T=0, paste in at a 100-cell horizontal offset or so lined up exactly with the end of the full recipe, then select the doubled area and delete everything. An XOR paste would work if the gliders happened to be in the right phase, but it's much much slower.

(Or there's a sneaky trick: make a copy of progress.txt when the compiler reaches exactly the right point -- or arrange the requested construction so the compilation will fail at the last step and the final gliders are never added!)

In Step 9 we have to build the lossless-elbow Snark. Here's the input pattern. This time it's small enough to be a little easier to understand:

x = 68, y = 60, rule = B3/S23 48b2o$49bo$47bo$47b5o14b2o$52bo13bo$49b3o12bobo$48bo15b2o$48b4o$46b2o 3bo3b2o$45bo2b3o4b2o$45b2obo$48bo$48b2o3$56b2o$57bo$54b3o$54bo37$4bo$ 2obobo$2obo2bo$4bobo$5bo! #C [[ THUMBSIZE 2 THEME 6 GRID GRIDMAJOR 0 SUPPRESS THUMBLAUNCH ]] #C [[ THEME 6 HEIGHT 1000 WIDTH 1000 ]]
block-on-mango marking start location for construction-arm elbow,
and the side where the glider stream will strike.
The Snark is the target pattern to be constructed.

(click above to open LifeViewer)

Giving this to slsparse as infile.rle is essentially asking for a single-channel recipe starting with a block at the block-and-mango location, with gliders aimed to strike the right side of the block. If compilation is successful, the result will be a Snark placed in that precise location relative to the elbow block.

One detail not mentioned in the Demonoid details above: starting from just the elbow, slsparse first automatically creates a target "hand" block and moves it to the correct location to start construction. For the Demonoid we're in an awkward situation: the new temporary lossless-elbow Snark has to be built a very long distance from the actual construction elbow block. So we really don't want to create a hand block and push it all the way to the Snark's location... we're going to have to find that initial part of the recipe, remove it, then adjust the starting location of the block so that the remaining slow salvo of gliders lines up with the faraway block target that we left in place in Step 8 above.

Miscellaneous Notes To Explain Better

I ended up doing Step 8 with a separate Python script, editing in the additional lanes needed to pull the hand block into the correct start position. See elbow-Snark-recipe.txt:

  1. actual recipe starts at E-1 E1 O-27 -- everything before that is the patch

recipeSnark="Snark:E23 E21 E19 E17 E15 E13 E11 E9 E7 E5 E3 E1 E-1 E-3 E-5 E15 E17 E-1 E1 O-27 O3 E11 O9 O15 O29 O15 O-1 E19 O7 O33 E11 O21 E-33 E-15 E-21 E-21 O-43 E25 E15 E27 E25 O31 E33 E27 E37 E43 O21 O23 E-9 E-17 E-29 O-19 E3 O-11 O87 O95 O101 E101 E111 O117 O73 O77 E83 E79 E71 O59 E79 E71 E81 O81 O67 O81 O97 E71 E63 O55 E39 O39 O39 O45 O69 E75 O41 O45 O57 O49 O65 O63 O67 E67 O43 E61 E35 E39 E27 O37 O-3 E1 E1 E33 E109 E95 E129 E131 E119 O99 E107 E107