123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- 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 models.
- All models have the extension \*.mvc, indicating that they are models and should be compiled as such.
- There is no constraint that this extension is mandatory.
- First, we show an example on how to create a simple PetriNet model.
- To take into account action language in the example model, we will also show an example for Finite State Automata afterwards.
- Example: Petri Nets
- -------------------
- Creating a simple Petri Net is easy using the Modelverse modelling language.
- An example is given below, which contains some places and transitions, with some connections between them::
- Place p1 {
- name = "place 1"
- tokens = 1
- }
- Place p2 {
- name = "place 2"
- tokens = 2
- }
- Transition t1 {
- name = "transition"
- }
- P2T p2t (p1, t1) {
- weight = 1
- }
- T2P t2p (t1, p2) {
- weight = 2
- }
- The name immediately after the type (e.g., *p1*), is the identifier used throughout the textual representation.
- All identification of the element at the model-level should happen based on defined attributes.
- The identifiers can also be overwritten internally, in which case the latest definition is used.
- Do note that there is no concept of scope here, so identifiers stay visible throughout the whole file.
- It is possible to have anonymous identifiers, but only if the identifier is not used in the remainder of the file (e.g., not the source of an association).
- For example, the two arcs could just as well have been defined as follows ::
- P2T (p1, t1) {
- weight = 1
- }
- T2P (t1, p2) {
- weight = 2
- }
- Example: Finite State Automata
- ------------------------------
- Next we use a simple Finite State Automata example model.
- This will introduce some new concepts: hierarchy, long strings, and code attributes.
- Hierarchy
- ^^^^^^^^^
- The Modelverse does not natively support a notion of hierarchy, but its modelling language can easily be used to represent hierarchy.
- Models can be indented, which means that a link is created from the container to the containee.
- If only one link type is allowed between both, the type is automatically selected.
- If multiple link types are possible, it is ambiguous and the model will fail to compile.
- For example, if we consider a hierarchical state::
- CompositeState s1 {
- name = "state 1"
- CompositeState s2 {
- name = "state 2"
- State s3 {
- name = "state 3"
- }
- }
- }
- State s4 {
- name = "state 4"
- }
- When the only allowed links between a *CompositeState* and any other state is this, the model will compile fine as it is.
- However, we also want to define transitions, which can go from a *CompositeState* to a normal *State* as well.
- As such, we must update the model as follows, specifying the association type::
- CompositeState s1 {
- name = "state 1"
- {Contains} CompositeState s2 {
- name = "state 2"
- {Contains} State s3 {
- name = "state 3"
- }
- }
- }
- State s4 {
- name = "state 4"
- }
- As there is no difference between *Contains* and *Transition*, there is nothing that prevents you from creating something like::
- State s1 {
- name = "state 1"
- {Transition} State {
- name = "state 2"
- }
- {Contains} State {
- name = "state 3"
- }
- }
- In this case, the state *state 1* and *state 2* are actually at the same level, with a transition between them.
- This can get rather confusing, and is therefore discouraged.
- Long string attributes
- ^^^^^^^^^^^^^^^^^^^^^^
- Sometimes longer string values are required in attributes, for example as code blocks or descriptions of elements.
- In this case, three double quotes are used to delimit this string, similar to Python.
- Note that an ordinary double quote is not allowed within this long string attribute, due to limitations of the parser::
- State s1 {
- description = """
- This is a lenghty description of the state.
- In this state, the execution will start.
- """
- }
- Code
- ^^^^
- Using code in the model definition is easy, and merely requires the use of the $ symbol around the text, instead of the usual " symbols.
- For example, to define a Transition with an action::
- State s1 {
- name = "state 1"
- }
- State s2 {
- name = "state 2"
- }
- Transition (s1, s2) {
- action = $
- include "primitives.alh"
- Void function action(model : Element):
- log("Test!")
- return !
- $
- }
- In this case, it is impossible to use code defined externally.
- All code between $ symbols is passed on as-is to the action language compiler.
- Note the import statements, which will likely be repeated in each and every code block.
- It is possible to define include statements at the top of the model, in which case the include is automatically prepended in each and every code block::
- include "primitives.alh"
- State s1 {
- name = "state 1"
- }
- State s2 {
- name = "state 2"
- }
- Transition (s1, s2) {
- action = $
- Void function action(model : Element):
- log("Test!")
- return !
- $
- }
- As mentioned before, the Action Language does not allow for subfunctions, but it is possible for there to be multiple functions between the dollar tags.
- In that case, the function with name *main* is executed first, or, if no such function exists, the topmost function is chosen.
- Using the Model Representation
- ------------------------------
- The question remains how to use this model representation with the Modelverse.
- The *model_add* operation can be extended with an additional parameter, specifying a textual model.
- It will then create a new model and initialize it with the model specified textually::
- >>> model_add("models/my_pn", "formalisms/PetriNets", open("my_pn.mvc", "r").read())
- Another function that can be used, is the *model_overwrite* function, which overwrites an existing model with the content of the provided textual model::
- >>> model_overwrite("models/my_pn", "formalisms/PetriNets", open("my_pn.mvc", "r").read())
|