Tutorials/slsparse

From LifeWiki
Revision as of 16:24, 28 November 2018 by Dvgrn (talk | contribs) (→‎More Features: 0-degree recipes for narrow metaclusters)
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. The content of infile.mc can actually be in either macrocell format or standard RLE, but the name must be "infile.mc".

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. There are recipes available for pushing any specific distance, but we'll mostly make use of the most efficient known long-distance move, a 44hd elbow push:

x = 530, y = 533, rule = B3/S23 528b2o$528b2o3$527b3o$529bo$528bo25$500b2o$501b2o$500bo20$478bo$478b2o $477bobo22$454b3o$456bo$455bo20$432bo$432b2o$431bobo21$409b2o$410b2o$ 409bo22$385b3o$387bo$386bo20$363bo$363b2o$362bobo21$340b2o$339bobo$ 341bo33$305b3o$307bo$306bo37$266b2o$267b2o$266bo22$242b2o$243b2o$242bo 20$220bo$220b2o$219bobo28$190bo$190b2o$189bobo21$167b2o$166bobo$168bo 22$143bo$143b2o$142bobo25$116b2o$115bobo$117bo21$93b3o$95bo$94bo20$71b 2o$70bobo$72bo21$48bo$48b2o$47bobo45$bo$b2o$obo! #C [[ THUMBSIZE 2 THEME 6 GRID GRIDMAJOR 0 SUPPRESS THUMBLAUNCH ]] #C [[ THEME 6 WIDTH 1000 HEIGHT 1000 STEP 1 PAUSE 2 X 260 Y -260 Z 6 PAUSE 0 STEP 25 PAUSE 2 T 2000 STEP 5 T 2195 PAUSE 2 LOOP 2196 ]]
44hd elbow push recipe

(click above to open LifeViewer)

2) The elbow is pushed out another 2048 cells, then builds the child's Circuit B (Snark).

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) Now we're back to something slmake can do! This time we just need to ask slmake to build a Snark reflector.

9) 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.

10) 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.

11) 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. 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.

12) 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.

13) Push the elbow block outward until it lines up with the syringe and H-to-2G, and shoot it down with six more *WSSes.

14) 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 8.

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.

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 THUMBNAIL THUMBSIZE 2 ZOOM -12 ]]
Southwest to northeast:
block-on-mango where construction-arm elbow starts,
Circuit A (syringe and H-to-2G),
Circuit B (Snark)

(click above to open LifeViewer)

Run slsparse the first time with

./slsparse.cpp

This creates an slsparse.exe file and automatically runs it. For future runs you can get away with just

./slsparse

until there's an update to the slsparse GitLabs repository, at which point you'll want to download and re-compile:

rm infile.mc
git pull
./slsparse.cpp

All of these commands are run directly from the slmake root folder.

When you run slsparse, if the program finds a way to build the contents of infile.mc, 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 8 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 = 72, rule = B3/S23 63b2o$62bo2bo$61bob2obo$60bobo2bobo$60bobo2bobo$61bob2obo$62bo2bo$63b 2o5$48b2o$49bo$47bo$47b5o14b2o$52bo13bo$49b3o12bobo$48bo15b2o$48b4o$ 46b2o3bo3b2o$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 600 WIDTH 600 ZOOM 6 ]]
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.
Starting block location marked by large PS4B still life.

(click above to open LifeViewer)

Giving this to slsparse by saving it as infile.mc is essentially asking for a single-channel recipe starting with a block at the mango-on-block 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: The large 24-bit 'PS4B' still life (pond siamese four beehives) in the above pattern marks the location of an existing target block. This tells slsparse to start with a block in this location, along with the mango-on-block elbow.

If the PS4B marker is not present, slsparse first automatically creates a target "hand" block and moves it to the correct location to start construction. In a multi-cluster constellation there may be several PS4Bs, and also several clusters with no PS4Bs; slsparse will automatically create new hand blocks when they're needed, and use existing ones if they have been marked.

For this last part of the Demonoid construction we have an awkward situation that needs a PS4B marker. 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 lossless-elbow Snark's intended location, way out at Circuit A. Instead we just mark the location of the leftover northeastern elbow block (from Step 5) relative to where we want the Snark to be, and slsparse does the rest.

More Features

  1. If infile.mc contains still lifes with a population of 32 cells or more, slsparse will not attempt to construct them -- but it will assume that they exist in the Life universe, and will attempt to find construction recipes for the remaining objects that do not damage the >=32-bit obstacles. This can be very useful if you need to build a new structure in close proximity to an existing one. Replace the existing structures with equivalent large obstacles, and slsparse will obey the additional constraints.
  2. If a partition of the construction is sufficiently far away that it's cheaper for slsparse to build a Cordership seed, trigger it, wait until the Cordership has traveled sufficiently far away, shoot down the Cordership, clean up the debris except for a single block, and proceed with the construction from there... then slsparse will do this automatically.
  3. If an elbow has to be moved closer to the single-channel source by a long distance, such that it is cheaper for slsparse to generate a 180-degree return glider, wait until the glider is close to the elbow, hit it with another glider, and clean up the debris to regenerate an elbow, slsparse will do this automatically. This is accomplished with an elbow duplication recipe similar to the one used in the Demonoid above. If it is necessary to jump back and forth between two distant points, an elbow will be left behind at the more distant location. The recipes involved are called "left parenthesis" (duplicate the elbow, convert the nearer elbow to a glider, convert the glider back to an elbow at the right distance) and "right parenthesis" (delete the near elbow, and send a cleanup salvo to standardize the far elbow. The current recipe leaves the far elbow in the form of a random-looking junk constellation.)
  4. If a metacluster is in the construction "danger zone" -- i.e., if it overlaps the construction lane, so that some of the final structure would interfere with the elbow-operation reactions necessary to construct it -- then slsparse will send two Snarkmaker recipes, to bend the construction arm to one side of the construction area so that the structure can be put in place safely. When the construction is done, slsparse will add two Snarkbreaker recipes to remove the temporary lossless elbows.
  5. If a sufficiently narrow metacluster is in the construction danger zone, with the required construction gliders no farther to the side than +/-107hd from the single-channel lane, then slsparse will automatically generate a 0-degree elbow and produce the required gliders directly instead of using Snarkmaker / Snarkbreaker pairs.
  6. If an infile.mc pattern contains a block-on-mango plus a set of unidirectional gliders on appropriate lanes that they can be generated by the designated elbow, then slsparse will create a single-channel recipe that generates gliders on those lanes in the specified order. This allows for the color of an entire salvo to be changed easily: moving the block-on-mango by one cell orthogonally and recompiling will produce an opposite-color salvo. The assumption is that the gliders constitute a P2 slow-salvo recipe, so only the parities of the gliders will be preserved. In other words, the resulting output recipe will only be useful if no synchronization is needed between the unidirectional gliders.