Reversible Wireless World

For discussion of other cellular automata.
bprentice
Posts: 920
Joined: September 10th, 2009, 6:20 pm
Location: Coos Bay, Oregon

Re: Reversible Wireless World

Post by bprentice » March 5th, 2014, 12:35 pm

Alexander,

Is there a step method for your six state SlAnt rule that is similar to this one?

viewtopic.php?f=11&t=1293&start=25#p10880

If so, could you please write it.

Brian

User avatar
alexv
Posts: 136
Joined: February 3rd, 2014, 11:14 am

Re: Reversible Wireless World

Post by alexv » March 5th, 2014, 1:00 pm

Brian,

Such step method may be written, but it is not written down in some explicit form right now.
In fact, source code used for generation of SlAnt CA (up to renumbering of states) are in
cll directory of CART project (simplc8s6.dpr and simplc9s6.dpr).

Alexander

PS I could say the step function would be more close to this one (without any tables)
viewtopic.php?f=11&t=1293#p10702
PPS I just have tried to write such step function, yet without any testing

Code: Select all

public int step(int row, int column)
  {
    int N  = squareCell.getNeighbor(row - 1, column    );
    int NE = squareCell.getNeighbor(row - 1, column + 1);
    int E  = squareCell.getNeighbor(row    , column + 1);
    int SE = squareCell.getNeighbor(row + 1, column + 1);
    int S  = squareCell.getNeighbor(row + 1, column    );
    int SW = squareCell.getNeighbor(row + 1, column - 1);
    int W  = squareCell.getNeighbor(row    , column - 1);
    int NW = squareCell.getNeighbor(row - 1, column - 1);

   
    int CellType[] = {0,1,0,1,2,2};

    int cell = squareCell.getNeighbor(row, column);

    int cCount = 0;
    if (CellType[N] == 1)   cCount++;
    if (CellType[E] == 1)   cCount++;
    if (CellType[S] == 1)   cCount++;
    if (CellType[W] == 1)   cCount++;
    
    int dCount = 0;
    if (CellType[NW] != 0)  dCount++;
    if (CellType[NE] != 0)  dCount++;
    if (CellType[SE] != 0)  dCount++;
    if (CellType[SW] != 0)  dCount++;
        
    int Cond = 0;
    if ((dCount == 0) && ((cCount == 1) || (cCount == 2)))
      Cond = 1;        
      
    if (Cond == 1)
    {
      if (cell == 0)
        return 4;
      else if (cell == 4)
        return 1;
      else if (cell == 1)
        return 3;
      else if (cell == 3)
        return 5;
      else if (cell == 5)
        return 2;
      else if (cell == 2)
        return 0; 
    }
    if (Cond == 0)
    {
      if (cell == 1)
        return 5;
      else if (cell == 5)
        return 1;
      else if (cell == 2)
        return 4;
      else if (cell == 4)
        return 2;
    }
    return cell;
  }

User avatar
alexv
Posts: 136
Joined: February 3rd, 2014, 11:14 am

Re: Reversible Wireless World

Post by alexv » March 6th, 2014, 7:42 am

I added updated version of archive with 32 new patterns discussed in comments (WlAntWorldNews.zip)
to initial post of the thread: viewtopic.php?f=11&t=1293

Alexander

EricG
Posts: 199
Joined: August 19th, 2011, 5:41 pm
Location: Chicago-area, USA

Re: Reversible Wireless World

Post by EricG » March 7th, 2014, 2:49 am

Alexander,

Thank you very much for slow ants!

From a game of life perspective, slow ants is my favorite rule of the bunch, since it doesn't explode quite as easily. I look forward to playing with it. But it raises questions for me!

Do you hope to someday see these ant rules implemented physically as a quantum dot cellular automata?

If so, does the slow ants rule pose a problem in that it runs twice as slowly? Or, is there a bottleneck in quantum cellular automata that makes the speed of the spaceships less important? (I know almost nothing about quantum CAs, but this thread has made me interested in learning more.)

Is the number of states a problem? Most of the quantum dot CA pages I can find from googling describe a two state cell, implemented with four quantum dots. (I did find an 8 dot cell, for three states). Are cellular automata with a larger number of states (eg 7 states) significantly harder to implement with quantum dots?


I was inspired by Brian's work, so below I'm going to post a script for Golly which takes a 2 state CA and produces the corresponding 4 state reversible CA. You can describe the 2 state CA as a lifelike rule ("B36/S23", etc), or, alternatively, the script allows you to use Alan Hensel's non-totalistic notation.

About the non-totalistic notation: earlier in this thread you asked about notations for rules which distinguish between the number of side neighbors (shared edges) and the number of corner neighbors (a single shared vertex). Brian pointed you to George Maydwell's notation, which was certainly the correct answer, particularly if you want to use a variety of tilings. But for the square grid, another answer is to use Alan Hensel's notation, which was discussed here:

viewtopic.php?f=11&t=936&p=6836

Hensel's notation is more fine-grained than Maydwell's -- it allows you to pick and choose desired neighbors more precisely. Note however, that the notation is isometric, or in other words, rules work the same however many times they are flipped or rotated 90 degrees. Here's a graphical chart (for Golly) showing how to use Hensel's notation:

Code: Select all

x = 147, y = 97, rule = 012345678//3
21.3A6.5A5.A3.A6.3A6.5A5.A3.A5.A3.A6.3A10.A5.4A6.5A5.A.A.A5.5A$20.A3.
A5.A9.A2.A6.A3.A7.A7.A3.A5.A3.A5.A3.A9.A5.A3.A7.A7.A.A.A9.A$20.A9.A9.
A.A7.A3.A7.A7.A3.A5.A3.A5.A3.A9.A5.A3.A7.A7.A.A.A8.A$20.A9.3A7.2A8.5A
7.A7.A3.A6.A.A6.A3.A9.A5.4A8.A7.A.A.A7.A$20.A9.A9.A.A7.A3.A7.A7.A3.A
7.A7.A.A.A5.A3.A5.A3.A7.A7.A.A.A6.A$20.A3.A5.A9.A2.A6.A3.A7.A8.A.A8.A
7.A2.A6.A3.A5.A3.A7.A7.A.A.A5.A$21.3A6.5A5.A3.A5.A3.A5.5A7.A9.A8.2A.A
6.3A6.A3.A7.A8.A.A6.5A4$.3A6.7A$A3.A5.A5.A$A2.2A5.A5.A$A.A.A5.A2.B2.A
$2A2.A5.A5.A$A3.A5.A5.A$.3A6.7A4$.2A17.7A3.7A$A.A17.A5.A3.A5.A$2.A17.
A.A3.A3.A2.A2.A$2.A17.A2.B2.A3.A2.B2.A$2.A17.A5.A3.A5.A$2.A17.A5.A3.A
5.A$5A15.7A3.7A4$.3A16.7A3.7A3.7A3.7A3.7A3.7A$A3.A15.A5.A3.A5.A3.A5.A
3.A5.A3.A5.A3.A5.A$4.A15.A.A.A.A3.A2.A2.A3.A.A3.A3.A.A3.A3.A2.A2.A3.A
3.A.A$3.A16.A2.B2.A3.A.AB2.A3.A2.B2.A3.A.AB2.A3.A2.B2.A3.A2.B2.A$2.A
17.A5.A3.A5.A3.A2.A2.A3.A5.A3.A2.A2.A3.A.A3.A$.A18.A5.A3.A5.A3.A5.A3.
A5.A3.A5.A3.A5.A$5A15.7A3.7A3.7A3.7A3.7A3.7A4$.3A16.7A3.7A3.7A3.7A3.
7A3.7A3.7A3.7A3.7A3.7A$A3.A15.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.
A3.A5.A3.A5.A3.A5.A$4.A15.A.A.A.A3.A2.A2.A3.A.A3.A3.A.2A2.A3.A3.A.A3.
A.A.A.A3.A2.2A.A3.A3.A.A3.A3.A.A3.A.A.A.A$2.2A16.A2.B2.A3.A.AB2.A3.A
2.BA.A3.A.AB2.A3.A2.AB.A3.A.AB2.A3.A2.B2.A3.A2.B2.A3.A2.BA.A3.A2.B2.A
$4.A15.A.A3.A3.A2.A2.A3.A2.A2.A3.A5.A3.A3.A.A3.A5.A3.A2.A2.A3.A.2A2.A
3.A2.A2.A3.A2.A2.A$A3.A15.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A
5.A3.A5.A3.A5.A$.3A16.7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A4$2.2A16.
7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A$.A.A16.A5.A3.A5.A
3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A$A
2.A16.A.A.A.A3.A2.A2.A3.A2.2A.A3.A.3A.A3.A.2A2.A3.A.A.A.A3.A.2A2.A3.A
.2A2.A3.A3.A.A3.A.A.A.A3.A.3A.A3.A.A3.A3.A.2A2.A$5A15.A2.B2.A3.A.ABA.
A3.A.AB2.A3.A.AB2.A3.A2.B2.A3.A.AB2.A3.A.AB2.A3.A.AB2.A3.A.ABA.A3.A2.
B2.A3.A2.B2.A3.A.AB2.A3.A2.B2.A$3.A16.A.A.A.A3.A2.A2.A3.A3.A.A3.A5.A
3.A.2A2.A3.A.A3.A3.A2.A2.A3.A3.A.A3.A2.A2.A3.A.A3.A3.A2.A2.A3.A2.2A.A
3.A2.2A.A$3.A16.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A
3.A5.A3.A5.A3.A5.A3.A5.A$3.A16.7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A
3.7A3.7A3.7A4$5A15.7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A3.7A$A19.A5.A3.A
5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A$4A16.A2.A2.A3.A.A
.A.A3.A2.2A.A3.A3.A.A3.A.2A2.A3.A.A3.A3.A.A.A.A3.A.2A2.A3.A.2A2.A3.A.
A.A.A$4.A15.A.ABA.A3.A2.BA.A3.A.AB2.A3.A2.AB.A3.A.AB2.A3.A.ABA.A3.A.A
BA.A3.A.AB2.A3.A.AB2.A3.A.ABA.A$4.A15.A2.2A.A3.A.A.A.A3.A.A.A.A3.A.3A
.A3.A.2A2.A3.A.2A2.A3.A.A3.A3.A2.2A.A3.A.A.A.A3.A2.A2.A$A3.A15.A5.A3.
A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A$.3A16.7A3.7A3.7A
3.7A3.7A3.7A3.7A3.7A3.7A3.7A4$.3A16.7A3.7A3.7A3.7A3.7A3.7A$A3.A15.A5.
A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A$A19.A2.A2.A3.A.A.A.A3.A2.2A.A3.A2.2A.
A3.A.A.A.A3.A.2A2.A$4A16.A.ABA.A3.A2.BA.A3.A.ABA.A3.A2.BA.A3.A.ABA.A
3.A.ABA.A$A3.A15.A.3A.A3.A.3A.A3.A.A.A.A3.A.3A.A3.A.A.A.A3.A2.2A.A$A
3.A15.A5.A3.A5.A3.A5.A3.A5.A3.A5.A3.A5.A$.3A16.7A3.7A3.7A3.7A3.7A3.7A
4$5A15.7A3.7A$4.A15.A5.A3.A5.A$3.A16.A2.2A.A3.A.3A.A$3.A16.A.ABA.A3.A
2.BA.A$2.A17.A.3A.A3.A.3A.A$2.A17.A5.A3.A5.A$2.A17.7A3.7A4$.3A6.7A$A
3.A5.A5.A$A3.A5.A.3A.A$.3A6.A.ABA.A$A3.A5.A.3A.A$A3.A5.A5.A$.3A6.7A!
If I'm not mistaken, WIant corresponds to the 2nd order technique applied to the rule described in Hensel's notation as"B1e2ei/S1e2ei" and WIant-4 corresponds to the 2nd order technique applied to "B1e2i/S1e2i"

[to be continued]
Last edited by EricG on March 7th, 2014, 3:07 am, edited 5 times in total.

EricG
Posts: 199
Joined: August 19th, 2011, 5:41 pm
Location: Chicago-area, USA

Re: Reversible Wireless World

Post by EricG » March 7th, 2014, 2:52 am

To play with Hensel's notation using Golly, here's a script that accepts Hensel's notation and outputs the corresponding the two state CA. Again, just to be clear, this one produces two state CAs - it is just to show how Hensel's notation works:

Code: Select all

# HenselNotation->WeightedLife2.0.py
# by Eric Goldstein, July 7 2012 (updated for Golly 2.5+ on March 7, 2014)

#  Most of the comments and code are from HenselNotation->Ruletable.py

# This script builds a Golly rule for Life32's non-totalistic notation. 
# The notation was originally adapted from Alan Hensel"s work on that subject.

dialog_box_message =  '''This script will allow you to enter the non-totalistic rule notation 
used by Johan Bontes' Life32 program, based on work by Alan Hensel.
Please look in the script file to see how the notation works.


An example rule is given below as a default.  Rules are case-insensitive.
B2a/S12, S12/B2a, and 12/2a are valid and equivalent.  

Inverse specifications are allowed.  For example, David Bell's Just Friends rule can be 
expressed B2-a/S12 indicating that all B2 arrangements are included except 2a.
 
Enter a rule here:
   '''

# Minor note:
# Unfortunately, Alan Hensel's notation for r and y are swapped in Life32.   
# Life32's rule dialog box shows the correct arrangements, but they are swapped in the implementation.
# What should work as 3r, 4r, and 5r, actually work as 3y, 4y, and 5y, and vice versa.
# This script swaps the definition of r and y just like Life32 does, so that patterns intended to be run
# on Life32 will run the same way in Golly.  

 
# Golly"s ruleTable format use the following notation:  
#  C,N,NE,E,SE,S,SW,W,NW,C' 
# where C is the current state, and C' is the new state, and
# where the eight neighbors in the Moore neighborhood are as shown below.

#     NW  N  NE 
#     W   C  E  
#     SW  S  SE 

# The lookup table below for Life32"s non-totalistic notation uses the eight neighbor values:
#   N,NE,E,SE,S,SW,W,NW



notationdict = { 
                 "1e" : [1,0,0,0,0,0,0,0],  #   N 
                 "1c" : [0,1,0,0,0,0,0,0],  #   NE
                 "2a" : [1,1,0,0,0,0,0,0],  #   N,  NE
                 "2e" : [1,0,1,0,0,0,0,0],  #   N,  E 
                 "2k" : [1,0,0,1,0,0,0,0],  #   N,  SE
                 "2i" : [1,0,0,0,1,0,0,0],  #   N,  S 
                 "2c" : [0,1,0,1,0,0,0,0],  #   NE, SE
                 "2v" : [0,1,0,0,0,1,0,0],  #   NE, SW
                 "3a" : [1,1,1,0,0,0,0,0],  #   N,  NE, E
                 "3v" : [1,1,0,1,0,0,0,0],  #   N,  NE, SE 
                 "3y" : [1,1,0,0,1,0,0,0],  #   N,  NE, S      (3r in non-swapped notation)
                 "3q" : [1,1,0,0,0,1,0,0],  #   N,  NE, SW
                 "3j" : [1,1,0,0,0,0,1,0],  #   N,  NE, W
                 "3i" : [1,1,0,0,0,0,0,1],  #   N,  NE, NW
                 "3e" : [1,0,1,0,1,0,0,0],  #   N,  E,  S
                 "3k" : [1,0,1,0,0,1,0,0],  #   N,  E,  SW
                 "3r" : [1,0,0,1,0,1,0,0],  #   N,  SE, SW     (3y in non-swapped notation)
                 "3c" : [0,1,0,1,0,1,0,0],  #   NE, SE, SW 
                 "4a" : [1,1,1,1,0,0,0,0],  #   N,  NE, E,  SE
                 "4y" : [1,1,1,0,1,0,0,0],  #   N,  NE, E,  S  (4r in non-swapped notation)
                 "4q" : [1,1,1,0,0,1,0,0],  #   N,  NE, E,  SW
                 "4i" : [1,1,0,1,1,0,0,0],  #   N,  NE, SE, S
                 "4r" : [1,1,0,1,0,1,0,0],  #   N,  NE, SE, SW (4y in non-swapped notation)
                 "4k" : [1,1,0,1,0,0,1,0],  #   N,  NE, SE, W
                 "4v" : [1,1,0,1,0,0,0,1],  #   N,  NE, SE, NW 
                 "4z" : [1,1,0,0,1,1,0,0],  #   N,  NE, S,  SW
                 "4j" : [1,1,0,0,1,0,1,0],  #   N,  NE, S,  W
                 "4t" : [1,1,0,0,1,0,0,1],  #   N,  NE, S,  NW
                 "4w" : [1,1,0,0,0,1,1,0],  #   N,  NE, SW, W
                 "4e" : [1,0,1,0,1,0,1,0],  #   N,  E,  S,  W
                 "4c" : [0,1,0,1,0,1,0,1],  #   NE, SE, SW, NW
                 "5a" : [0,0,0,1,1,1,1,1],  #   SE, S,  SW, W,  NW
                 "5v" : [0,0,1,0,1,1,1,1],  #   E,  S,  SW, W,  NW
                 "5y" : [0,0,1,1,0,1,1,1],  #   E,  SE, SW, W,  NW (5r in non-swapped notation)
                 "5q" : [0,0,1,1,1,0,1,1],  #   E,  SE, S,  W,  NW
                 "5j" : [0,0,1,1,1,1,0,1],  #   E,  SE, S,  SW, NW 
                 "5i" : [0,0,1,1,1,1,1,0],  #   E,  SE, S,  SW, W 
                 "5e" : [0,1,0,1,0,1,1,1],  #   NE, SE, SW, W,  NW, 
                 "5k" : [0,1,0,1,1,0,1,1],  #   NE, SE, S,  W,  NW
                 "5r" : [0,1,1,0,1,0,1,1],  #   NE, E,  S,  W, NW  (5y in non-swapped notation)
                 "5c" : [1,0,1,0,1,0,1,1],  #   N,  E,  S,  W,  NW
                 "6a" : [0,0,1,1,1,1,1,1],  #   E,  SE, S,  SW, W,  NW
                 "6e" : [0,1,0,1,1,1,1,1],  #   NE, SE, S,  SW, W,  NW
                 "6k" : [0,1,1,0,1,1,1,1],  #   NE, E,  S,  SW, W,  NW
                 "6i" : [0,1,1,1,0,1,1,1],  #   NE, E,  SE, SW, W,  NW
                 "6c" : [1,0,1,0,1,1,1,1],  #   N,  E,  S,  SW, W,  NW
                 "6v" : [1,0,1,1,1,0,1,1],  #   N,  E,  SE, S,  W,  NW
                 "7e" : [0,1,1,1,1,1,1,1],  #   NE, E,  SE, S,  SW, W,  NW 
                 "7c" : [1,0,1,1,1,1,1,1]   #   N,  E,  SE, S,  SW, W,  NW
               

                }

#  Here's a graphical depiction of the notation.
dummyvariable = '''
x = 147, y = 97, rule = B/S012345678
21b3o6b5o5bo3bo6b3o6b5o5bo3bo5bo3bo6b3o10bo5b4o6b5o5bobobo5b5o$20bo3bo
5bo9bo2bo6bo3bo7bo7bo3bo5bo3bo5bo3bo9bo5bo3bo7bo7bobobo9bo$20bo9bo9bob
o7bo3bo7bo7bo3bo5bo3bo5bo3bo9bo5bo3bo7bo7bobobo8bo$20bo9b3o7b2o8b5o7bo
7bo3bo6bobo6bo3bo9bo5b4o8bo7bobobo7bo$20bo9bo9bobo7bo3bo7bo7bo3bo7bo7b
obobo5bo3bo5bo3bo7bo7bobobo6bo$20bo3bo5bo9bo2bo6bo3bo7bo8bobo8bo7bo2bo
6bo3bo5bo3bo7bo7bobobo5bo$21b3o6b5o5bo3bo5bo3bo5b5o7bo9bo8b2obo6b3o6bo
3bo7bo8bobo6b5o4$b3o6b7o$o3bo5bo5bo$o2b2o5bo5bo$obobo5bo2bo2bo$2o2bo5b
o5bo$o3bo5bo5bo$b3o6b7o4$b2o17b7o3b7o$obo17bo5bo3bo5bo$2bo17bobo3bo3bo
2bo2bo$2bo17bo2bo2bo3bo2bo2bo$2bo17bo5bo3bo5bo$2bo17bo5bo3bo5bo$5o15b
7o3b7o4$b3o16b7o3b7o3b7o3b7o3b7o3b7o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo
5bo3bo5bo$4bo15bobobobo3bo2bo2bo3bobo3bo3bobo3bo3bo2bo2bo3bo3bobo$3bo
16bo2bo2bo3bob2o2bo3bo2bo2bo3bob2o2bo3bo2bo2bo3bo2bo2bo$2bo17bo5bo3bo
5bo3bo2bo2bo3bo5bo3bo2bo2bo3bobo3bo$bo18bo5bo3bo5bo3bo5bo3bo5bo3bo5bo
3bo5bo$5o15b7o3b7o3b7o3b7o3b7o3b7o4$b3o16b7o3b7o3b7o3b7o3b7o3b7o3b7o3b
7o3b7o3b7o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo
3bo5bo$4bo15bobobobo3bo2bo2bo3bobo3bo3bob2o2bo3bo3bobo3bobobobo3bo2b2o
bo3bo3bobo3bo3bobo3bobobobo$2b2o16bo2bo2bo3bob2o2bo3bo2b2obo3bob2o2bo
3bo2b2obo3bob2o2bo3bo2bo2bo3bo2bo2bo3bo2b2obo3bo2bo2bo$4bo15bobo3bo3bo
2bo2bo3bo2bo2bo3bo5bo3bo3bobo3bo5bo3bo2bo2bo3bob2o2bo3bo2bo2bo3bo2bo2b
o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$b
3o16b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o4$2b2o16b7o3b7o3b7o3b7o3b7o
3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o$bobo16bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3b
o5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$o2bo16bobobobo3bo2bo2bo
3bo2b2obo3bob3obo3bob2o2bo3bobobobo3bob2o2bo3bob2o2bo3bo3bobo3bobobobo
3bob3obo3bobo3bo3bob2o2bo$5o15bo2bo2bo3bob3obo3bob2o2bo3bob2o2bo3bo2bo
2bo3bob2o2bo3bob2o2bo3bob2o2bo3bob3obo3bo2bo2bo3bo2bo2bo3bob2o2bo3bo2b
o2bo$3bo16bobobobo3bo2bo2bo3bo3bobo3bo5bo3bob2o2bo3bobo3bo3bo2bo2bo3bo
3bobo3bo2bo2bo3bob2o2bo3bo2bo2bo3bo2b2obo3bo2b2obo$3bo16bo5bo3bo5bo3bo
5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$3bo16b
7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o4$5o15b7o3b7o3b7o3b
7o3b7o3b7o3b7o3b7o3b7o3b7o$o19bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5b
o3bo5bo3bo5bo3bo5bo$4o16bo2bo2bo3bobobobo3bo2b2obo3bo3bobo3bob2o2bo3bo
bo3bo3bobobobo3bob2o2bo3bob2o2bo3bobobobo$4bo15bob3obo3bo2b2obo3bob2o
2bo3bo2b2obo3bob2o2bo3bob3obo3bob3obo3bob2o2bo3bob2o2bo3bob3obo$4bo15b
o2b2obo3bobobobo3bobobobo3bob3obo3bob2o2bo3bob2o2bo3bobo3bo3bo2b2obo3b
obobobo3bo2bo2bo$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo
3bo5bo3bo5bo$b3o16b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o4$b3o16b7o3b
7o3b7o3b7o3b7o3b7o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$o19bo2bo
2bo3bobobobo3bo2b2obo3bo2b2obo3bobobobo3bob2o2bo$4o16bob3obo3bo2b2obo
3bob3obo3bo2b2obo3bob3obo3bob3obo$o3bo15bob3obo3bob3obo3bobobobo3bob3o
bo3bobobobo3bo2b2obo$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$b3o16b
7o3b7o3b7o3b7o3b7o3b7o4$5o15b7o3b7o$4bo15bo5bo3bo5bo$3bo16bo2b2obo3bob
3obo$3bo16bob3obo3bo2b2obo$2bo17bob3obo3bob3obo$2bo17bo5bo3bo5bo$2bo
17b7o3b7o4$b3o6b7o$o3bo5bo5bo$o3bo5bob3obo$b3o6bob3obo$o3bo5bob3obo$o
3bo5bo5bo$b3o6b7o!
'''



         # This is the isotropy function's order:  NW,NN,NE,WW,ME,EE,SW,SS,SE
         # This is the notationdict's order:     N,NE,E,SE,S,SW,W,NW

#  So, a conversion function is necessary to use notationdict.  
#   the conversion function takes a notationdict entry like "1,1,1,0,0,0,0,0" and 
#   returns "0 1 1 0 0 1 0 0 0"
# and then isotropy can be run on that result.

def convertorder (totalistic_num, notation_letter):
    n = notationdict[totalistic_num+notation_letter]
    return convertorderaux(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7])

def convertorderaux (x2, x3, x6, x9, x8, x7, x4, x1):
    return [x1, x2, x3, x4, 0, x6, x7, x8, x9]

def isotropy (x1, x2, x3, x4, x5, x6, x7, x8, x9):
   return [[x1, x2, x3, x4, x5, x6, x7, x8, x9],
             [x3, x2, x1, x6, x5, x4, x9, x8, x7],
             [x7, x8, x9, x4, x5, x6, x1, x2, x3],
             [x1, x4, x7, x2, x5, x8, x3, x6, x9],
             [x9, x6, x3, x8, x5, x2, x7, x4, x1],
             [x7, x4, x1, x8, x5, x2, x9, x6, x3],
             [x9, x8, x7, x6, x5, x4, x3, x2, x1],
             [x3, x6, x9, x2, x5, x8, x1, x4, x7]
            ]

# Jason Summers JustFriends weighting scheme:
mNW = 1
mNN = 2
mNE = 4
mWW = 128
mEE = 8
mSW = 64
mSS = 32
mSE = 16


def create_isotropy_rows (input_isotropy_list, bs):
  result = ""

  for row in input_isotropy_list:
    numterm = 0
    if row[0] == 1:
       numterm = numterm +  mNW
   
    if row[1] == 1:
       numterm = numterm + mNN 
  

    if row[2] == 1:
       numterm = numterm +  mNE 
 
    if row[3] == 1:
       numterm = numterm + mWW 
   
    if  row[5] == 1:
       numterm = numterm + mEE 
  
    if  row[6] == 1:
       numterm = numterm + mSW 
   

    if  row[7] == 1:
       numterm = numterm + mSS 
  
    if  row[8] == 1:
       numterm = numterm + mSE 
    result = result + bs + str(numterm) + ", "
  return result



# The following function takes a rule element like B2a or B2-a and creates the appropriate ruleTable row.
# Parameters:
# bs is a string with one of two values "0," to indicate birth, and "1," to indicates survival.
# totalistic_num is one character string "0" ... "8"
# notation_letter is a one character string indicating Hensel's notation "a", 
# inverse_list is a list of notation letters for inverse notation 

def create_table_row(bs,totalistic_num, notation_letter, inverse_list):
   result = ""
   if totalistic_num == "0":
     result = bs + "0, "   
   elif totalistic_num == "8":
     result =  bs + str(mNW+mNN+mNE+mWW+mEE+mSW+mSS+mSE) + ", "        
   elif notation_letter != "none":
      myinput = convertorder(totalistic_num, notation_letter)
      result =  create_isotropy_rows(isotropy(myinput[0],myinput[1],myinput[2],myinput[3],myinput[4],myinput[5],myinput[6],myinput[7],myinput[8]), bs)


   elif inverse_list != []:
      for i in notationdict: 
         if not (i[1] in inverse_list) and i.startswith(totalistic_num):
             myinput = convertorder(totalistic_num, i.replace(totalistic_num, ""))
             result = result+ create_isotropy_rows(isotropy(myinput[0],myinput[1],myinput[2],myinput[3],myinput[4],myinput[5],myinput[6],myinput[7],myinput[8]), bs)   
   else: 
      for i in notationdict:
         if i.startswith(totalistic_num):
             myinput = convertorder(totalistic_num, i.replace(totalistic_num, ""))
             result = result + create_isotropy_rows(isotropy(myinput[0],myinput[1],myinput[2],myinput[3],myinput[4],myinput[5],myinput[6],myinput[7],myinput[8]), bs)   
   return result



import golly
from glife.RuleTree import *


CR = chr(13)
LF = chr(10)




rulestring = golly.getstring(dialog_box_message, "B2a/S12") 


# The following code cleans up the rulestring
# so that it makes a valid and somewhat readable file name - eg "B2-a_S12.table"

rulestring = rulestring.replace(" ", "")
rulestring = rulestring.lower()
rulestring = rulestring.replace("b", "B")
rulestring = rulestring.replace("s", "S")


# Now we check to see if there are decay states
rulestring_parts = rulestring.split("/")
rulestring_firstpart = rulestring_parts[0]
rulestring_secondpart = rulestring_parts[1]
if len(rulestring_parts) == 3:
   rulestring_thirdpart = rulestring_parts[2]
   rulestring_thirdpart = rulestring_thirdpart.replace("c", "")
   decaystates = int(rulestring_thirdpart)
    
else:
   decaystates = 0





# The variable named rulestring will be parsed.  
# The variable named rule_name will be the name of the new file.
# Valid rules contain a slash character but filenames can not include slashes.

rule_name = rulestring.replace("/", "_")  

rulestring = rulestring_firstpart + "/" + rulestring_secondpart


# To do:  Allow the user to specify their own name for a rule.

#  The following code cleans up the rule string to 
#  make life easier for the parser.

if rulestring.startswith("B") or rulestring.startswith("S"):
    rulestring = rulestring.replace("/", "")
else:
    rulestring = rulestring.replace("/", "B")

rulestring = rulestring + "\n"  




# Now create the header for the rule table


# Now that the header for the rule table has been created, 
# parse the rulestring, and add rows to the ruleTable as we go.

# Lets say rule strings contain "rule elements", such as B2i, or B2-a, which are composed of: 
# 1) a birth or survival flag 
# 2) a "totalistic context" consisting of an integer between zero and 8
# 3) a "notation_letter".   
# 4) a flag for "positive" or "inverse" notation

bs = "RS"                        # Use "mME" for survival or "BIRTH" for birth
totalistic_context = "none"      # "none" will be replaced with "0" through
                                 # "8" by the parser.
last_totalistic_context = "none" # Lets the parser remember the previous  
                                 # integer it encountered.
notation_letter = "none"         # "none","a", "e", "i", etc.
positive_or_inverse = "positive" 
inverse_list = []

finalrulestring = ""
for x in rulestring:
  if x == "S" or x == "B" or x.isdigit() or x == "\n":
     last_totalistic_context = totalistic_context   
     totalistic_context = x                         
     if last_totalistic_context != "none"  and notation_letter == "none":
         finalrulestring = finalrulestring + create_table_row(bs, last_totalistic_context, "none",[])           
     if last_totalistic_context != "none" and  positive_or_inverse == "inverse":
         finalrulestring = finalrulestring + create_table_row(bs, last_totalistic_context, "none", inverse_list) 
     # Now lets get ready to move on to the next character.
     notation_letter = "none"
     inverse_list = []
     positive_or_inverse = "positive"
     if x == "S" or x == "B":
         totalistic_context = "none"
     if x == "S":
         bs = "RS"
     if x == "B": 
         bs = "RB"
  elif x == "-":
    positive_or_inverse = "inverse"
  elif x in ["c", "a", "e", "k", "i", "v", "j", "y", "q", "r", "w", "t", "z"] and totalistic_context != "none":
     if positive_or_inverse == "positive":
        notation_letter = x
        finalrulestring = finalrulestring + create_table_row(bs, totalistic_context, notation_letter, [])   
     else:
        notation_letter = x
        inverse_list.append(x) 


finalrulestring = "NW1,NN2,NE4,WW128,ME0,EE8,SW64,SS32,SE16," + "HI" + str(decaystates) + ", " + finalrulestring

golly.getstring('''
Here is the Weighted Life version - you can copy it below:                                                                                                                                    .''', finalrulestring)


#  Part 2:   This is WeightedLife->RuleTree

from glife.RuleTree import *


# Default values
RS = []
RB = []
ME_weight = 0
NW_weight = 1 
NN_weight = 1    
NE_weight = 1
WW_weight = 1     
EE_weight = 1
SW_weight = 1         
SS_weight = 1
SE_weight = 1

CR = chr(13)
LF = chr(10)
   
#name = "Temporary-rule-name" 
name =  rule_name

#WeightedRulestring = golly.getstring(dialog_box_message, "Name=Temporary-rule-name NW4,NN1,NE0,WW1, ME0,EE4,SW0,SS4, SE1,HI0,RS1,RS6,RS8,RB5,RB6") 

WeightedRulestring = finalrulestring

#WeightedRulestring = WeightedRulestring.replace("ame = ", "ame=")


WeightedRulestring = WeightedRulestring.replace(" ", ",")
WeightedRulestring = WeightedRulestring.replace(CR, ",")
WeightedRulestring = WeightedRulestring.replace(LF, ",")
 
for x in WeightedRulestring.split(","):
   if x.startswith("Name=") or x.startswith("name="):
      name = x.split("ame=")[1]
   else:
      x = x.upper()
      if x.startswith("NW"):
         NW_weight = int(x.split("NW")[1])
      elif x.startswith("NN"):
         NN_weight = int(x.split("NN")[1])
      elif x.startswith("NE"):
         NE_weight = int(x.split("NE")[1])
      elif x.startswith("WW"):
         WW_weight = int(x.split("WW")[1])
      elif x.startswith("EE"):
         EE_weight = int(x.split("EE")[1])
      elif x.startswith("SW"):
         SW_weight = int(x.split("SW")[1])
      elif x.startswith("SS"):
         SS_weight = int(x.split("SS")[1])
      elif x.startswith("SE"):
         SE_weight = int(x.split("SE")[1])
      elif x.startswith("ME"):
         ME_weight = int(x.split("ME")[1])
      elif x.startswith("RS"):
         RS.append(int(x.split("RS")[1]))
      elif x.startswith("RB"):
         RB.append(int(x.split("RB")[1]))
      elif x.startswith("HI"):
         n_states = (int(x.split("HI")[1]))

if n_states < 3:
      n_states = 2
if n_states > 256:
    n_states = 256
if n_states > 8:
    golly.getstring('''Ruletrees with more than 8 or so states can take a long time to compute.  

Save your work before continuing. Once this script starts computing your rule, 
if you want to stop the calculation, you may have to abort Golly itelf.

Choose the cancel option now to stop this script.''', "Proceed")

n_neighbors = 8

def transition_function(a):
    # order for 8 neighbors is NW, NE, SW, SE, N, W, E, S, C

    n = NW_weight*(a[0] == 1) + NE_weight*(a[1] == 1) + SW_weight*(a[2] == 1) + SE_weight*(a[3] == 1) + NN_weight*(a[4] == 1) + WW_weight*(a[5] == 1) + EE_weight*(a[6] == 1) + SS_weight*(a[7] == 1) + ME_weight*(a[8] == 1)

    if  a[8] == 1 and n in RS:
        return 1 
    
    if a[8] == 0 and n in RB:
        return 1

    if a[8] > 0 and a[8] < (n_states - 1):
        return a[8] + 1

  
golly.show("Please wait while ruletree is being created...")

# The code below this line is copied from make-ruletree.py 

try:

    MakeRuleTreeFromTransitionFunction( n_states, n_neighbors, transition_function,
                                        golly.getdir("rules")+name+".tree" )
    
    # use name.tree to create name.rule (with no icons);
    # note that if name.rule already exists then we only replace the info in
    # the @TREE section to avoid clobbering any other info added by the user
    ConvertTreeToRule(name, n_states, [])
    
    golly.setalgo("RuleLoader")
    golly.setrule(name)
    golly.show("Created "+golly.getdir("rules")+name+".rule and switched to that rule.")

except:
    import sys
    import traceback
    exception, msg, tb = sys.exc_info()
    golly.warn(\
'''A problem was encountered with the supplied rule:'''+ '\n'.join(traceback.format_exception(exception, msg, tb)))
    golly.exit()

Last edited by EricG on March 8th, 2014, 12:53 pm, edited 5 times in total.

EricG
Posts: 199
Joined: August 19th, 2011, 5:41 pm
Location: Chicago-area, USA

Re: Reversible Wireless World

Post by EricG » March 7th, 2014, 2:55 am

And here's almost the exact same script, but slightly modified at the bottom, so that it uses the 2nd order technique to produce a four state reversible CA rule for Golly:

Code: Select all

# Reversible2ndOrder.py
#  by Eric Goldstein, March 7, 2014

#  All but a few lines of this code are from HenselNotation->WeightedLife.py

#  This script allows you to enter a description of a two state CA and produces 
#  a  four state reversible rule using Fredkin's 2nd Order technique

# You can describe the two state CA as a lifelike rule (eg "B2/S24") or you can use
# Life32's non-totalistic notation, which was adapted from Alan Hensel"s 
# non-totalistic notation. 



#  Here's a graphical depiction of the non-totalistic notation.
dummyvariable = '''
x = 147, y = 97, rule = B/S012345678
21b3o6b5o5bo3bo6b3o6b5o5bo3bo5bo3bo6b3o10bo5b4o6b5o5bobobo5b5o$20bo3bo
5bo9bo2bo6bo3bo7bo7bo3bo5bo3bo5bo3bo9bo5bo3bo7bo7bobobo9bo$20bo9bo9bob
o7bo3bo7bo7bo3bo5bo3bo5bo3bo9bo5bo3bo7bo7bobobo8bo$20bo9b3o7b2o8b5o7bo
7bo3bo6bobo6bo3bo9bo5b4o8bo7bobobo7bo$20bo9bo9bobo7bo3bo7bo7bo3bo7bo7b
obobo5bo3bo5bo3bo7bo7bobobo6bo$20bo3bo5bo9bo2bo6bo3bo7bo8bobo8bo7bo2bo
6bo3bo5bo3bo7bo7bobobo5bo$21b3o6b5o5bo3bo5bo3bo5b5o7bo9bo8b2obo6b3o6bo
3bo7bo8bobo6b5o4$b3o6b7o$o3bo5bo5bo$o2b2o5bo5bo$obobo5bo2bo2bo$2o2bo5b
o5bo$o3bo5bo5bo$b3o6b7o4$b2o17b7o3b7o$obo17bo5bo3bo5bo$2bo17bobo3bo3bo
2bo2bo$2bo17bo2bo2bo3bo2bo2bo$2bo17bo5bo3bo5bo$2bo17bo5bo3bo5bo$5o15b
7o3b7o4$b3o16b7o3b7o3b7o3b7o3b7o3b7o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo
5bo3bo5bo$4bo15bobobobo3bo2bo2bo3bobo3bo3bobo3bo3bo2bo2bo3bo3bobo$3bo
16bo2bo2bo3bob2o2bo3bo2bo2bo3bob2o2bo3bo2bo2bo3bo2bo2bo$2bo17bo5bo3bo
5bo3bo2bo2bo3bo5bo3bo2bo2bo3bobo3bo$bo18bo5bo3bo5bo3bo5bo3bo5bo3bo5bo
3bo5bo$5o15b7o3b7o3b7o3b7o3b7o3b7o4$b3o16b7o3b7o3b7o3b7o3b7o3b7o3b7o3b
7o3b7o3b7o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo
3bo5bo$4bo15bobobobo3bo2bo2bo3bobo3bo3bob2o2bo3bo3bobo3bobobobo3bo2b2o
bo3bo3bobo3bo3bobo3bobobobo$2b2o16bo2bo2bo3bob2o2bo3bo2b2obo3bob2o2bo
3bo2b2obo3bob2o2bo3bo2bo2bo3bo2bo2bo3bo2b2obo3bo2bo2bo$4bo15bobo3bo3bo
2bo2bo3bo2bo2bo3bo5bo3bo3bobo3bo5bo3bo2bo2bo3bob2o2bo3bo2bo2bo3bo2bo2b
o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$b
3o16b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o4$2b2o16b7o3b7o3b7o3b7o3b7o
3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o$bobo16bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3b
o5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$o2bo16bobobobo3bo2bo2bo
3bo2b2obo3bob3obo3bob2o2bo3bobobobo3bob2o2bo3bob2o2bo3bo3bobo3bobobobo
3bob3obo3bobo3bo3bob2o2bo$5o15bo2bo2bo3bob3obo3bob2o2bo3bob2o2bo3bo2bo
2bo3bob2o2bo3bob2o2bo3bob2o2bo3bob3obo3bo2bo2bo3bo2bo2bo3bob2o2bo3bo2b
o2bo$3bo16bobobobo3bo2bo2bo3bo3bobo3bo5bo3bob2o2bo3bobo3bo3bo2bo2bo3bo
3bobo3bo2bo2bo3bob2o2bo3bo2bo2bo3bo2b2obo3bo2b2obo$3bo16bo5bo3bo5bo3bo
5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$3bo16b
7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o4$5o15b7o3b7o3b7o3b
7o3b7o3b7o3b7o3b7o3b7o3b7o$o19bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5b
o3bo5bo3bo5bo3bo5bo$4o16bo2bo2bo3bobobobo3bo2b2obo3bo3bobo3bob2o2bo3bo
bo3bo3bobobobo3bob2o2bo3bob2o2bo3bobobobo$4bo15bob3obo3bo2b2obo3bob2o
2bo3bo2b2obo3bob2o2bo3bob3obo3bob3obo3bob2o2bo3bob2o2bo3bob3obo$4bo15b
o2b2obo3bobobobo3bobobobo3bob3obo3bob2o2bo3bob2o2bo3bobo3bo3bo2b2obo3b
obobobo3bo2bo2bo$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo
3bo5bo3bo5bo$b3o16b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o3b7o4$b3o16b7o3b
7o3b7o3b7o3b7o3b7o$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$o19bo2bo
2bo3bobobobo3bo2b2obo3bo2b2obo3bobobobo3bob2o2bo$4o16bob3obo3bo2b2obo
3bob3obo3bo2b2obo3bob3obo3bob3obo$o3bo15bob3obo3bob3obo3bobobobo3bob3o
bo3bobobobo3bo2b2obo$o3bo15bo5bo3bo5bo3bo5bo3bo5bo3bo5bo3bo5bo$b3o16b
7o3b7o3b7o3b7o3b7o3b7o4$5o15b7o3b7o$4bo15bo5bo3bo5bo$3bo16bo2b2obo3bob
3obo$3bo16bob3obo3bo2b2obo$2bo17bob3obo3bob3obo$2bo17bo5bo3bo5bo$2bo
17b7o3b7o4$b3o6b7o$o3bo5bo5bo$o3bo5bob3obo$b3o6bob3obo$o3bo5bob3obo$o
3bo5bo5bo$b3o6b7o!
'''





dialog_box_message =  '''This script will allow you to enter either totalistic lifelike rules
or the non-totalistic rule notation used by Johan Bontes' Life32 program, based on work by Alan Hensel.
Please look in the script file to see how the non-totalistic notation works.

An example rule is given below as a default.  Rules are case-insensitive.
B2a/S12, S12/B2a, and 12/2a are valid and equivalent.  

Inverse specifications are allowed.  For example, David Bell's Just Friends rule can be 
expressed B2-a/S12 indicating that all B2 arrangements are included except 2a.
 
Enter a rule here:
   '''

# Minor note:
# Unfortunately, Alan Hensel's notation for r and y are swapped in Life32.   
# Life32's rule dialog box shows the correct arrangements, but they are swapped in the implementation.
# What should work as 3r, 4r, and 5r, actually work as 3y, 4y, and 5y, and vice versa.
# This script swaps the definition of r and y just like Life32 does, so that patterns intended to be run
# on Life32 will run the same way in Golly.  

 
# Golly"s ruleTable format use the following notation:  
#  C,N,NE,E,SE,S,SW,W,NW,C' 
# where C is the current state, and C' is the new state, and
# where the eight neighbors in the Moore neighborhood are as shown below.

#     NW  N  NE 
#     W   C  E  
#     SW  S  SE 

# The lookup table below for Life32"s non-totalistic notation uses the eight neighbor values:
#   N,NE,E,SE,S,SW,W,NW



notationdict = { 
                 "1e" : [1,0,0,0,0,0,0,0],  #   N 
                 "1c" : [0,1,0,0,0,0,0,0],  #   NE
                 "2a" : [1,1,0,0,0,0,0,0],  #   N,  NE
                 "2e" : [1,0,1,0,0,0,0,0],  #   N,  E 
                 "2k" : [1,0,0,1,0,0,0,0],  #   N,  SE
                 "2i" : [1,0,0,0,1,0,0,0],  #   N,  S 
                 "2c" : [0,1,0,1,0,0,0,0],  #   NE, SE
                 "2v" : [0,1,0,0,0,1,0,0],  #   NE, SW
                 "3a" : [1,1,1,0,0,0,0,0],  #   N,  NE, E
                 "3v" : [1,1,0,1,0,0,0,0],  #   N,  NE, SE 
                 "3y" : [1,1,0,0,1,0,0,0],  #   N,  NE, S      (3r in non-swapped notation)
                 "3q" : [1,1,0,0,0,1,0,0],  #   N,  NE, SW
                 "3j" : [1,1,0,0,0,0,1,0],  #   N,  NE, W
                 "3i" : [1,1,0,0,0,0,0,1],  #   N,  NE, NW
                 "3e" : [1,0,1,0,1,0,0,0],  #   N,  E,  S
                 "3k" : [1,0,1,0,0,1,0,0],  #   N,  E,  SW
                 "3r" : [1,0,0,1,0,1,0,0],  #   N,  SE, SW     (3y in non-swapped notation)
                 "3c" : [0,1,0,1,0,1,0,0],  #   NE, SE, SW 
                 "4a" : [1,1,1,1,0,0,0,0],  #   N,  NE, E,  SE
                 "4y" : [1,1,1,0,1,0,0,0],  #   N,  NE, E,  S  (4r in non-swapped notation)
                 "4q" : [1,1,1,0,0,1,0,0],  #   N,  NE, E,  SW
                 "4i" : [1,1,0,1,1,0,0,0],  #   N,  NE, SE, S
                 "4r" : [1,1,0,1,0,1,0,0],  #   N,  NE, SE, SW (4y in non-swapped notation)
                 "4k" : [1,1,0,1,0,0,1,0],  #   N,  NE, SE, W
                 "4v" : [1,1,0,1,0,0,0,1],  #   N,  NE, SE, NW 
                 "4z" : [1,1,0,0,1,1,0,0],  #   N,  NE, S,  SW
                 "4j" : [1,1,0,0,1,0,1,0],  #   N,  NE, S,  W
                 "4t" : [1,1,0,0,1,0,0,1],  #   N,  NE, S,  NW
                 "4w" : [1,1,0,0,0,1,1,0],  #   N,  NE, SW, W
                 "4e" : [1,0,1,0,1,0,1,0],  #   N,  E,  S,  W
                 "4c" : [0,1,0,1,0,1,0,1],  #   NE, SE, SW, NW
                 "5a" : [0,0,0,1,1,1,1,1],  #   SE, S,  SW, W,  NW
                 "5v" : [0,0,1,0,1,1,1,1],  #   E,  S,  SW, W,  NW
                 "5y" : [0,0,1,1,0,1,1,1],  #   E,  SE, SW, W,  NW (5r in non-swapped notation)
                 "5q" : [0,0,1,1,1,0,1,1],  #   E,  SE, S,  W,  NW
                 "5j" : [0,0,1,1,1,1,0,1],  #   E,  SE, S,  SW, NW 
                 "5i" : [0,0,1,1,1,1,1,0],  #   E,  SE, S,  SW, W 
                 "5e" : [0,1,0,1,0,1,1,1],  #   NE, SE, SW, W,  NW, 
                 "5k" : [0,1,0,1,1,0,1,1],  #   NE, SE, S,  W,  NW
                 "5r" : [0,1,1,0,1,0,1,1],  #   NE, E,  S,  W, NW  (5y in non-swapped notation)
                 "5c" : [1,0,1,0,1,0,1,1],  #   N,  E,  S,  W,  NW
                 "6a" : [0,0,1,1,1,1,1,1],  #   E,  SE, S,  SW, W,  NW
                 "6e" : [0,1,0,1,1,1,1,1],  #   NE, SE, S,  SW, W,  NW
                 "6k" : [0,1,1,0,1,1,1,1],  #   NE, E,  S,  SW, W,  NW
                 "6i" : [0,1,1,1,0,1,1,1],  #   NE, E,  SE, SW, W,  NW
                 "6c" : [1,0,1,0,1,1,1,1],  #   N,  E,  S,  SW, W,  NW
                 "6v" : [1,0,1,1,1,0,1,1],  #   N,  E,  SE, S,  W,  NW
                 "7e" : [0,1,1,1,1,1,1,1],  #   NE, E,  SE, S,  SW, W,  NW 
                 "7c" : [1,0,1,1,1,1,1,1]   #   N,  E,  SE, S,  SW, W,  NW
               

                }


# This is the isotropy function's order:  NW,NN,NE,WW,ME,EE,SW,SS,SE
# This is the notationdict's order:     N,NE,E,SE,S,SW,W,NW

#  So, a conversion function is necessary to use notationdict.  
#   the conversion function takes a notationdict entry like "1,1,1,0,0,0,0,0" and 
#   returns "0 1 1 0 0 1 0 0 0"
# and then isotropy can be run on that result.

def convertorder (totalistic_num, notation_letter):
    n = notationdict[totalistic_num+notation_letter]
    return convertorderaux(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7])

def convertorderaux (x2, x3, x6, x9, x8, x7, x4, x1):
    return [x1, x2, x3, x4, 0, x6, x7, x8, x9]

def isotropy (x1, x2, x3, x4, x5, x6, x7, x8, x9):
   return [[x1, x2, x3, x4, x5, x6, x7, x8, x9],
             [x3, x2, x1, x6, x5, x4, x9, x8, x7],
             [x7, x8, x9, x4, x5, x6, x1, x2, x3],
             [x1, x4, x7, x2, x5, x8, x3, x6, x9],
             [x9, x6, x3, x8, x5, x2, x7, x4, x1],
             [x7, x4, x1, x8, x5, x2, x9, x6, x3],
             [x9, x8, x7, x6, x5, x4, x3, x2, x1],
             [x3, x6, x9, x2, x5, x8, x1, x4, x7]
            ]

# Jason Summers JustFriends weighting scheme:
mNW = 1
mNN = 2
mNE = 4
mWW = 128
mEE = 8
mSW = 64
mSS = 32
mSE = 16


def create_isotropy_rows (input_isotropy_list, bs):
  result = ""

  for row in input_isotropy_list:
    numterm = 0
    if row[0] == 1:
       numterm = numterm +  mNW
   
    if row[1] == 1:
       numterm = numterm + mNN 
  

    if row[2] == 1:
       numterm = numterm +  mNE 
 
    if row[3] == 1:
       numterm = numterm + mWW 
   
    if  row[5] == 1:
       numterm = numterm + mEE 
  
    if  row[6] == 1:
       numterm = numterm + mSW 
   

    if  row[7] == 1:
       numterm = numterm + mSS 
  
    if  row[8] == 1:
       numterm = numterm + mSE 
    result = result + bs + str(numterm) + ", "
  return result



# The following function takes a rule element like B2a or B2-a and creates the appropriate ruleTable row.
# Parameters:
# bs is a string with one of two values "0," to indicate birth, and "1," to indicates survival.
# totalistic_num is one character string "0" ... "8"
# notation_letter is a one character string indicating Hensel's notation "a", 
# inverse_list is a list of notation letters for inverse notation 

def create_table_row(bs,totalistic_num, notation_letter, inverse_list):
   result = ""
   if totalistic_num == "0":
     result = bs + "0, "   
   elif totalistic_num == "8":
     result =  bs + str(mNW+mNN+mNE+mWW+mEE+mSW+mSS+mSE) + ", "        
   elif notation_letter != "none":
      myinput = convertorder(totalistic_num, notation_letter)
      result =  create_isotropy_rows(isotropy(myinput[0],myinput[1],myinput[2],myinput[3],myinput[4],myinput[5],myinput[6],myinput[7],myinput[8]), bs)


   elif inverse_list != []:
      for i in notationdict: 
         if not (i[1] in inverse_list) and i.startswith(totalistic_num):
             myinput = convertorder(totalistic_num, i.replace(totalistic_num, ""))
             result = result+ create_isotropy_rows(isotropy(myinput[0],myinput[1],myinput[2],myinput[3],myinput[4],myinput[5],myinput[6],myinput[7],myinput[8]), bs)   
   else: 
      for i in notationdict:
         if i.startswith(totalistic_num):
             myinput = convertorder(totalistic_num, i.replace(totalistic_num, ""))
             result = result + create_isotropy_rows(isotropy(myinput[0],myinput[1],myinput[2],myinput[3],myinput[4],myinput[5],myinput[6],myinput[7],myinput[8]), bs)   
   return result



import golly
from glife.RuleTree import *


CR = chr(13)
LF = chr(10)




rulestring = golly.getstring(dialog_box_message, "B2a/S12") 


# The following code cleans up the rulestring
# so that it makes a valid and somewhat readable file name - eg "B2-a_S12.table"

rulestring = rulestring.replace(" ", "")
rulestring = rulestring.lower()
rulestring = rulestring.replace("b", "B")
rulestring = rulestring.replace("s", "S")


# Now we check to see if there are decay states
rulestring_parts = rulestring.split("/")
rulestring_firstpart = rulestring_parts[0]
rulestring_secondpart = rulestring_parts[1]
if len(rulestring_parts) == 3:
   rulestring_thirdpart = rulestring_parts[2]
   rulestring_thirdpart = rulestring_thirdpart.replace("c", "")
   decaystates = int(rulestring_thirdpart)
    
else:
   decaystates = 0





# The variable named rulestring will be parsed.  
# The variable named rule_name will be the name of the new file.
# Valid rules contain a slash character but filenames can not include slashes.

rule_name = rulestring.replace("/", "_")  

rulestring = rulestring_firstpart + "/" + rulestring_secondpart


# To do:  Allow the user to specify their own name for a rule.

#  The following code cleans up the rule string to 
#  make life easier for the parser.

if rulestring.startswith("B") or rulestring.startswith("S"):
    rulestring = rulestring.replace("/", "")
else:
    rulestring = rulestring.replace("/", "B")

rulestring = rulestring + "\n"  




# Now create the header for the rule table


# Now that the header for the rule table has been created, 
# parse the rulestring, and add rows to the ruleTable as we go.

# Lets say rule strings contain "rule elements", such as B2i, or B2-a, which are composed of: 
# 1) a birth or survival flag 
# 2) a "totalistic context" consisting of an integer between zero and 8
# 3) a "notation_letter".   
# 4) a flag for "positive" or "inverse" notation

bs = "RS"                        # Use "mME" for survival or "BIRTH" for birth
totalistic_context = "none"      # "none" will be replaced with "0" through
                                 # "8" by the parser.
last_totalistic_context = "none" # Lets the parser remember the previous  
                                 # integer it encountered.
notation_letter = "none"         # "none","a", "e", "i", etc.
positive_or_inverse = "positive" 
inverse_list = []

finalrulestring = ""
for x in rulestring:
  if x == "S" or x == "B" or x.isdigit() or x == "\n":
     last_totalistic_context = totalistic_context   
     totalistic_context = x                         
     if last_totalistic_context != "none"  and notation_letter == "none":
         finalrulestring = finalrulestring + create_table_row(bs, last_totalistic_context, "none",[])           
     if last_totalistic_context != "none" and  positive_or_inverse == "inverse":
         finalrulestring = finalrulestring + create_table_row(bs, last_totalistic_context, "none", inverse_list) 
     # Now lets get ready to move on to the next character.
     notation_letter = "none"
     inverse_list = []
     positive_or_inverse = "positive"
     if x == "S" or x == "B":
         totalistic_context = "none"
     if x == "S":
         bs = "RS"
     if x == "B": 
         bs = "RB"
  elif x == "-":
    positive_or_inverse = "inverse"
  elif x in ["c", "a", "e", "k", "i", "v", "j", "y", "q", "r", "w", "t", "z"] and totalistic_context != "none":
     if positive_or_inverse == "positive":
        notation_letter = x
        finalrulestring = finalrulestring + create_table_row(bs, totalistic_context, notation_letter, [])   
     else:
        notation_letter = x
        inverse_list.append(x) 


finalrulestring = "NW1,NN2,NE4,WW128,ME0,EE8,SW64,SS32,SE16," + "HI" + str(decaystates) + ", " + finalrulestring

#golly.getstring('''
#Here is the Weighted Life version - you can copy it #below:                                                                                                                                    #.''', finalrulestring)


#  Part 2:   This is WeightedLife->RuleTree

from glife.RuleTree import *


# Default values
RS = []
RB = []
ME_weight = 0
NW_weight = 1 
NN_weight = 1    
NE_weight = 1
WW_weight = 1     
EE_weight = 1
SW_weight = 1         
SS_weight = 1
SE_weight = 1

CR = chr(13)
LF = chr(10)
   
#name = "Temporary-rule-name" 
name =  "Reversible2ndOrder_"+rule_name

#WeightedRulestring = golly.getstring(dialog_box_message, "Name=Temporary-rule-name NW4,NN1,NE0,WW1, ME0,EE4,SW0,SS4, SE1,HI0,RS1,RS6,RS8,RB5,RB6") 

WeightedRulestring = finalrulestring

#WeightedRulestring = WeightedRulestring.replace("ame = ", "ame=")


WeightedRulestring = WeightedRulestring.replace(" ", ",")
WeightedRulestring = WeightedRulestring.replace(CR, ",")
WeightedRulestring = WeightedRulestring.replace(LF, ",")
 
for x in WeightedRulestring.split(","):
   if x.startswith("Name=") or x.startswith("name="):
      name = x.split("ame=")[1]
   else:
      x = x.upper()
      if x.startswith("NW"):
         NW_weight = int(x.split("NW")[1])
      elif x.startswith("NN"):
         NN_weight = int(x.split("NN")[1])
      elif x.startswith("NE"):
         NE_weight = int(x.split("NE")[1])
      elif x.startswith("WW"):
         WW_weight = int(x.split("WW")[1])
      elif x.startswith("EE"):
         EE_weight = int(x.split("EE")[1])
      elif x.startswith("SW"):
         SW_weight = int(x.split("SW")[1])
      elif x.startswith("SS"):
         SS_weight = int(x.split("SS")[1])
      elif x.startswith("SE"):
         SE_weight = int(x.split("SE")[1])
      elif x.startswith("ME"):
         ME_weight = int(x.split("ME")[1])
      elif x.startswith("RS"):
         RS.append(int(x.split("RS")[1]))
      elif x.startswith("RB"):
         RB.append(int(x.split("RB")[1]))
      elif x.startswith("HI"):
         n_states = (int(x.split("HI")[1]))

#if n_states < 3:
#      n_states = 2
#if n_states > 256:
#    n_states = 256
#if n_states > 8:
#    golly.getstring('''Ruletrees with more than 8 or so states can take a long time to compute.  
#
#Save your work before continuing. Once this script starts computing your rule, 
#if you want to stop the calculation, you may have to abort Golly itelf.
#
#Choose the cancel option now to stop this script.''', "Proceed")

n_states = 4   # Using the 2nd Order technique on a 2 state CA requires 4 states.

n_neighbors = 8

def transition_function(a):
    # order for 8 neighbors is NW, NE, SW, SE, N, W, E, S, C

    n = NW_weight*(a[0] == 1 or a[0] == 3 ) + NE_weight*(a[1] == 1 or a[1] == 3) + SW_weight*(a[2] == 1 or a[2] == 3) + SE_weight*(a[3] == 1 or a[3] == 3) + NN_weight*(a[4] == 1 or a[4] == 3) + WW_weight*(a[5] == 1 or a[5] == 3) + EE_weight*(a[6] == 1 or a[6] == 3) + SS_weight*(a[7] == 1 or a[7] == 3) + ME_weight*(a[8] == 1 or a[8] == 3)

    if a[8] == 1:  #  Alive (& Dead in last generation)

       if n in RS:
           return 3
       else:
           return 2  

    if a[8] == 3: #  Alive (& Alive in last generation)
       if n in RS:
           return 2
       else:
           return 3  

    if a[8] == 2: #  Dead  (& Alive in last generation)
       if n in RB:
           return 0
       else:
           return 1  
    else: # a[8] =  0  # ( Dead  & Dead in last generation)
       if n in RB:
           return 1
       else:
           return 0  

  
  


golly.show("Please wait while ruletree is being created...")

# The code below this line is copied from make-ruletree.py 

try:

    MakeRuleTreeFromTransitionFunction( n_states, n_neighbors, transition_function,
                                        golly.getdir("rules")+name+".tree" )
    
    # use name.tree to create name.rule (with no icons);
    # note that if name.rule already exists then we only replace the info in
    # the @TREE section to avoid clobbering any other info added by the user
    ConvertTreeToRule(name, n_states, [])
    
    golly.setalgo("RuleLoader")
    golly.setrule(name)
    golly.show("Created "+golly.getdir("rules")+name+".rule and switched to that rule.")

except:
    import sys
    import traceback
    exception, msg, tb = sys.exc_info()
    golly.warn(\
'''A problem was encountered with the supplied rule:'''+ '\n'.join(traceback.format_exception(exception, msg, tb)))
    golly.exit()



Edited March 8 to swap state 2 and state 3 as suggested below
Last edited by EricG on March 8th, 2014, 1:03 pm, edited 6 times in total.

EricG
Posts: 199
Joined: August 19th, 2011, 5:41 pm
Location: Chicago-area, USA

Re: Reversible Wireless World

Post by EricG » March 7th, 2014, 3:02 am

Using the script, I found an interesting simplification of your ant rules. My guess is that you already discovered it(!), but maybe someone else will find it interesting. The rule is B1e/S1e (or, in other words, the rule is B1/S1 in the von Neuman neighborhood, so Hensel's notation is overkill for this rule! EDIT: Whoops. That was a late night mistake. B1/S1V is not equivalent to B1e/S1e - the latter prohibits corner neighbors, the von Neuman neighborhood just ignores them). Anyway, the simpler rule produces at least some of the same behaviors as your ant rules. I haven't played with it enough to know if it provides enough for logic gates, but it seems promising. The appeal for me is that there is no need to specify "the opposite tile" as is needed with WIant-4, and perhaps that will be helpful when working with oddball tilings, which is one of my interests.

Here's a few patterns I found from playing around for a few minutes. The rule supports your regular ants, but it is easy to grow the ants into "snakes". You can also control the snake's growth, resulting in ships that grow and shrink as they bounce off reflectors.

Code: Select all

x = 159, y = 82, rule = Reversible2ndOrder_B1e_S1e
131.5C16.5C$131.5C16.5C2$131.2C22.2C$131.2C22.2C4$134.B$134.C$134.A$
8.2C46.2C$8.2C46.5C$5.3C50.3C$5.3C15.ACB14.BCA15.3C$5.3C50.3C$5.5C46.
2C$8.2C46.2C7$4C23.2C22.2C78.2C22.2C$4C23.2C22.2C78.2C2.ACB17.2C$3C
27.2C63.2C$3C27.2C63.2C34.5C16.5C$2C129.5C16.5C3$96.2C$28.A67.2C$28.C
69.2C$28.C23.BCA43.2C$4.B23.C19.2C48.2C$4.C23.B19.2C46.2C$4.C41.2C48.
2C$4.C41.2C43.ACB$4.A41.2C$48.2C$48.2C$154.5C$31.3C120.5C$.2C27.4C97.
5C$.2C27.4C15.2C80.5C21.2C$4.2C23.4C16.2C106.2C$4.2C23.4C60.2C36.2C.A
CB$93.2C36.2C9$36.2A$4.2A.BC2A7CB.A11CB3.2A$4.2A7$157.2C$4.2A9.B2CB
17.2A119.2C$4.2A30.2A93.2C$131.2C12.ACB6.5C$154.5C$131.5C$131.5C8$4.
2B29.2A$4.2B15.ACB5.ACB3.2A!
For people who don't want to use the script, here's the Golly rule:

Code: Select all

@RULE Reversible2ndOrder_B1e_S1e

@TREE

num_states=4
num_neighbors=8
num_nodes=20
1 0 2 1 3
1 1 3 0 2
2 0 1 0 1
2 1 0 1 0
3 2 3 2 3
2 0 0 0 0
3 3 5 3 5
4 4 6 4 6
3 5 5 5 5
4 6 8 6 8
5 7 9 7 9
4 8 8 8 8
5 11 11 11 11
6 10 12 10 12
6 12 12 12 12
7 13 14 13 14
7 14 14 14 14
8 15 16 15 16
8 16 16 16 16
9 17 18 17 18

@COLORS

0 255 255 255
1 255 0 0
2 127 255 0
3 0 0 255

(Edited the rule and the example RLE March 8 to swap states 2 and states 3 as suggested below. Also added Alexander's colors to the rule.)


Finally: Brian, yes, it is good to be back, and I hope to catch up on a number of subjects. I couldn't resist letting this subject jump the queue!
Last edited by EricG on March 8th, 2014, 11:46 am, edited 2 times in total.

EricG
Posts: 199
Joined: August 19th, 2011, 5:41 pm
Location: Chicago-area, USA

Re: Reversible Wireless World

Post by EricG » March 7th, 2014, 3:25 am

If anyone reading this thread is utterly perplexed by what is going on, you might find it helpful to compare Wolfram's Rule 214 with Wolfram's description of the 2nd order technique applied to rule 214. That's what helped me figure it out!

Wolfram's elementary CA Rule 214: http://atlas.wolfram.com/01/01/214/
Reversible rule derived from Rule 214: https://www.wolframscience.com/nksonline/page-437

User avatar
alexv
Posts: 136
Joined: February 3rd, 2014, 11:14 am

Re: Reversible Wireless World

Post by alexv » March 7th, 2014, 6:22 am

EricG wrote:I found an interesting simplification of your ant rules. My guess is that you already discovered it(!), but maybe someone else will find it interesting. The rule is B1e/S1e
Eric, thank you for your comments! Yes, the rule was found (~2004) before ants (~2012?)
(and called "simpl" or "snakes" :lol: ). The tb3 file is
0 1 0
1 1 0
After some collisions snakes are changing length and so items
0 2 0
1 2 0
were added to "cut" such "snakes" into two ants (so, in fact, ants formally was not derived from WireWorld
and a similarity was mentioned later) and produce splits. So snakes, indeed, may be used in some gates,
e.g. Fredkin gate shown above works, but Toffoli does not.

Alexander

PS Numeration of states in your example seems changed in comparison with second order rule used for ants.
Ants had pattern "132" but in your case them "123".

PPS Snakes with initial order correspond to tree

Code: Select all

num_states=4
num_neighbors=8
num_nodes=20
1 0 2 1 3
1 1 3 0 2
2 0 1 0 1
2 1 0 1 0
2 0 0 0 0
3 2 3 2 3
3 3 4 3 4
3 4 4 4 4
4 5 6 5 6
4 6 7 6 7
4 7 7 7 7
5 8 9 8 9
5 10 10 10 10
6 11 12 11 12
6 12 12 12 12
7 13 14 13 14
7 14 14 14 14
8 15 16 15 16
8 16 16 16 16
9 17 18 17 18
Last edited by alexv on March 13th, 2014, 1:21 pm, edited 1 time in total.

User avatar
alexv
Posts: 136
Joined: February 3rd, 2014, 11:14 am

Re: Reversible Wireless World

Post by alexv » March 7th, 2014, 7:26 am

EricG wrote: Do you hope to someday see these ant rules implemented physically as a quantum dot cellular automata?
Eric,

Why are you asking about "quantum dot cellular automata"? My activity is not related with this particular project.
"No comment" 8)

Alexander

PS I think you should google "quantum cellular automata" instead, because it is a different story
Last edited by alexv on March 7th, 2014, 8:22 am, edited 1 time in total.

User avatar
alexv
Posts: 136
Joined: February 3rd, 2014, 11:14 am

Re: Reversible Wireless World

Post by alexv » March 7th, 2014, 7:44 am

EricG wrote:If I'm not mistaken, WIant corresponds to the 2nd order technique applied to the rule described in Hensel's notation as"B1e2ei/S1e2ei" and WIant-4 corresponds to the 2nd order technique applied to "B1e2i/S1e2i"
Indeed, it looks so. Thanks again.

Alexander

bprentice
Posts: 920
Joined: September 10th, 2009, 6:20 pm
Location: Coos Bay, Oregon

Re: Reversible Wireless World

Post by bprentice » March 7th, 2014, 7:52 am

Eric,

When I tried to run your example here:

viewtopic.php?f=11&t=1293&start=75#p11154

on Reversible Square Cell I found that states 2 and 3 were reversed. It would be nice if we were consistent.

Brian

User avatar
alexv
Posts: 136
Joined: February 3rd, 2014, 11:14 am

Re: Reversible Wireless World

Post by alexv » March 7th, 2014, 8:30 am

bprentice wrote:
on Reversible Square Cell I found that states 2 and 3 were reversed. It would be nice if we were consistent.
Brian,

I also mentioned that in earlier comment. IMHO, it is from script. In fact, in reversible rule in Golly repository
1 and 2 are reversed, but it is due to use of "opposite direction of time". If to consider binary notation
ant pattern: ...132... means ...110... in the base layer and ...011... in the memory layer, so with
reversed states ant/snake 123 is not consistent with general ideas, yet may look natural for the particular CA
(I myself changed state numeration in SlAnt and "Wireless Ant World with 7 states").

Alexander

bprentice
Posts: 920
Joined: September 10th, 2009, 6:20 pm
Location: Coos Bay, Oregon

Re: Reversible Wireless World

Post by bprentice » March 8th, 2014, 10:25 am

The archive "Wireless Ant World.zip" has been updated here:

http://bprentice.webenet.net/Java%20Squ ... 0World.zip

A Square Cell version of SlAnt has been added and the pattern collection has been extended. Included are patterns for five rules that support Knight Ships. These can be run on Reversible Square Cell 2.

Brian Prentice

EricG
Posts: 199
Joined: August 19th, 2011, 5:41 pm
Location: Chicago-area, USA

Re: Reversible Wireless World

Post by EricG » March 8th, 2014, 11:34 am

About the states, good point! Thanks.
I edited the script and Alexander's snakes rule above so that state 2 and state 3 are swapped.

For fun, here's a hexagonal version. It is adapted from the non-totalistic hexagonal script for two state rules posted here: viewtopic.php?f=11&t=1328#p11073 (see the gif posted there).

Code: Select all

# 2ndOrderCallahanHexNotation.py

# This script extends Callahan's non-totalistic hexagonal notation.  
# It allows the user to enter a description of a two state CA 
# (the user can enter either a totalistic rule or a non-tototalistic rule) and 
# it produces a four state reversible CA using Fredkin's 2nd order method.

import golly
from glife.RuleTree import *

dialog_box_message =  '''This script will convert Callhan's (extended) non-totalistic hexagonal notation into a four state reversible CA using Fredkin's 2nd order method.'''

dummyvariable = '''

The following may be scrambled a bit.
See the gif posted here: http://www.conwaylife.com/forums/viewtopic.php?f=11&t=1328#p11073  
       . .     
 0:   . x .      
       . .           

       O .     
 1:   . x .      
       . .           

       O O            O .            O .
 2o:  . x .     2m:  . x O     2p:  . x .
       . .            . .            . O


       O O            O O            O .
 3o:  O x .     3m:  . x .     3p:  . x O
       . .            . O            O .


       O O            O O            O O
 4o:  O x O     4m:  . x O     4p:  . x .
       . .            O .            O O

        O O     
 5:    O x O      
        O .           

        O O     
 6:    O x O      
        O O              


'''


CR = chr(13)
LF = chr(10)

rulestring = golly.getstring(dialog_box_message, "B2o/S2m34") 

rulestring = rulestring.replace(" ", "")
rulestring = rulestring.lower()
rulestring = rulestring.replace("b", "B")
rulestring = rulestring.replace("s", "S")
rulestring = rulestring.replace("c", "C")


rulestring = rulestring.replace("hex_", "")
rulestring = rulestring.replace("_", "/")
rulestring_parts = rulestring.split("/")
rulestring_firstpart = rulestring_parts[0]
rulestring_secondpart = rulestring_parts[1]
if len(rulestring_parts) == 3:
   rulestring_thirdpart = rulestring_parts[2]
   rulestring_thirdpart = rulestring_thirdpart.replace("C", "")
   decaystates = int(rulestring_thirdpart)
    
else:
   decaystates = 0

rule_name = rulestring.replace("/", "_")  

rulestring = rulestring_firstpart + "/" + rulestring_secondpart

if rulestring.startswith("B") or rulestring.startswith("S"):
    rulestring = rulestring.replace("/", "")
else:
    rulestring = rulestring.replace("/", "B")

rulestring = rulestring + "\n"  

Callahandict = {
  "0":   [0],
  "1":   [1, 2, 4, 8, 16, 32],
  "2o":  [3,   6,  12,  24, 48,  33],
  "2m":  [5,   10,  20,  40,  17,  34],
  "2p":  [9,  18,  36], 
  "3o":  [7,  14,  28,  56,  49,  35],
  "3m":  [11,  22,  44,   25,  50,  37,  52, 26, 13, 38, 19, 41],
  "3p":  [21,   42],  
  "4o":  [15,   30,   60,   57,  51,   39],
  "4m":  [23,    46,   29,   58,    53,  43],
  "4p":  [27,   54,   45],
  "5":   [62, 61, 31, 59, 47, 55],
  "6":   [63]
}

def create_rule_element(bs,totalistic_num, notation_letter, inverse_list):
   result = ""
   if notation_letter != "none":
      for col in Callahandict[totalistic_num+notation_letter]:
         result = result + bs + str(col) + ","
   else:
     for row in Callahandict:
        if row.startswith(totalistic_num):
           for col in Callahandict[row]:
               result = result + bs + str(col) + ","
   return result
        





bs = "RS"                       
totalistic_context = "none"      
last_totalistic_context = "none" 
notation_letter = "none"         

finalrulestring = ""
for x in rulestring:
  if x == "S" or x == "B" or x.isdigit() or x == "\n":
     last_totalistic_context = totalistic_context   
     totalistic_context = x                         
     if last_totalistic_context != "none"  and notation_letter == "none":
         finalrulestring = finalrulestring + create_rule_element(bs, last_totalistic_context, "none",[])           
     # Now lets get ready to move on to the next character.
     notation_letter = "none"
     if x == "S" or x == "B":
         totalistic_context = "none"
     if x == "S":
         bs = "RS"
     if x == "B": 
         bs = "RB"
  elif x in ["o","m","p"] and totalistic_context != "none":
        notation_letter = x
        finalrulestring = finalrulestring + create_rule_element(bs, totalistic_context, notation_letter, [])  
 
finalrulestring = "NW1,NN2,NE0,WW32,ME0,EE4,SW0,SS16,SE8," + "HI" + str(decaystates) + ", " + finalrulestring

#golly.getstring('''
#Here is the Weighted Life version - you can copy it #below:                                                                                                                                    #.''', finalrulestring)



#  Part 2:   This is WeightedLife->RuleTree

from glife.RuleTree import *


# Default values
RS = []
RB = []
ME_weight = 0
NW_weight = 1 
NN_weight = 1    
NE_weight = 1
WW_weight = 1     
EE_weight = 1
SW_weight = 1         
SS_weight = 1
SE_weight = 1

CR = chr(13)
LF = chr(10)
   
#name = "Temporary-rule-name" 
name =  "Reversible2ndOrder_Hex_"+rule_name


#WeightedRulestring = golly.getstring(dialog_box_message, "Name=Temporary-rule-name NW4,NN1,NE0,WW1, ME0,EE4,SW0,SS4, SE1,HI0,RS1,RS6,RS8,RB5,RB6") 

WeightedRulestring = finalrulestring

#WeightedRulestring = WeightedRulestring.replace("ame = ", "ame=")


WeightedRulestring = WeightedRulestring.replace(" ", ",")
WeightedRulestring = WeightedRulestring.replace(CR, ",")
WeightedRulestring = WeightedRulestring.replace(LF, ",")
 
for x in WeightedRulestring.split(","):
   if x.startswith("Name=") or x.startswith("name="):
      name = x.split("ame=")[1]
   else:
      x = x.upper()
      if x.startswith("NW"):
         NW_weight = int(x.split("NW")[1])
      elif x.startswith("NN"):
         NN_weight = int(x.split("NN")[1])
      elif x.startswith("NE"):
         NE_weight = int(x.split("NE")[1])
      elif x.startswith("WW"):
         WW_weight = int(x.split("WW")[1])
      elif x.startswith("EE"):
         EE_weight = int(x.split("EE")[1])
      elif x.startswith("SW"):
         SW_weight = int(x.split("SW")[1])
      elif x.startswith("SS"):
         SS_weight = int(x.split("SS")[1])
      elif x.startswith("SE"):
         SE_weight = int(x.split("SE")[1])
      elif x.startswith("ME"):
         ME_weight = int(x.split("ME")[1])
      elif x.startswith("RS"):
         RS.append(int(x.split("RS")[1]))
      elif x.startswith("RB"):
         RB.append(int(x.split("RB")[1]))
      elif x.startswith("HI"):
         n_states = (int(x.split("HI")[1]))

#if n_states < 3:
#      n_states = 2
#if n_states > 256:
#    n_states = 256
#if n_states > 8:
#    golly.getstring('''Ruletrees with more than 8 or so states can take a long time to compute.  
#
#Save your work before continuing. Once this script starts computing your rule, 
#if you want to stop the calculation, you may have to abort Golly itelf.
#
#Choose the cancel option now to stop this script.''', "Proceed")

n_states = 4   # Using the 2nd Order technique on a 2 state CA requires 4 states.

n_neighbors = 8

def transition_function(a):
    # order for 8 neighbors is NW, NE, SW, SE, N, W, E, S, C

    n = NW_weight*(a[0] == 1 or a[0] == 3 ) + NE_weight*(a[1] == 1 or a[1] == 3) + SW_weight*(a[2] == 1 or a[2] == 3) + SE_weight*(a[3] == 1 or a[3] == 3) + NN_weight*(a[4] == 1 or a[4] == 3) + WW_weight*(a[5] == 1 or a[5] == 3) + EE_weight*(a[6] == 1 or a[6] == 3) + SS_weight*(a[7] == 1 or a[7] == 3) + ME_weight*(a[8] == 1 or a[8] == 3)

    if a[8] == 1:  #  Alive (& Dead in last generation)

       if n in RS:
           return 3
       else:
           return 2  

    if a[8] == 3: #  Alive (& Alive in last generation)
       if n in RS:
           return 2
       else:
           return 3  

    if a[8] == 2: #  Dead  (& Alive in last generation)
       if n in RB:
           return 0
       else:
           return 1  
    else: # a[8] =  0  (# Dead  & Dead in last generation)
       if n in RB:
           return 1
       else:
           return 0  

  

golly.show("Please wait while a rule file is being created...")

# The code below this line is copied from make-ruletree.py 

try:

    MakeRuleTreeFromTransitionFunction( n_states, n_neighbors, transition_function,
                                        golly.getdir("rules")+name+".tree" )
    
    # use name.tree to create name.rule (with no icons);
    # note that if name.rule already exists then we only replace the info in
    # the @TREE section to avoid clobbering any other info added by the user
    ConvertTreeToRule(name, n_states, [])
    
    golly.setalgo("RuleLoader")
    golly.setrule(name)
    golly.show("Created "+golly.getdir("rules")+name+".rule and switched to that rule.")

except:
    import sys
    import traceback
    exception, msg, tb = sys.exc_info()
    golly.warn(\
'''A problem was encountered with the supplied rule:'''+ '\n'.join(traceback.format_exception(exception, msg, tb)))
    golly.exit()

Here's a ship bouncing back and fourth via a chain of reflectors for a while before things get out of synch and everything explodes. I doubt this is the most interesting hex rule.

Code: Select all

x = 81, y = 115, rule = Reversible2ndOrder_Hex_B2o3o_S2o
2B23$48.2B35$67.2B14$7.2B13$79.2B14$19.2B4$33.A$33.CB$33.AB9$50.2B!
--

About "quantum CAs": googling leads to three separate kinds of research- people who want to build smaller conventional computer chips using quantum dots, people who want to build a truly quantum computer (with qbits, etc), and people who want to describe the universe as a CA. (Except, the lines between the second and third groups seem rather blurry!)

This seemed interesting, and even relevant to this newsgroup:
A Quantum Game of Life
http://www.jgrattage.webspace.virginmed ... jon/3DQCA/

(Scroll down to see the 2D version)
Last edited by EricG on March 8th, 2014, 1:28 pm, edited 1 time in total.

User avatar
alexv
Posts: 136
Joined: February 3rd, 2014, 11:14 am

Re: Reversible Wireless World

Post by alexv » March 8th, 2014, 12:16 pm

EricG wrote:About the states, good point! Thanks.
I edited the script and Alexander's snakes rule above so that state 2 and state 3 are swapped.
I suppose, Reversible2ndOrder.py also should be changed?

Alexander

User avatar
alexv
Posts: 136
Joined: February 3rd, 2014, 11:14 am

Re: Reversible Wireless World

Post by alexv » March 8th, 2014, 12:44 pm

EricG wrote: This seemed interesting, and even relevant to this newsgroup:
A Quantum Game of Life ...
They are using Margolus partition. Moving object are rather simple and natural in such a way,
but something similar with second-order CA was a challenge. Yet, 3D ants may be done as well
Image
The picture (and a vti file for Ready with implementation such a flight in a comment) are here
http://ayvlasov.wordpress.com/2013/07/3 ... bricks-ca/

Alexander

EricG
Posts: 199
Joined: August 19th, 2011, 5:41 pm
Location: Chicago-area, USA

Re: Reversible Wireless World

Post by EricG » March 8th, 2014, 12:59 pm

Yes, I meant to change the 2nd order reversible rule script but I accidentally changed the 2 state version instead. I think everything is changed the way it should be now.

I'd be very interested in hearing about the larger context of your work. Are you trying to describe the entire universe or are you merely trying to build the most amazing computer ever created? :-)

User avatar
alexv
Posts: 136
Joined: February 3rd, 2014, 11:14 am

Re: Reversible Wireless World

Post by alexv » March 8th, 2014, 1:06 pm

Eric, It is not my work, but reversible CA may be useful (e.g. some experiments with them
are disproving some wrong "obvious" intuitive ideas about behavior of reversible systems).

Alexander

User avatar
alexv
Posts: 136
Joined: February 3rd, 2014, 11:14 am

Re: Reversible Wireless World

Post by alexv » March 8th, 2014, 1:18 pm

bprentice wrote:The archive "Wireless Ant World.zip" has been updated here:
Brian, Thank you,

Relating your deleted comment. The only shorter version of SlAnt step I could imagine is (not checked):

Code: Select all

public int step(int row, int column)
  {
    int N  = squareCell.getNeighbor(row - 1, column    );
    int NE = squareCell.getNeighbor(row - 1, column + 1);
    int E  = squareCell.getNeighbor(row    , column + 1);
    int SE = squareCell.getNeighbor(row + 1, column + 1);
    int S  = squareCell.getNeighbor(row + 1, column    );
    int SW = squareCell.getNeighbor(row + 1, column - 1);
    int W  = squareCell.getNeighbor(row    , column - 1);
    int NW = squareCell.getNeighbor(row - 1, column - 1);

    int CellType[] = {0,1,0,1,2,2};

    int cell = squareCell.getNeighbor(row, column);

    int cCount = 0;
    if (CellType[N] == 1)   cCount++;
    if (CellType[E] == 1)   cCount++;
    if (CellType[S] == 1)   cCount++;
    if (CellType[W] == 1)   cCount++;
    
    int dCount = 0;
    if (CellType[NW] != 0)  dCount++;
    if (CellType[NE] != 0)  dCount++;
    if (CellType[SE] != 0)  dCount++;
    if (CellType[SW] != 0)  dCount++;

    int ifNot[] = {0,5,4,3,2,1};
    int ifYes[] = {4,3,0,5,1,2}; 
    
        
    if ((dCount == 0) && ((cCount == 1) || (cCount == 2)))
      return ifYes[cell];
    else
      return ifNot[cell]; 
  }

Alexander

bprentice
Posts: 920
Joined: September 10th, 2009, 6:20 pm
Location: Coos Bay, Oregon

Re: Reversible Wireless World

Post by bprentice » March 9th, 2014, 12:42 pm

My Java Reversible CA Software is archived here:

http://bprentice.webenet.net/Java%20Squ ... e%20CA.zip

A new version of Reversible Square Cell called "Reversible Square Cell 3" has been added. With this new version, the size of the rule table can be changed using the Rule Table Options Dialog. Also, any number of neighbors for the two distinct neighborhoods may be selected using the Neighbor Selector.

See this post for a brief description of how to specify a new rule:

viewtopic.php?f=11&t=1293&start=50#p11111

This new version is experimental. Any criticisms are welcome.

Brian

User avatar
alexv
Posts: 136
Joined: February 3rd, 2014, 11:14 am

Re: Reversible Wireless World

Post by alexv » March 15th, 2014, 6:22 am

I forgot to mention wide class of "ships" (due to them I even decided to delete from initial post
sentence about "single glider" existing in WlANt). Yet, it is not clear, if they may be considered
as "true" ships or not. Below is couple patterns to illustrate the trick with simplest "hexagonal ship".

Code: Select all

# Reflecions of "hexagonal ship" (or "ants herd two aphids") 
x = 24, y = 11, rule = WlAnt
.2C18.2C$.2C18.2C$2C20.2C$2C9.ACB8.2C$2C20.2C$2C8.AB.AB7.2C$2C20.2C$
2C9.ACB8.2C$2C20.2C$.2C18.2C$.2C18.2C!

Code: Select all

# Collisions and reflections of two "hexagonal ships"
x = 28, y = 11, rule = WlAnt
.2C22.2C$.2C22.2C$2C24.2C$2C5.BCA8.ACB5.2C$2C24.2C$2C4.BA.BA6.AB.AB4.
2C$2C24.2C$2C5.BCA8.ACB5.2C$2C24.2C$.2C22.2C$.2C22.2C!
Alexander

bprentice
Posts: 920
Joined: September 10th, 2009, 6:20 pm
Location: Coos Bay, Oregon

Re: Reversible Wireless World

Post by bprentice » March 15th, 2014, 12:15 pm

Several pattern collections have been added to the archive here:

http://bprentice.webenet.net/Java%20Squ ... e%20CA.zip

All of the new collections can be run on "Java Reversible CA/Reversible Square Cell 3/SquareCell.jar". Of particular interest is the collection in the directory "Java Reversible CA/Reversible Square Cell 3/Patterns/Rule 014" This rule supports Knight Ships, Diagonal Ships and Orthogonal Ships. The Orthogonal ships have many different speeds some of them are very slow.

File S003.sqc has fifteen patterns which differ only in their length. The range being from 12 to 26. Here is a table showing the behavior of these patterns:
Table.png
Table.png (21.08 KiB) Viewed 16823 times
Ship S004.sqc has a period of 767 and an x displacement of 1. Perhaps a member of this Forum who is an analyst can answer the following questions. Can the behavior of a pattern with a length of 12 + n be predicted without running the pattern? Is there a slowest ship?

Brian

User avatar
alexv
Posts: 136
Joined: February 3rd, 2014, 11:14 am

Re: Reversible Wireless World

Post by alexv » March 15th, 2014, 2:57 pm

Brian

If I understand your extended scheme in #NS correctly - It is always 5x5 square with each cell (except
central cell and unused cells) marked either by 1 or by 2 and so the square has two different regions
used for calculation of number of cells into each one? You may freely use own name or "trademark"
for such extension (the SlAnt is evolved in yet another direction with changing amount of states).

Alexander

bprentice
Posts: 920
Joined: September 10th, 2009, 6:20 pm
Location: Coos Bay, Oregon

Re: Reversible Wireless World

Post by bprentice » March 15th, 2014, 3:51 pm

Alexander,
alexv wrote:If I understand your extended scheme in #NS correctly - It is always 5x5 square with each cell (except
central cell and unused cells) marked either by 1 or by 2 and so the square has two different regions
used for calculation of number of cells into each one? You may freely use own name or "trademark"
for such extension (the SlAnt is evolved in yet another direction with changing amount of states).
I think you understand it correctly. It is best explained by the step method code. Notice that the rule table now has a size of 2 x ruleTableRows x ruleTableColumns (not necessarily 2 x 5 x 5) and that the number of neighbors in each set need no longer be four. See also the significant change to line 177.

I would prefer to give you the credit for my work. Thank you for giving me the opportunity to explore reversible rules.

Brian

Post Reply