Browse Source

Added test for add_MT_language operation

Yentl Van Tendeloo 8 years ago
parent
commit
1b746a08c4

BIN
bootstrap/bootstrap.m.gz


+ 1 - 2
bootstrap/model_management.alc

@@ -15,12 +15,11 @@ Element function model_fuse(models : Element):
 	String key
 	Element selected_MM
 	String type
-	Element models
 
 	// Read out some data first
 	tagged_model = set_pop(models)
 	set_add(models, tagged_model)
-	new_model = instantiate_model(tagged_model[1])
+	new_model = instantiate_model(tagged_model[1]["metamodel"])
 
 	// Do the iteration
 	while (read_nr_out(models)):

+ 31 - 55
core/core_algorithm.alc

@@ -295,7 +295,6 @@ Void function user_function_skip_init(user_id : String):
 	while (do_continue):
 		output("Ready for command...")
 		cmd = input()
-		log("EXECED " + cmd)
 		if (cmd == "help"):
 			output("Model operations")
 			output("    model_add                       -- Add a new model")
@@ -597,11 +596,10 @@ Void function user_function_skip_init(user_id : String):
 			String location
 			String new_model_id
 
-			source = create_node()
-			target = create_node()
 			old_type_id = ""
 
 			// Read involved formalisms
+			all_formalisms = create_node()
 			output("Formalisms to include (terminate with empty string)?")
 			name = input()
 			while (name != ""):
@@ -623,61 +621,39 @@ Void function user_function_skip_init(user_id : String):
 				name = input()
 
 			// Merge both into a single metamodel
-			if (read_nr_out(source) > 0):
-				if (read_nr_out(target) > 0):
-					output("Name of the RAMified tranformation metamodel?")
-					name = input()
-					if (get_model_id(name) == ""):
-						String merged_formalism_id
-						String ramified_formalism_id
-						String source_formalism_id
-						String tracability_link
-
-						// New location is available, so write
-						merged_formalism = model_fuse(all_formalisms)
-
-						location = "/models/" + cast_id2s(merged_formalism)
-						export_node(location, merged_formalism)
-
-						// Manage meta-info
-						new_model_id = instantiate_node(core, "Model", "")
-						merged_formalism_id = new_model_id
-						instantiate_attribute(core, new_model_id, "name", "__merged_" + name)
-						instantiate_attribute(core, new_model_id, "location", location)
-						instantiate_attribute(core, new_model_id, "permissions", "200")
-						instantiate_link(core, "owner", "", new_model_id, user_id)
-						instantiate_link(core, "instanceOf", "", new_model_id, type_id)
-
-						// Add tracability links at this level
-						while (read_nr_out(all_formalisms) > 0):
-							source_formalism_id = list_read(set_pop(all_formalisms), 1)
-							tracability_link = instantiate_link(core, "tracability", "", merged_formalism_id, source_formalism_id)
-							instantiate_attribute(core, tracability_link, "type", "merged")
-
-						// Merge complete, now RAMify!
-						ramified_formalism = ramify(merged_formalism)
-
-						location = "/models/" + cast_id2s(ramified_formalism)
-						export_node(location, ramified_formalism)
-
-						// Manage meta-info
-						new_model_id = instantiate_node(core, "Model", "")
-						instantiate_attribute(core, new_model_id, "name", name)
-						instantiate_attribute(core, new_model_id, "location", location)
-						instantiate_attribute(core, new_model_id, "permissions", "200")
-						instantiate_link(core, "owner", "", new_model_id, user_id)
-						instantiate_link(core, "instanceOf", "", new_model_id, type_id)
-
-						// Add tracability link at this level
-						tracability_link = instantiate_link(core, "tracability", "", ramified_formalism_id, merged_formalism_id)
-						instantiate_attribute(core, tracability_link, "type", "RAMified")
+			if (read_nr_out(all_formalisms) > 0):
+				output("Name of the RAMified transformation metamodel?")
+				name = input()
+				if (get_model_id(name) == ""):
+					String merged_formalism_id
+					String ramified_formalism_id
+					String source_formalism_id
+					String tracability_link
+
+					// New location is available, so write
+					merged_formalism = model_fuse(all_formalisms)
+					model_create(merged_formalism, "__merged_" + name, user_id, type_id)
+					merged_formalism_id = get_model_id("__merged_" + name)
+
+					// Add tracability links at this level
+					while (read_nr_out(all_formalisms) > 0):
+						source_formalism_id = list_read(set_pop(all_formalisms), 1)
+						tracability_link = instantiate_link(core, "tracability", "", merged_formalism_id, source_formalism_id)
+						instantiate_attribute(core, tracability_link, "type", "merged")
+
+					// Merge complete, now RAMify!
+					ramified_formalism = ramify(merged_formalism)
+					model_create(ramified_formalism, name, user_id, type_id)
+					ramified_formalism_id = get_model_id(name)
+
+					// Add tracability link at this level
+					tracability_link = instantiate_link(core, "tracability", "", ramified_formalism_id, merged_formalism_id)
+					instantiate_attribute(core, tracability_link, "type", "RAMified")
 
-					else:
-						output("Model already exists!")
 				else:
-					output("At least one target formalism is required")
+					output("Model already exists!")
 			else:
-				output("At least one source formalism is required")
+				output("At least one formalism is required")
 
 		elif (cmd == "transformation_reRAMify"):
 			String model_id

+ 1 - 5
integration/code/petrinets.mvc

@@ -1,6 +1,4 @@
-import models/SimpleClassDiagrams as SCD
-
-SCD PetriNets{
+SimpleClassDiagrams PetriNets{
     Class Natural {}
     Class Place{
         tokens : Natural
@@ -13,5 +11,3 @@ SCD PetriNets{
         weight : Natural
     }
 }
-
-export PetriNets to models/PetriNets

+ 46 - 1
integration/test_mvc.py

@@ -1,6 +1,6 @@
 import unittest
 
-from utils import run_file, get_constructor, get_model_constructor
+from utils import run_file, get_constructor, get_raw_model_constructor
 
 all_files = [   "core/mini_modify.alc",
                 "core/core_formalism.mvc",
@@ -231,3 +231,48 @@ class TestModelverseCore(unittest.TestCase):
                 "Ready for command...",
             ],
             mode))
+
+    def test_po_transform_add_MT_language(self):
+        self.transform_add_MT_language("PO")
+
+    def transform_add_MT_language(self, mode):
+        self.assertTrue(run_file(all_files,
+            [ "root",
+                "model_add",
+                "SimpleClassDiagrams",
+                "PetriNets",
+                ] + get_raw_model_constructor(open("integration/code/petrinets.mvc", "r").read()) + [
+                "model_list_full",
+                "transformation_add_MT_language",
+                "PetriNets",
+                "",
+                "PetriNets_RAM",
+                "model_list_full",
+            ],
+            [   "Desired username for admin user?",
+                "Welcome to the Model Management Interface v2.0!",
+                "Use the 'help' command for a list of possible commands",
+                "Ready for command...",
+                "Creating new model!",
+                "Model type?",
+                "Model name?",
+                "Waiting for model constructors...",
+                "Model upload success!",
+                "Ready for command...",
+                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin    86   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody    14   PetriNets : SimpleClassDiagrams",
+                     "  200  root admin    53   core : CoreFormalism"]),
+                "Ready for command...",
+                "Formalisms to include (terminate with empty string)?",
+                "Name of the RAMified transformation metamodel?",
+                "Ready for command...",
+                set(["  221  root admin    673   SimpleClassDiagrams : SimpleClassDiagrams",
+                     "  221  root admin    86   CoreFormalism : SimpleClassDiagrams",
+                     "  200  root nobody    14   PetriNets : SimpleClassDiagrams",
+                     "  200  root nobody    14   __merged_PetriNets_RAM : SimpleClassDiagrams",
+                     "  200  root nobody    328   PetriNets_RAM : SimpleClassDiagrams",
+                     "  200  root admin    76   core : CoreFormalism"]),
+                "Ready for command...",
+            ],
+            mode))

+ 18 - 1
integration/utils.py

@@ -299,6 +299,23 @@ def get_model_constructor(code):
         f.write(code)
         f.flush()
 
-    constructors = ["upload"] + do_compile("__model.mvc", "interface/HUTN/grammars/modelling.g", "M") + ["exit"]
+    constructors = do_compile("__model.mvc", "interface/HUTN/grammars/modelling.g", "M") + ["exit"]
+
+    return constructors
+
+def get_raw_model_constructor(code):
+    # First change multiple spaces to a tab
+    code_fragments = code.split("\n")
+    code_fragments = [i for i in code_fragments if i.strip() != ""]
+    code_fragments = [i.replace("    ", "\t") for i in code_fragments]
+    initial_tabs = min([len(i) - len(i.lstrip("\t")) for i in code_fragments])
+    code_fragments = [i[initial_tabs:] for i in code_fragments]
+    code = "\n".join(code_fragments)
+
+    with open("__model.mvc", "w") as f:
+        f.write(code)
+        f.flush()
+
+    constructors = do_compile("__model.mvc", "interface/HUTN/grammars/modelling_raw.g", "MR") + ["exit"]
 
     return constructors

+ 50 - 0
interface/HUTN/grammars/modelling_raw.g

@@ -0,0 +1,50 @@
+grammar{
+    start: (include_files | model | NEWLINE)+;
+
+    include_files: INCLUDE STRVALUE NEWLINE;
+
+    model: MODEL_ID MODEL_ID NEWLINE? LCURLY NEWLINE? (model_element)* RCURLY;
+
+    model_element: MODEL_ID MODEL_ID? inheritance? (LPAR MODEL_ID COMMA MODEL_ID RPAR)? NEWLINE? LCURLY NEWLINE? (model_attribute)* RCURLY NEWLINE?;
+
+    inheritance: COLON MODEL_ID (COMMA MODEL_ID)*;
+
+    model_attribute : ((LCURLY MODEL_ID RCURLY)? model_element)
+                    | (MODEL_ID COLON MODEL_ID (LCURLY NEWLINE? model_attr_instance* RCURLY)? NEWLINE?)
+                    | (model_attr_instance)
+                    | (NEWLINE? DOLLAR ANYTHING_EXCEPT_DOLLAR DOLLAR NEWLINE?);
+
+    model_attr_instance: (MODEL_ID ASSIGN value NEWLINE?)
+                       | (MODEL_ID ASSIGN NEWLINE? DOLLAR ANYTHING_EXCEPT_DOLLAR DOLLAR NEWLINE?);
+
+    value
+        : DEC_NUMBER
+        | FLOAT_NUMBER
+        | TRUE
+        | FALSE
+        | STRVALUE;
+
+    tokens{
+        MODEL_ID: '[a-zA-Z_][a-zA-Z_0-9]*';
+        MV_URL: '[a-zA-Z_0-9/]*';
+        LCURLY: '{';
+        RCURLY: '}';
+        NEWLINE: '(\r?\n)+';
+        DEC_NUMBER: '[+-]?(0|[1-9]\d*[lL]?)';
+        FLOAT_NUMBER: '[+-]?((\d+\.\d*|\.\d+)([eE][-+]?\d+)?|\d+[eE][-+]?\d+)';
+        STRVALUE: 'u?r?("(?!"").*?(?<!\\)(\\\\)*?"|\'(?!\'\').*?(?<!\\)(\\\\)*?\')';
+        TRUE: 'True';
+        FALSE: 'False';
+        ASSIGN: '=';
+        DOLLAR: '\$';
+        WS: '[ ]+' @Impl;
+        TAB: '[\t]+' @Impl;
+        COLON : ':';
+        LPAR: '\(';
+        RPAR: '\)';
+        COMMA: ',';
+        ANYTHING_EXCEPT_DOLLAR: '[^$]*';
+        INCLUDE: 'include';
+        EXCLAMATION: '!';
+    }
+}

+ 2 - 0
interface/HUTN/hutn_compiler/compiler.py

@@ -146,6 +146,7 @@ def main(input_file, grammar_file, mode, args=[], symbols=None):
     from constructors_object_visitor import ConstructorsObjectVisitor
     from model_visitor import ModelVisitor
     from model_object_visitor import ModelObjectVisitor
+    from model_raw_visitor import ModelRawVisitor
 
     modes = {
         "N" : [],
@@ -159,6 +160,7 @@ def main(input_file, grammar_file, mode, args=[], symbols=None):
         "CO" : [SemanticsVisitor, ConstructorsObjectVisitor],
         "M" : [ModelVisitor],
         "MO" : [ModelObjectVisitor],
+        "MR" : [ModelRawVisitor],
     }
     try:
         visitors = [v(args) for v in modes[mode]]

+ 161 - 0
interface/HUTN/hutn_compiler/model_raw_visitor.py

@@ -0,0 +1,161 @@
+from visitor import Visitor
+from compiler import main as do_compile
+import os
+
+def empty(s):
+    return None
+
+class ModelRawVisitor(Visitor):
+    def __init__(self, args):
+        Visitor.__init__(self, args)
+        self.constructors = []
+        self.free_id = 0
+        self.name_maps = {}
+        self.current_model = None
+        self.current_element = []
+        self.includes = []
+
+    def dump(self):
+        return self.constructors
+
+    def __getattr__(self, attr):
+        if attr.startswith("visit_"):
+            return empty
+        else:
+            raise AttributeError()
+
+    def visit_start(self, tree):
+        for t in tree.get_tail():
+            self.visit(t)
+
+    def visit_include_files(self, tree):
+        self.includes.append(tree.get_children("STRVALUE")[0].get_text())
+
+    def visit_model(self, tree):
+        children = tree.get_children("MODEL_ID")
+        model_type = children[0].get_text()
+        model_name = children[-1].get_text()
+        self.current_model = model_name
+        for element in tree.get_children("model_element"):
+            self.visit(element)
+
+    def visit_model_element(self, tree):
+        children = tree.get_children("MODEL_ID")
+        element_type = children[0].get_text()
+        if len(children) == 2 or len(children) == 4:
+            element_name = children[1].get_text()
+        else:
+            element_name = "__%s" % self.free_id
+            self.free_id += 1
+
+        if len(children) > 2:
+            # So we have a source and target; but aren't sure which is which, because the name is optional!
+            source_name = children[-2].get_text()
+            target_name = children[-1].get_text()
+            self.constructors.extend(["instantiate_link", element_type, element_name, source_name, target_name])
+        else:
+            self.constructors.extend(["instantiate_node", element_type, element_name])
+
+        self.current_element.append(element_name)
+
+        if tree.get_children("inheritance"):
+            self.visit(tree.get_children("inheritance")[0])
+            
+        for attr in tree.get_children("model_attribute"):
+            self.visit(attr)
+
+        self.current_element.pop()
+
+        return element_name
+
+    def visit_inheritance(self, tree):
+        for token in tree.get_children("MODEL_ID"):
+            superclass = token.get_text()
+            self.constructors.extend(["instantiate_link", "Inheritance", "%s_inherits_from_%s" % (self.current_element[-1], superclass), self.current_element[-1], superclass])
+
+    def visit_model_attribute(self, tree):
+        children = tree.get_children("MODEL_ID")
+        is_definition = bool(tree.get_children("COLON"))
+        is_constraint = bool(tree.get_children("DOLLAR"))
+        is_assign = bool(tree.get_children("model_attr_instance"))
+        is_nested = bool(tree.get_children("model_element"))
+
+        if is_definition:
+            attr_name = children[0].get_text()
+            attr_type = children[1].get_text()
+            self.constructors.extend(["instantiate_link", "Association", self.current_element[-1] + "_" + attr_name, self.current_element[-1], attr_type])
+            full_attribute_name = self.current_element[-1] + "_" + attr_name
+            self.constructors.extend(["instantiate_attribute", full_attribute_name, "name", attr_name])
+            if is_assign:
+                # There are also some attributes to set!
+                self.current_element.append(full_attribute_name)
+
+                for f in tree.get_children("model_attr_instance"):
+                    self.visit(f)
+
+                self.current_element.pop()
+        elif is_assign:
+            self.visit(tree.get_children("model_attr_instance")[0])
+        elif is_constraint:
+            constraint = tree.get_children("ANYTHING_EXCEPT_DOLLAR")[0].get_text()
+            whitespaces = len(constraint) - len(constraint.lstrip())
+            constraint = "\n".join(["\t" + line[whitespaces-1:].replace("    ", "\t") for line in constraint.split("\n") if len(line.strip()) != 0])
+            constraint = "".join(["include %s\n" % i for i in self.includes]) + \
+                         "String function constraint(model : Element, name : String):\n" + \
+                         "\tElement self\n" + \
+                         '\tself = model["model"][name]\n' + \
+                         constraint + "\n"
+            with open(".constraint.alc", 'w') as f:
+                f.write(constraint)
+                f.flush()
+            directory = os.path.realpath(__file__).rsplit(os.sep, 1)[0]
+            compiled = do_compile(".constraint.alc", directory + "/../grammars/actionlanguage.g", "CS")
+            self.constructors.extend(["add_constraint", self.current_element[-1]] + compiled)
+        elif is_nested:
+            if tree.get_children("MODEL_ID"):
+                contains_link = tree.get_children("MODEL_ID")[0].get_text()
+            else:
+                contains_link = ""
+            entry = self.visit(tree.get_children("model_element")[0])
+            self.constructors.extend(["instantiate_link", contains_link, "__%s" % self.free_id, self.current_element[-1], entry])
+            self.free_id += 1
+
+    def visit_model_attr_instance(self, tree):
+        def constructors_compile(code):
+            code_fragments = code.split("\n")
+	    code_fragments = [i for i in code_fragments if i.strip() != ""]
+	    code_fragments = [i.replace("    ", "\t") for i in code_fragments]
+	    initial_tabs = min([len(i) - len(i.lstrip("\t")) for i in code_fragments])
+	    code_fragments = [i[initial_tabs:] for i in code_fragments]
+	    code = "\n".join(code_fragments)
+            code += "\n"
+
+            with open(".code.alc", 'w') as f:
+                f.write(code)
+                f.flush()
+            directory = os.path.realpath(__file__).rsplit(os.sep, 1)[0]
+            compiled = do_compile(".code.alc", directory + "/../grammars/actionlanguage.g", "CS")
+            return compiled
+
+        children = tree.get_children("MODEL_ID")
+        attr_name = children[0].get_text()
+        if tree.get_children("value"):
+            # Value attribute
+            attr_value = tree.get_children("value")[0].get_tail()[0]
+            if attr_value.head == "STRVALUE":
+                attr_value = attr_value.get_text()[1:-1]
+            elif attr_value.head == "TRUE":
+                attr_value = True
+            elif attr_value.head == "FALSE":
+                attr_value = False
+            elif attr_value.head == "DEC_NUMBER":
+                attr_value = int(attr_value.get_text())
+            elif attr_value.head == "FLOAT_NUMBER":
+                attr_value = float(attr_value.get_text())
+            else:
+                raise Exception(attr_value.head)
+            self.constructors.extend(["instantiate_attribute", self.current_element[-1], attr_name, attr_value])
+        elif tree.get_children("DOLLAR"):
+            # Coded attribute
+            self.constructors.extend(["instantiate_attribute_code", self.current_element[-1], attr_name])
+            self.constructors.extend(constructors_compile(tree.get_children("ANYTHING_EXCEPT_DOLLAR")[0].get_text()))

+ 2 - 0
kernel/modelverse_kernel/compiled.py

@@ -326,6 +326,8 @@ def get_superclasses(a, b, **remainder):
                     src, dst = srcdst
                     # Find elem in elems
                     worklist.append(dst)
+                    if dst is None:
+                        print("Read edge gives error for edge: " + str(elem))
 
     raise PrimitiveFinished(result)