Kaynağa Gözat

Update documentation for new activity execution

Yentl Van Tendeloo 7 yıl önce
ebeveyn
işleme
861f5c6c52

BIN
bootstrap/bootstrap.m.gz


+ 70 - 13
doc/operations.rst

@@ -23,15 +23,15 @@ On the other hand, procedural algorithms are relatively easy (when implemented n
 The functions on model transformations are exposed using the *transformation_add_MT* and *transformation_execute_MT* operations.
 Examples as shown in the previous section::
 
-    >>> def callback():
-    ...     instantiate(None, "Association", edge=("PetriNets/Transition", "ReachabilityGraph/Transition"), ID="PN2RG_Transition")
+    >>> def callback(model):
+    ...     instantiate(model, "Association", edge=("PetriNets/Transition", "ReachabilityGraph/Transition"), ID="PN2RG_Transition")
     >>> transformation_add_MT({"PetriNets": "formalisms/PetriNets"}, {"ReachabilityGraph": "formalisms/ReachabilityGraph"}, "models/pn_analyse", open("models/pn_analyse.mvc", "r").read(), callback)
 
 A situation in which model transformations are effective, is when the transformation is to map a Domain Specific Language (DSL) to a General Purpose Language (GPL).
 For example, when defining a mapping between a RPGame DSL and the PetriNets formalism, to facilitate formal analysis::
 
-    >>> def callback():
-    ...     instantiate(None, "Association", edge=("RPGame/Tile", "PetriNets/Place"), ID="Tracability_link")
+    >>> def callback(model):
+    ...     instantiate(model, "Association", edge=("RPGame/Tile", "PetriNets/Place"), ID="Tracability_link")
     >>> rule = \
     ...     """
     ...     Composite composite {
@@ -81,8 +81,8 @@ As with model transformations, the names of model entities are prefixed with the
 
 For example, when defining the PetriNets analysis in action language, which is a much better match than model transformations::
 
-    >>> def callback():
-    ...     instantiate(None, "Association", edge=("PetriNets/Transition", "ReachabilityGraph/Transition"), ID="PN2RG_Transition")
+    >>> def callback(model):
+    ...     instantiate(model, "Association", edge=("PetriNets/Transition", "ReachabilityGraph/Transition"), ID="PN2RG_Transition")
     >>> code = \
     ...     """
     ...     include "primitives.alh"
@@ -114,8 +114,8 @@ As with model transformations, the names of model entities are prefixed with the
 
 For example, when defining an operation to refine or revise a model in a DSL with respect to the requirements, such as the RPGame language from before::
 
-    >>> def callback():
-    ...     instantiate(None, "Association", edge=("Requirements/Actor", "RPGame/Player"))
+    >>> def callback(model):
+    ...     instantiate(model, "Association", edge=("Requirements/Actor", "RPGame/Player"))
     >>> transformation_add_MANUAL({"RPGame": "formalisms/RPGame", "Requirements": "formalisms/Requirements"}, {"RPGame": "formalisms/RPGame"}, "revise_rpg", callback)
 
 Its execution, however, differs significantly from before, as we will see next.
@@ -134,9 +134,9 @@ As before, the first parameter of the operations (*model_name*) should be set to
 
 For example, to specify the operations that have to be done in a manual operation, all in Python syntax::
 
-    >>> def callback():
-    ...     tiles = [instantiate(None, "RPGame/Tile") for _ in range(100)]
-    ...     left_links = [instantiate(None, "RPGame/left", edge=(tiles[i], tiles[i+1])) for i in range(len(tiles) - 1)]
+    >>> def callback(model):
+    ...     tiles = [instantiate(model, "RPGame/Tile") for _ in range(100)]
+    ...     left_links = [instantiate(model, "RPGame/left", edge=(tiles[i], tiles[i+1])) for i in range(len(tiles) - 1)]
     ...     ...
     >>> transformation_execute_MANUAL("revise_rpg", {"RPGame": "models/my_rpg", "Requirements": "models/rpg_requirements"}, {"RPGame": "models/my_rpg"}, callback)
 
@@ -144,12 +144,12 @@ Alternatively, the operations might only be known at runtime, thereby requiring
 Note that, in this case, the code in the callback is effectively the user interface offered to the user in this specific context.
 As such, the code can be completely tailored to the domain and problem at hand (e.g., a *create random level* operation).
 
-    >>> def callback():
+    >>> def callback(model):
     ...     while True:
     ...         print("Please perform operation on RPGame!)"
     ...         inp = raw_input()
     ...         if inp == "new tile":
-    ...             instantiate(None, "RPGame/Tile")
+    ...             instantiate(model, "RPGame/Tile")
     ...         elif inp == "create random level":
     ...             ...
     ...         ...
@@ -163,6 +163,63 @@ Instead, the callback is invoked when the action language, either standalone or
 The return value of the callback is made available to the action language (fragment) when it executes the *input* operations, and can be a single primitive type, or a list.
 In case it is a list, the primitive types are offered to the action language individually, requiring multiple *input* calls.
 
+Statechart callbacks
+^^^^^^^^^^^^^^^^^^^^
+
+While manual operations can refer to a Python function as callback, this is not the case for the execution of a model transformation or action language fragment.
+In this case, a more complex interaction is required, which depends on the use of SCCD (Statecharts + Class Diagrams).
+When executing the activity, a reference to a running statechart is passed, instead of a callback function.
+This statechart can have an input and output port, which can be used to communicate with the Modelverse.
+Data sent on the output port will arrive in the running activity (in the *input()* call), and data sent out in the activity with *output(X)* will be received on the input port.
+
+An example is given below of a model transformation that prints out a Petri Net using a model transformation::
+
+    >>> ctrl = log_output.Controller(keep_running=False)
+    >>> thrd = threading.Thread(target=ctrl.start)
+    >>> thrd.daemon = True
+    >>> thrd.start()
+
+    >>> transformation_execute_MT("test/print_pn", {"PetriNet": "test/my_pn"}, {}, (ctrl, "inp", "outp"))
+
+This command starts up the model transformation and immediately connects it to a running Statechart called *log_output*.
+Its definition is shown below::
+
+    <?xml version="1.0" encoding="UTF-8"?>
+    <diagram author="Yentl Van Tendeloo" name="Logging">
+        <description>
+            Print all incoming data
+        </description>
+    
+        <inport name="inp"/>
+        <outport name="outp"/>
+    
+        <class name="Logging" default="true">
+            <scxml initial="init">
+                <state id="init">
+                    <transition event="input" port="inp" target=".">
+                        <parameter name="value"/>
+                        <script>
+                            print(value)
+                        </script>
+                    </transition>
+    
+                    <transition after="0.1" target="."/>
+    
+                    <transition event="terminate" port="inp" target="../finished">
+                        <script>
+                            print("Terminating")
+                        </script>
+                    </transition>
+                </state>
+    
+                <state id="finished"/>
+            </scxml>
+        </class>
+    </diagram>
+
+Similarly, the SCCD model could have raised input to its output port (*outp*), which would then be received in the transformation.
+Note that the call to *transformation_execute_MT* is always blocking and always returns whether or not the activity was successfully terminated.
+
 Process Model
 -------------
 

+ 4 - 4
doc/process_enactment.rst

@@ -33,11 +33,11 @@ For example, a manual operation will require user input, for which this callback
 In this case, lets assume that an activity in the process model, termed *refine_petrinet*, is a manual operation and requires user interaction.
 The call then becomes::
 
-    >>> def callback():
+    >>> def callback(model):
     ...     # Any code required to create the Petrinet
-    ...     p = instantiate(None, "Place")
-    ...     t = instantiate(None, "Transition")
-    ...     instantiate(None, "P2T", (p, t))
+    ...     p = instantiate(model, "Place")
+    ...     t = instantiate(model, "Transition")
+    ...     instantiate(model, "P2T", (p, t))
     ...     # Alternatively, we could have used raw_input() or so to prompt the user
     ...
     >>> process_execute("models/query_state_space", {}, {"models/refine_petrinet": callback})

+ 1 - 1
wrappers/modelverse_SCCD.py

@@ -1,7 +1,7 @@
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
-Date:   Thu Apr  5 16:51:38 2018
+Date:   Fri Apr  6 10:27:34 2018
 
 Model author: Yentl Van Tendeloo
 Model name:   MvK Server