Search NKS | Online
21 - 30 of 46 for FoldList
![](/common/images/search/spacer.gif)
For 1D elementary rules the list is {{-1}, {0}, {1}} , while for 2D 5-neighbor rules it is {{-1, 0}, {0, -1}, {0, 0}, {0, 1}, {1, 0}} . … One can specify a neighborhood configuration by giving in the same order as the offset list the color of each cell in the neighborhood. … A single step in evolution of a general cellular automaton with state a and rule number num is then given by
Map[IntegerDigits[num, k, k^Length[os]] 〚 -1 - # 〛 &, Apply[Plus, MapIndexed[k^(Length[os] - First[#2]) RotateLeft[a, #1] &, os]], {-1}]
or equivalently by
Map[IntegerDigits[num, k, k^Length[os]] 〚 -# - 1 〛 &, ListCorrelate[Fold[ReplacePart[k #1, 1, #2 + r + 1] &, Array[0 &, Table[2r + 1, {d}]], os], a, r + 1], {d}]
With this setup, a network consisting of just one node is {{1, 1}} and a 1D array of n nodes can be obtained with
CyclicNet[n_] := RotateRight[ Table[Mod[{i - 1, i + 1}, n] + 1, {i, n}]]
With above connections represented as 1 and the below connections as 2 , the node reached by following a succession s of connections from node i is given by
Follow[list_, i_, s_List] := Fold[list 〚 #1 〛 〚 #2 〛 &, i, s]
The total number of distinct nodes reached by following all possible succession of connections up to length d is given by
NeighborNumbers[list_, i_Integer, d_Integer] := Map[Length, NestList[Union[Flatten[list 〚 # 〛 ]] &, Union[list 〚 i 〛 ], d - 1]]
For each such list the rules for the network system then specify how the connections from node i should be rerouted. The rule {2, 3} {{2, 1}, {1}} specifies that when NeighborNumbers gives {2, 3} for a node i , the connections from that node should become {Follow[list, i, {2, 1}], Follow[list, i, {1}]} . … With rules set up in this way, each step in the evolution of a network system is given by
NetEvolveStep[{depth_Integer, rule_List}, list_List] := Block[ {new = {}}, Join[Table[Map[NetEvolveStep1[#, list, i] &, Replace[NeighborNumbers[list, i, depth], rule]], {i, Length[list]}], new]]
NetEvolveStep1[s : {___Integer}, list_, i_] := Follow[list, i, s]
NetEvolveStep1[{s1 : {___Integer}, s2 : {___Integer}}, list_, i_] := Length[list] + Length[ AppendTo[new, {Follow[list, i, s1], Follow[list, i, s2]}]]
The set of nodes that can be reached from node i is given by
ConnectedNodes[list_, i_] := FixedPoint[Union[Flatten[{#, list 〚 # 〛 }]] &, {i}]
and disconnected nodes can be removed using
RenumberNodes[list_, seq_] := Map[Position[seq, #] 〚 1, 1 〛 &, list 〚 seq 〛 , {2}]
The sequence of networks obtained on successive steps by applying the rules and then removing all nodes not connected to node number 1 is given by
NetEvolveList[rule_, init_, t_Integer] := NestList[(RenumberNodes[#, ConnectedNodes[#, 1]] &)[ NetEvolveStep[rule, #]] &, init, t]
Note that the nodes in each network are not necessarily numbered in the order that they appear on successive lines in the pictures in the main text.
Block cellular automata
With a rule of the form {{1, 1} {1, 1}, {1, 0} {1, 0}, {0, 1} {0, 0}, {0, 0} {0, 1}} the evolution of a block cellular automaton with blocks of size n can be implemented using
BCAEvolveList[{n_Integer, rule_}, init_, t_] := FoldList[BCAStep[{n, rule}, #1, #2]&, init, Range[t]] /; Mod[Length[init], n] 0
BCAStep[{n_, rule_}, a_, d_] := RotateRight[ Flatten[Partition[RotateLeft[a, d], n]/.rule], d]
Starting with a single black cell, none of the k = 2 , n = 2 block cellular automata generate anything beyond simple nested patterns.
The reason is that it is always possible to encode any finite list of integers as a single integer, as discussed on page 1120 . … Any real number x can be represented as a set of integers using for example
Rest[FoldList[Plus, 1, ContinuedFraction[x]]]
but except when x is rational this list is not finite. … (The function σ above can for example be used to specify the order in which to sample elements in RealDigits[list] ).
Then the rules for the language consisting of balanced runs of parentheses (see page 939 ) can be written as
{s[e] s[e, e], s[e] s["(", e, ")"], s[e] s["(",")"]}
Different expressions in the language can be obtained by applying different sequences of these rules, say using (this gives so-called leftmost derivations)
Fold[# /. rules 〚 #2 〛 &, s[e], list]
Given an expression, one can then use the following to find a list of rules that will generate it—if this exists:
Parse[rules_, expr_] := Catch[Block[{t = {}}, NestWhile[ ReplaceList[#, MapIndexed[ReverseRule, rules]] &, {{expr, {}}}, (# /. … = {}) &];]]
ReverseRule[a_ b_, {i_}] := {___, {s[x___, b, y___], {u___}}, ___} {s[x, a, y], {i, u}} /; FreeQ[s[x], s[a]]
In general, there will in principle be more than one such list, and to pick the appropriate list in a practical situation one normally takes the rules of the language to apply with a certain precedence—which is how, for example, x + y z comes to be interpreted in Mathematica as Plus[x, Times[y, z]] rather than Times[Plus[x, y], z] .
Implementation [of proof example]
Given the axioms in the form
s[1] = (a_ ⊼ a_) ⊼ (a_ ⊼ b_) a;
s[2, x_] := b_ (b ⊼ b) ⊼ (b ⊼ x); s[3] = a_ ⊼ (a_ ⊼ b_) a ⊼ (b ⊼ b); s[4] = a_ ⊼ (b_ ⊼ b_) a ⊼ (a ⊼ b);
s[5] = a_ ⊼ (a_ ⊼ (b_ ⊼ c_)) b ⊼ (b ⊼ (a ⊼ c));
the proof shown here can be represented by
{{s[2, b], {2}}, {s[4], {}}, {s[2, (b ⊼ b) ⊼ ((a ⊼ a) ⊼ (b ⊼ b))], {2, 2}}, {s[1], {2, 2, 1}}, {s[2, b ⊼ b], {2, 2, 2, 2, 2, 2}], {s[5], {2, 2, 2}}, {s[2, b ⊼ b], {2, 2, 2, 2, 2, 1}}, {s[1], {2, 2, 2, 2, 2}}, {s[3], {2, 2, 2}}, {s[1], {2, 2, 2, 2}}, {s[4], {2, 2, 2}}, {s[5], {}}, {s[2, a], {2, 2, 1}}, {s[1], {2, 2}}, {s[3], {}}, {s[1], {2}}}
and applied using
FoldList[Function[{u, v}, MapAt[Replace[#, v 〚 1 〛 ] &, u, {v 〚 2 〛 }]], a ⊼ b, proof]
If the rules for a one-element-dependence tag system are given in the form {2, {{0, 1}, {0, 1, 1}}} (compare page 1114 ), the initial conditions for the Turing machine are
TagToMTM[{2, rule_}, init_] := With[{b = FoldList[Plus, 1, Map[Length, rule] + 1]}, Drop[Flatten[{Reverse[Flatten[{1, Map[{Map[ {1, 0, Table[0, {b 〚 # + 1 〛 }]} &, #], 1} &, rule], 1}]], 0, 0, Map[{Table[2, {b 〚 # + 1 〛 }], 3} &, init]}], -1]]
surrounded by 0 's, with the head on the leftmost 2 , in state 1 .
TMToRM[rules_] := Module[{segs, adrs}, segs = Map[TMCompile, rules] ; adrs = Thread[Map[First, rules] Drop[FoldList[Plus, 1, Map[Length, segs]], -1]]; MapIndexed[(# /. … Given the list of successive configurations of the register machine, the steps that correspond to successive steps of Turing machine evolution can be obtained from
(Flatten[Partition[Complement[#, #-1], 1, 2]]&)[ Position[list, {_,{_,_,0}}]]
The program given above works for Turing machines with any number of states, but it requires some simple extensions to handle more than two possible colors for each cell.
To emulate cellular automaton evolution one starts by encoding a list of cell values by the single combinator
p[num[Length[list]]][ Fold[p[Nest[s, k, #2]][#1] &, p[k][k], list]] //. crules
where
num[n_] := Nest[inc, s[k], n]
inc = s[s[k[s]][k]]
One can recover the original list by using
Extract[expr, Map[Reverse[IntegerDigits[#, 2]] &, 3 + 59(16^Range[Depth[expr[s[k]][s][k] //. crules] - 1, 1, -1] - 1)/ 15)]]/.
(Notably, FoldList normally seems more difficult to understand than NestList .)
![](/common/images/search/spacer.gif)