123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- 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 mostly 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.
- Language description
- --------------------
- The modelling language defines data structures, which will be formed as models in the Modelverse.
- Several constructs are supported.
- 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*.
- Include
- ^^^^^^^
- When combined with action language, the action language might require some includes of header files.
- To do this, the includes can be placed at the top of the hierarchy.
- 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.
- 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.
- 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{
- Class 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{
- Class 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
|