In 2.9 we discussed the fact that some rules—even though the rules themselves are connected—can lead to hypergraphs that are disconnected. And—unless one is dealing with rules with disconnected left-hand sides—any hypergraphs that are disconnected must also be causally disconnected.
As a simple example of what can happen, consider the rule:
{{x, y}} -> {{y, z}, {y, z}}
The evolution of this rule quickly leads to disconnected hypergraphs:
Framed[#, FrameStyle -> LightGray] & /@
ResourceFunction[
"WolframModel"][{{x, y}} -> {{y, z}, {y, z}}, {{1, 2}}, 4][
"StatesPlotsList", ImageSize -> Tiny]
The corresponding causal graph is a tree:
ResourceFunction[
"WolframModel"][{{x, y}} -> {{y, z}, {y, z}}, {{0, 0}},
6]["LayeredCausalGraph"]
In this particular case, the different branches happen to correspond to isomorphic hypergraphs, so that in our usual way of creating a multiway graph, this rule leads to a connected multiway graph, which even shows causal invariance:
CloudGet["https://wolfr.am/LmHho8Tr"]; newgraph[
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{x, y}} -> {{y, z}, {y, z}}}, {{{0, 0}}}, 5,
"StatesGraph", VertexSize -> 1]]
(Note that causal invariance is in a sense easier to achieve with disconnected hypergraphs, because there is no possibility of overlap, or of ambiguity in updates.)
In the case of an extremely simple rule like
the evolution is immediately disconnected
Framed[#, FrameStyle -> LightGray] & /@
ResourceFunction["WolframModel"][{{x}} -> {{y}, {z}}, {{0}}, 4][
"StatesPlotsList", ImageSize -> {60, 60}]
the causal graph is a tree
ResourceFunction[
"WolframModel"][{{x}} -> {{y}, {z}}, {{0}}, 5, "LayeredCausalGraph"]
but the multiway graph consists of a simple “counting” sequence of states:
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{x}} -> {{y}, {z}}}, {{{0}}}, 5, "StatesGraph",
VertexSize -> 1]
In other rules, the disconnected pieces are not isomorphic, and the multiway graph can split. An example where this occurs is the rule:
{{x, y}, {x, z}} -> {{x, x}, {y, u}, {u, v}}
Framed[#, FrameStyle -> LightGray] & /@
ResourceFunction[
"WolframModel"][{{1, 2}, {1, 3}} -> {{1, 1}, {2, 4}, {4, 5}}, {{0,
0}, {0, 0}}, 6]["StatesPlotsList", ImageSize -> {70, UpTo[60]}]
The multiway graph in this case is a tree:
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{1, 2}, {1, 3}} -> {{1, 1}, {2, 4}, {4,
5}}}, {{{0, 0}, {0, 0}}}, 5, "StatesGraph",
VertexSize -> 1] // LayeredGraphPlot
The multiway causal graph, however, does not have an exponential tree structure, but instead effectively just has one branch for each disconnected component in the hypergraph:
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{1, 2}, {1, 3}} -> {{1, 1}, {2, 4}, {4,
5}}}, {{{0, 0}, {0, 0}}}, 7,
"CausalGraphStructure"] // LayeredGraphPlot
As a result, for this rule the ordinary causal graph has a simple, sequential form:
ResourceFunction[
"WolframModel"][{{1, 2}, {1, 3}} -> {{1, 1}, {2, 4}, {4, 5}}, {{0,
0}, {0, 0}}, 6, "CausalGraph"]
As a related example, consider the rule:
{{x, y}, {y, z}} -> {{u, v}, {v, x}, {x, y}}
Framed[#, FrameStyle -> LightGray] & /@
ResourceFunction[
"WolframModel"][{{1, 2}, {2, 3}} -> {{4, 5}, {5, 1}, {1, 2}}, {{0,
0}, {0, 0}}, 6]["StatesPlotsList", ImageSize -> {70, UpTo[60]}]
In this case, the multiway graph has the two-branch form
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{1, 2}, {2, 3}} -> {{4, 5}, {5, 1}, {1,
2}}}, {{{0, 0}, {0, 0}}}, 6, "StatesGraph", VertexSize -> 5]
and the multiway causal graph has the similarly two-branch form
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{1, 2}, {2, 3}} -> {{4, 5}, {5, 1}, {1,
2}}}, {{{0, 0}, {0, 0}}}, 6,
"CausalGraphStructure"] // LayeredGraphPlot
though the ordinary causal graph is still just:
ResourceFunction[
"WolframModel"][{{1, 2}, {2, 3}} -> {{4, 5}, {5, 1}, {1, 2}}, {{0,
0}, {0, 0}}, 6, "CausalGraph"]
Sometimes there can be multiple branches in both the multiway graph and the ordinary causal graph. An example occurs in the rule
{{{x, y}, {x, z}} -> {{y, y}, {z, u}, {z, v}}}
Framed[#, FrameStyle -> LightGray] & /@
ResourceFunction[
"WolframModel"][{{{x, y}, {x, z}} -> {{y, y}, {z, u}, {z,
v}}}, {{0, 0}, {0, 0}}, 6]["StatesPlotsList",
ImageSize -> {70, UpTo[60]}]
where the multiway graph is
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{x, y}, {x, z}} -> {{y, y}, {z, u}, {z,
v}}}, {{{0, 0}, {0, 0}}}, 5, "StatesGraph",
VertexSize -> 1] // LayeredGraphPlot
the multiway causal graph is
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{x, y}, {x, z}} -> {{y, y}, {z, u}, {z,
v}}}, {{{0, 0}, {0, 0}}}, 5, "CausalGraph"]
and the ordinary causal graph is:
ResourceFunction[
"WolframModel"][{{{x, y}, {x, z}} -> {{y, y}, {z, u}, {z, v}}}, {{0,
0}, {0, 0}}, 6, "CausalGraph"]
Is it possible to have both an infinitely branching multiway graph, and an infinitely branching ordinary causal graph? One of the issues is that in general it can be undecidable whether this is ultimately infinite branching. Consider for example the rule:
{ {{x, x}, {x, y}} -> {{y, y}, {y, y}, {x, z}}}
Framed[#, FrameStyle -> LightGray] & /@
ResourceFunction[
"WolframModel"][{{x, x}, {x, y}} -> {{y, y}, {y, y}, {x, z}}, {{0,
0}, {0, 0}}, 6]["StatesPlotsList", ImageSize -> {70, UpTo[60]}]
The ordinary causal graph for this rule has the form
ResourceFunction[
"WolframModel"][{{{x, x}, {x, y}} -> {{y, y}, {y, y}, {x, z}}}, {{0,
0}, {0, 0}}, 10, "CausalGraph"]
or in a different rendering after more steps:
ResourceFunction[
"WolframModel"][{{{x, x}, {x, y}} -> {{y, y}, {y, y}, {x, z}}}, {{0,
0}, {0, 0}}, 20, "CausalGraph"]
The multiway causal graph in this case is:
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{x, x}, {x, y}} -> {{y, y}, {y, y}, {x,
z}}}, {{{0, 0}, {0, 0}}}, 6, "CausalGraphStructure"]
But now the multiway graph is:
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{x, x}, {x, y}} -> {{y, y}, {y, y}, {x,
z}}}, {{{0, 0}, {0, 0}}}, 5, "StatesGraph",
VertexSize -> 1] // LayeredGraphPlot
Continuing for more steps yields:
LayeredGraphPlot[
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{x, x}, {x, y}} -> {{y, y}, {y, y}, {x,
z}}}, {{{0, 0}, {0, 0}}}, 7, "StatesGraphStructure"],
AspectRatio -> 1/3]
But while it is fairly clear that this multiway graph does not show causal invariance, it is not clear whether it will branch forever or not.
As a similar example, consider the rule:
{{x, y}, {y, z}} -> {{x, x}, {x, y}, {w, y}}
Framed[#, FrameStyle -> LightGray] & /@
ResourceFunction[
"WolframModel"][{{x, y}, {y, z}} -> {{x, x}, {x, y}, {w, y}}, {{0,
0}, {0, 0}}, 6]["StatesPlotsList", ImageSize -> {70, UpTo[60]}]
This yields the same ordinary causal graph as the previous rule
ResourceFunction[
"WolframModel"][{{x, y}, {y, z}} -> {{x, x}, {x, y}, {w, y}}, {{0,
0}, {0, 0}}, 10, "CausalGraph"]
but now its multiway graph has a form that appears slightly more likely to branch forever:
LayeredGraphPlot[
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{x, y}, {y, z}} -> {{x, x}, {x, y}, {w,
y}}}, {{{0, 0}, {0, 0}}}, 7, "StatesGraphStructure"],
AspectRatio -> 1/3]
All the examples we have seen so far involve explicit disconnection of hypergraphs. However, it is also possible to have causal disconnection even without explicit disconnection of hypergraphs. As a very simple example, consider the rule:
{{x, x}} -> {{x, x}, {x, x}}
ResourceFunction[
"WolframModel"][{{x, x}} -> {{x, x}, {x, x}}, {{0, 0}, {0, 0}},
5]["StatesPlotsList", ImageSize -> {50, UpTo[40]}]
The causal graph in this case is
ResourceFunction[
"WolframModel"][{{x, x}} -> {{x, x}, {x, x}}, {{0, 0}},
6]["LayeredCausalGraph"]
although the multiway graph is just:
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{x, x}} -> {{x, x}, {x, x}}}, {{{0,
0}}}, 5, "StatesGraph", VertexSize -> 1]
For the rule
{{x, y}} -> {{x, x}, {x, z}}
ResourceFunction[
"WolframModel"][{{x, y}} -> {{x, x}, {x, z}}, {{0, 0}, {0, 0}},
5]["StatesPlotsList", ImageSize -> {50, UpTo[40]}]
the causal graph is again a tree
ResourceFunction[
"WolframModel"][{{x, y}} -> {{x, x}, {x, z}}, {{0, 0}},
6]["LayeredCausalGraph"]
but now the multiway graph is:
CloudGet["https://wolfr.am/LmHho8Tr"]; newgraph[
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{x, y}} -> {{x, x}, {x, z}}}, {{{0, 0}}}, 5,
"StatesGraph", VertexSize -> 1]]
The rule
{{x, y}} -> {{x, y}, {y, z}}
gives exactly the same causal graph, but now its hypergraph is a tree:
ResourceFunction[
"WolframModel"][{{x, y}} -> {{x, y}, {y, z}}, {{0, 0}, {0, 0}},
5]["StatesPlotsList", "MaxImageSize" -> 100]
Like some of the rules shown above, its multiway graph is somewhat complex:
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{x, y}} -> {{x, y}, {y, z}}}, {{{0,
0}}}, 5, "StatesGraph", VertexSize -> 1]
It is actually fairly common to have causal graphs that look like the corresponding hypergraphs in the case of rules where effectively only one update happens at a time. An example occurs in the case of the rule (see 3.10):
RulePlot[ResourceFunction[
"WolframModel"][{{1, 2, 2}, {3, 1, 4}} -> {{2, 5, 2}, {2, 3,
5}, {4, 5, 5}}]]
ResourceFunction[
"WolframModel"][{{1, 2, 2}, {3, 1, 4}} -> {{2, 5, 2}, {2, 3, 5}, {4,
5, 5}},
Table[{0, 0, 0}, 2], 100, {"FinalStatePlot", "CausalGraph"}]
So far, we have only considered fairly minimal initial conditions. But as soon as it is possible to have multiple independent events occur in the initial conditions, it is also possible to get completely disconnected causal graphs. (Note that if an “initial creation event” to create the initial conditions was added, then the causal graphs would again be connected.) As an example of disconnected causal graphs, consider the rule
with an initial condition consisting of connected unary relations:
ResourceFunction[
"WolframModel"][{{x}} -> {{x}, {x}}, {{1}, {2}, {1, 2}},
4]["StatesPlotsList", ImageSize -> Tiny]
This rule yields a disconnected causal graph:
Framed[ResourceFunction[
"WolframModel"][{{x}} -> {{x}, {x}}, {{1}, {2}, {1, 2}}, 4][
"CausalGraph", GraphLayout -> {"PackingLayout" -> "NestedGrid"}],
FrameStyle -> LightGray]
The multiway graph in this case is connected, and shows causal invariance:
ResourceFunction["MultiwaySystem"][
"WolframModel" -> {{{x}} -> {{x}, {x}}}, {{{1}, {2}, {1,
2}}}, 5, "StatesGraphStructure"]
Sometimes the relationship between disconnection in the hypergraph and the existence of disconnected causal graphs can be somewhat complex. This shows results for the rule above with initial conditions consisting of increasing numbers of self-loops:
GraphicsGrid[
Partition[
Table[GraphicsRow[
Framed[Show[#, ImageSize -> {70, UpTo[80]}],
FrameStyle -> LightGray] & /@
ResourceFunction[
"WolframModel"][{{1, 2, 2}, {3, 1, 4}} -> {{2, 5, 2}, {2, 3,
5}, {4, 5, 5}}, Table[{0, 0, 0}, n],
50, {"FinalStatePlot", "CausalGraph"}]], {n, 2, 10}], 3]]
Even with rather simple rules, the forms of branching in causal graphs can be quite complex—even when the actual hypergraphs remain simple. Here are a few examples:
res = ResourceFunction["ParallelMapMonitored"][
With[{eo = ResourceFunction["WolframModel"][#1, #2, #3]}, {Labeled[
eo["FinalStatePlot", ImageSize -> Tiny],
RulePlot[ResourceFunction["WolframModel"][#1],
ImageSize -> Tiny]],
eo["CausalGraph", ImageSize -> Tiny]}] & @@ # &, {{{{1,
2}, {2, 3}} -> {{4, 5}, {4, 1}, {3, 5}}, Automatic,
23}, {{{1, 2}, {2, 3}} -> {{2, 3}, {3, 1}, {4, 1}}, Automatic,
14}, {{{1, 2}, {2, 3}} -> {{1, 4}, {4, 2}, {3, 2}}, Automatic,
14}, {{{1, 2}, {2, 3}} -> {{1, 3}, {3, 2}, {2, 4}}, Automatic,
15}}];
GraphicsGrid[Partition[Map[GraphicsRow, res], 2]]