Browse Source

Added semantics to the notebook

Yentl Van Tendeloo 3 years ago
parent
commit
5b3e3fc617
2 changed files with 347 additions and 6 deletions
  1. 347 6
      New_MM.ipynb
  2. 0 0
      example_integration.ipynb

+ 347 - 6
New_MM.ipynb

@@ -172,8 +172,8 @@
        " ('State.name', 'String'),\n",
        " ('Transition', 'Association'),\n",
        " ('Transition.name', 'String'),\n",
-       " ('__1049623', 'Class_name'),\n",
-       " ('__1049695', 'Class_name')}"
+       " ('__1049544', 'Class_name'),\n",
+       " ('__1049616', 'Class_name')}"
       ]
      },
      "execution_count": 7,
@@ -193,7 +193,7 @@
     {
      "data": {
       "text/plain": [
-       "'__1054163'"
+       "'__1054084'"
       ]
      },
      "execution_count": 8,
@@ -257,8 +257,8 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "All initial element IDs: {'__1063142'}\n",
-      "All state element IDs: {'__1054163', '__1063142'}\n"
+      "All initial element IDs: {'__1063063'}\n",
+      "All state element IDs: {'__1063063', '__1054084'}\n"
      ]
     }
    ],
@@ -362,7 +362,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Lower cardinality violation for outgoing edge of type State_name at NODE __1054163 (ID: 1054163)\n"
+      "Lower cardinality violation for outgoing edge of type State_name at NODE __1054084 (ID: 1054084)\n"
      ]
     }
    ],
@@ -755,6 +755,347 @@
     "define_attribute(mm, transition, \"script\", al_attr)\n",
     "attribute_optional(mm, transition, \"script\", True)"
    ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Semantics"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "While we have created the syntax of the new language, it should still be possible to define the semantics.\n",
+    "The Modelverse supports three main types of activity, each with their own ideal problem domain."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Manual"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The first type of activity is also the easiest to define, as it is a manual activity.\n",
+    "Many types of activity, or modifications of a model, have to be done manually as they augment information.\n",
+    "For example, refinement is a typical operation that requires a modeller to manually add information to the model.\n",
+    "\n",
+    "For our own defined FSAs, assume that we want to add a *revise* activity, in which the modeller is prompted to modify the model.\n",
+    "While this does not give much information to the Modelverse, it is required, for example, to integrate manual activities in a process model."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "transformation_add_MANUAL({\"FSA\": \"formalisms/MyOwnFSA\"}, {\"FSA\": \"formalisms/MyOwnFSA\"}, \"formalisms/MyOwnFSA_activities/revise\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now we can see it in action.\n",
+    "But as was mentioned, it will take manual operations, in our case through the use of a callback function."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Before:\n",
+      "[]\n",
+      "After:\n",
+      "[{'__id': '__1278360', '__type': 'State', 'name': 'new_state'}]\n"
+     ]
+    }
+   ],
+   "source": [
+    "def callback(model):\n",
+    "    state = instantiate(model, \"FSA/State\")\n",
+    "    attr_assign(model, state, \"name\", \"new_state\")\n",
+    "    \n",
+    "model_add(\"models/my_FSA\", \"formalisms/MyOwnFSA\")\n",
+    "\n",
+    "print(\"Before:\")\n",
+    "print(element_list_nice(\"models/my_FSA\"))\n",
+    "\n",
+    "transformation_execute_MANUAL(\"formalisms/MyOwnFSA_activities/revise\", {\"FSA\": \"models/my_FSA\"}, {\"FSA\": \"models/my_FSA\"}, callback)\n",
+    "\n",
+    "print(\"After:\")\n",
+    "print(element_list_nice(\"models/my_FSA\"))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Action Language"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Another typical execution scenario is for procedural operations to execute.\n",
+    "In the simplest case, this merely calls some action language code with the selected model as a parameter.\n",
+    "Note that this parameter will be a single model, consisting of the merged model and metamodel.\n",
+    "\n",
+    "For our own defined FSAs, assume that we want to add a simple simulation algorithm.\n",
+    "Note the \"return True\" at the end, signifying that the operation was terminated OK and that changes can be propagated."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [],
+   "source": [
+    "transformation_add_AL({\"FSA\": \"formalisms/MyOwnFSA\"}, {}, \"formalisms/MyOwnFSA_activities/simulate\", \"\"\"\n",
+    "include \"primitives.alh\"\n",
+    "include \"modelling.alh\"\n",
+    "include \"object_operations.alh\"\n",
+    "include \"conformance_scd.alh\"\n",
+    "include \"io.alh\"\n",
+    "include \"metamodels.alh\"\n",
+    "include \"mini_modify.alh\"\n",
+    "include \"library.alh\"\n",
+    "\n",
+    "Boolean function main(model : Element):\n",
+    "    String input_value\n",
+    "    Float start_time\n",
+    "    String current_state\n",
+    "    String old_state\n",
+    "    Element transitions\n",
+    "    String transition\n",
+    "\n",
+    "    start_time = time()\n",
+    "\n",
+    "    Element all_states\n",
+    "    String element_name\n",
+    "    all_states = allInstances(model, \"FSA/State\")\n",
+    "    while (set_len(all_states) > 0):\n",
+    "        element_name = set_pop(all_states)\n",
+    "        if (read_type(model, element_name) == \"FSA/InitialState\"):\n",
+    "            current_state = element_name\n",
+    "            old_state = element_name\n",
+    "            break!\n",
+    "\n",
+    "    while (time() - start_time < 10.0):\n",
+    "        if (has_input()):\n",
+    "            input_value = list_read(string_split(input(), \"\\\\n\"), 0)\n",
+    "\n",
+    "            transitions = allOutgoingAssociationInstances(model, current_state, \"FSA/Transition\")\n",
+    "            while (set_len(transitions) > 0):\n",
+    "                transition = set_pop(transitions)\n",
+    "                if (cast_string(read_attribute(model, transition, \"trigger\")) == input_value):\n",
+    "                    if (element_neq(read_attribute(model, transition, \"raise\"), read_root())):\n",
+    "                        log(cast_value(time() - start_time) + \" output \" + cast_string(read_attribute(model, transition, \"raise\")))\n",
+    "                        output(cast_value(time() - start_time) + \" output \" + cast_string(read_attribute(model, transition, \"raise\")))\n",
+    "                    if (element_neq(read_attribute(model, transition, \"script\"), read_root())):\n",
+    "                        Element func\n",
+    "                        func = get_func_AL_model(import_node(read_attribute(model, transition, \"script\")))\n",
+    "                        func()\n",
+    "                    current_state = readAssociationDestination(model, transition)\n",
+    "                    break!\n",
+    "\n",
+    "        log(cast_value(time() - start_time) + \" \" + cast_string(read_attribute(model, current_state, \"name\")))\n",
+    "        sleep(0.2)\n",
+    "    return True!\n",
+    "    \"\"\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now we can see it in action.\n",
+    "For now, we just rely on the end time of the simulation (and no inputs happen), but otherwise we would have to couple it to an SCCD model."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "model_add(\"models/my_FSA\", \"formalisms/MyOwnFSA\", \"\"\"\n",
+    "    InitialState init{\n",
+    "        name = \"initial\"\n",
+    "    }\n",
+    "    State s1{\n",
+    "        name = \"S1\"\n",
+    "    }\n",
+    "    State s2{\n",
+    "        name = \"S2\"\n",
+    "    }\n",
+    "    Transition (init, s1) {\n",
+    "    }\n",
+    "    Transition (s1, s2) {\n",
+    "        trigger = \"A\"\n",
+    "    }\n",
+    "    \"\"\")\n",
+    "transformation_execute_AL(\"formalisms/MyOwnFSA_activities/simulate\", {\"FSA\": \"models/my_FSA\"}, {})"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Model Transformation"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Finally, it is possible to define a model transformation.\n",
+    "This requires RAMification and such, but this is all done transparently by the Modelverse.\n",
+    "Defining a model transformation is therefore identical to defining an Action Language activity, except that now we pass a model of transformations and rules, instead of passing an action language fragment.\n",
+    "\n",
+    "For our defined FSAs, assume that we want to add a simple optimization transformation, removing all states that have no incoming transition."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "transformation_add_MT({\"FSA\": \"formalisms/MyOwnFSA\"}, {\"FSA\": \"formalisms/MyOwnFSA\"}, \"formalisms/MyOwnFSA_activities/optimize\", \"\"\"\n",
+    "include \"primitives.alh\"\n",
+    "include \"modelling.alh\"\n",
+    "include \"object_operations.alh\"\n",
+    "\n",
+    "Composite schedule {\n",
+    "    {Contains} Success success {}\n",
+    "    {Contains} ForAll optimize {\n",
+    "        NAC { \n",
+    "            Pre_FSA/State nac_s_1 {\n",
+    "                label = \"0\"\n",
+    "            }\n",
+    "            Pre_FSA/State nac_s_2 {\n",
+    "                label = \"1\"\n",
+    "            }\n",
+    "            Pre_FSA/Transition nac_s_3 (nac_s_2, nac_s_1) {\n",
+    "                label = \"2\"\n",
+    "            }\n",
+    "        }\n",
+    "        LHS {\n",
+    "            Pre_FSA/State pre_s_1 {\n",
+    "                label = \"0\"\n",
+    "                constraint = $\n",
+    "                    Boolean function not_initial(model : Element, name : String):\n",
+    "                        if (read_type(model, name) == \"FSA/InitialState\"):\n",
+    "                            return False!\n",
+    "                        else:\n",
+    "                            return True!\n",
+    "                $\n",
+    "            }\n",
+    "        }\n",
+    "        RHS {\n",
+    "        }\n",
+    "    }    \n",
+    "}\n",
+    "\n",
+    "Initial (schedule, optimize) {}\n",
+    "OnSuccess (optimize, optimize) {}\n",
+    "OnFailure (optimize, success) {}\n",
+    "    \"\"\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now we can see it in action."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Before:\n",
+      "[{'__id': 'a', '__type': 'InitialState', 'name': 'A'}, {'__id': 'b', '__type': 'State', 'name': 'B'}, {'__id': 'c', '__type': 'State', 'name': 'C'}, {'__id': '__0', '__type': 'Transition', '__source': 'a', '__target': 'b', 'trigger': None, 'raise': None, 'script': {'AL': ''}}]\n",
+      "After:\n",
+      "[{'__id': 'a', '__type': 'InitialState', 'name': 'A'}, {'__id': 'b', '__type': 'State', 'name': 'B'}, {'__id': '__0', '__type': 'Transition', '__source': 'a', '__target': 'b', 'trigger': None, 'raise': None, 'script': {'AL': ''}}]\n"
+     ]
+    }
+   ],
+   "source": [
+    "model_add(\"models/my_FSA\", \"formalisms/MyOwnFSA\", \"\"\"\n",
+    "    InitialState a {\n",
+    "        name = \"A\"\n",
+    "    }\n",
+    "    State b {\n",
+    "        name = \"B\"\n",
+    "    }\n",
+    "    State c {\n",
+    "        name = \"C\"\n",
+    "    }\n",
+    "    Transition (a, b) {}\n",
+    "\"\"\")\n",
+    "\n",
+    "print(\"Before:\")\n",
+    "print(all_instances(\"models/my_FSA\", \"State\"))\n",
+    "\n",
+    "transformation_execute_MT(\"formalisms/MyOwnFSA_activities/optimize\", {\"FSA\": \"models/my_FSA\"}, {\"FSA\": \"models/my_FSA\"})\n",
+    "\n",
+    "print(\"After:\")\n",
+    "print(all_instances(\"models/my_FSA\", \"State\"))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Traceability Links"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "It is often useful to have multiple metamodels that integrate with one another.\n",
+    "For example, when defining denotational semantics, we might want to create traceability links between both formalisms.\n",
+    "As in the Modelverse everything must be explicitly modelled, these links should also follow the usual modelling conventions.\n",
+    "That is, the links must have a type defined.\n",
+    "For that purpose, the Modelverse create a *merged* metamodel on which the activities actually occur.\n",
+    "It is possible to define a callback in each of the *transformation_add_* operations, which are then able to alter this merged metamodel.\n",
+    "Such alterations can, for example, include adding a traceability link between elements from different origining metamodels.\n",
+    "For more details, refer to the documentation."
+   ]
   }
  ],
  "metadata": {

tutorial.ipynb → example_integration.ipynb