Tutorials/slsparse

From LifeWiki
Jump to navigation Jump to search

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, standard RLE, or LifeHistory (see below), 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

./slsparse.cpp

(Yes, you compile slsparse by running the .cpp file as if it were an executable file. This is an excessive piece of cleverness, not the way that .cpp files normally work, but the early lines of the .cpp file are arranged so that the file can be interpreted as a valid bash script that produces a compiled slsparse executable, and then runs it.)

A First Trial Run

Before we get into building a Demonoid, here's a simple example of a construction that you should be able to compile using slsparse:

x = 90, y = 103, rule = B3/S23 31b2o$31b2o5b2o$38b2o3$7b2o8b2o17b2o$7b2o9bo17b2o$18bobo21b2o$19b2o21b 2o$b2o$b2o$5b2o21b2o$5b2o20bo2bo$28bobo$23b2o4bo$24bo$2o19b3o$2o19bo 21bo$41b3o$40bo$40b2o7$14b2o$7b2o5b2o$8bo$5b3o$5bo41b2o$10b2o35b2o$10b 2o3$42b2o$42b2o$46b2o$46b2o$5b2o21b2o$5b2o21bobo$11b2o17bo9b2o$11b2o 17b2o8b2o3$9b2o$9b2o5b2o$16b2o24$52b3o$52bo$53bo24$88bo$87bobo$83b2obo 2bo$83b2obobo$87bo! #C [[ THUMBSIZE 2 THEME 6 GRID GRIDMAJOR 0 SUPPRESS THUMBLAUNCH ]] #C [[ HEIGHT 640 WIDTH 640 THUMBSIZE 2 ZOOM 4 THEME 6 ]]
infile pattern for slsparse, for a p256 oscillator
(click above to open LifeViewer)

There are three parts to this slsparse input file:

  • the actual constellation to be constructed, in the northwest in this case;
  • the optional slow salvo of gliders to be constructed after the constellation is complete -- in this case, just one glider to activate the seed;
  • the location and orientation of the initial single-channel elbow that will produce all the slow-salvo construction gliders.

The location of the elbow block is signalled by the placement of a pseudo still life, a block placed one cell away from a mango. The location and orientation of the mango specify where the single-channel glider stream will strike the block. Note that the diagonal width of the mango matches the diagonal width of a single-channel glider lane aimed to hit the block correctly (where the first glider will create a pi-heptomino).

Save the above RLE from LifeViewer, as infile.mc in the slmake root directory. There's no need to actually convert the pattern into macrocell format, though that will work too.

Once you've supplied the input file, simply run slsparse -- no command-line options are needed:

./slsparse

When the compilation is complete, open outfile.mc in Golly. You should see a very long stream of single-channel gliders aimed at a block in the southwest corner. When you run the pattern, the single-channel stream will compile the p256 oscillator seed and trigger it with the specified glider.

Variations

As described in more detail below, by default slsparse will create a target block using a specialized initial slow salvo, and will then push it to whatever location it needs to complete the requested construction. Sometimes you may instead want to start a construction with a pre-placed initial target block. This can be signaled in infile.mc with a specific complex still life, outlining the exact position of the block:

x = 113, y = 134, rule = B3/S23 3b2o$2bo2bo$bob2obo$obo2bobo$obo2bobo$bob2obo$2bo2bo$3b2o24$54b2o$54b 2o5b2o$61b2o3$30b2o8b2o17b2o$30b2o9bo17b2o$41bobo21b2o$42b2o21b2o$24b 2o$24b2o$28b2o21b2o$28b2o20bo2bo$51bobo$46b2o4bo$47bo$23b2o19b3o$23b2o 19bo21bo$64b3o$63bo$63b2o7$37b2o$30b2o5b2o$31bo$28b3o$28bo41b2o$33b2o 35b2o$33b2o3$65b2o$65b2o$69b2o$69b2o$28b2o21b2o$28b2o21bobo$34b2o17bo 9b2o$34b2o17b2o8b2o3$32b2o$32b2o5b2o$39b2o24$75b3o$75bo$76bo24$111bo$ 110bobo$106b2obo2bo$106b2obobo$110bo! #C [[ THUMBSIZE 2 THEME 6 GRID GRIDMAJOR 0 SUPPRESS THUMBLAUNCH ]] #C [[ HEIGHT 640 WIDTH 640 THUMBSIZE 2 ZOOM 4 THEME 6 ]]
infile pattern for slsparse, for a p256 oscillator -- starting block location specified by 24-bit PS4B still life (far NW)
(click above to open LifeViewer)

If the block's starting position is too close to some of the objects being constructed, or even partially or completely overlaps them, then an alternate method of specifying the starting block location can be used. Convert the starting pattern into LifeHistory format, then mark the block location with red state-4 cells. Use white state-3 cells for any cells in the starting target block that overlap a live cell in the pattern-to-construct. Example:

x = 91, y = 103, rule = LifeHistory 32.2A$32.2A5.2A$39.2A3$8.2A8.2A17.2A$8.2A9.A17.2A$19.A.A21.2A$20.2A 21.2A$2.2A$2.2A$6.2A21.2A$6.2A20.A2.A$29.A.A$24.2A4.A$25.A$.2A19.3A$D CA19.A21.A$2D40.3A$41.A$41.2A7$15.2A$8.2A5.2A$9.A$6.3A$6.A41.2A$11.2A 35.2A$11.2A3$43.2A$43.2A$47.2A$47.2A$6.2A21.2A$6.2A21.A.A$12.2A17.A9. 2A$12.2A17.2A8.2A3$10.2A$10.2A5.2A$17.2A24$53.3A$53.A$54.A24$89.A$88. A.A$84.2A.A2.A$84.2A.A.A$88.A! #C [[ THUMBSIZE 2 THEME 6 GRID GRIDMAJOR 0 SUPPRESS THUMBLAUNCH ]] #C [[ HEIGHT 640 WIDTH 640 THUMBSIZE 2 ZOOM 4 THEME 6 ]]
infile pattern for slsparse, for a p256 oscillator -- LifeHistory format
(click above to open LifeViewer)

Demonoid specifics

Let's assign names to the various widely separated parts of our planned Demonoid. (TBD: 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:

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 [[ HEIGHT 600 WIDTH 600 THUMBNAIL THUMBSIZE 2 ZOOM -12 THEME 6 ]]
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 [[ HEIGHT 720 WIDTH 720 THUMBSIZE 2 ZOOM 8 THEME 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.

As described in the Variations section 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.