Rules for classifying Life ash

For general discussion about Conway's Game of Life.
Post Reply
User avatar
apg
Moderator
Posts: 3007
Joined: June 1st, 2009, 4:32 pm

Rules for classifying Life ash

Post by apg »

Firstly, I will open with the following picture:
The ash left behind by Ed, with still-lifes, p2 oscillators and other periods colour-coded.
The ash left behind by Ed, with still-lifes, p2 oscillators and other periods colour-coded.
classified.png (6.59 KiB) Viewed 8515 times
This is the ash left behind by Schneelocke's 30K-generation methuselah, Ed. In the image, the pattern is clustered into objects (connected components of nonzero cells), each of which is coloured either blue, red or green depending on whether the pattern is a still-life, p2 oscillator or something rarer, respectively.

You may think that this was produced by a Python script (which would be slow). Instead, it was generated simply by running rules in Golly. To classify the ash of a methuselah, perform the following steps in succession:
  • Run the methuselah to completion in B3/S23, and discard any escaped spaceships.
  • Convert to the rule CoalesceObjects, and run for the maximum period of any constituent object.
  • Convert to the rule ClassifyObjects, and run for the maximum size of any constituent object.
The result is the arrangement above.

I'm also going to write a third rule to identify and delete especially common objects such as blocks, blinkers and beehives. This 'pre-processing' will confer a significant performance advantage over solely using a Python script for censusing objects. I want the performance bottleneck to lie in QuickLife running the pattern to completion, rather than my script censusing the output.

Okay, so I suppose I ought to explain my motivation. I'm designing a soup search script, along the lines of Nathaniel's soup search and Andrzej Okrasinsky's screensaver (but entirely in a Golly script). A slight difference is that the soups will be 16-by-16 rather than 20-by-20, being SHA-256 hashes written in a square grid.

A much more significant difference is that this will be the client script of a peer-to-peer cryptocurrency I'm designing (inspired by the CAcoin thread on these forums) where the proof-of-work is finding Life soups that either have long stabilisation times, or produce rare objects, or some combination thereof.

Specifically, the 'score' of a soup will be the sum of its stabilisation time and any 'bonuses' awarded by the presence of rare objects. Bonuses associated with things like pulsars and pentadecathlons will be preset, whereas bonuses associated with rarer objects discovered by this soup search will depend on the rarity (as determined by the search itself!) and fluctuate over time. If the score of the soup exceeds a given difficulty target, you win that particular vertex of the blockchain.

I'm hoping that this will appeal to both Life enthusiasts and cryptocurrency aficionados alike, for several reasons.

1. There will be the same competitive enjoyment as the original soup search, although this will probably be faster due to the optimisations mentioned above.

2. There will be the prospect of making new Life discoveries.

3. Financial incentives for mining are automatically incorporated, as they are with Bitcoin.

4. There isn't a cat in hell's chance that mining the cryptocurrency will be the sole preserve of people with bespoke ASICs, since no conceivable ASIC would be significantly faster than Golly running on a general-purpose PC. Litecoin and Primecoin were also designed with this in mind.

5. It produces pretty pictures!

Anyway, you probably want the rules themselves. Here they are in the Golly 2.5 rule format:

CoalesceObjects.rule

Code: Select all

@RULE CoalesceObjects

A variant of HistoricalLife which separates a field of ash into
distinct objects.

state 0:  vacuum
state 1:  ON
state 2:  OFF


@TABLE

n_states:3
neighborhood:Moore
symmetries:permute

var a={0,2}
var b={0,2}
var c={0,2}
var d={0,2}
var e={0,2}
var f={0,2}
var g={0,2}
var h={0,1,2}
var i={0,1,2}
var j={0,1,2}
var k={0,1,2}
var l={0,1,2}
var m={0,1,2}
var n={0,1,2}
var o={0,1,2}
var p={0,1,2}

# 3-neighbour birth/survival
h,1,1,1,a,b,c,d,e,1
h,1,1,a,1,b,c,d,e,1
h,1,1,a,b,1,c,d,e,1
h,1,a,1,b,1,c,d,e,1
h,1,a,1,b,c,1,d,e,1

# 2-neighbour survival
1,1,1,a,b,c,d,e,f,1
1,1,a,1,b,c,d,e,f,1
1,1,a,b,1,c,d,e,f,1
1,1,a,b,c,1,d,e,f,1

# Bridge inductors
e,1,1,1,1,h,i,j,k,2
e,1,1,1,h,1,i,j,k,2
e,1,1,1,h,i,1,j,k,2
e,1,1,h,1,1,i,j,k,2
e,1,1,h,1,i,1,j,k,2
e,1,1,h,1,i,j,1,k,2
e,1,1,h,i,1,1,j,k,2
e,1,h,1,i,1,j,1,k,2

# On state dies and becomes the history state
1,i,j,k,l,m,n,o,p,2
2,i,j,k,l,m,n,o,p,2


# Off state remains in off state by default



@COLORS

1  255  255  255
2  127  127  127

ClassifyObjects.rule

Code: Select all

@RULE ClassifyObjects

This passively classifies objects as either still-lifes, p2 oscillators
or higher-period oscillators. It is mandatory that one first runs the
rule CoalesceObjects.

state 0:  vacuum
state 1:  input ON
state 2:  input OFF

state 3:  ON, will die
state 4:  OFF, will remain off
state 5:  ON, will survive
state 6:  OFF, will become alive

state 7:  ON, still-life
state 8:  OFF, still-life

state 9:  ON, p2 oscillator
state 10: OFF, p2 oscillator

state 11: ON, higher-period object
state 12: OFF, higher-period object


@TABLE

n_states:13
neighborhood:Moore
symmetries:permute

var da={0,2,4,6,8,10,12}
var db={0,2,4,6,8,10,12}
var dc={0,2,4,6,8,10,12}
var dd={0,2,4,6,8,10,12}
var de={0,2,4,6,8,10,12}
var df={0,2,4,6,8,10,12}
var dg={0,2,4,6,8,10,12}
var dh={0,2,4,6,8,10,12}

var la={1,3,5,7,9,11}
var lb={1,3,5,7,9,11}
var lc={1,3,5,7,9,11}
var ld={1,3,5,7,9,11}
var le={1,3,5,7,9,11}
var lf={1,3,5,7,9,11}
var lg={1,3,5,7,9,11}
var lh={1,3,5,7,9,11}

var a={0,1,2,3,4,5,6,7,8,9,10,11,12}
var b={0,1,2,3,4,5,6,7,8,9,10,11,12}
var c={0,1,2,3,4,5,6,7,8,9,10,11,12}
var d={0,1,2,3,4,5,6,7,8,9,10,11,12}
var e={0,1,2,3,4,5,6,7,8,9,10,11,12}
var f={0,1,2,3,4,5,6,7,8,9,10,11,12}
var g={0,1,2,3,4,5,6,7,8,9,10,11,12}
var h={0,1,2,3,4,5,6,7,8,9,10,11,12}

var pa={0,3,4}
var pb={0,3,4}
var pc={0,3,4}
var pd={0,3,4}
var pe={0,3,4}
var pf={0,3,4}
var pg={0,3,4}
var ph={0,3,4}

var qa={5,6}
var qb={5,6}
var qc={5,6}
var qd={5,6}
var qe={5,6}
var qf={5,6}
var qg={5,6}
var qh={5,6}


2,la,lb,lc,dd,de,df,dg,dh,6
2,a,b,c,d,e,f,g,h,4

1,la,lb,lc,dd,de,df,dg,dh,5
1,la,lb,dc,dd,de,df,dg,dh,5
1,a,b,c,d,e,f,g,h,3

5,qa,qb,qc,pd,pe,pf,pg,ph,7
5,qa,qb,pc,pd,pe,pf,pg,ph,7
5,a,b,c,d,e,f,g,h,11

3,qa,qb,qc,pd,pe,pf,pg,ph,9
3,a,b,c,d,e,f,g,h,11

4,qa,qb,qc,pd,pe,pf,pg,ph,12
4,a,b,c,d,e,f,g,h,8

6,qa,qb,qc,pd,pe,pf,pg,ph,12
6,qa,qb,pc,pd,pe,pf,pg,ph,12
6,a,b,c,d,e,f,g,h,10

# Propagate interestingness
7,11,b,c,d,e,f,g,h,11
7,12,b,c,d,e,f,g,h,11
7,9,b,c,d,e,f,g,h,9
7,10,b,c,d,e,f,g,h,9
8,11,b,c,d,e,f,g,h,12
8,12,b,c,d,e,f,g,h,12
8,9,b,c,d,e,f,g,h,10
8,10,b,c,d,e,f,g,h,10
9,11,b,c,d,e,f,g,h,11
9,12,b,c,d,e,f,g,h,11
10,11,b,c,d,e,f,g,h,12
10,12,b,c,d,e,f,g,h,12


@COLORS

1  255  255  255
2  127  127  127
7    0    0  255
8    0    0  127
9  255    0    0
10 127    0    0
11   0  255    0
12   0  127    0
What do you do with ill crystallographers? Take them to the mono-clinic!
User avatar
apg
Moderator
Posts: 3007
Joined: June 1st, 2009, 4:32 pm

Re: Rules for classifying Life ash

Post by apg »

This rule removes and counts any blocks, blinkers and beehives from the output of ClassifyObjects, thereby removing 84% of the objects that need to be censused. Run this for precisely 4 generations, noting the population counts after each generation.

ExpungeObjects.rule

Code: Select all

@RULE ExpungeObjects

This removes unwanted blocks, blinkers and beehives.
It is mandatory that one first runs the rule ClassifyObjects.

Run this for four generations, and observe the population
counts after 1, 2, 3 and 4 generations. This will give the
following data:

number of blocks = (p(2) - p(1))/4
number of blinkers = (p(3) - p(2))/5
number of beehives = (p(4) - p(3))/8


@TABLE

n_states:14
neighborhood:Moore
symmetries:rotate4reflect

var a={0,1,2,3,4,5,6,7,8,9,10,11,12,13}
var b={0,1,2,3,4,5,6,7,8,9,10,11,12,13}
var c={0,1,2,3,4,5,6,7,8,9,10,11,12,13}
var d={0,1,2,3,4,5,6,7,8,9,10,11,12,13}
var e={0,1,2,3,4,5,6,7,8,9,10,11,12,13}
var f={0,1,2,3,4,5,6,7,8,9,10,11,12,13}
var g={0,1,2,3,4,5,6,7,8,9,10,11,12,13}
var h={0,1,2,3,4,5,6,7,8,9,10,11,12,13}

# Death
6,a,b,c,d,e,f,g,h,0
a,6,b,c,d,e,f,g,h,0

# Block
7,7,7,7,0,0,0,0,0,1
1,1,1,1,0,0,0,0,0,0
1,a,b,c,d,e,f,g,h,7

# Blinker
10,0,0,0,9,9,9,0,0,2
9,9,10,0,0,0,0,0,10,3
2,a,b,c,d,e,f,g,h,10
3,a,b,c,d,e,f,g,h,9
9,2,0,3,0,2,0,3,0,6

# Beehive
7,0,7,8,7,0,0,0,0,1
7,0,0,7,8,8,7,0,0,1
8,7,7,8,7,7,0,7,0,4
4,1,1,4,1,1,0,1,0,5
4,a,b,c,d,e,f,g,h,8
5,a,b,c,d,e,f,g,h,6


@COLORS

7    0    0  255
8    0    0  127
9  255    0    0
10 127    0    0
11   0  255    0
12   0  127    0
It doesn't remove objects that are parts of larger pseudo-objects, so bi-blocks will survive the expunging process. They're not sufficiently common to matter, though -- this is just a preprocessing step to speed up the censusing process.
What do you do with ill crystallographers? Take them to the mono-clinic!
User avatar
Andrew
Moderator
Posts: 1065
Joined: June 2nd, 2009, 2:08 am
Location: Melbourne, Australia
Contact:

Re: Rules for classifying Life ash

Post by Andrew »

Very nice idea! Can't wait to see your soup searching script in action (happy to test beta versions!).

I assume the 1st phase of the script (ie. running a soup to "completion") will look something like oscar.py but with extra code to detect a soup with both an oscillating population and an expanding boundary (due to escaping gliders or spaceships)?

Will the soup's score include a few extra points for an escaping ship other than a glider (eg. L/M/HWSS are much rarer)? And a huge bonus for a completely new type of ship?
Use Glu or Glui to explore CA rules on non-periodic tilings: DominoLife and HatLife and SpectreLife
User avatar
apg
Moderator
Posts: 3007
Joined: June 1st, 2009, 4:32 pm

Re: Rules for classifying Life ash

Post by apg »

Andrew wrote:Very nice idea! Can't wait to see your soup searching script in action (happy to test beta versions!).
Thank you!
Andrew wrote:I assume the 1st phase of the script (ie. running a soup to "completion") will look something like oscar.py but with extra code to detect a soup with both an oscillating population and an expanding boundary (due to escaping gliders or spaceships)?
Yes. I'm trying to minimise 'mean time per soup', so this phase will actually be divided into several steps. Based on experimentation, I think that I can get 'mean time per soup' down to 0.1 seconds per CPU on my laptop with the following approach. Indeed, the instructions below are sufficiently precise that I can probably write a Python script in a few hours -- but first I need to finish packing for a flight in 90 minutes' time!

1. Run QuickLife for multiples of 30 generations, up to a maximum of 6000 generations. If 20 consecutive snapshots have the same population, then assume the pattern has stabilised (and set P = 30) and jump to step 3.

2. 'Oscar' (with a base step of 6) a 2000-by-2000 square centred on the origin until it stabilises with a period P (or times out after 20000 + T generations, where T is the target score, in which case give up trying to run the soup to completion since it already comfortably wins the vertex of the blockchain). If the population of the entire pattern (not just the central square) is not P-periodic, then we either have an ultra-rare spaceship or infinite-growth pattern such as a switch engine.

Note: At this point, the configuration is considered to have stabilised; the current generation is an upper bound on the stabilisation time.

3. Run CoalesceObjects for 2^n > min(8,P) generations (or 2^10 if there is a possibility of an infinite-growth pattern, as determined by the previous step), and then run ClassifyObjects for 2^10 generations.

4. If there is a possibility of an infinite growth pattern, then use the HandlePlumes.rule (which I prepared earlier but haven't posted yet), which ensures that the objects in the plume of the switch engine are reassessed. (Otherwise, disjoint objects can end up being grouped together if they appeared from the smoke during the CoalesceObjects phase.)

5. Run ExpungeObjects to kill and count any blocks, blinkers or beehives.

6. Separate the ash field into objects (connected components of non-ground cells in the current rule), and then convert each object back to B3/S23. For each moving component produced, verify that it isn't a disjoint union of gliders (in which case separate them).

7. If an object is an oscillator or spaceship, then convert to a standard form (so that identical objects in different phases or orientations are considered equal).

8. If the object is not an oscillator or spaceship, then run it for a while and analyse the population to determine whether it is (with almost certainty) a known naturally-occurring form of the switch engine. If so, the 'standard form' will just be the string "block-laying switch engine" or "glider-producing switch engine". Otherwise, it's sufficiently rare that we'll keep it in its current form rather than converting to a standard form.

9. Categorise the resulting objects (possibly splitting pseudo-objects depending on consensus) and compute the sum B of the bonuses.

10. If there is a possibility that the score exceeds the target, re-run the pattern to determine the stabilisation time C exactly. (For concreteness, we're defining 'stabilisation time' to be 'time until the population henceforth becomes expressible as the sum of a periodic function and a linear function'.) Calculate the score S = B + C, and compare it with the target score T.
Andrew wrote:Will the soup's score include a few extra points for an escaping ship other than a glider (eg. L/M/HWSS are much rarer)? And a huge bonus for a completely new type of ship?
Absolutely!
What do you do with ill crystallographers? Take them to the mono-clinic!
User avatar
dvgrn
Moderator
Posts: 12047
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI
Contact:

Re: Rules for classifying Life ash

Post by dvgrn »

calcyman wrote:This rule removes and counts any blocks, blinkers and beehives from the output of ClassifyObjects, thereby removing 84% of the objects that need to be censused.
Nice trick! I guess it's not as easy, or not worth the time, to do a similar rule to take care of loaf/boat/tub/pond/ship? I suppose with larger sized objects it's a little harder to rule out larger variants like lakes that have most of the same local neighborhoods.
User avatar
apg
Moderator
Posts: 3007
Joined: June 1st, 2009, 4:32 pm

Re: Rules for classifying Life ash

Post by apg »

Correct, boats and loaves aren't common enough to warrant this. Gliders, on the other hand, are incredibly annoying since they are both common and mobile -- so much so that writing this 17-state rule was necessary to detect the pesky critters:

Code: Select all

@RULE IdentifyGliders

Run this after CoalesceObjects to find any gliders.

state 0:  vacuum
state 1:  ON
state 2:  OFF


@TABLE

n_states:17
neighborhood:Moore
symmetries:rotate4reflect

var a={0,2}
var b={0,2}
var c={0,2}
var d={0,2}
var e={0,2}
var f={0,2}
var g={0,2}
var h={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
var i={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
var j={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
var k={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
var l={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
var m={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
var n={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
var o={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
var p={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
var q={3,4}
var r={9,10}
var s={11,12}

1,1,a,1,1,b,1,c,d,3
d,1,1,1,1,a,b,1,c,4

3,i,j,k,l,m,n,o,p,5
4,i,j,k,l,m,n,o,p,6

1,q,i,j,a,b,c,k,l,7
d,q,i,j,a,b,c,k,l,8
1,i,a,b,c,d,e,j,q,7
f,i,a,b,c,d,e,j,q,8

5,7,8,7,7,8,7,8,8,9
6,7,7,7,7,8,8,7,8,10
5,i,j,k,l,m,n,o,p,15
6,i,j,k,l,m,n,o,p,16
15,i,j,k,l,m,n,o,p,1
16,i,j,k,l,m,n,o,p,2

7,i,j,k,l,m,n,o,p,11
8,i,j,k,l,m,n,o,p,12

9,i,j,k,l,m,n,o,p,13
10,i,j,k,l,m,n,o,p,14
11,r,j,k,l,m,n,o,p,13
11,i,r,k,l,m,n,o,p,13
12,r,j,k,l,m,n,o,p,14
12,i,r,k,l,m,n,o,p,14

11,i,j,k,l,m,n,o,p,1
12,i,j,k,l,m,n,o,p,2

@COLORS

1  255  255  255
2  127  127  127
13 255  255    0
14 127  127    0
It's not perfect, since it only checks a one-cell border around the glider, but any failures are non-fatal (since they will be caught by a suitably modified version of ClassifyObjects).
Part of a period-2 oscillator pretending to be a glider.
Part of a period-2 oscillator pretending to be a glider.
nonfatal.png (16.08 KiB) Viewed 8415 times
The planned sequence of rules is now:

CoalesceObjects ==> IdentifyGliders ==> ClassifyObjects (modified) ==> ExpungeObjects (modified)

It also means that gliders in close proximity will be automatically expunged, without ever having chance to foil the census script into believing them to be a single spaceship.
What do you do with ill crystallographers? Take them to the mono-clinic!
fluffykitty
Posts: 1178
Joined: June 14th, 2014, 5:03 pm
Contact:

Re: Rules for classifying Life ash

Post by fluffykitty »

calcyman wrote:...4. If there is a possibility of an infinite growth pattern, then use the HandlePlumes.rule (which I prepared earlier but haven't posted yet), which ensures that the objects in the plume of the switch engine are reassessed. (Otherwise, disjoint objects can end up being grouped together if they appeared from the smoke during the CoalesceObjects phase.)
Will you post it?
calcyman wrote:...

Code: Select all

@RULE CoalesceObjects

A variant of HistoricalLife which separates a field of ash into
distinct objects.

state 0:  vacuum
state 1:  ON
state 2:  OFF


@TABLE

n_states:3
neighborhood:Moore
symmetries:permute

var a={0,2}
var b={0,2}
var c={0,2}
var d={0,2}
var e={0,2}
var f={0,2}
var g={0,2}
var h={0,1,2}
var i={0,1,2}
var j={0,1,2}
var k={0,1,2}
var l={0,1,2}
var m={0,1,2}
var n={0,1,2}
var o={0,1,2}
var p={0,1,2}

# 3-neighbour birth/survival
h,1,1,1,a,b,c,d,e,1
h,1,1,a,1,b,c,d,e,1
h,1,1,a,b,1,c,d,e,1
h,1,a,1,b,1,c,d,e,1
h,1,a,1,b,c,1,d,e,1

# 2-neighbour survival
1,1,1,a,b,c,d,e,f,1
1,1,a,1,b,c,d,e,f,1
1,1,a,b,1,c,d,e,f,1
1,1,a,b,c,1,d,e,f,1

# Bridge inductors
e,1,1,1,1,h,i,j,k,2
e,1,1,1,h,1,i,j,k,2
e,1,1,1,h,i,1,j,k,2
e,1,1,h,1,1,i,j,k,2
e,1,1,h,1,i,1,j,k,2
e,1,1,h,1,i,j,1,k,2
e,1,1,h,i,1,1,j,k,2
e,1,h,1,i,1,j,1,k,2

# On state dies and becomes the history state
1,i,j,k,l,m,n,o,p,2
2,i,j,k,l,m,n,o,p,2


# Off state remains in off state by default



@COLORS

1  255  255  255
2  127  127  127
Uh, you must've forgotten that you used permute symmetry? Corrected:

Code: Select all

@RULE CoalesceObjects

A variant of HistoricalLife which separates a field of ash into
distinct objects.

state 0:  vacuum
state 1:  ON
state 2:  OFF


@TABLE

n_states:3
neighborhood:Moore
symmetries:permute

var a={0,2}
var b={0,2}
var c={0,2}
var d={0,2}
var e={0,2}
var f={0,2}
var g={0,2}
var h={0,1,2}
var i={0,1,2}
var j={0,1,2}
var k={0,1,2}
var l={0,1,2}
var m={0,1,2}
var n={0,1,2}
var o={0,1,2}
var p={0,1,2}

# 3-neighbour birth/survival
h,1,1,1,a,b,c,d,e,1

# 2-neighbour survival
1,1,1,a,b,c,d,e,f,1

# Bridge inductors
e,1,1,1,1,h,i,j,k,2

# On state dies and becomes the history state
1,i,j,k,l,m,n,o,p,2
2,i,j,k,l,m,n,o,p,2


# Off state remains in off state by default



@COLORS

1  255  255  255
2  127  127  127
User avatar
apg
Moderator
Posts: 3007
Joined: June 1st, 2009, 4:32 pm

Re: Rules for classifying Life ash

Post by apg »

Will you post it?
HandlePlumes isn't particularly impressive; it just converts p1 and p2 objects back to two states, so that they can be rerun in ClassifyObjects.

And naturally I'll post it when I release the prototype census script.
What do you do with ill crystallographers? Take them to the mono-clinic!
User avatar
Lewis
Posts: 337
Joined: March 17th, 2009, 5:26 pm
Contact:

Re: Rules for classifying Life ash

Post by Lewis »

How will the census classify something like the two pentadecathlons below:

Code: Select all

x = 16, y = 11, rule = B3/S23
2bo2bo4bo2bo$3o2b6o2b3o$2bo2bo4bo2bo6$bo2b2o4b2o2bo$o3b3o2b3o3bo$bo2b
2o4b2o2bo!
Despite the fact they don't interact in any generation their rotors overlap by 2 cells, and running them under CoalesceObjects appears to classify them as one large object.
(Admittedly, the chance of two PDs occurring in this way naturally is really low anyway...)

Also, how well would the census be able to cope with other life-like rules? CoalesceObjects can be modified to work for other rules (I had a go at modifying it for 2x2 and b35/s23, mainly just to get an idea of how rule tables work) but do other parts of the program operate using things that only work specific to Life (like the methods for detecting infinite growth etc.)?
User avatar
apg
Moderator
Posts: 3007
Joined: June 1st, 2009, 4:32 pm

Re: Rules for classifying Life ash

Post by apg »

Despite the fact they don't interact in any generation their rotors overlap by 2 cells, and running them under CoalesceObjects appears to classify them as one large object.
Correct. But it's always confusing how we should handle things, as shown by the following thought experiment.

A reflectorless rotating oscillator is like a spaceship, but travels in a loop rather than a line. Suppose we have a RRO with period 600.

Now, we can take the disjoint union of this RRO and a copy advanced by 300 generations. The resulting pattern is period-300, not period-600, even though it is composed of two completely non-interacting period-600 oscillators.

(RROs do exist, a la universal construction, but would have a much larger period than this.)
What do you do with ill crystallographers? Take them to the mono-clinic!
Post Reply