Wolfram Research

Function Repository Resource:

WolframModel

Source Notebook

Generate evolutions of Wolfram model systems

Contributed by: Wolfram Research

ResourceFunction["WolframModel"][rules,init,t]

generates an object representing the evolution of the Wolfram model with the specified rules from the initial condition init for t generations.

ResourceFunction["WolframModel"][rules,init,t,prop]

gives the property prop of the evolution.

ResourceFunction["WolframModel"][rules]

represents an operator form of ResourceFunction["WolframModel"] that can be applied to an expression.

Details and Options

Rules can be a list of the form {rule1,rule2,} where each of the rulei has the form {{a1,a2,},{b1,b2,}, }{{u1,u2,},}. In this case, the ai etc. can be any expressions, but are assumed to be pattern variables for the purposes of the rule.
Rules of the form <|"PatternRules"rules|> can be used to specify explicit pattern rules, in which pattern variables must be given as x_, etc., and literals are treated verbatim.
The initial condition init should be of the form {{i1,i2,},{j1,j2,},}.
The initial condition can be Automatic, in which case the minimum {{1,1,},} initial condition that provides a unification of the rule will be used.
ResourceFunction["WolframModel"][rules,init,t,] gives results for t complete generations, or fewer if a fixed point is reached earlier.
ResourceFunction["WolframModel"][rules,init,assoc,] can be used to specify alternative termination criteria. Possible elements in assoc include:
"MaxEvents" maximum number of events to allow
"MaxGenerations" maximum number of generations to allow
"MaxVertices" maximum number of hypergraph vertices
"MaxEdges" maximum number of hypergraph edges
"MaxVertexDegree" maximum degree of any vertex
A generation is defined to end when no more updates can be done without re-updating a node that has already been updated in that generation.
Each generation in effect contains all updates in a single layer in the causal network.
In ResourceFunction["WolframModel"][rules,init,t,prop], possible forms for prop include:
"EvolutionObject" (default) the complete evolution object
"StatesList" the list of states for each complete generation
"StatesPlotsList" list of plots of states
"FinalState" the final state only
"FinalStatePlot" plot of the final state
"AllEventsStatesList" the list of all states after all updating events
"AllEventsList" the list of all updating events during the evolution
"AllEventsRuleIndices" list of indices of transformation rules used during the evolution
"EventsStatesList" the list of successive events and states during the evolution
"EventsStatesPlotsList" list of plots of successive states with each event highlighted
"AllEventsEdgesList" the list of all edges in the order they are generated by events
"EdgeCreatorEventIndices" the indices of the updating event that creates each edge
"EdgeDestroyerEventIndices" the indices of the updating event that destroys each edge
"VertexCountList" the list of vertex counts for each complete generation
"EdgeCountList" the list of edge counts for each complete generation
"GenerationsCount" the number of complete and partial generations
"GenerationEventsCountList" the number of events between successive generations
"GenerationEventsList" the list of events between successive generations
"EdgeGenerationsList" which generation each edge is associated with
"EventGenerationsList" which generation each event is associated with
"AllEventsCount" the total number of events in the evolution
"CausalGraph" the causal graph for the evolution
"LayeredCausalGraph" the causal graph rendered in layered form
"ExpressionsEventsGraph" the causal graph that includes both expressions and events as vertices
{ prop 1 , prop 2 , } list of results for multiple properties
ResourceFunction["WolframModel"][rules][state] gives the result of one generation of evolution from state according to rules.
RulePlot[ResourceFunction["WolframModel"][rules]] gives a visual representation of the specified Wolfram model rules.
The property "EventsList" gives specifications of all updating events done on the system. Each is given as the index of the original rule used, as well as the indices of the edges used. These indices can be converted to instantiated edges using "AllEventsEdgesList".
"EventsStatesList" gives pairs of events and the states they produce. The events are specified as a list of edges from "AllEventsEdgesList".
The following options for ResourceFunction["WolframModel"] can be used:
EventOrderingFunction Automatic how to order possible updating events
EventSelectionFunction "GlobalSpacelike" how to select the rule matches to be instantiated
IncludeBoundaryEvents None whether to include initial or final events
IncludePartialGenerations Automatic whether to include incomplete generations
Method Automatic the method to use ("LowLevel", "Symbolic")
TimeConstraint Infinity how much CPU time to allow the evolution to run
VertexNamingFunction Automatic how to name generated elements
VertexNamingFunctionAll renames all vertices to be labeled sequentially starting from 1 , across all generations in the evolution.
VertexNamingFunctionAutomatic uses any existing labels, and labels each new vertex with the smallest unallocated integer.
VertexNamingFunctionNone uses internal symbol names for new vertices.
Possible settings for IncludeBoundaryEvents include "Initial", "Final", All and None.
Possible settings for EventOrderingFunction include:
Automatic use standard order (least-recent edge, rule ordering, rule index)
"Random" pick the next event at random
{ ord 1 , ord 2 , } use the specified sequence of criteria to determine the next event
With the default setting EventOrderingFunctionAutomatic, ResourceFunction["WolframModel"] chooses first whatever possible event involves as its newest edge the least recently generated edge. In case of a tie, the permutation of edges closest to the order from the statement of the rule is used. If there is still a tie, then the smallest index rule is used.
Possible ordering criteria:
"OldestEdge" sort rule inputs by edge index, and pick the smallest list
"LeastOldEdge" sort rule inputs by edge index, and pick the largest list
"LeastRecentEdge" sort rule inputs by edge index in reverse order, and pick the smallest list
"NewestEdge" sort rule inputs by edge index in reverse order, and pick the largest list
"RuleOrdering" pick the smallest list of edge indices, arranged as in the rule input
"ReverseRuleOrdering" pick the largest list of edge indices, arranged as in the rule input
"RuleIndex" use the earlier rule in a multirule system
"ReverseRuleIndex" use the later rule in a multirule system
"Random" out of events selected by other criteria, pick one uniformly at random
EventSelectionFunction determines the type of the singleway/multiway system to run. Possible values:
"GlobalSpacelike" a normal singleway system, expressions are deleted after they are used
None a match-all multiway system that matches spacelike, branchlike and timelike expressions
See the SetReplace README for a more detailed documentation.
Install the SetReplace paclet to get syntax autocompletion, better performance and bleeding-edge functionality.

Examples

Basic Examples

Run a Wolfram model for two generations, and give the states generated:

In[1]:=
ResourceFunction[
 "WolframModel"][{{x, y}} -> {{x, y}, {y, z}}, {{1, 2}}, 2, "StatesList"]
Out[1]=

Give only the final state:

In[2]:=
ResourceFunction[
 "WolframModel"][{{x, y}} -> {{x, y}, {y, z}}, {{1, 2}}, 2, "FinalState"]
Out[2]=

Run a Wolfram model for 10 generations, and visualize the result:

In[3]:=
ResourceFunction[
 "WolframModel"][{{x, y}, {x, z}} -> {{x, z}, {x, w}, {y, w}, {z, w}}, {{0, 0}, {0, 0}}, 10, "FinalStatePlot"]
Out[3]=

Visualize a Wolfram model rule:

In[4]:=
RulePlot[ResourceFunction[
  "WolframModel"][{{x, y}, {x, z}} -> {{x, z}, {x, w}, {y, w}, {z, w}}]]
Out[4]=

Generate a symbolic representation of Wolfram model evolution:

In[5]:=
evolution = ResourceFunction[
  "WolframModel"][{{x, y}, {x, z}} -> {{x, z}, {x, w}, {y, w}, {z, w}}, {{0, 0}, {0, 0}}, 10]
Out[5]=

Find the state after three generations:

In[6]:=
evolution[3]
Out[6]=

Find the casual graph for the evolution:

In[7]:=
evolution["CausalGraph"]
Out[7]=

Scope

Multiple Rules

Multiple rules can be specified as a list of rules:

In[8]:=
evolution = ResourceFunction[
  "WolframModel"][{{{1, 1, 2}} -> {{2, 2, 1}, {2, 3, 2}, {1, 2, 3}}, {{1, 2, 1}, {3, 4, 2}} -> {{4, 3, 2}}}, {{1, 1, 1}}, 4]
Out[8]=

See which rules were used for each replacement:

In[9]:=
evolution["AllEventsRuleIndices"]
Out[9]=

Pattern Rules

Use explicit patterns to specify rules:

In[10]:=
ResourceFunction[
 "WolframModel"][<|
  "PatternRules" -> {a_?EvenQ, b_?OddQ} :> {a + b, a - b}|>, {1, 2, 3,
   4, 5}, \[Infinity], "AllEventsStatesList"]
Out[10]=

New vertices can be created with a Module:

In[11]:=
ResourceFunction[
 "WolframModel"][<|
  "PatternRules" -> {{a_, b_}} :> Module[{c}, {{a, c}, {c, b}}]|>, {{1, 2}}, 3, "StatesList"]
Out[11]=

Automatic Initial State

An initial state consisting of an appropriate number of (hyper) self-loops can be automatically produced for anonymous (non-pattern) rules:

In[12]:=
ResourceFunction[
  "WolframModel"][{{1, 2}, {1, 2}} -> {{3, 2}, {3, 2}, {2, 1}, {1, 3}}, Automatic, 0][0]
Out[12]=

That even works for multiple rules, in which case the loops are chosen in such a way that any of the rules can match:

In[13]:=
ResourceFunction[
  "WolframModel"][{{{1, 2}, {1, 2}} -> {{3, 2}, {3, 2}, {2, 1, 3}, {2,
       3}}, {{2, 1, 3}, {2, 3}} -> {{2, 1}, {1, 3}}}, Automatic, 0][0]
Out[13]=

Termination Criteria

Run for two complete generations:

In[14]:=
ResourceFunction[
 "WolframModel"][{{x, y}} -> {{x, y}, {y, z}}, {{1, 2}}, 2, "StatesList"]
Out[14]=

Allow a total of four events:

In[15]:=
ResourceFunction[
 "WolframModel"][{{x, y}} -> {{x, y}, {y, z}}, {{1, 2}}, <|
  "MaxEvents" -> 4|>, "StatesList"]
Out[15]=

Stop either after four events or when the state is about to exceed five vertices, whichever is sooner:

In[16]:=
ResourceFunction[
 "WolframModel"][{{x, y}} -> {{x, y}, {y, z}}, {{1, 2}}, <|
  "MaxEvents" -> 4, "MaxVertices" -> 5|>, "StatesList"]
Out[16]=

Stop once the maximum vertex degree is about to exceed 20:

In[17]:=
ResourceFunction[
 "WolframModel"][{{1, 2}, {1, 2}, {3, 1}} -> {{1, 1}, {1, 4}, {2, 1}, {2, 4}, {4, 3}}, {{1, 1}, {1, 1}, {1, 1}}, <|
  "MaxVertexDegree" -> 20|>]
Out[17]=

Properties

"StatesList" yields the list of states at each generation:

In[18]:=
ResourceFunction[
 "WolframModel"][{{x, y}} -> {{x, y}, {y, z}}, {{1, 2}}, 2, "StatesList"]
Out[18]=

Make the list of plots of all states:

In[19]:=
ResourceFunction[
 "WolframModel"][{{1, 2, 3}, {4, 5, 6}, {1, 4}} -> {{2, 7, 8}, {3, 9, 10}, {5, 11, 12}, {6, 13, 14}, {8, 12}, {11, 10}, {13, 7}, {14, 9}}, {{1, 1, 1}, {1, 1, 1}, {1, 1}, {1, 1}, {1, 1}}, 5, "StatesPlotsList"]
Out[19]=

"FinalState" yields the state obtained after all replacements of the evolution have been made:

In[20]:=
ResourceFunction[
 "WolframModel"][{{1, 2, 3}, {4, 5, 6}, {1, 4}} -> {{2, 7, 8}, {3, 9, 10}, {5, 11, 12}, {6, 13, 14}, {8, 12}, {11, 10}, {13, 7}, {14, 9}}, {{1, 1, 1}, {1, 1, 1}, {1, 1}, {1, 1}, {1, 1}}, 2, "FinalState"]
Out[20]=

Make the plot of the final state:

In[21]:=
ResourceFunction[
 "WolframModel"][{{1, 2, 3}, {4, 5, 6}, {1, 4}} -> {{2, 7, 8}, {3, 9, 10}, {5, 11, 12}, {6, 13, 14}, {8, 12}, {11, 10}, {13, 7}, {14, 9}}, {{1, 1, 1}, {1, 1, 1}, {1, 1}, {1, 1}, {1, 1}}, 6, "FinalStatePlot"]
Out[21]=

"StatesList" shows a compressed version of the evolution. To see how a state changes with each applied replacement, use "AllEventsStatesList":

In[22]:=
ResourceFunction[
 "WolframModel"][{{x, y}} -> {{x, y}, {y, z}}, {{1, 2}}, 2, "AllEventsStatesList"]
Out[22]=

"AllEventsList" returns all replacement events throughout the evolution:

In[23]:=
ResourceFunction[
 "WolframModel"][{{1, 2}} -> {{3, 4}, {3, 1}, {4, 1}, {2, 4}}, {{1, 1}}, 2, "AllEventsList"]
Out[23]=

"AllEventsRuleIndices" returns which rule was used for each event:

In[24]:=
ResourceFunction[
 "WolframModel"][{{{1, 1, 2}} -> {{2, 2, 1}, {2, 3, 2}, {1, 2, 3}}, {{1, 2, 1}, {3, 4, 2}} -> {{4, 3, 2}}}, {{1, 1, 1}}, 4, "AllEventsRuleIndices"]
Out[24]=

"EventsStatesList" just produces a list of {event,state} pairs, where state is the complete state right after this event is applied:

In[25]:=
ResourceFunction[
  "WolframModel"][{{1, 2}} -> {{3, 4}, {3, 1}, {4, 1}, {2, 4}}, {{1, 1}}, 2, "EventsStatesList"] // Column
Out[25]=

"EventsStatesPlotsList" plots not only the states, but also the events that produced them:

In[26]:=
ResourceFunction[
 "WolframModel"][{{1, 2, 3}, {4, 5, 6}, {1, 4}} -> {{2, 7, 8}, {3, 9, 10}, {5, 11, 12}, {6, 13, 14}, {8, 12}, {11, 10}, {13, 7}, {14, 9}}, {{1, 1, 1}, {1, 1, 1}, {1, 1}, {1, 1}, {1, 1}}, 2, "EventsStatesPlotsList"]
Out[26]=

"AllEventsEdgesList" returns the list of edges throughout evolution:

In[27]:=
ResourceFunction[
 "WolframModel"][{{x, y}} -> {{x, y}, {y, z}}, {{1, 2}}, 2, "AllEventsEdgesList"]
Out[27]=

Get creator and destroyer events for each edge throughout the evolution:

In[28]:=
ResourceFunction[
 "WolframModel"][{{x, y}} -> {{x, y}, {y, z}}, {{1, 2}}, 2, {"EdgeCreatorEventIndices", "EdgeDestroyerEventIndices"}]
Out[28]=

"VertexCountList" and "EdgeCountList" return counts of vertices and edges, respectively, in each state of "StatesList":

In[29]:=
ResourceFunction[
 "WolframModel"][{{1, 2, 3}, {2, 4, 5}} -> {{6, 6, 3}, {2, 6, 2}, {6, 4, 2}, {5, 3, 6}}, {{1, 1, 1}, {1, 1, 1}}, 10, {"VertexCountList",
   "EdgeCountList"}]
Out[29]=

"GenerationsCount" returns both complete and partial generation counts:

In[30]:=
ResourceFunction[
 "WolframModel"][{{1, 2}} -> {{1, 3}, {1, 3}, {3, 2}}, {{1, 1}}, <|
  "MaxEvents" -> 42|>, "GenerationsCount"]
Out[30]=

"GenerationEventsCountList" gives the number of events per each generation:

In[31]:=
ResourceFunction[
 "WolframModel"][{{1, 2}} -> {{1, 3}, {1, 3}, {3, 2}}, {{1, 1}}, 5, "GenerationEventsCountList"]
Out[31]=

"GenerationEventsList" returns the same list of events, but splits them into sublists for each generation:

In[32]:=
ResourceFunction[
  "WolframModel"][{{1, 2}} -> {{3, 4}, {3, 1}, {4, 1}, {2, 4}}, {{1, 1}}, 2, "GenerationEventsList"] // Column
Out[32]=

"EdgeGenerationsList" yields the list of generation numbers for each edge in "AllEventsEdgesList":

In[33]:=
ResourceFunction[
 "WolframModel"][{{1, 2}, {1, 3}, {1, 4}} -> {{2, 2}, {3, 2}, {3, 4}, {3, 5}}, {{1, 1}, {1, 1}, {1, 1}}, 5, "EdgeGenerationsList"]
Out[33]=

"EventsGenerationsList" gives the same for events:

In[34]:=
ResourceFunction[
 "WolframModel"][{{1, 2}, {1, 3}, {1, 4}} -> {{2, 2}, {3, 2}, {3, 4}, {3, 5}}, {{1, 1}, {1, 1}, {1, 1}}, 5, "EventGenerationsList"]
Out[34]=

"AllEventsCount" returns the overall number of events throughout the evolution:

In[35]:=
ResourceFunction[
 "WolframModel"][{{1, 2}} -> {{1, 3}, {1, 3}, {3, 2}}, {{1, 1}}, 5, "AllEventsCount"]
Out[35]=

Get a causal graph for an evolution:

In[36]:=
ResourceFunction[
 "WolframModel"][{{1, 2, 3}, {4, 5, 6}, {1, 4}} -> {{3, 7, 8}, {9, 2, 10}, {11, 12, 5}, {13, 14, 6}, {7, 12}, {11, 9}, {13, 10}, {14, 8}}, {{1, 1, 1}, {1, 1, 1}, {1, 1}, {1, 1}, {1, 1}}, 20, "CausalGraph"]
Out[36]=

The causal graph can be layered, putting events from each generation on a different level:

In[37]:=
ResourceFunction[
 "WolframModel"][{{1, 2, 3}, {4, 5, 6}, {1, 4}} -> {{3, 7, 8}, {9, 2, 10}, {11, 12, 5}, {13, 14, 6}, {7, 12}, {11, 9}, {13, 10}, {14, 8}}, {{1, 1, 1}, {1, 1, 1}, {1, 1}, {1, 1}, {1, 1}}, 10, "LayeredCausalGraph"]
Out[37]=

Options

VertexNamingFunction

Use symbolic names for new vertices:

In[38]:=
ResourceFunction[
 "WolframModel"][{{1, 2}} -> {{1, 3}, {1, 3}, {3, 2}}, {{v1, v1}}, 2, "StatesList", "VertexNamingFunction" -> None]
Out[38]=

Sequentially rename all vertices, including the initial condition:

In[39]:=
ResourceFunction[
 "WolframModel"][{{1, 2}} -> {{1, 3}, {1, 3}, {3, 2}}, {{v1, v1}}, 2, "StatesList", "VertexNamingFunction" -> All]
Out[39]=

IncludePartialGenerations

Drop partial generations from the evolution:

In[40]:=
ResourceFunction[
 "WolframModel"][{{1, 2}} -> {{1, 3}, {1, 3}, {3, 2}}, {{1, 1}}, <|
  "MaxEvents" -> 42|>, "IncludePartialGenerations" -> False]
Out[40]=

IncludeBoundaryEvents

Include the initial event in a causal graph:

In[41]:=
ResourceFunction[
 "WolframModel"][<|"PatternRules" -> {a_, b_} :> a + b|>, {3, 8, 8, 8,
   2, 10, 0, 9, 7}, Infinity, "LayeredCausalGraph", "IncludeBoundaryEvents" -> "Initial"]
Out[41]=

Include the final event in the list of events:

In[42]:=
ResourceFunction[
 "WolframModel"][<|"PatternRules" -> {a_, b_} :> a + b|>, {3, 8, 8, 8,
   2, 10, 0, 9, 7}, Infinity, "AllEventsList", "IncludeBoundaryEvents" -> "Final"]
Out[42]=

Include both the initial and the final events in "EventsStatesList":

In[43]:=
ResourceFunction[
  "WolframModel"][{{1, 2}} -> {{3, 4}, {3, 1}, {4, 1}, {2, 4}}, {{1, 1}}, 2, "EventsStatesList", "IncludeBoundaryEvents" -> All] // Column
Out[43]=

Method

Use symbolic implementation to compute the evolution (which is faster if vertex degrees are large):

In[44]:=
ResourceFunction[
  "WolframModel"][{{{0}} -> {{0}, {0}, {0}}, {{0}, {0}, {0}} -> \
{{0}}}, {{0}}, <|"MaxEvents" -> 30|>, Method -> "Symbolic"] // AbsoluteTiming
Out[44]=

Compare:

In[45]:=
ResourceFunction[
  "WolframModel"][{{{0}} -> {{0}, {0}, {0}}, {{0}, {0}, {0}} -> \
{{0}}}, {{0}}, <|"MaxEvents" -> 30|>] // AbsoluteTiming
Out[45]=

TimeConstraint

Return the evolution object after running the evolution for one second:

In[46]:=
ResourceFunction[
 "WolframModel"][{{1, 2}} -> {{1, 3}, {1, 3}, {3, 2}}, {{1, 1}}, Infinity, TimeConstraint -> 1]
Out[46]=

EventOrderingFunction

Show final states from five random event orderings:

In[47]:=
Table[ResourceFunction[
  "WolframModel"][{{x, y}, {x, z}} -> {{x, z}, {x, w}, {y, w}, {z, w}}, {{0, 0}, {0, 0}}, 10, "FinalStatePlot", "EventOrderingFunction" -> "Random"], 5]
Out[47]=

Compare results for the default ordering with the "RuleOrdering":

In[48]:=
ResourceFunction[
   "WolframModel"][{{1, 2}, {2, 3}} -> {{4, 2}, {4, 1}, {2, 1}, {3, 4}}, {{1, 2}, {2, 3}, {3, 4}, {4, 1}}, 5, "FinalStatePlot", "EventOrderingFunction" -> #] & /@ {Automatic, "RuleOrdering"}
Out[48]=

Properties and Relations

Use ResourceFunction["WolframModelPlot"] to visualize states of WolframModel:

In[49]:=
ResourceFunction["WolframModelPlot"] /@ ResourceFunction[
  "WolframModel"][{{1, 2}, {2, 3}} -> {{4, 2}, {4, 1}, {2, 1}, {3, 4}}, {{1, 2}, {2, 3}, {3, 4}, {4, 1}}, 7, "StatesList"]
Out[49]=

Get an evolution object:

In[50]:=
evolution = ResourceFunction[
  "WolframModel"][{{1, 2}, {2, 3}} -> {{4, 2}, {4, 1}, {2, 1}, {3, 4}}, {{1, 2}, {2, 3}, {3, 4}, {4, 1}}, 7]
Out[50]=

Extract the state after one hundred events from the object:

In[51]:=
ResourceFunction["WolframModelPlot"][
 evolution["StateAfterEvent", 100]]
Out[51]=

Use RulePlot to visualize the rule:

In[52]:=
RulePlot[ResourceFunction[
  "WolframModel"][{{1, 2}, {2, 3}} -> {{4, 2}, {4, 1}, {2, 1}, {3, 4}}]]
Out[52]=

Possible Issues

The evolution order (and hence the result) might change after canonicalization of the rule:

In[53]:=
ResourceFunction[
 "WolframModel"][{{x, y}, {x, z}} -> {{x, z}, {x, w}, {y, w}, {z, w}}, Automatic, 3, "StatesPlotsList"]
Out[53]=
In[54]:=
ResourceFunction["WolframModel"][
 ResourceFunction[
  "FindCanonicalWolframModel"][{{x, y}, {x, z}} -> {{x, z}, {x, w}, {y, w}, {z, w}}], Automatic, 3, "StatesPlotsList"]
Out[54]=

Using custom step limiters might produce a state in between generations:

In[55]:=
ResourceFunction[
 "WolframModel"][{{1, 2, 3}, {4, 5, 6}, {2, 5}, {5, 2}} -> {{7, 1, 8}, {9, 3, 10}, {11, 4, 12}, {13, 6, 14}, {7, 13}, {13, 7}, {8, 10}, {10, 8}, {9, 11}, {11, 9}, {12, 14}, {14, 12}}, {{1, 2, 3}, {4, 5, 6}, {1, 4}, {4, 1}, {2, 5}, {5, 2}, {3, 6}, {6, 3}}, <|
  "MaxVertices" -> 300, "MaxEvents" -> 200|>, "FinalStatePlot"]
Out[55]=

Set "IncludePartialGenerations"False to drop partial generations:

In[56]:=
ResourceFunction[
 "WolframModel"][{{1, 2, 3}, {4, 5, 6}, {2, 5}, {5, 2}} -> {{7, 1, 8}, {9, 3, 10}, {11, 4, 12}, {13, 6, 14}, {7, 13}, {13, 7}, {8, 10}, {10, 8}, {9, 11}, {11, 9}, {12, 14}, {14, 12}}, {{1, 2, 3}, {4, 5, 6}, {1, 4}, {4, 1}, {2, 5}, {5, 2}, {3, 6}, {6, 3}}, <|
  "MaxVertices" -> 300, "MaxEvents" -> 200|>, "FinalStatePlot", "IncludePartialGenerations" -> False]
Out[56]=

Options for properties like "CausalGraph" cannot be given in WolframModel:

In[57]:=
ResourceFunction[
 "WolframModel"][{{1, 2, 3}, {4, 5, 6}, {1, 4}} -> {{3, 7, 8}, {9, 2, 10}, {11, 12, 5}, {13, 14, 6}, {7, 12}, {11, 9}, {13, 10}, {14, 8}}, {{1, 1, 1}, {1, 1, 1}, {1, 1}, {1, 1}, {1, 1}}, 12, "CausalGraph", VertexLabels -> Automatic]
Out[57]=

The options can be given to an evolution object, however:

In[58]:=
ResourceFunction[
  "WolframModel"][{{1, 2, 3}, {4, 5, 6}, {1, 4}} -> {{3, 7, 8}, {9, 2,
      10}, {11, 12, 5}, {13, 14, 6}, {7, 12}, {11, 9}, {13, 10}, {14, 8}}, {{1, 1, 1}, {1, 1, 1}, {1, 1}, {1, 1}, {1, 1}}, 12]["CausalGraph", VertexLabels -> Automatic]
Out[58]=

"FinalDistinctElementsCount" is not equivalent to "FinalVertexCount":

In[59]:=
ResourceFunction[
 "WolframModel"][<|
  "PatternRules" -> {{a_}} :> {{a + 1}, {a - 1}, {{a + 2, a - 2}}}|>, {{1}}, 7, "VertexCountList"]
Out[59]=
In[60]:=
ResourceFunction[
   "WolframModel"][<|
    "PatternRules" -> {{a_}} :> {{a + 1}, {a - 1}, {{a + 2, a - 2}}}|>, {{1}}, #, "FinalDistinctElementsCount"] & /@ Range[0, 7]
Out[60]=

That happens if nontrivial nesting is present, and the following is counted as three vertices but four distinct elements:

In[61]:=
ResourceFunction[
 "WolframModel"][<|
  "PatternRules" -> {{a_}} :> {{a + 1}, {a - 1}, {{a + 2, a - 2}}}|>, {{1}}, 1, "FinalState"]
Out[61]=

The "LowLevel" implementation (the default) is slow if the number of potential matches is very large (which could occur in states with large vertex degrees):

In[62]:=
AbsoluteTiming[
 ResourceFunction[
  "WolframModel"][{{{0}} -> {{0}, {0}, {0}}, {{0}, {0}, {0}} -> \
{{0}}}, {{0}}, <|"MaxEvents" -> 30|>, Method -> "LowLevel"]]
Out[62]=

The "Symbolic" implementation might help in such cases:

In[63]:=
AbsoluteTiming[
 ResourceFunction[
  "WolframModel"][{{{0}} -> {{0}, {0}, {0}}, {{0}, {0}, {0}} -> \
{{0}}}, {{0}}, <|"MaxEvents" -> 30|>, Method -> "Symbolic"]]
Out[63]=

A single "EventOrderingFunction" might be insufficient to select a single event and produce deterministic evolution:

In[64]:=
Table[ResourceFunction[
  "WolframModel"][{{{1, 2}, {1, 3}, {1, 4}} -> {{5, 6}, {6, 7}, {7, 5}, {5, 7}, {7, 6}, {6, 5}, {5, 2}, {6, 3}, {7, 4}, {2, 7}, {4, 5}}, {{1, 2}, {1, 3}, {1, 4}, {1, 5}} -> {{2, 3}, {3, 4}}}, {{1,
     1}, {1, 1}, {1, 1}}, <|"MaxEvents" -> 30|>, "FinalStatePlot", "EventOrderingFunction" -> "LeastRecentEdge"], 3]
Out[64]=

Use multiple ordering functions to get deterministic behavior:

In[65]:=
Table[ResourceFunction[
  "WolframModel"][{{{1, 2}, {1, 3}, {1, 4}} -> {{5, 6}, {6, 7}, {7, 5}, {5, 7}, {7, 6}, {6, 5}, {5, 2}, {6, 3}, {7, 4}, {2, 7}, {4, 5}}, {{1, 2}, {1, 3}, {1, 4}, {1, 5}} -> {{2, 3}, {3, 4}}}, {{1,
     1}, {1, 1}, {1, 1}}, <|"MaxEvents" -> 30|>, "FinalStatePlot", "EventOrderingFunction" -> {"LeastRecentEdge", "RuleOrdering"}], 3]
Out[65]=

Neat Examples

Make a causal graph for a system that computes the Total of a list of numbers:

In[66]:=
With[{evolution = ResourceFunction[
    "WolframModel"][<|"PatternRules" -> {a_, b_} :> a + b|>, {3, 8, 8,
      8, 2, 10, 0, 9, 7}, Infinity]}, With[{causalGraph = evolution["LayeredCausalGraph"]}, Graph[causalGraph, VertexLabels -> Thread[VertexList[causalGraph] -> Map[evolution["AllEventsEdgesList"][[#]] &, Last /@ evolution["AllEventsList"], {2}]]]]]
Out[66]=

Show which rule is used for each event on a causal graph:

In[67]:=
With[{evolution = ResourceFunction[
    "WolframModel"][{{{1, 1, 2}} -> {{2, 2, 1}, {2, 3, 2}, {1, 2, 3}}, {{1, 2, 1}, {3, 4, 2}} -> {{4, 3, 2}}}, {{1, 1, 1}}, 6]},
  With[{causalGraph = evolution["LayeredCausalGraph"]}, Graph[causalGraph, VertexStyle -> Thread[VertexList[causalGraph] -> Replace[evolution["AllEventsRuleIndices"], {1 -> Black, 2 -> White}, {1}]], VertexSize -> Medium]]]
Out[67]=

Color edges of different generations differently in a "StatesPlotsList":

In[68]:=
With[{evolution = ResourceFunction[
    "WolframModel"][{{1, 2}, {1, 3}, {1, 4}} -> {{2, 2}, {3, 2}, {3, 4}, {3, 5}}, {{1, 1}, {1, 1}, {1, 1}}, 5]}, MapThread[
  ResourceFunction["WolframModelPlot"][#, EdgeStyle -> #2] &, {evolution["StatesList"], Replace[evolution[
        "EdgeGenerationsList"][[#]] & /@ (evolution[
         "StateEdgeIndicesAfterEvent", #] &) /@ Prepend[0]@Accumulate@evolution["GenerationEventsCountList"], g_ :> ColorData["Rainbow"][g/5], {2}]}]]
Out[68]=

Plot a result of a uniformly random evolution trimmed at a complete number of generations:

In[69]:=
ResourceFunction[
 "WolframModel"][{{1, 2, 3}, {2, 4, 5}} -> {{6, 6, 3}, {2, 6, 2}, {6, 4, 2}, {5, 3, 6}}, {{1, 1, 1}, {1, 1, 1}}, <|
  "MaxEvents" -> 10000|>, "FinalStatePlot", "EventOrderingFunction" -> "Random", "IncludePartialGenerations" -> False]
Out[69]=

Show the result of an evolution for all single-event ordering functions:

In[70]:=
ResourceFunction[
    "WolframModel"][{{{1, 2}, {1, 3}, {1, 4}} -> {{5, 6}, {6, 7}, {7, 5}, {5, 7}, {7, 6}, {6, 5}, {5, 2}, {6, 3}, {7, 4}, {2, 7}, {4, 5}}, {{1, 2}, {1, 3}, {1, 4}, {1, 5}} -> {{2, 3}, {3, 4}}}, {{1, 1}, {1, 1}, {1, 1}}, <|"MaxEvents" -> 30|>, "EventOrderingFunction" -> {#, "LeastRecentEdge", "RuleOrdering", "RuleIndex"}]["FinalStatePlot", PlotLabel -> #] & /@ {"OldestEdge", "LeastOldEdge", "LeastRecentEdge", "NewestEdge", "RuleOrdering", "ReverseRuleOrdering", "RuleIndex", "ReverseRuleIndex", "Random"}
Out[70]=

Resource History

Related Resources

License Information