Browse Source

Add model transformations to the Python API

Yentl Van Tendeloo 8 years ago
parent
commit
2762a48807
5 changed files with 124 additions and 13 deletions
  1. 5 3
      core/core_algorithm.alc
  2. 4 4
      core/mini_modify.alc
  3. 63 0
      models/my_pn.mvc
  4. 2 2
      models/reachabilitygraph_print.mvc
  5. 50 4
      wrappers/modelverse.py

+ 5 - 3
core/core_algorithm.alc

@@ -1067,13 +1067,15 @@ String function cmd_transformation_execute(user_id : String, transformation_name
 					output("Success: ready for AL execution")
 				elif (read_type(core, transformation_id) == "ManualOperation"):
 					output("Success: ready for MANUAL execution")
+				else:
+					output("Success: ready for MT execution")
 
 				result = execute_operation(transformation_id, inputs, dict_keys(outputs), read_root())
 
 				// Now write out the models again
 				if (element_eq(result, read_root())):
 					// Something went wrong!
-					return "Transformation failed: " + transformation_name!
+					return "Failure"!
 				else:
 					keys = dict_keys(result)
 					while (read_nr_out(keys) > 0):
@@ -1202,7 +1204,6 @@ String function cmd_transformation_add_MT_language(user_id : String, model_names
 	Element all_formalisms
 	Element merged_formalism
 	Element ramified_formalism
-	String old_type_id
 	String type_id
 	String location
 	String new_model_id
@@ -1216,6 +1217,7 @@ String function cmd_transformation_add_MT_language(user_id : String, model_names
 		if (model_id != ""):
 			if (allow_read(user_id, model_id)):
 				type_name = read_attribute(core, set_pop(allAssociationDestinations(core, model_id, "instanceOf")), "name")
+				type_id = get_model_id(type_name)
 				if (type_name != "SimpleClassDiagrams"):
 					return "Can only RAMify models of type SimpleClassDiagrams"!
 				else:
@@ -1833,7 +1835,7 @@ Void function user_function_skip_init(user_id : String):
 		elif (cmd == "model_list_full"):
 			output(cmd_model_list_full())
 		elif (cmd == "transformation_add_MT_language"):
-			output(cmd_transformation_add_MT_language(user_id, set_input("Model names?"), single_input("RAMified metamodel name?")))
+			output(cmd_transformation_add_MT_language(user_id, set_input("Metamodel names?"), single_input("RAMified metamodel name?")))
 		elif (cmd == "transformation_RAMify"):
 			output(cmd_transformation_RAMify(user_id, single_input("Metamodel name?"), single_input("Target metamodel name?")))
 		elif (cmd == "transformation_add_MANUAL"):

+ 4 - 4
core/mini_modify.alc

@@ -381,17 +381,18 @@ Element function modify(model : Element, write : Boolean):
 String function single_input(prompt : String):
 	if (verbose):
 		output(prompt)
+
 	return input()!
 
 Element function set_input(prompt : String):
 	Element result
+	Element inp
 
-	result = create_node()
 	if (verbose):
 		output(prompt)
 		output("-- Set input: empty string to terminate set")
 
-	Element inp
+	result = create_node()
 	while (True):
 		inp = input()
 		if (value_eq(inp, "")):
@@ -402,13 +403,12 @@ Element function set_input(prompt : String):
 Element function dict_input(prompt : String):
 	Element result
 	Element key
-	
-	result = create_node()
 
 	if (verbose):
 		output(prompt)
 		output("-- Dict input: empty key to terminate dict")
 
+	result = create_node()
 	while (True):
 		key = input()
 		if (value_eq(key, "")):

+ 63 - 0
models/my_pn.mvc

@@ -0,0 +1,63 @@
+import models/PetriNets_Design as PetriNets
+
+PetriNets pn {
+    Place critical_section_1 {
+        tokens = 0
+        name = "critical_section_1"
+    }
+    Place critical_section_2 {
+        tokens = 0
+        name = "critical_section_2"
+    }
+    Place lock_available {
+        tokens = 1
+        name = "lock_available"
+    }
+
+    Transition release_section_1 {
+        name = "release_section_1"
+    }
+    Transition release_section_2 {
+        name = "release_section_2"
+    }
+    Transition acquire_section_1 {
+        name = "acquire_section_1"
+    }
+    Transition acquire_section_2 {
+        name = "acquire_section_2"
+    }
+
+    P2T (critical_section_1, release_section_1) {
+        weight = 1
+    }
+
+    P2T (critical_section_2, release_section_2) {
+        weight = 1
+    }
+
+    P2T (lock_available, acquire_section_1) {
+        weight = 1
+    }
+
+    P2T (lock_available, acquire_section_2) {
+        weight = 1
+    }
+
+    T2P (release_section_1, lock_available) {
+        weight = 1
+    }
+
+    T2P (release_section_2, lock_available) {
+        weight = 1
+    }
+
+    T2P (acquire_section_1, critical_section_1) {
+        weight = 1
+    }
+
+    T2P (acquire_section_2, critical_section_2) {
+        weight = 1
+    }
+}
+
+export pn to models/pn

+ 2 - 2
models/reachabilitygraph_print.mvc

@@ -25,7 +25,7 @@ ReachabilityGraph_RAM reachabilitygraph_print {
                             while (read_nr_out(all_values) > 0):
                                 place = set_pop(all_values)
                                 dict_add(dict_values, read_attribute(model, place, "name"), read_attribute(model, place, "tokens"))
-                            log((cast_v2s(read_attribute(model, name, "name")) + ": ") + dict_to_string(dict_values))
+                            output((cast_v2s(read_attribute(model, name, "name")) + ": ") + dict_to_string(dict_values))
                             return!
                         $
                 }
@@ -55,7 +55,7 @@ ReachabilityGraph_RAM reachabilitygraph_print {
                     label = "2"
                     action = $
                         Void function action(model : Element, name : String, mapping : Element):
-                            log((((cast_v2s(read_attribute(model, mapping["0"], "name")) + " --[") + cast_v2s(read_attribute(model, name, "name"))) + "]--> ") + cast_v2s(read_attribute(model, mapping["1"], "name")))
+                            output((((cast_v2s(read_attribute(model, mapping["0"], "name")) + " --[") + cast_v2s(read_attribute(model, name, "name"))) + "]--> ") + cast_v2s(read_attribute(model, mapping["1"], "name")))
                             return!
                         $
                 }

+ 50 - 4
wrappers/modelverse.py

@@ -366,13 +366,30 @@ def transformation_between(source, target):
         return []
     lst = [v for v in output.split("\n")]
 
-def transformation_add_MT_language():
+def transformation_add_MT_language(metamodels, RAMified_name):
     """Create a new Model Transformation language out of a set of metamodels."""
-    raise NotImplementedError()
+    global mode
+    if mode != 2:
+        raise InvalidMode()
+
+    _input(["transformation_add_MT_language"] + metamodels + ["", RAMified_name])
+    _handle_output("Success")
 
-def transformation_add_MT():
+def transformation_add_MT(RAMified_metamodel, source_metamodels, target_metamodels, operation_name, code):
     """Create a new model transformation."""
-    raise NotImplementedError()
+    global mode
+    if mode != 2:
+        raise InvalidMode()
+
+    try:
+        compiled = _compile_model(code)
+    except Exception as e:
+        raise CompilationError(e)
+
+    _input(["transformation_add_MT", RAMified_metamodel] + source_metamodels + [""] + target_metamodels + ["", operation_name])
+    _handle_output("Waiting for model constructors...")
+    _input(compiled)
+    _handle_output("Success")
 
 def transformation_add_AL(source_metamodels, target_metamodels, operation_name, code):
     """Create a new action language model, which can be executed."""
@@ -423,6 +440,35 @@ def transformation_execute_AL(operation_name, input_models_dict, output_models_d
     else:
         return False
 
+def transformation_execute_MT(operation_name, input_models_dict, output_models_dict, callback=lambda i: None):
+    """Execute an existing model operation."""
+    global mode
+    if mode != 2:
+        raise InvalidMode()
+
+    mv_dict_rep = []
+    for key, value in input_models_dict.items():
+        mv_dict_rep += [key, value]
+    mv_dict_rep += [""]
+    for key, value in output_models_dict.items():
+        mv_dict_rep += [key, value]
+    mv_dict_rep += [""]
+
+    _input(["transformation_execute", operation_name] + mv_dict_rep)
+    _handle_output("Success: ready for MT execution")
+
+    # We are now executing, so everything we get is part of the dialog, except if it is the string for transformation termination
+    while _output() not in ["Success", "Failure"]:
+        reply = callback(_last_output())
+        if reply is not None:
+            _input(reply)
+
+    # Got termination message, so we are done!
+    if _last_output() == "Success":
+        return True
+    else:
+        return False
+
 def transformation_list():
     """List existing model operations."""
     raise NotImplementedError()