|
@@ -0,0 +1,209 @@
|
|
|
+Modelling Language
|
|
|
+==================
|
|
|
+
|
|
|
+Apart from the action language, the Modelverse also has a modelling language.
|
|
|
+With this language, models (*i.e.*, data) can be defined in addition to the algorithms.
|
|
|
+
|
|
|
+This language is still work in progress, but should be decent enough to construct simple metamodels and instantiate them.
|
|
|
+All models have the extension \*.mvc, indicating that they are models and should be compiled as such.
|
|
|
+
|
|
|
+If you want to create models interactively, such as with another tool, it is strongly recommended to use the interactive interface to do this, as the modelling language is completely static.
|
|
|
+
|
|
|
+Language description
|
|
|
+--------------------
|
|
|
+
|
|
|
+The modelling language defines data structures, which will be formed as models in the Modelverse.
|
|
|
+
|
|
|
+Several constructs are supported.
|
|
|
+
|
|
|
+Include
|
|
|
+^^^^^^^
|
|
|
+
|
|
|
+When combined with action language, for example with code fragments, the action language might require some includes of header files.
|
|
|
+To do this, the includes can be placed at the top of the hierarchy.
|
|
|
+The structure is as follows::
|
|
|
+
|
|
|
+ include "primitives.alh"
|
|
|
+
|
|
|
+Model
|
|
|
+^^^^^
|
|
|
+
|
|
|
+Every model is defined by first specifying the type of model to instantiate, followed by the name of the model to create.
|
|
|
+The name of the model can then later on be referenced in other models (as type, or for exporting).
|
|
|
+Within the model, all names of the type model can be used as types again.
|
|
|
+This is only used internally for bootstrapping purposes, so feel free to write whatever you want here.
|
|
|
+
|
|
|
+The structure is as follows::
|
|
|
+
|
|
|
+ SimpleClassDiagrams PetriNets{
|
|
|
+ ...
|
|
|
+ }
|
|
|
+
|
|
|
+All further operations happen inside such a definition.
|
|
|
+
|
|
|
+Instance
|
|
|
+^^^^^^^^
|
|
|
+
|
|
|
+A model consists of some instances.
|
|
|
+These instances are instances of types specified by the model that is the metaclass of the current model.
|
|
|
+
|
|
|
+The structure is as follows::
|
|
|
+
|
|
|
+ SimpleClassDiagrams PetriNets {
|
|
|
+ Class Place {
|
|
|
+ ...
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+Attribute
|
|
|
+^^^^^^^^^
|
|
|
+
|
|
|
+Each model instance can contain attributes.
|
|
|
+There are two kinds of attributes: defining attributes, or value attributes.
|
|
|
+
|
|
|
+For defining attributes, the structure is as follows::
|
|
|
+
|
|
|
+ Class A{
|
|
|
+ my_parameter : ParameterType
|
|
|
+ }
|
|
|
+
|
|
|
+This defines a parameter called *my_parameter* which is typed by *ParameterType*.
|
|
|
+*ParameterType* must always be a type defined in the type that is being instantiated.
|
|
|
+Even if this is a primitive, such as *Integer*, the metamodel must define what it calls an *Integer*.
|
|
|
+While this might seem bothersome, this clearly defines the notion of what a type means, without having to resort to the implementation.
|
|
|
+
|
|
|
+Value attributes are similar, but have a different syntax, and contain an actual value.
|
|
|
+Their structure is as follows::
|
|
|
+
|
|
|
+ A a{
|
|
|
+ my_parameter = 1
|
|
|
+ }
|
|
|
+
|
|
|
+They assign a value to a previously defined attribute.
|
|
|
+In this case, it is important that the value conforms to the type specified in the defining attribute.
|
|
|
+
|
|
|
+Merge with Action Language
|
|
|
+--------------------------
|
|
|
+
|
|
|
+It is of course possible to incorporate action language inside of a model.
|
|
|
+A typical use case for this is the definition of constraints or actions.
|
|
|
+Action language is surrounded by dollar signs ($), which causes the parser to redirect the text between dollar signs to the action language parser.
|
|
|
+All includes necessary for the compilation of the action code, must be provided at the top of the document.
|
|
|
+
|
|
|
+Examples
|
|
|
+--------
|
|
|
+
|
|
|
+Some simple examples of models are provided below.
|
|
|
+This code only makes the specified models available in code; to do something with these models, an algorithms has to read out the model and operate on it.
|
|
|
+
|
|
|
+Petri Net metamodel
|
|
|
+^^^^^^^^^^^^^^^^^^^
|
|
|
+
|
|
|
+A simple Petri Net metamodel can be created, based on the SimpleClassDiagrams metamodel.
|
|
|
+This looks like this::
|
|
|
+
|
|
|
+ import models/SimpleClassDiagrams as SCD
|
|
|
+
|
|
|
+ SCD PetriNets{
|
|
|
+ SimpleAttribute Natural {}
|
|
|
+ Class Place{
|
|
|
+ tokens : Natural
|
|
|
+ }
|
|
|
+ Class Transition{}
|
|
|
+ Association P2T (Place, Transition) {
|
|
|
+ weight : Natural
|
|
|
+ }
|
|
|
+ Association T2P (Transition, Place) {
|
|
|
+ weight : Natural
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ export PetriNets to models/PetriNets
|
|
|
+
|
|
|
+Note that in this metamodel, there is no constraint placed on the value of a Natural: it can literaly be anything.
|
|
|
+That is why usually, you want to place constraints on the value.
|
|
|
+In this case, the value needs to be an integer, and it must be larger than or equal to zero.
|
|
|
+Such constraints are written in the action language, surrounded by dollar signs::
|
|
|
+
|
|
|
+ import models/SimpleClassDiagrams as SCD
|
|
|
+ include "primitives.alh"
|
|
|
+
|
|
|
+ SCD PetriNets{
|
|
|
+ SimpleAttribute Natural {
|
|
|
+ $
|
|
|
+ if (bool_not(is_physical_int(self))):
|
|
|
+ return "Natural has no integer value at " + name!
|
|
|
+ elif (integer_lt(self, 0)):
|
|
|
+ return "Natural does not have a positive or zero value at " + name!
|
|
|
+ else:
|
|
|
+ return "OK"!
|
|
|
+ $
|
|
|
+ }
|
|
|
+ Class Place{
|
|
|
+ tokens : Natural {
|
|
|
+ target_lower_cardinality = 1
|
|
|
+ target_upper_cardinality = 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Class Transition{}
|
|
|
+ Association P2T (Place, Transition) {
|
|
|
+ weight : Natural {
|
|
|
+ target_lower_cardinality = 1
|
|
|
+ target_upper_cardinality = 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Association T2P (Transition, Place) {
|
|
|
+ weight : Natural {
|
|
|
+ target_lower_cardinality = 1
|
|
|
+ target_upper_cardinality = 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+Petri Net instance
|
|
|
+^^^^^^^^^^^^^^^^^^
|
|
|
+
|
|
|
+The previous metamodel can then be instantiated::
|
|
|
+
|
|
|
+ import models/PetriNets as PetriNets
|
|
|
+
|
|
|
+ PetriNets my_petrinet {
|
|
|
+ Place p1 {
|
|
|
+ tokens = 1
|
|
|
+ }
|
|
|
+ Place p2 {
|
|
|
+ tokens = 3
|
|
|
+ }
|
|
|
+ Transition t1 {}
|
|
|
+ P2T (p1, t1) {
|
|
|
+ weight = 1
|
|
|
+ }
|
|
|
+ T2P (t1, p2) {
|
|
|
+ weight = 2
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ export my_petrinet to models/my_petrinet
|
|
|
+
|
|
|
+Use in interactive interface
|
|
|
+----------------------------
|
|
|
+
|
|
|
+The interactive interface, such as the *prompt.py* script, can also invoke the model compiler.
|
|
|
+In this case, however, the import, export, and model type and model name parameters are ignored as they have to be defined and checked in the bigger context of the MvC.
|
|
|
+
|
|
|
+Internal use only
|
|
|
+-----------------
|
|
|
+
|
|
|
+Some constructs only make sense in the context of the bootstrap generation.
|
|
|
+These constructs can still be used at all times, but are meaningless.
|
|
|
+
|
|
|
+Import
|
|
|
+^^^^^^
|
|
|
+
|
|
|
+An import pulls in a model and makes it accessible using a simpler identifier.
|
|
|
+The structure is as follows::
|
|
|
+
|
|
|
+ import path/in/modelverse as my_model
|
|
|
+
|
|
|
+After this import, the model that was previously exported to *path/in/modelverse* becomes available as *my_model*.
|
|
|
+
|