Graph Grammars Tutorial
By Denis Dube
This tutorial continues where the Advanced Meta-modelling Tutorial left off.
1) Open the formalism generated from the above. You need to have something similar to the above (a class and an association), and give them each a "name" and "number" attribute (the other attributes are not used in this tutorial). Now press "T" to bring up the Graph Grammar editing dialog.
2) Give your GG a name. Then press New to create a new rule. The screen below appears (you can re-size as desired).
On the LHS of the rule create an instance of a QuickTurialClass. When you edit it, you'll be able to match attributes or any attributes. Below the rule is set to specifically match only those "QuickTurialClass" instances that have the number zero. The GGLabel is important, since if it doesn't appear on the RHS then the "QuickTurialClass" will be deleted when this rule is run.
3) Press "Copy LHS" to make the RHS equivalent to the LHS.
Now edit the copied "QuickTurialClass" instance. The dialog is different now. You can either copy the attribute values from the LHS or specify the attribute using code (NOTE: if you choose, for example, to put an arbitrary string in "name" and remove the checks from both Copy from LHS and Enabled? then it will probably work… but the GG documentation generator will likely crash).
4) To specify an attribute with code, one typically obtains a reference to an object on the LHS, accesses an attribute, modifies it, and then returns it. The code below finds the LHS object with GG label 1, gets the number attribute, then increases it by 1, and finally returns it (thus executing this rule causes the attribute to increment by 1).
LHSvalue = self.getMatched(graphID, self.LHS.nodeWithLabel(1)).number.getValue()
return LHSvalue + 1
5) It is possible to create arbitrary stuff in the RHS. Here is one example:
6) Give the rule a name, and press OK in the bottom. Then Save GG (always good to save!). The saved file has this name: QuickTutorialGG_GG_mdl.py
If you press Generate latex document, the entire GG will be pretty formatted and the LHS & RHS views converted to EPS to form a .tex document that can then be used to generate a PS or PDF file.
7) Press Generate GG code (i.e.: you can put it in same place as you saved the GG model) and then Execute GG code to actually run the GG.
Note that the generated code has a ggQuickTut_GG_exec.py and then a ggRuleQuickTut_GG_rule.py file (there's as many files as there are rules).
8) The execute GG dialog looks like the above. Press ok.
If STEPbySTEP is not selected, the GG just runs as fast as possible.
LetEntitiesMove does… I have no idea…
Animate does nothing (there for historical reasons)
Sequential Random execution: if two (or more) rules have the same order, then the one executed is chosen randomly.
Sequential Manual execution: deterministic execution.
Parallel execution: if two (or more) rules have the same order, they are executed in parallel.
9) After 2 steps of execution, the canvas looks like as follows:
10) Note how when we execute this rule, it will occur only once for each "QuickTurialClass" since the LHS is required to have the number 0 and the RHS increments it by 1. In general, this happy state of affairs does not happen. So lets change the LHS so it matches everything (<ANY>). Now the GG will execute forever!
11) Condition. To prevent the GG from looping forever, introduce a condition (Enable it then press Edit). The basic idea is this, we find a node associated with some GG label on the LHS, then check if the node has some arbitrary attribute (which we shall add to the node whenever we execute the rule in the next step).
node = self.getMatched(graphID, self.LHS.nodeWithLabel(1))
return not hasattr(node, "_rule_1_executed_already")
12) Action. Whenever the rule is executed, this action code is run. Hence we add an extra attribute to the LHS node.
13) Save, Gen, Exec the grammar. The result is shown below. It matched the existing circles with the attribute set to 1 because of the <ANY> matching, but it only executed once for each circle because of the condition/action added to the rule.
NOTE: If memory leaks bother you, you can remove all these added attributes in the Graph Grammar final action :)
14) Curious what the "Generic Links" button does? This is if you need to connect different formalisms or components that would not normally be allowed to connect to one another. This is a brute force method, as it completely disables the normal "this can connect to that" checking.
15) What if you want to match an association that could be connected to anything (you don't care what it's connected to). It is easy to draw the association labelled 7, but not 3 as shown below.
To draw the association separately (without creating a new button in your *_META.py buttons model), what you do is draw your class instances and the association between them as you would normally. Then you select one of the instances (say 5), and press the button "Isolate Association" in the LHS "Transformation" toolbar. Do the same for the instance labelled 6 and then the association 7 will be as disconnected as association 3.