CITE THIS NOTEBOOK: An Empirical Study - String Rewrite System Reducibility by Leon Zhao. Wolfram Community JAN 13 2023.
This project is aimed at trying to characterize how the starting state of a string rewrite system effects the result at certain time steps. In specific we explore the simplest case of binary strings. The main motivation is to investigate the influence of the initial conditions and rewrite rules in the rewrite system. Evidently, some rules yield behavior more predictable that that yielded by other rules.

Background

Of interest in the winter school project is the idea of multiway systems, where from very simple sets of rules we are able to represent extremely complex behavior. Although the behavior in general is very complicated, because the rule set is so simple we seek out simple patterns across all possible string inputs of fixed length to some string substitution rule. The aim of this project is to empirically study this behavior by using Mathematica to compute the number of paths in the corresponding digraph of the string substitution system. Specifically, in this project we measure the distribution of the first bit for a given string substitution rule

Method

For a given string substitution rule, the goal is to generate a graph for all
n
2
initial strings of length
n
, then for each vertex in that graph we compute the number of paths from the root to this vertex. Summing across all vertices in all generated graphs, we produce an approximation for the probability. This is mainly done using the built in functions of FindLength, ResourceFunction[“multiway”] and the GeneralUtilities library, which are to curried together to generate and then compute the total number of paths for each . We make good use of some of Mathematica’s more functional aspects through Map and Replace

Implementation

MultiwaySystem[Rules_]:=Function[​​InitialState,​​ResourceFunction["MultiwaySystem"][​​Rules,​​InitialState,​​StringLength[InitialState],​​"StatesGraph",​​GraphLayout->"LayeredDigraphEmbedding"​​]​​]​​​​GenerateMultiway=MultiwaySystem[{"01"->"1","10"->"0"}]​​<<GeneralUtilities`​​​​M=Map[​​Graph|->Map[​​to|->Pair[StringTake[GraphSources[Graph][[1]],1],Length[FindPath[Graph,GraphSources[Graph][[1]],to,Infinity,All]]],​​Select[VertexList[Graph],#!=GraphSources[Graph]&]​​],​​GenerateMultiway/@StringJoin@@@Tuples[{"0","1"},3]​​]​​Flatten[M]​​Select[Flatten[M],#[[1]]=="0"&]​​Total[Map[x|->x[[2]],Select[Flatten[M],#[[1]]=="0"&]]]​​​​GetTotals[L_]:=Pair[​​Total[Map[x|->x[[2]],Select[Flatten[L],#[[1]]=="0"&]]],​​Total[Map[x|->x[[2]],Select[Flatten[L],#[[1]]=="1"&]]]​​]​​​​SolveRules[rules_,n_:5]:=​​GetTotals[​​Map[​​Graph|->Map[​​to|->Pair[StringTake[to,1],Length[FindPath[Graph,GraphSources[Graph][[1]],to,Infinity,All]]],​​VertexList[Graph]​​],​​MultiwaySystem[rules]/@StringJoin@@@Tuples[{"0","1"},n]​​]​​]​​​​SolveRules[{"01"->"1","10"->"0"}]​​SolveRules[{"01"->"0","10"->"1"}]​​​​SolveRules[{"01"->"0","10"->"0"}]​​SolveRules[{"01"->"1","10"->"1"}]​​​​SolveRules[{"01"->"1","10"->"1","11"->"1","00"->"1"}]​​SolveRules[{"01"->"1","10"->"0","11"->"1","00"->"0"}]​​​​SolveRules[{"01"->"0","10"->"0","11"->"1","00"->"1"}]​​SolveRules[{"01"->"0","10"->"1","11"->"0","00"->"1"}]​​​​SolveRules[{"00"->"1","11"->"1"}]​​SolveRules[{"01"->"1","11"->"1"}]​​SolveRules[{"01"->"1","11"->"0"}]​​​​SolveRules[{"10"->"1","00"->"1"},3]​​SolveRules[{"10"->"1","00"->"1"},4]​​SolveRules[{"10"->"1","00"->"1"},5]​​​​G=MultiwaySystem[{"10"->"1","00"->"1"}]/@StringJoin@@@Tuples[{"0","1"},5]

Results

Rule
Probability of 0 as first bit
Probability of 1 as first bit
{000,010,100,110}
0.83
0.17
{000,010,100,111}
0.80
0.20
{000,010,100}
0.80
0.20
{000,010,101,110}
0.75
0.25
{000,010,101,111}
0.50
0.50
{000,010,101}
0.70
0.30
{000,010,110}
0.82
0.18
{000,010,111}
0.67
0.33
{000,010}
0.74
0.26
{000,011,100,110}
0.67
0.33
{000,011,100,111}
0.59
0.41
{000,011,100}
0.59
0.41
{000,011,101,110}
0.35
0.65
{000,011,101,111}
0.20
0.80
{000,011,101}
0.29
0.71
{000,011,110}
0.50
0.50
{000,011,111}
0.22
0.78
{000,011}
0.30
0.70
{000,100,110}
0.82
0.18
{000,100,111}
0.78
0.22
{000,100}
0.79
0.21
{000,101,110}
0.66
0.34
{000,101,111}
0.33
0.67
{000,101}
0.50
0.50
{000,110}
0.74
0.26
{000,111}
0.50
0.50
{000}
0.65
0.35
{001,010,100,110}
0.61
0.39
{001,010,100,111}
0.50
0.50
{001,010,100}
0.73
0.27
{001,010,101,110}
0.50
0.50
{001,010,101,111}
0.25
0.75
{001,010,101}
0.41
0.59
{001,010,110}
0.57
0.43
{001,010,111}
0.34
0.66
{001,010}
0.50
0.50
{001,011,100,110}
0.50
0.50
{001,011,100,111}
0.33
0.67
{001,011,100}
0.41
0.59
{001,011,101,110}
0.39
0.61
{001,011,101,111}
0.17
0.83
{001,011,101}
0.23
0.77
{001,011,110}
0.41
0.59
{001,011,111}
0.18
0.82
{001,011}
0.25
0.75
{001,100,110}
0.75
0.25
{001,100,111}
0.44
0.56
{001,100}
0.50
0.50
{001,101,110}
0.43
0.57
{001,101,111}
0.18
0.82
{001,101}
0.25
0.75
{001,110}
0.50
0.50
{001,111}
0.26
0.74
{001}
0.32
0.68
{010,100,110}
0.77
0.23
{010,100,111}
0.71
0.29
{010,100}
0.73
0.27
{010,101,110}
0.50
0.50
{010,101,111}
0.30
0.70
{010,101}
0.50
0.50
{010,110}
0.68
0.32
{010,111}
0.50
0.50
{010}
0.72
0.28
{011,100,110}
0.59
0.41
{011,100,111}
0.41
0.59
{011,100}
0.50
0.50
{011,101,110}
0.43
0.57
{011,101,111}
0.20
0.80
{011,101}
0.27
0.73
{011,110}
0.28
0.72
{011,111}
0.21
0.79
{011}
0.28
0.72
{100,110}
0.75
0.25
{100,111}
0.70
0.30
{100}
0.72
0.28
{101,110}
0.50
0.50
{101,111}
0.21
0.79
{101}
0.28
0.72
{110}
0.68
0.32
{111}
0.35
0.65

Trivia & Insights

Future Work

For the current problem, the trivia should be explored a little bit more to see if there’s any interesting insights to the appearance of Stirling Numbers. Additionally, the current approximation of probability has everything assumed to be independent, which is not the case in reality. If instead of considering the entire graph, we consider across a certain number of time steps or distance from the root of the graph, then we will regain independence. Additionally we should check correspondences between certain indices, for instance it’s possible the middle portion of a string having more ones correlates to having more ones at the start of the ending string for any particular rule.
​
To extend the project we may try non-binary strings as well. In the case of binary strings, a brute force evaluation is efficient on small enough strings. If we were to apply this to longer strings as well as more complex replacement rules, then either a faster evaluation algorithm for counting paths should be designed, or a robust method of approximating across different strings with some corresponding error approximation.