Ruletable format extensions proposal

For general discussion about Conway's Game of Life.
User avatar
b-engine
Posts: 1526
Joined: October 26th, 2023, 4:11 am
Location: Somewhere on earth

Re: Thread for your website-related questions

Post by b-engine » April 12th, 2024, 10:20 am

dvgrn wrote:
April 12th, 2024, 9:51 am
But there's a problem: not everyone can use and know how to use Nutshell; I doesn't even understand a single pixel of the readme file. Can Nutshell have GUI?
My rules
-
100th post: 18 November 2023
1000th post: 8 March 2024
10000th post:
-
Warning: This user has grammar issues, and auto-capitalize everything he clicked.

User avatar
confocaloid
Posts: 3117
Joined: February 8th, 2022, 3:15 pm

Re: Ruletable format extensions proposal

Post by confocaloid » April 12th, 2024, 10:27 am

dvgrn wrote:
April 12th, 2024, 9:51 am
[...]
Re: the bound vs. unbound variables question: @tommyaweosme, you might be interested in trying out Nutshell. [...]
Note: I did not go far beyond skimming the documentation / examples.

Overall, the examples look and feel foreign. The rueltabel examples/nutshells/roed.ruel looks and feels like a mishmash of "variable" names, compass directions and several different special symbols.

That probably can be overcome with enough practice in using that format. But certainly more complicated (perhaps it's fair to say "bloated"). There is value in keeping the syntax sufficiently simple, so that it can be quickly learned.
dvgrn wrote:
April 12th, 2024, 9:51 am
[...]Here's a quote from the documentation:
Variables
All variable names are unbound, always, because needing to define eight separate "any state" vars is ridiculous.

That's not to say, however, that there is no concept of binding variables in Nutshell! It's just that you don't bind by name. Nutshell's actual idea of binding is explained later on.
[...]
This is basically one of points where I disagree.

I think it's fine to define eight separate vars, whenever one needs eight separate independent variables. Different names = different variables. Same name = same variable.
If the ruletable is written manually, that helps to keep it human-readable.
If the ruletable is autogenerated from some source, then, well, what's wrong with autogenerating eight separate vars for eight separate independent variables?
127:1 B3/S234c User:Confocal/R (isotropic CA, incomplete)
Unlikely events happen.
My silence does not imply agreement, nor indifference. If I disagreed with something in the past, then please do not construe my silence as something that could change that.

User avatar
dvgrn
Moderator
Posts: 10729
Joined: May 17th, 2009, 11:00 pm
Location: Madison, WI
Contact:

Re: Thread for your website-related questions

Post by dvgrn » April 12th, 2024, 12:47 pm

b-engine wrote:
April 12th, 2024, 10:20 am
But there's a problem: not everyone can use and know how to use Nutshell; I doesn't even understand a single pixel of the readme file. Can Nutshell have GUI?
Well... a GUI could certainly be built (using Golly's Lua overlay, for example) that would write out Nutshell ".ruel" tables, which would then transpile to actual Golly ruletables.

Given that Nutshell hasn't seen a lot of use recently, it's not clear who exactly would use something like that, though. There's some irreducible complexity here, so not everyone would magically know how to use a Nutshell-generating GUI either.

I'm not sure that's actually a problem, though. I mentioned Nutshell and posted a link to it, mostly just to make it a little more likely that people who need Nutshell will know that it exists. People tend to need Nutshell when they've gotten pretty good at building ruletables, but for particular cases they start having to write their own scripts to create very complex or very large rule tables, or otherwise they start having to fight through generating an unreasonable number of cases by hand -- which is when hard-to-find errors tend to creep in, and Nutshell can be a hugely helpful shortcut.

Long story short, Nutshell format is just another available option; the nice thing about it is that anyone who doesn't like it doesn't need to use it -- the transpiled ruletable will always be available as an alternative, since that's the final endpoint of any Nutshell "ruel" file.
confocaloid wrote:
April 12th, 2024, 10:27 am
If the ruletable is autogenerated from some source, then, well, what's wrong with autogenerating eight separate vars for eight separate independent variables?
Nothing is wrong with that at all -- that's exactly what Nutshell does (if I'm understanding this correctly). The point of Nutshell is to allow a more compact and easier-to-edit notation, that produces plain-vanilla ruletables that would be really difficult to generate manually.

User avatar
wirehead
Posts: 259
Joined: June 18th, 2022, 2:37 pm
Location: fish: wirehead: command not found
Contact:

Re: Ruletable format extensions proposal

Post by wirehead » April 12th, 2024, 9:31 pm

Looking at this, I have an idea to sort of implement tommyawesome's proposal.

Normal var declarations behave as expected. So if a has n values, "3, a, a, 0, 0, 0, 0, 0, 0, a" expands into n rows.

However if you put a tilde before the variable name it unbinds the variable within that transition (making it like a tommyawesome lvar) -- "3, ~a, a, 0, 0, 0, 0, 0, 0, a" expands into n^2 rows. It would be a syntax error to use a variable in the output state column, without having the same variable bound at least once in the neighborhood.

How does this sound?
Langton's ant: Can't play the drums, can be taught.

User avatar
confocaloid
Posts: 3117
Joined: February 8th, 2022, 3:15 pm

Re: Ruletable format extensions proposal

Post by confocaloid » April 13th, 2024, 1:52 am

wirehead wrote:
April 12th, 2024, 9:31 pm
How does this sound?
I think the idea is interesting. With a "sigil" used directly within the affected rule, reading a single rule suffices to understand where are bound variables, and where are "one-time" variables not bound to any name. (Anyway that would be better than having to scroll back and forth to declarations of variables while reading.)

One will need to choose the syntax. Prefixing a tilde makes it easy to misread "~a" as negation of the value of "a".
Maybe prefix with asterisk instead? Or that would be confusing too, for some other reason?

If the variable a is

Code: Select all

var a={2,5}
then the single rule

Code: Select all

3, *a, *a, a, 0, 0, 0, 0, 0, a
will expand into eight rules without variables:

Code: Select all

3, 2, 2, 2, 0, 0, 0, 0, 0, 2
3, 2, 5, 2, 0, 0, 0, 0, 0, 2
3, 5, 2, 2, 0, 0, 0, 0, 0, 2
3, 5, 5, 2, 0, 0, 0, 0, 0, 2
3, 2, 2, 5, 0, 0, 0, 0, 0, 5
3, 2, 5, 5, 0, 0, 0, 0, 0, 5
3, 5, 2, 5, 0, 0, 0, 0, 0, 5
3, 5, 5, 5, 0, 0, 0, 0, 0, 5
127:1 B3/S234c User:Confocal/R (isotropic CA, incomplete)
Unlikely events happen.
My silence does not imply agreement, nor indifference. If I disagreed with something in the past, then please do not construe my silence as something that could change that.

User avatar
wirehead
Posts: 259
Joined: June 18th, 2022, 2:37 pm
Location: fish: wirehead: command not found
Contact:

Re: Ruletable format extensions proposal

Post by wirehead » April 13th, 2024, 11:21 am

confocaloid wrote:
April 13th, 2024, 1:52 am
One will need to choose the syntax. Prefixing a tilde makes it easy to misread "~a" as negation of the value of "a".
Maybe prefix with asterisk instead? Or that would be confusing too, for some other reason?
After some more thought, I think the best sigil would be &, sort of like int& in C++ where it makes a "reference" to an int variable which behaves like it's a normal int but it just references the original variable that was referenced.

Also, with regards to ~ meaning negate, that might also be worthwhile to implement natively, so that you don't have to make two variables for A and notA. (And this would also apply to individual states, too so that in a 5 state rule writing ~3 means {0, 1 2, 4}.) We could go even farther and allow even more set operations on variables, such as a+b for set union, a-b for asymmetric subtraction, a^b for symmetric difference, a*b for intersection, etc. But then we run the risk of making Golly rule tables turing complete which may or may not be the goal.
Langton's ant: Can't play the drums, can be taught.

User avatar
confocaloid
Posts: 3117
Joined: February 8th, 2022, 3:15 pm

Re: Ruletable format extensions proposal

Post by confocaloid » April 13th, 2024, 2:27 pm

Also (alternatively?), one could allow array-indexing notation for different versions of the same variable. Then the following would be possible, with only one variable declaration and only one written rule:

Code: Select all

var a={3,4}
0, a[1], a[1], a[1], a[1], a[2], a[2], a[2], a[2], 1
The above rule would expand to four rules without any variables:

Code: Select all

0, 3, 3, 3, 3, 3, 3, 3, 3, 1
0, 3, 3, 3, 3, 4, 4, 4, 4, 1
0, 4, 4, 4, 4, 3, 3, 3, 3, 1
0, 4, 4, 4, 4, 4, 4, 4, 4, 1
Currently, to do the same thing, one has to declare two variables with the same set of allowed values:

Code: Select all

var a={3,4}
var b={3,4}
0, a, a, a, a, b, b, b, b, 1
Indeed, array-indexing notation could be a cleaner way to specify 256 rules at once:

Code: Select all

var a={3,4}
0, a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], 1
That would make it easy to see that there are eight independent variables.
wirehead wrote:
April 13th, 2024, 11:21 am
[...]
Also, with regards to ~ meaning negate, that might also be worthwhile to implement natively, so that you don't have to make two variables for A and notA. (And this would also apply to individual states, too so that in a 5 state rule writing ~3 means {0, 1 2, 4}.) [...]
I'm not sure it's a good idea to allow negation inside a rule. What would the following expand to? (Note that there are two occurrences of "a" and two occurrences of "~a" in a single rule.)

Code: Select all

n_states:5
var a={2, 3, 4}
0, 0, 0, a, a, ~a, ~a, 0, 0, 1
There are several possible choices I can see:
  • One could interpret "~a" as "any cellstate in the set of values allowed for a, except the value of a". Then the above example would expand to 6 rules. (There are three choices for a. For every choice of a, there are two remaining choices for ~a from the same set.)

    Code: Select all

    0, 0, 0, 2, 2, 3, 3, 0, 0, 1
    0, 0, 0, 2, 2, 4, 4, 0, 0, 1
    0, 0, 0, 3, 3, 2, 2, 0, 0, 1
    0, 0, 0, 3, 3, 4, 4, 0, 0, 1
    0, 0, 0, 4, 4, 2, 2, 0, 0, 1
    0, 0, 0, 4, 4, 3, 3, 0, 0, 1
  • Alternatively, one could interpret "~a" as "any cellstate from 0 through n_states-1, except the value of a". Then the above example would expand to 12 rules. (There are three choices for a. For every choice of a, there are four choices of ~a.)
  • Alternatively, one could interpret "~a" as the arithmetic expression (n_states - 1 - a). Then the above example would expand to three rules:

    Code: Select all

    0, 0, 0, 2, 2, 2, 2, 0, 0, 1
    0, 0, 0, 3, 3, 1, 1, 0, 0, 1
    0, 0, 0, 4, 4, 0, 0, 0, 0, 1
  • Alternatively, one could interpret "~a" as the bitwise NOT of a. But that wouldn't work well unless the number of cellstates is a power of two.
Neither of these possibilities feels like "the single best choice" to me.
wirehead wrote:
April 13th, 2024, 11:21 am
[...] We could go even farther and allow even more set operations on variables, such as a+b for set union, a-b for asymmetric subtraction, a^b for symmetric difference, a*b for intersection, etc. But then we run the risk of making Golly rule tables turing complete which may or may not be the goal.
Do you think arithmetic operations should accept and return sets?

I believe arithmetic with single cellstates would be more useful and intuitive. For example:

Code: Select all

n_states:16
var a={2,3,10}
var b={1,5}
0, 0, 0, 0, 0, 0, a, b, a+b, a+b
That would expand to six rules without variables:

Code: Select all

n_states:16
0, 0, 0, 0, 0, 0, 2, 1, 3, 3
0, 0, 0, 0, 0, 0, 2, 5, 7, 7
0, 0, 0, 0, 0, 0, 3, 1, 4, 4
0, 0, 0, 0, 0, 0, 3, 5, 8, 8
0, 0, 0, 0, 0, 0, 10, 1, 11, 11
0, 0, 0, 0, 0, 0, 10, 5, 15, 15
One would have to deal with arithmetic underflow/overflow. One possibility is simply discarding rules, whenever the result of an expression is out of range. (So, if the last example above is modified to have 14 cellstates instead of 16, then it would expand to only 5 rules. The sixth rule would be discarded due to 10 + 5 overflowing.)
Other possibilities are to use wraparound arithmetic or saturation arithmetic. That could be made configurable.
127:1 B3/S234c User:Confocal/R (isotropic CA, incomplete)
Unlikely events happen.
My silence does not imply agreement, nor indifference. If I disagreed with something in the past, then please do not construe my silence as something that could change that.

User avatar
wirehead
Posts: 259
Joined: June 18th, 2022, 2:37 pm
Location: fish: wirehead: command not found
Contact:

Re: Ruletable format extensions proposal

Post by wirehead » April 13th, 2024, 5:21 pm

confocaloid wrote:
April 13th, 2024, 2:27 pm
I'm not sure it's a good idea to allow negation inside a rule. ... Neither of these possibilities feels like "the single best choice" to me.
I was thinking more along the lines of typical set negation you learn in high school algebra 2 class -- i.e. "not A" means the same as U-A where U is all allowed cellstates. So if it is a 10 state rule and a={3,4,6,7} then ~a={0,1,2,5,8,9}.
confocaloid wrote:
April 13th, 2024, 2:27 pm
Do you think arithmetic operations should accept and return sets?
Yeah, that is what Python uses instead of the mathy symbols a∪b, a∩b which aren't ASCII, and a\b which more often than not causes parsing problems.
confocaloid wrote:
April 13th, 2024, 2:27 pm
I believe arithmetic with single cellstates would be more useful and intuitive.
You, perhaps, but I am not as familiar with vector/matrix math that this seems most like. Why should A+B mean sum of all combinations, versus set union? If this behavior is desired, I think the asterisk operator * and thinking of it as "multiplying" two sets to produce a matrix of permutations would suffice.

If anything, IMHO the operations that should operate like vectors are the bitwise operators, because I would think it's more common for cellular automata rules to use bit planes to store multiple on-off states in a numeric state, versus the sum of any two numeric states be anything useful. Because & is a common bitwise operator I think the sigil for unbinding a variable can be "?".

OTOH if you are making a rule where the states, or some subset of them more likely, cycles through sequentially, you could write "a, ?any, ?any, ?any, ..., (a+1)%N" to express this.

We're getting into very muddy waters here so I appreciate all feedback.
Langton's ant: Can't play the drums, can be taught.

User avatar
confocaloid
Posts: 3117
Joined: February 8th, 2022, 3:15 pm

Re: Ruletable format extensions proposal

Post by confocaloid » April 13th, 2024, 6:04 pm

wirehead wrote:
April 13th, 2024, 5:21 pm
[...]
confocaloid wrote:
April 13th, 2024, 2:27 pm
I believe arithmetic with single cellstates would be more useful and intuitive.
You, perhaps, but I am not as familiar with vector/matrix math that this seems most like. Why should A+B mean sum of all combinations, versus set union? If this behavior is desired, I think the asterisk operator * and thinking of it as "multiplying" two sets to produce a matrix of permutations would suffice.
[...]
Not really. What I described in my previous post wouldn't need vectors or matrices. It would be integer arithmetic with state values.
In the imagined examples I posted earlier, an expression like "a+b" (inside a rule) is a simple arithmetic expression that uses variables a and b.

For another example, in a rule like

Code: Select all

3, 0, a, 0, b, 0, a + b, 0, a - b, 4
there would be only two independent variables (a and b), which would have to be declared. Expressions "a + b" and "a - b" would be evaluated for every possible way to assign values to variables a and b.
If a takes values from the set {5,6} and b takes values from the set {0,3} then the above would be equivalent to four rules:

Code: Select all

3, 0, 5, 0, 0, 0, 5, 0, 5, 4
3, 0, 5, 0, 3, 0, 8, 0, 2, 4
3, 0, 6, 0, 0, 0, 6, 0, 6, 4
3, 0, 6, 0, 3, 0, 9, 0, 3, 4
For another example, the following would be possible, and I believe it would be quite readable:

Code: Select all

@TABLE
neighborhood: Moore
n_states:     10
symmetries:   permute
overflow:     saturation

var a={1,2,3,4,5,6,7,8,9}
var x={0,1,2,3,4,5,6,7,8,9}

0,    a[1], a[2], a[3], 0, 0, 0, 0, 0, 1        # a state-1 cell is born when it has exactly three nonzero neighbours
a[0], a[1], a[2], a[3], 0, 0, 0, 0, 0, a[0]+1   # a nonzero cell survives when it has exactly three...
a[0], a[1], a[2],    0, 0, 0, 0, 0, 0, a[0]+1   # ... or two nonzero neighbours
x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8],  0   # otherwise, every cell becomes or remains 0
When a cell survives, its state is incremented if that is possible. If an overflow happens (when trying to increment a state-9 cell) then it remains state-9 because the ruletable uses saturation arithmetic ("overflow: saturation").
The resulting CA is basically Conway's Life, except every alive cell remembers how long it is alive, until it reaches state 9 when it stops counting.

I think the above can be expanded into the currently supported syntax for ruletables in the following way:

Code: Select all

@TABLE
neighborhood:Moore
n_states:10
symmetries:permute

var a1={1,2,3,4,5,6,7,8,9}
var a2=a1
var a3=a1
var x={0,1,2,3,4,5,6,7,8,9}
var x1=x
var x2=x
var x3=x
var x4=x
var x5=x
var x6=x
var x7=x
var x8=x

0, a1, a2, a3, 0, 0, 0, 0, 0, 1
1, a1, a2, a3, 0, 0, 0, 0, 0, 2
2, a1, a2, a3, 0, 0, 0, 0, 0, 3
3, a1, a2, a3, 0, 0, 0, 0, 0, 4
4, a1, a2, a3, 0, 0, 0, 0, 0, 5
5, a1, a2, a3, 0, 0, 0, 0, 0, 6
6, a1, a2, a3, 0, 0, 0, 0, 0, 7
7, a1, a2, a3, 0, 0, 0, 0, 0, 8
8, a1, a2, a3, 0, 0, 0, 0, 0, 9
9, a1, a2, a3, 0, 0, 0, 0, 0, 9
1, a1, a2, 0, 0, 0, 0, 0, 0, 2
2, a1, a2, 0, 0, 0, 0, 0, 0, 3
3, a1, a2, 0, 0, 0, 0, 0, 0, 4
4, a1, a2, 0, 0, 0, 0, 0, 0, 5
5, a1, a2, 0, 0, 0, 0, 0, 0, 6
6, a1, a2, 0, 0, 0, 0, 0, 0, 7
7, a1, a2, 0, 0, 0, 0, 0, 0, 8
8, a1, a2, 0, 0, 0, 0, 0, 0, 9
9, a1, a2, 0, 0, 0, 0, 0, 0, 9
x, x1, x2, x3, x4, x5, x6, x7, x8,  0
edit: attempted to slightly improve readability of posted examples, without any significant changes in the proposed feature
Last edited by confocaloid on April 13th, 2024, 10:05 pm, edited 2 times in total.
127:1 B3/S234c User:Confocal/R (isotropic CA, incomplete)
Unlikely events happen.
My silence does not imply agreement, nor indifference. If I disagreed with something in the past, then please do not construe my silence as something that could change that.

User avatar
squareroot12621
Posts: 638
Joined: March 23rd, 2022, 4:53 pm

Re: Ruletable format extensions proposal

Post by squareroot12621 » April 13th, 2024, 6:59 pm

I like these suggested additions to ruletables. However, I'm not a huge fan of the a[n] syntax for "copy n of the array a", because it looks like you're taking the nᵗʰ element of a. If I had to suggest an alternative, I would choose a.n, which (I think) is what Nutshell already internally uses.

Code: Select all

4b8o$4b8o$4b8o$4b8o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4b8o$4b8o$4b8o$4b8o![[ THEME 0 AUTOSTART GPS 8 Z 16 T 1 T 1 Z 19.027 T 2 T 2 Z 22.627 T 3 T 3 Z 26.909 T 4 T 4 Z 32 T 5 T 5 Z 38.055 T 6 T 6 Z 45.255 T 7 T 7 Z 53.817 LOOP 8 ]]

User avatar
confocaloid
Posts: 3117
Joined: February 8th, 2022, 3:15 pm

Re: Ruletable format extensions proposal

Post by confocaloid » April 13th, 2024, 7:14 pm

squareroot12621 wrote:
April 13th, 2024, 6:59 pm
[...] However, I'm not a huge fan of the a[n] syntax for "copy n of the array a", because it looks like you're taking the nᵗʰ element of a. [...]
"a[4]" looks like taking an element of an array "a", precisely because it is meant to be readable as "taking an element of an array of variables".

When you're declaring a variable, like so:

Code: Select all

var a={3,4,5}
- with the current syntax you are just declaring a single variable named "a".

My suggestion is backwards compatible. The same syntax would still declare the same variable "a". However, it would also declare independent variables "a[1]", "a[2]", "a[3]", and so on, each of them with the same set of allowed values.
squareroot12621 wrote:
April 13th, 2024, 6:59 pm
[...] If I had to suggest an alternative, I would choose a.n, which (I think) is what Nutshell already internally uses.
A disadvantage of using the dot is that it would not highlight the fact that all variables a.something have the exact same set of allowed values. That would be similar to the syntax used for accessing a member of a struct/record in several programming languages, and members of a struct/record can have different types.
127:1 B3/S234c User:Confocal/R (isotropic CA, incomplete)
Unlikely events happen.
My silence does not imply agreement, nor indifference. If I disagreed with something in the past, then please do not construe my silence as something that could change that.

User avatar
squareroot12621
Posts: 638
Joined: March 23rd, 2022, 4:53 pm

Re: Ruletable format extensions proposal

Post by squareroot12621 » April 13th, 2024, 8:33 pm

confocaloid wrote:
April 13th, 2024, 7:14 pm
squareroot12621 wrote:
April 13th, 2024, 6:59 pm
[...] However, I'm not a huge fan of the a[n] syntax for "copy n of the array a", because it looks like you're taking the nᵗʰ element of a. [...]
"a[4]" looks like taking an element of an array "a", precisely because it is meant to be readable as "taking an element of an array of variables".…
Yes, a[4] does give you an element of a. (As does anything with a at the beginning.) However, to me, it looks like it's taking specifically the fourth element of a, not any of the others.
Just to be clear: If a were defined to {0, 1, 2, 3, 4}, would a[4] refer to (A) just state 3, or (B) an independent copy of a?
confocaloid wrote:
April 13th, 2024, 7:14 pm
squareroot12621 wrote:
April 13th, 2024, 6:59 pm
[...] If I had to suggest an alternative, I would choose a.n, which (I think) is what Nutshell already internally uses.
A disadvantage of using the dot is that it would not highlight the fact that all variables a.something have the exact same set of allowed values. That would be similar to the syntax used for accessing a member of a struct/record in several programming languages, and members of a struct/record can have different types.
…Then what else would we use? a#n, maybe?

Code: Select all

4b8o$4b8o$4b8o$4b8o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4b8o$4b8o$4b8o$4b8o![[ THEME 0 AUTOSTART GPS 8 Z 16 T 1 T 1 Z 19.027 T 2 T 2 Z 22.627 T 3 T 3 Z 26.909 T 4 T 4 Z 32 T 5 T 5 Z 38.055 T 6 T 6 Z 45.255 T 7 T 7 Z 53.817 LOOP 8 ]]

User avatar
confocaloid
Posts: 3117
Joined: February 8th, 2022, 3:15 pm

Re: Ruletable format extensions proposal

Post by confocaloid » April 13th, 2024, 8:58 pm

squareroot12621 wrote:
April 13th, 2024, 8:33 pm
confocaloid wrote:
April 13th, 2024, 7:14 pm
[...]
"a[4]" looks like taking an element of an array "a", precisely because it is meant to be readable as "taking an element of an array of variables".…
Yes, a[4] does give you an element of a. (As does anything with a at the beginning.) However, to me, it looks like it's taking specifically the fourth element of a, not any of the others.
Just to be clear: If a were defined to {0, 1, 2, 3, 4}, would a[4] refer to (A) just state 3, or (B) an independent copy of a?
In the existing ruletable syntax, writing

Code: Select all

var a={0, 1, 2, 3, 4}
declares a single variable that can take values from the set {0, 1, 2, 3, 4}.
After that, one can use it in rules. For example,

Code: Select all

1, a, a, a, a, a, a, a, a, 2
would use just one variable a. That is equivalent to five rules (one rule for each allowed value of a).
Note that in the above, the variable a is not an array. It doesn't have any smaller elements. Its value is a single cellstate.

My suggestion is to have

Code: Select all

var a={0, 1, 2, 3, 4}
additionally implicitly declare "subscripted" variables a[1], a[2], a[3] and so on, whenever those variables are used later in the rules.
Every such variable would have the same set of allowed values.
The effect is that instead of declaring a single variable, one would declare an array of variables, all of the same type (i.e. with the same set of allowed values). Therefore the array-like notation makes sense in this case.

Then the rule

Code: Select all

1, a[1], a[2], a[3], a[4], a[1], a[2], a[3], a[4], 2
would use four independent variables, each of which can take values from the same set {0, 1, 2, 3, 4}. That would expand to 5^4 variable-free rules.

The rule

Code: Select all

1, a[1], a[1], a[2], a[2], a[2], a[3], a[3], a[3], 2
would use three independent variables (a[1] used twice, a[2] used three times, a[3] used three times in the rule). That would expand to 5^3 variable-free rules.
127:1 B3/S234c User:Confocal/R (isotropic CA, incomplete)
Unlikely events happen.
My silence does not imply agreement, nor indifference. If I disagreed with something in the past, then please do not construe my silence as something that could change that.

User avatar
confocaloid
Posts: 3117
Joined: February 8th, 2022, 3:15 pm

Re: Ruletable format extensions proposal

Post by confocaloid » April 13th, 2024, 10:52 pm

confocaloid wrote:
April 13th, 2024, 8:58 pm
squareroot12621 wrote:
April 13th, 2024, 8:33 pm
[...] However, to me, it looks like it's taking specifically the fourth element of a, not any of the others. [...]
[...] Note that in the above, the variable a is not an array. It doesn't have any smaller elements. Its value is a single cellstate. [...]
As a side note, in the existing Golly ruletable syntax, the meanings of the colon ':' and the equals sign '=' are exchanged.

For example, the following is a fragment of an existing ruletable in the existing Golly ruletable format: (example taken from Rule:B3S23clustersv0)

Code: Select all

@TABLE
n_states:3
neighborhood:Moore
symmetries:permute

var d={0,2}
var d1=d
var d2=d
I think it would make more sense if the section @TABLE started as follows instead:

Code: Select all

@TABLE
n_states=3
neighborhood=Moore
symmetries=permute

var d: {0,2}
var d1: d
var d2: d
The reason why "n_states=3" would be clearer is because "n_states" is the number of cellstates, in this case equal to 3. The left part is the name of a property, and the right part is the value of that property.

The reason why "var d: {0,2}" would be clearer is because "d" is the name of a declared variable, which in this case can take values from the set {0,2}. The left part is the name of a variable, and the right part is the type of that variable (set of allowed values).

The existing syntax does it the other way round. The line "var d={0,2}" incorrectly suggests that d must be "equal to" the set {0,2} which cannot be true.
That exchange between ':' and '=' is unfortunate, but probably too late to change at this point.
127:1 B3/S234c User:Confocal/R (isotropic CA, incomplete)
Unlikely events happen.
My silence does not imply agreement, nor indifference. If I disagreed with something in the past, then please do not construe my silence as something that could change that.

User avatar
wirehead
Posts: 259
Joined: June 18th, 2022, 2:37 pm
Location: fish: wirehead: command not found
Contact:

Re: Ruletable format extensions proposal

Post by wirehead » April 17th, 2024, 9:54 pm

confocaloid wrote:
April 16th, 2024, 10:23 am
Bump "Re: Rule Tables + Weighted Life + Larger than Life"
This other topic seems mildly related, so I’m linking to it.

My other idea is that since Golly has Lua and Python built in, the simplest solution to all the rule table problems may be just allowing the user to literally write an actual transition function. There could be some more checks to ensure that the function is deterministic (disable random module, global variables, etc.) and then maybe the MakeRuleTreeFromFunction code could be ported to C++ to make it built in to Golly. Does this sound feasible? (looking at the Golly maintainers for feedback here.)
Langton's ant: Can't play the drums, can be taught.

User avatar
confocaloid
Posts: 3117
Joined: February 8th, 2022, 3:15 pm

Re: Ruletable format extensions proposal

Post by confocaloid » April 18th, 2024, 5:19 am

wirehead wrote:
April 13th, 2024, 11:21 am
[...] But then we run the risk of making Golly rule tables turing complete which may or may not be the goal.
wirehead wrote:
April 17th, 2024, 9:54 pm
[...] There could be some more checks to ensure that the function is deterministic (disable random module, global variables, etc.) [...]
I think precomputing the rules using a PRNG wouldn't be a particularly serious problem. It would just mean that a pattern would evolve differently each time (unless the same fixed seed is used always). Might be unexpected, but also might be useful if the PRNG does minor tweaks that don't affect most patterns while still introducing some controlled nondeterminism.

The big problem would come with infinite loops, unbounded memory usage, filesystem access, and so on. You wouldn't want to have an infinite loop or a virus deleting all user files it can find, when the Golly user is trying to do something as simple as "File -> Open Pattern..."

Ruletables are "passive data". I think that's good (they are very powerful even in their current form, yet sufficiently easy to learn and (hopefully) safe to use).
I also think it would be possible to make ruletables significantly more expressive, while still keeping them human-readable "passive data".
wirehead wrote:
April 13th, 2024, 5:21 pm
Because & is a common bitwise operator I think the sigil for unbinding a variable can be "?".

OTOH if you are making a rule where the states, or some subset of them more likely, cycles through sequentially, you could write "a, ?any, ?any, ?any, ..., (a+1)%N" to express this.

We're getting into very muddy waters here so I appreciate all feedback.
I agree that some explicit sigil character for "unbinding" would be useful in situations similar to the "catch-all" rule ("all other cells die or stay dead") visible at the end of many existing ruletables. It would be possible to write

Code: Select all

var x: {0,1,2,3,4,5,6,7}
...
?x, ?x,?x,?x,?x,?x,?x,?x,?x, 0
(actually, such "sigil" would create an independent copy of an existing variable, with the same type)

OTOH sigils would not cover rules like this:

Code: Select all

var a: {1,2,3}
var b: {1,2,3}
0,  a,b,a,b,a,b,a,b,   1
In this example, a and b can independently take values from the same set {1,2,3}, but each is used more than once in the rule. Trying to use sigils would lead to

Code: Select all

var a: {1,2,3}
0,  ?a,?a,?a,?a,?a,?a,?a,?a,  1
which would be a different rule (instead of 2 independent variables each used 4 times, one would have 8 independent variables each used 1 time).
To avoid declaring two variables with the same set of allowed values, one would need to have some "numbered sigils", which would be something equivalent to

Code: Select all

var a: {1,2,3}
0,  a[1],a[2],a[1],a[2],a[1],a[2],a[1],a[2],  1
127:1 B3/S234c User:Confocal/R (isotropic CA, incomplete)
Unlikely events happen.
My silence does not imply agreement, nor indifference. If I disagreed with something in the past, then please do not construe my silence as something that could change that.

User avatar
b-engine
Posts: 1526
Joined: October 26th, 2023, 4:11 am
Location: Somewhere on earth

Re: Ruletable format extensions proposal

Post by b-engine » April 18th, 2024, 5:54 am

The changes shorten a long ruletable:

Code: Select all

@RULE B-Univ
#State 1 is wire
#State 2 is turn right signal/command
#State 3 is signal tail, also emulates B2ae/S
#State 4 is turn left signal/command
#State 5 is the hand
#State 6 is retract signal/command
#State 7 is extend signal/command
@TABLE
n_states=8
neighborhood=Moore
symmetries=rotate4
var s:{2,4,6,7}
var s2:{4,6,7}
var s3:{2,6,7}
var s4:{2,4,7}
var s5:{2,4,6}
var ts:{2,4}
var a:{0,1,2,3,4,5,6,7}
var w:{0,1,3,5}
var b:{0,5}
var l:{0,3}
var h:{1,5}
0,1,0,1,0,0,0,0,0,1
0,5,1,*w,*w,*a,*a,*a,6,5
0,5,4,*a,*a,*a,*a,*a,*a,5
0,5,0,0,0,a,1,1,2,0
0,5,0,*a,*a,*a,*a,*a,2,5
0,1,3,2,5,0,0,0,0,0
0,*a,2,5,*a,*a,*a,*a,0,5
0,5,1,*a,*a,*a,*a,*a,6,5
0,6,5,0,0,0,0,0,5,1
0,6,5,*w,*w,*w,*w,*w,5,3
0,3,0,3,0,0,0,0,0,3
0,3,3,0,0,0,0,0,0,3
0,0,3,3,0,0,0,0,0,3
0,0,3,6,5,5,0,0,0,6
s,3,0,5,1,1,1,5,0,0
1,3,5,*w,*w,*w,*w,*w,5,0
3,5,0,5,*w,1,*w,5,0,0
5,0,1,0,0,0,0,0,0,0
5,0,3,1,1,0,0,1,0,0
5,s,3,h,0,0,0,a,1,5
5,s,3,5,*a,*a,*a,*a,1,5
5,5,*w,1,*w,0,0,6,0,3
5,0,5,3,1,*w,*w,*a,*a,0
5,*w,1,3,5,0,*a,*a,*w,0
5,0,3,ts,1,*w,*w,*w,*w,0
5,*w,1,ts,3,0,*w,*w,*w,0
5,0,3,7,1,*w,*w,*w,*w,0
5,*w,1,7,3,0,*w,*w,*w,0
5,1,0,5,*w,1,*w,5,0,1
5,0,6,5,0,w,0,0,0,0
5,0,5,6,0,1,0,0,0,6
3,*l,*l,*l,*l,*l,*l,*l,*l,0
5,5,*b,*b,*b,*b,*b,*b,*b,0
5,*b,5,*b,*b,*b,*b,*b,*b,0
5,ts,0,5,*a,0,*a,0,0,1
5,ts,0,0,*a,0,*a,5,0,1
5,5,s,*w,*w,*w,*w,*w,*w,5
1,0,5,s,0,0,0,w,0,1
1,s,0,0,0,0,0,5,0,s
1,s,0,0,0,*w,0,5,0,1
1,0,5,5,5,0,*a,0,*a,5
1,0,1,1,0,3,0,1,1,0
1,5,1,s,3,0,0,0,0,1
1,s,1,5,a,1,0,0,0,7
1,7,5,5,a,1,0,0,0,2
1,2,5,5,a,1,0,0,0,4
1,4,5,5,a,1,0,0,0,6
1,s,*w,*w,*a,*w,*a,*w,*w,s
3,1,*a,*a,5,6,5,*a,*a,5
6,s4,*w,*w,*w,3,*w,*w,*w,1
6,3,0,5,*a,1,*a,5,0,1
6,3,*w,*w,*w,5,*w,*w,*w,5
7,5,*a,*a,*a,*a,*a,*a,*a,3
s,1,*a,*a,*a,*a,*a,*a,*a,3
3,*a,*a,*a,*a,*a,*a,*a,*a,1
5,7,*a,*a,*a,*a,*a,*a,*a,7
5,6,*a,*a,*a,*a,*a,*a,*a,0
0,7,0,*a,*a,*a,*a,*a,0,5
6,0,*a,*a,*a,*a,*a,*a,*a,0
s,0,*a,*a,*a,*a,*a,*a,*a,1
@NAMES
0 dead
1 wire
2 RIGHT command
3 signal tail
4 LEFT command
5 hand
6 RETRACT command
7 EXTEND command
@COLORS
1 0 0 255
2 0 255 0
3 255 0 0
4 255 255 0
5 255 0 255
6 255 255 255
7 0 255 255
My rules
-
100th post: 18 November 2023
1000th post: 8 March 2024
10000th post:
-
Warning: This user has grammar issues, and auto-capitalize everything he clicked.

User avatar
confocaloid
Posts: 3117
Joined: February 8th, 2022, 3:15 pm

Re: Ruletable format extensions proposal

Post by confocaloid » April 18th, 2024, 6:20 am

b-engine wrote:
April 18th, 2024, 5:54 am
The changes shorten a long ruletable:
Yes the already mentioned changes would allow to shorten many existing ruletables. I'm more interested in what would remain hard.

Suppose all of the following becomes possible:
  • When x is an existing variable, writing ?x implicitly declares and uses a new copy of x, with the same set of allowed values.
  • When n is a decimal integer literal and x is an existing variable, writing x[n] uses an (implicitly declared) numbered copy of x, with the same set of allowed values.
  • The neighborhood to be used can be changed in the middle of a ruletable. That would affect all rules listed later in the text, until the next neighborhood switch or until end-of-file (whichever comes first).
  • The symmetries to be applied to rules can be changed in the middle of a ruletable. That would affect all rules listed later in the text, until the next symmetries switch or until end-of-file (whichever comes first).
  • When writing a rule, in addition to literal cellstate numbers and variables, it is possible to use arithmetic expressions that evaluate to a cellstate number. For example "a+b" or "a+1" or "(a+9)%10" could be used inside a rule (subject to some restrictions to make this well-defined).
Question: What are ruletables (I'm looking for examples in actual practice) that would still remain unnecessarily long or complicated, even if all the above features become available?

edit: relevant links: TheFormat FutureWork
127:1 B3/S234c User:Confocal/R (isotropic CA, incomplete)
Unlikely events happen.
My silence does not imply agreement, nor indifference. If I disagreed with something in the past, then please do not construe my silence as something that could change that.

User avatar
wirehead
Posts: 259
Joined: June 18th, 2022, 2:37 pm
Location: fish: wirehead: command not found
Contact:

Re: Ruletable format extensions proposal

Post by wirehead » April 18th, 2024, 9:23 pm

confocaloid wrote:
April 18th, 2024, 5:19 am
I think precomputing the rules using a PRNG wouldn't be a particularly serious problem. It would just mean that a pattern would evolve differently each time (unless the same fixed seed is used always). Might be unexpected, but also might be useful if the PRNG does minor tweaks that don't affect most patterns while still introducing some controlled nondeterminism.
Well, if the rule is supposed to be random, then it's supposed to be random on every invocation of the rule function, which will totally break Hashlife. So if nondeterminism is allowed, then it will have to be run under an algorithm called "Naive" which does what you would expect (for every cell, evaluate the rule function), which would obviously be slow, especially if the rule is something mostly-deterministic-but-not-always (such as "B3/S23, but on each tick an Eater 1 has a 1% chance of dying"), and you're running a huge pattern.
confocaloid wrote:
April 18th, 2024, 5:19 am
The big problem would come with infinite loops, unbounded memory usage, filesystem access, and so on. You wouldn't want to have an infinite loop or a virus deleting all user files it can find, when the Golly user is trying to do something as simple as "File -> Open Pattern..."
Good point, I hand't thought about executing arbitrary code. You could setup Python/Lua to restrict network/filesystem access, etc, add a timeout (that triggers a KeyboardInterrupt after like 15 seconds). but then again, closing every possible hole is the reason that security bounty hunters have a job.

You could try to limit calls to the code to speed it up by "compiling" the ruletable once and automatically adding a tree to the file with the code in it (same sort of operation as the existing "clean up old rules"), but it would still have to be run to do that, so fair concern.
confocaloid wrote:
April 18th, 2024, 5:19 am
which would be a different rule (instead of 2 independent variables each used 4 times, one would have 8 independent variables each used 1 time).
To avoid declaring two variables with the same set of allowed values, one would need to have some "numbered sigils", which would be something equivalent to

Code: Select all

var a: {1,2,3}
0,  a[1],a[2],a[1],a[2],a[1],a[2],a[1],a[2],  1
I'm still going to side with squareroot12621 on this one: to a programmer, this looks more like array indexing.

For this kind of functionality, using angle brackets (so a<1>, a<2>, etc.) seems more like an intuitive solution (the <> syntax usually means "instantiate a template" in languages that support it such as C++ and Java).
Langton's ant: Can't play the drums, can be taught.

User avatar
confocaloid
Posts: 3117
Joined: February 8th, 2022, 3:15 pm

Re: Ruletable format extensions proposal

Post by confocaloid » April 18th, 2024, 10:46 pm

wirehead wrote:
April 18th, 2024, 9:23 pm
You could try to limit calls to the code to speed it up by "compiling" the ruletable once and automatically adding a tree to the file with the code in it (same sort of operation as the existing "clean up old rules"), but it would still have to be run to do that, so fair concern.
If the aim is to construct a ruletable programmatically and write it to a separate file, then a Golly script (Lua/Python) can already do that.

Unlike supported rulestrings (e.g. Hensel notation, weighted neighbourhoods, MAP), ruletables/ruletrees currently have to be stored in separate files. It would be cleaner if one could construct an in-memory ruletable/ruletree programmatically and bundle it with the pattern (save in the same file, copy when the pattern is copied to the clipboard). That would put multistate RuleLoader-supported cellular automata on an equal footing with CA that can be defined by a supported rulestring.
wirehead wrote:
April 18th, 2024, 9:23 pm
I'm still going to side with squareroot12621 on this one: to a programmer, this looks more like array indexing.
It's good if the syntax looks like array indexing. Because it's meant to look like an array of variables, all of the same type and with the same set of allowed values.
wirehead wrote:
April 18th, 2024, 9:23 pm
For this kind of functionality, using angle brackets (so a<1>, a<2>, etc.) seems more like an intuitive solution (the <> syntax usually means "instantiate a template" in languages that support it such as C++ and Java).
I think angle brackets would be unnecessarily hard to read and write. With some additional assumptions about future syntax, imagine rules like these:

Code: Select all

0, a<1>, a<2>, 0, 0, 0, 0, 0, 0, a<1> if a<1> < a<2> else a<2>
0, b<1>, b<2>, b<3>, 0, 0, 0, 0, 0, b<1> if b<1> > b<2> and b<2> > b<3> else b<3>
Currently I can't tell whether I will end up implementing some alternative syntax for ruletables, but if that happens, I'll definitely use square brackets. Rules like this would be much easier to read and write:

Code: Select all

0, a[1], a[2], 0, 0, 0, 0, 0, 0, a[1] if a[1] < a[2] else a[2]
0, b[1], b[2], b[3], 0, 0, 0, 0, 0, b[1] if b[1] > b[2] and b[2] > b[3] else b[3]
127:1 B3/S234c User:Confocal/R (isotropic CA, incomplete)
Unlikely events happen.
My silence does not imply agreement, nor indifference. If I disagreed with something in the past, then please do not construe my silence as something that could change that.

User avatar
squareroot12621
Posts: 638
Joined: March 23rd, 2022, 4:53 pm

Re: Ruletable format extensions proposal

Post by squareroot12621 » April 19th, 2024, 9:58 pm

confocaloid wrote:
April 18th, 2024, 10:46 pm
wirehead wrote:
April 18th, 2024, 9:23 pm
I'm still going to side with squareroot12621 on this one: to a programmer, this looks more like array indexing.
It's good if the syntax looks like array indexing. Because it's meant to look like an array of variables, all of the same type and with the same set of allowed values.
I wouldn't say so—if a were defined to be {1, 3, 5, 7}, a[1] looks like it could only be equal to 1 (or 3 if you're a true programmer). In actuality, though, it could work as any element of a. These two views aren't the same.
(For even more confusion, try a[1] and a[2] together.)
confocaloid wrote:
April 18th, 2024, 10:46 pm
wirehead wrote:
April 18th, 2024, 9:23 pm
For this kind of functionality, using angle brackets (so a<1>, a<2>, etc.) seems more like an intuitive solution (the <> syntax usually means "instantiate a template" in languages that support it such as C++ and Java).
I think angle brackets would be unnecessarily hard to read and write. With some additional assumptions about future syntax, imagine rules like these:

Code: Select all

0, a<1>, a<2>, 0, 0, 0, 0, 0, 0, a<1> if a<1> < a<2> else a<2>
0, b<1>, b<2>, b<3>, 0, 0, 0, 0, 0, b<1> if b<1> > b<2> and b<2> > b<3> else b<3>
Currently I can't tell whether I will end up implementing some alternative syntax for ruletables, but if that happens, I'll definitely use square brackets. Rules like this would be much easier to read and write:

Code: Select all

0, a[1], a[2], 0, 0, 0, 0, 0, 0, a[1] if a[1] < a[2] else a[2]
0, b[1], b[2], b[3], 0, 0, 0, 0, 0, b[1] if b[1] > b[2] and b[2] > b[3] else b[3]
I do agree that angle brackets are not the most optimal solution. I propose a#1 instead, which doesn't clash with any symbols that would actually be useful in a ruletable, and clearly states "copy #1 of a".

Code: Select all

4b8o$4b8o$4b8o$4b8o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4o8b4o$4b8o$4b8o$4b8o$4b8o![[ THEME 0 AUTOSTART GPS 8 Z 16 T 1 T 1 Z 19.027 T 2 T 2 Z 22.627 T 3 T 3 Z 26.909 T 4 T 4 Z 32 T 5 T 5 Z 38.055 T 6 T 6 Z 45.255 T 7 T 7 Z 53.817 LOOP 8 ]]

User avatar
confocaloid
Posts: 3117
Joined: February 8th, 2022, 3:15 pm

Re: Ruletable format extensions proposal

Post by confocaloid » April 20th, 2024, 5:46 am

squareroot12621 wrote:
April 19th, 2024, 9:58 pm
confocaloid wrote:
April 18th, 2024, 10:46 pm
[...]
It's good if the syntax looks like array indexing. Because it's meant to look like an array of variables, all of the same type and with the same set of allowed values.
I wouldn't say so—if a were defined to be {1, 3, 5, 7}, a[1] looks like it could only be equal to 1 (or 3 if you're a true programmer). In actuality, though, it could work as any element of a. These two views aren't the same.
"If a were defined to be {1, 3, 5, 7}" -- how do you do that in a ruletable, exactly?

To be clear, code like this doesn't define a to be {1, 3, 5, 7}

Code: Select all

var a = {1, 3, 5, 7}
0, a, a, a, 0, 0, 0, 0, 0, 4
Instead, the above code declares a as a variable that can take values from the set {1, 3, 5, 7}.

When you're later writing a rule that uses a, such as "0, a, a, a, 0, 0, 0, 0, 0, 4" in the example above, a stands for a single cellstate (and not a set!), in the same way as 0 and 4 each stand for a single cellstate. It's just that a can be either one of cellstates 1, 3, 5, 7. Hence the single rule expands to four rules:

Code: Select all

0, 1, 1, 1, 0, 0, 0, 0, 0, 4
0, 3, 3, 3, 0, 0, 0, 0, 0, 4
0, 5, 5, 5, 0, 0, 0, 0, 0, 4
0, 7, 7, 7, 0, 0, 0, 0, 0, 4
Note that the above is already existing supported syntax. One cannot define a variable to be a set; instead, one declares a variable that can take values from a given set.
Consequently, a doesn't have any internal elements (even though the set of allowed values of a does).
squareroot12621 wrote:
April 19th, 2024, 9:58 pm
(For even more confusion, try a[1] and a[2] together.)
I fail to see any significant danger of confusion in this pseudocode (which I think can become an actual syntax as written):

Code: Select all

var a : {1, 3, 5, 7}                                         # the variable a can take values from the set {1, 3, 5, 7}
0, a[1], a[1], a[1], 0, 0, 0, 0, 0, a[1]                     # if there are three alive neighbours all the same cellstate, then the middle cell is born with the same cellstate
0, a[1], a[2], a[2], 0, 0, 0, 0, 0, a[2]                     # if there are three alive neighbours with two distinct cellstates, then the middle cell is born with the majority cellstate
0, a[1], a[2], a[3], 0, 0, 0, 0, 0, 16 - a[1] - a[2] - a[3]  # if there are three alive neighbours all pairwise distinct, then the middle cell is born with the fourth unused cellstate
squareroot12621 wrote:
April 19th, 2024, 9:58 pm
I do agree that angle brackets are not the most optimal solution. I propose a#1 instead, which doesn't clash with any symbols that would actually be useful in a ruletable, and clearly states "copy #1 of a".
"#" will not work, because it will obviously clash with comments which extend from the first "#" to the end of line.
127:1 B3/S234c User:Confocal/R (isotropic CA, incomplete)
Unlikely events happen.
My silence does not imply agreement, nor indifference. If I disagreed with something in the past, then please do not construe my silence as something that could change that.

Post Reply