セルオートマトンはセルの次の状態を決めるために遷移規則を必要とします。例えば Tempesti loop であれば以下のページにあるルールを使います。
ruletablerepository/Tempesti.table at gh-pages · GollyGang/ruletablerepository · GitHub
このページを見ると一番最初のルールは
2,b,0,0,0,a,1,1,1,a
です。これは以下のルールと同義です。
1b0
120 -> a
1a0
Tempesti loop では Moore近傍を用いるので、中心セルの斜め方向にあるセルの状態も考慮して計9個のセル状態から次のセルの状態を決めます。ところで、Tempesti loop の状態数は10なので0から9までの数値を使うので、a や b といった記号は使わないはずです。この記号の意味はなんでしょうか。
Tempesti.tableには
var a = {5,6,7,8,9}
var b= {5,6,7,8,9}
とあります。
これは a は5から9までの数字を取りうるよーという意味です。つまりルール「2,b,0,0,0,a,1,1,1,a」が実際に表現しているのは1つのルールではなく、下記の25個のルールです。
2500051115 2600051115 2700051115 2800051115 2900051115 2500061116 2600061116 2700061116 2800061116 2900061116 2500071117 2600071117 2700071117 2800071117 2900071117 2500081118 2600081118 2700081118 2800081118 2900081118 2500091119 2600091119 2700091119 2800091119 2900091119
このように a や b といった記号を使っていたのはルールの数が膨大になってしまうのを防ぐためだったわけです。ただ、私が以前作ったりしているセルオートマトンのプログラムは上述の表記法に対応したプログラムになっていないので、Tempesti.tableをそのまま使うことができません。ルールが膨大な量になるかもしれませんが、以前作ったプログラムを再利用するために、ルールをすべて書き下す必要があります。
プログラム
Tempesti.tableを読み込み、a や b などの記号を含まないルールの集合を書きだすプログラムをPythonで作成しました。
f = open("Tempesti.table","r") g = open("test.txt","a+") lines = f.readlines() d = dict() for line in lines: if line[0]=="#": continue elif line[0:3]=="var": expr = line.split(" ")[1] v, s = expr.split("=") l = s[1:-2].split(",") d[v] = l elif True not in [k in line for k in d.keys()]: g.write(line.replace(",","")) else: rules = [line] for k in d.keys(): l = [] ids = [] processed_rules = [] for i,rule in enumerate(rules): if k in rule: processed_rules.append(rule) for v in d[k]: l.append(rule.replace(k,v)) for r in processed_rules: rules.remove(r) rules.extend(l) for r in rules: g.write(r.replace(",","")) f.close() g.close()
実行結果
もともとのTempesti.tableは1062行のファイルでした。展開後のファイルの中身はどうでしょうか。
PS > Get-Content .\test.txt -totalcount 10 n_states:10 neighborhood:Moore symmetries:none 2500051115 2600051115 2700051115 2800051115 2900051115 2500061116 2600061116
記号がちゃんと数字に置換されています。大丈夫そうです。
展開後のファイルの行数も確認します。
PS > $log = Get-Content .\test.txt PS > $log | Measure-Object -Line -Character -Word | Format-List Lines,Words,Characters Lines : 35325 Words : 35325 Characters : 381330
35325行です。めちゃくちゃ増えています。ただ、メモリが足りなくなるほど膨大な量というわけでもないので、展開後のルールを使ってTempesti loop を作れそうです。