@@ -38,101 +38,101 @@ end
3838import . algae
3939
4040let
41- #=
42- Note that in this very example we do not need to store any data or state inside
43- the nodes, so types `A` and `B` do not require fields.
44-
45- The axiom is simply defined as an instance of type of `A`:
46- =#
47- axiom = algae. A ()
48-
49- #=
50- The rewriting rules are implemented in VPL as objects of type `Rule`. In VPL, a
51- rewriting rule substitutes a node in a graph with a new node or subgraph and is
52- therefore composed of two parts:
53-
54- 1. A condition that is tested against each node in a graph to choose which nodes
55- to rewrite.
56- 2. A subgraph that will replace each node selected by the condition above.
57-
58- In VPL, the condition is split into two components:
59-
60- 1. The type of node to be selected (in this example that would be `A` or `B`).
61- 2. A function that is applied to each node in the graph (of the specified type)
62- to indicate whether the node should be selected or not. This function is
63- optional (the default is to select every node of the specified type).
64-
65- The replacement subgraph is specified by a function that takes as input the node
66- selected and returns a subgraph defined as a combination of node objects.
67- Subgraphs (which can also be used as axioms) are created by linearly combining
68- objects that inherit from `Node`. The operation `+` implies a linear
69- relationship between two nodes and `[]` indicates branching.
70-
71- The implementation of the two rules of algae growth model in VPL is as follows:
72- =#
73- rule1 = Rule (algae. A, rhs = x -> algae. A () + algae. B ())
74- rule2 = Rule (algae. B, rhs = x -> algae. A ())
75-
76- #=
77- Note that in each case, the argument `rhs` is being assigned an anonymous (aka
78- *lambda*) function. This is a function without a name that is defined directly
79- in the assigment to the argument. That is, the Julia expression `x -> A() + B()`
80- is equivalent to the following function definition:
81- =#
82- function rule_1 (x)
83- algae. A () + algae. B ()
84- end
85-
86- #=
87- For simple rules (especially if the right hand side is just a line of code) it
88- is easier to just define the right hand side of the rule with an anonymous
89- function rather than creating a standalone function with a meaningful name.
90- However, standalone functions are easier to debug as you can call them directly
91- from the REPL.
92-
93- With the axiom and rules we can now create a `Graph` object that represents the
94- algae organism. The first argument is the axiom and the second is a tuple with
95- all the rewriting rules:
96- =#
97- organism = Graph (axiom = axiom, rules = (rule1, rule2))
98-
99- #=
100- If we apply the rewriting rules iteratively, the graph will grow, in this case
101- representing the growth of the algae organism. The rewriting rules are applied
102- on the graph with the function `rewrite!()`:
103- =#
104- rewrite! (organism)
105-
106- #=
107- Since there was only one node of type `A`, the only rule that was applied was
108- `rule1`, so the graph should now have two nodes of types `A` and `B`,
109- respectively. We can confirm this by drawing the graph. We do this with the
110- function `draw()` which will always generate the same representation of the
111- graph, but different options are available depending on the context where the
112- code is executed. By default, `draw()` will create a new window where an
113- interactive version of the graph will be drawn and one can zoom and pan with the
114- mouse.
115- =#
116- import GLMakie
117- draw (organism)
118-
119- #=
120- Notice that each node in the network representation is labelled with the type of
121- node (`A` or `B` in this case) and a number in parenthesis. This number is a
122- unique identifier associated to each node and it is useful for debugging
123- purposes (this will be explained in more advanced examples).
124-
125- Applying multiple iterations of rewriting can be achieved with a simple loop:
126- =#
127- for i = 1 : 4
41+ #=
42+ Note that in this very example we do not need to store any data or state inside
43+ the nodes, so types `A` and `B` do not require fields.
44+
45+ The axiom is simply defined as an instance of type of `A`:
46+ =#
47+ axiom = algae. A ()
48+
49+ #=
50+ The rewriting rules are implemented in VPL as objects of type `Rule`. In VPL, a
51+ rewriting rule substitutes a node in a graph with a new node or subgraph and is
52+ therefore composed of two parts:
53+
54+ 1. A condition that is tested against each node in a graph to choose which nodes
55+ to rewrite.
56+ 2. A subgraph that will replace each node selected by the condition above.
57+
58+ In VPL, the condition is split into two components:
59+
60+ 1. The type of node to be selected (in this example that would be `A` or `B`).
61+ 2. A function that is applied to each node in the graph (of the specified type)
62+ to indicate whether the node should be selected or not. This function is
63+ optional (the default is to select every node of the specified type).
64+
65+ The replacement subgraph is specified by a function that takes as input the node
66+ selected and returns a subgraph defined as a combination of node objects.
67+ Subgraphs (which can also be used as axioms) are created by linearly combining
68+ objects that inherit from `Node`. The operation `+` implies a linear
69+ relationship between two nodes and `[]` indicates branching.
70+
71+ The implementation of the two rules of algae growth model in VPL is as follows:
72+ =#
73+ rule1 = Rule (algae. A, rhs = x -> algae. A () + algae. B ())
74+ rule2 = Rule (algae. B, rhs = x -> algae. A ())
75+
76+ #=
77+ Note that in each case, the argument `rhs` is being assigned an anonymous (aka
78+ *lambda*) function. This is a function without a name that is defined directly
79+ in the assigment to the argument. That is, the Julia expression `x -> A() + B()`
80+ is equivalent to the following function definition:
81+ =#
82+ function rule_1 (x)
83+ algae. A () + algae. B ()
84+ end
85+
86+ #=
87+ For simple rules (especially if the right hand side is just a line of code) it
88+ is easier to just define the right hand side of the rule with an anonymous
89+ function rather than creating a standalone function with a meaningful name.
90+ However, standalone functions are easier to debug as you can call them directly
91+ from the REPL.
92+
93+ With the axiom and rules we can now create a `Graph` object that represents the
94+ algae organism. The first argument is the axiom and the second is a tuple with
95+ all the rewriting rules:
96+ =#
97+ organism = Graph (axiom = axiom, rules = (rule1, rule2))
98+
99+ #=
100+ If we apply the rewriting rules iteratively, the graph will grow, in this case
101+ representing the growth of the algae organism. The rewriting rules are applied
102+ on the graph with the function `rewrite!()`:
103+ =#
128104 rewrite! (organism)
129- end
130-
131- # And we can verify that the graph grew as expected:
132- draw (organism)
133105
134- # The network is rather boring as the system is growing linearly (no branching)
135- # but it already illustrates how graphs can grow rapidly in just a few
136- # iterations. Remember that the interactive visualization allows adjusting the
137- # zoom, which is handy when graphs become large.
106+ #=
107+ Since there was only one node of type `A`, the only rule that was applied was
108+ `rule1`, so the graph should now have two nodes of types `A` and `B`,
109+ respectively. We can confirm this by drawing the graph. We do this with the
110+ function `draw()` which will always generate the same representation of the
111+ graph, but different options are available depending on the context where the
112+ code is executed. By default, `draw()` will create a new window where an
113+ interactive version of the graph will be drawn and one can zoom and pan with the
114+ mouse.
115+ =#
116+ import GLMakie
117+ draw (organism)
118+
119+ #=
120+ Notice that each node in the network representation is labelled with the type of
121+ node (`A` or `B` in this case) and a number in parenthesis. This number is a
122+ unique identifier associated to each node and it is useful for debugging
123+ purposes (this will be explained in more advanced examples).
124+
125+ Applying multiple iterations of rewriting can be achieved with a simple loop:
126+ =#
127+ for i = 1 : 4
128+ rewrite! (organism)
129+ end
130+
131+ # And we can verify that the graph grew as expected:
132+ draw (organism)
133+
134+ # The network is rather boring as the system is growing linearly (no branching)
135+ # but it already illustrates how graphs can grow rapidly in just a few
136+ # iterations. Remember that the interactive visualization allows adjusting the
137+ # zoom, which is handy when graphs become large.
138138end
0 commit comments