Browse Source

Patched change in model_types semantics

Yentl Van Tendeloo 7 years ago
parent
commit
9593768dcf

+ 18 - 1
bootstrap/semi_primitives.alc

@@ -420,7 +420,7 @@ String function reverseKeyLookup(dict : Element, element : Element):
 	
 	
 	return ""!
 	return ""!
 
 
-Element function reverseKeyLookupMulti(dict : Element, element : Element):
+Element function reverseKeyLookupMultiValue(dict : Element, element : Element):
 	Integer nr_out
 	Integer nr_out
 	Integer counter
 	Integer counter
 	Element link
 	Element link
@@ -437,6 +437,23 @@ Element function reverseKeyLookupMulti(dict : Element, element : Element):
 	
 	
 	return result!
 	return result!
 
 
+Element function reverseKeyLookupMultiID(dict : Element, element : Element):
+	Integer nr_out
+	Integer counter
+	Element link
+	Element result
+
+	result = set_create()
+	nr_out = read_nr_out(dict)
+	counter = 0
+	while (counter < nr_out):
+		if (element_eq(read_edge_dst(read_out(dict, counter)), element)):
+			// Got a match
+			set_add(result, read_edge_dst(read_out(read_out(dict, counter), 0)))
+		counter = counter + 1
+	
+	return result!
+
 Boolean function list_in(list : Element, elem : Element):
 Boolean function list_in(list : Element, elem : Element):
 	Integer i
 	Integer i
 	i = 0
 	i = 0

+ 31 - 10
bootstrap/typing.alc

@@ -11,6 +11,8 @@ Element function get_type_mapping(model : Element):
 	Element edge
 	Element edge
 	Element keys
 	Element keys
 	String key
 	String key
+	String m_name
+	String mm_name
 
 
 	keys = dict_keys(model["type_mapping"])
 	keys = dict_keys(model["type_mapping"])
 
 
@@ -20,9 +22,11 @@ Element function get_type_mapping(model : Element):
 		mm = model["metamodel"]["model"][model["type_mapping"][key]]
 		mm = model["metamodel"]["model"][model["type_mapping"][key]]
 		edge = create_edge(m, mm)
 		edge = create_edge(m, mm)
 
 
-		dict_add_fast(tm_model, cast_id(m), m)
-		if (bool_not(dict_in(tm_model, cast_id(mm)))):
-			dict_add_fast(tm_model, cast_id(mm), mm)
+		m_name = "instance_" + key
+		mm_name = "type_" + cast_string(model["type_mapping"][key])
+		dict_add_fast(tm_model, m_name, m)
+		if (bool_not(dict_in(tm_model, mm_name))):
+			dict_add_fast(tm_model, mm_name, mm)
 		dict_add_fast(tm_model, cast_id(edge), edge)
 		dict_add_fast(tm_model, cast_id(edge), edge)
 
 
 	return tm_model!
 	return tm_model!
@@ -30,24 +34,41 @@ Element function get_type_mapping(model : Element):
 Void function set_type_mapping(model : Element, type_mapping_model : Element):
 Void function set_type_mapping(model : Element, type_mapping_model : Element):
 	// Serialize model to dictionary
 	// Serialize model to dictionary
 	Element type_mapping
 	Element type_mapping
-	Element rev_model
-	Element rev_metamodel
 	Element keys
 	Element keys
 	String key
 	String key
+	String source_name
+	String destination_name
+	String tmp_source_name
+	String tmp_destination_name
+	Element lookups
 
 
 	type_mapping = dict_create()
 	type_mapping = dict_create()
 	keys = dict_keys(type_mapping_model)
 	keys = dict_keys(type_mapping_model)
-	rev_model = make_reverse_dictionary(model["model"])
-	rev_metamodel = make_reverse_dictionary(model["metamodel"]["model"])
 
 
 	while (set_len(keys) > 0):
 	while (set_len(keys) > 0):
 		key = set_pop(keys)
 		key = set_pop(keys)
 		if (is_edge(type_mapping_model[key])):
 		if (is_edge(type_mapping_model[key])):
-			if (bool_not(bool_or(dict_in(rev_model, cast_id(type_mapping_model[key])), dict_in(rev_metamodel, cast_id(type_mapping_model[key]))))):
+			lookups = reverseKeyLookupMultiID(type_mapping_model, read_edge_src(type_mapping_model[key]))
+			source_name = ""
+			while (set_len(lookups) > 0):
+				tmp_source_name = set_pop(lookups)
+				if (string_startswith(tmp_source_name, "instance_")):
+					source_name = string_replace(tmp_source_name, "instance_", "")
+					break!
+
+			lookups = reverseKeyLookupMultiID(type_mapping_model, read_edge_dst(type_mapping_model[key]))
+			destination_name = ""
+			while (set_len(lookups) > 0):
+				tmp_destination_name = set_pop(lookups)
+				if (string_startswith(tmp_destination_name, "type_")):
+					destination_name = string_replace(tmp_destination_name, "type_", "")
+					break!
+
+			if (bool_and(dict_in(model["model"], source_name), dict_in(model["metamodel"]["model"], destination_name))):
 				// Element is in neither model or metamodel
 				// Element is in neither model or metamodel
 				// Must be a typing link!
 				// Must be a typing link!
 				// So add it
 				// So add it
-				dict_add_fast(type_mapping, rev_model[cast_id(read_edge_src(type_mapping_model[key]))], rev_metamodel[cast_id(read_edge_dst(type_mapping_model[key]))])
+				dict_add_fast(type_mapping, source_name, destination_name)
 
 
 	dict_overwrite(model, "type_mapping", type_mapping)
 	dict_overwrite(model, "type_mapping", type_mapping)
 	return!
 	return!
@@ -58,7 +79,7 @@ Element function elements_typed_by(model : Element, type_name : String):
 	String temp
 	String temp
 
 
 	result = set_create()
 	result = set_create()
-	temp_result = reverseKeyLookupMulti(get_type_mapping_as_dict(model), type_name)
+	temp_result = reverseKeyLookupMultiValue(get_type_mapping_as_dict(model), type_name)
 	while (set_len(temp_result) > 0):
 	while (set_len(temp_result) > 0):
 		temp = set_pop(temp_result)
 		temp = set_pop(temp_result)
 		if (dict_in(model["model"], temp)):
 		if (dict_in(model["model"], temp)):

+ 1 - 1
examples/multi_conformance.py

@@ -52,7 +52,7 @@ model_add("formalisms/simple_mm", "formalisms/SimpleClassDiagrams", mm)
 model_add("models/model_string", "formalisms/simple_mm", model_string)
 model_add("models/model_string", "formalisms/simple_mm", model_string)
 model_add("models/model_integer", "formalisms/simple_mm", model_integer)
 model_add("models/model_integer", "formalisms/simple_mm", model_integer)
 
 
-transformation_add_AL({"model": "formalisms/simple_mm", "metamodel": "formalisms/SimpleClassDiagrams", "type_mapping": "formalisms/TypeMapping"}, {}, "models/conformance_AToMPM", open("models/Conformance/AToMPM.alc", 'r').read())
+transformation_add_AL({"model": "formalisms/Bottom", "metamodel": "formalisms/SimpleClassDiagrams", "type_mapping": "formalisms/TypeMapping"}, {}, "models/conformance_AToMPM", open("models/Conformance/AToMPM.alc", 'r').read())
 #transformation_add_AL({"model": "formalisms/simple_mm", "metamodel": "formalisms/SimpleClassDiagrams", "type_mapping": "formalisms/TypeMapping"}, {}, "models/conformance_MetaDepth", open("models/Conformance/MetaDepth.alc", 'r').read())
 #transformation_add_AL({"model": "formalisms/simple_mm", "metamodel": "formalisms/SimpleClassDiagrams", "type_mapping": "formalisms/TypeMapping"}, {}, "models/conformance_MetaDepth", open("models/Conformance/MetaDepth.alc", 'r').read())
 
 
 print(model_types("models/model_string"))
 print(model_types("models/model_string"))

+ 2 - 1
interface/HUTN/includes/primitives.alh

@@ -116,7 +116,8 @@ Element function set_create()
 Element function list_create()
 Element function list_create()
 Element function dict_create()
 Element function dict_create()
 String function reverseKeyLookup(a: Element, b: Element)
 String function reverseKeyLookup(a: Element, b: Element)
-Element function reverseKeyLookupMulti(a: Element, b: Element)
+Element function reverseKeyLookupMultiValue(a: Element, b: Element)
+Element function reverseKeyLookupMultiID(a: Element, b: Element)
 Element function dict_values(dict : Element)
 Element function dict_values(dict : Element)
 Boolean function is_error(a : Element)
 Boolean function is_error(a : Element)
 Element function range(max : Integer)
 Element function range(max : Integer)

+ 19 - 1
kernel/modelverse_kernel/compiled.py

@@ -50,7 +50,25 @@ def get_superclasses(a, b, **remainder):
 
 
     yield [("RETURN", [{'id': result}])]
     yield [("RETURN", [{'id': result}])]
 
 
-def reverseKeyLookupMulti(a, b, **remainder):
+def reverseKeyLookupMultiID(a, b, **remainder):
+    edges, result = yield [("RO", [a['id']]), ("CN", [])]
+    expanded_edges = yield [("RE", [i]) for i in edges]
+    values = [i[1] for i in expanded_edges]
+
+    # Keep results in a local Python set, as we want to bundle as many requests as possible
+    todo = set()
+    for i, edge in enumerate(values):
+        if b['id'] == edge:
+            todo.add(i)
+
+    outgoings = yield [("RO", [edges[i]]) for i in todo]
+    values = yield [("RE", [outgoing[0]]) for outgoing in outgoings]
+    edges = yield [("CE", [result, result]) for value in values]
+    yield [("CE", [edge, value[1]]) for edge, value in zip(edges, values)]
+
+    yield [("RETURN", [{'id': result}])]
+
+def reverseKeyLookupMultiValue(a, b, **remainder):
     if "value" not in b:
     if "value" not in b:
         b['value'], = yield [("RV", [b['id']])]
         b['value'], = yield [("RV", [b['id']])]
 
 

+ 6 - 0
models/Conformance/AToMPM.alc

@@ -27,10 +27,16 @@ Boolean function main(model : Element):
 	// TODO other option: make the type mapping refer to names/IDs instead of identifiers, although this is problematic in case we connect to ourselves (self-conformance!)
 	// TODO other option: make the type mapping refer to names/IDs instead of identifiers, although this is problematic in case we connect to ourselves (self-conformance!)
 	Element links
 	Element links
 	String link
 	String link
+	Element type_mapping
+	type_mapping = dict_create()
+
 	links = allInstances(model, "type_mapping/TypeLink")
 	links = allInstances(model, "type_mapping/TypeLink")
 	while (set_len(links) > 0):
 	while (set_len(links) > 0):
 		link = set_pop(links)
 		link = set_pop(links)
 		log("Association connects: " + readAssociationSource(model, link) + " --> " + readAssociationDestination(model, link))
 		log("Association connects: " + readAssociationSource(model, link) + " --> " + readAssociationDestination(model, link))
+		dict_add(type_mapping, "model/" + string_replace(readAssociationSource(model, link), "type_mapping/instance_", ""), "metamodel/" + string_replace(readAssociationDestination(model, link), "type_mapping/type_", ""))
+	
+	log("Found type mapping: " + dict_to_string(type_mapping))
 
 
 	String class
 	String class
 	Element instances
 	Element instances

+ 2 - 2
wrappers/classes/modelverse.xml

@@ -435,7 +435,7 @@
 
 
                             <transition cond="self.expect_response_partial('Success: ')" target="../send_metadata">
                             <transition cond="self.expect_response_partial('Success: ')" target="../send_metadata">
                                 <script>
                                 <script>
-                                    self.registered_metamodel[self.parameters[0]] = set(self.split_response(self.responses.pop(0))).pop()
+                                    self.registered_metamodel[self.parameters[0]] = set(self.split_response(self.responses.pop(0))).pop().split(", ")[0]
                                 </script>
                                 </script>
                             </transition>
                             </transition>
                         </state>
                         </state>
@@ -2012,7 +2012,7 @@
 
 
                         <transition cond="self.expect_response_partial('Success: ')" target="../OK">
                         <transition cond="self.expect_response_partial('Success: ')" target="../OK">
                             <script>
                             <script>
-                                self.registered_metamodel[self.current_model] = set(self.split_response(self.responses.pop(0))).pop()
+                                self.registered_metamodel[self.current_model] = set(self.split_response(self.responses.pop(0))).pop().split(", ")[0]
                             </script>
                             </script>
                         </transition>
                         </transition>
                     </state>
                     </state>

+ 3 - 3
wrappers/modelverse_SCCD.py

@@ -1,7 +1,7 @@
 """
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
 
-Date:   Thu May 24 17:42:24 2018
+Date:   Fri May 25 10:59:57 2018
 
 
 Model author: Yentl Van Tendeloo
 Model author: Yentl Van Tendeloo
 Model name:   MvK Server
 Model name:   MvK Server
@@ -2598,7 +2598,7 @@ class Modelverse(RuntimeClassBase):
         return self.parameters[0] not in self.registered_metamodel
         return self.parameters[0] not in self.registered_metamodel
     
     
     def _initialized_behaviour_operations_model_overwrite_search_0_exec(self, parameters):
     def _initialized_behaviour_operations_model_overwrite_search_0_exec(self, parameters):
-        self.registered_metamodel[self.parameters[0]] = set(self.split_response(self.responses.pop(0))).pop()
+        self.registered_metamodel[self.parameters[0]] = set(self.split_response(self.responses.pop(0))).pop().split(", ")[0]
     
     
     def _initialized_behaviour_operations_model_overwrite_search_0_guard(self, parameters):
     def _initialized_behaviour_operations_model_overwrite_search_0_guard(self, parameters):
         return self.expect_response_partial('Success: ')
         return self.expect_response_partial('Success: ')
@@ -3357,7 +3357,7 @@ class Modelverse(RuntimeClassBase):
         return self.current_model not in self.registered_metamodel
         return self.current_model not in self.registered_metamodel
     
     
     def _initialized_behaviour_going_manual_search_0_exec(self, parameters):
     def _initialized_behaviour_going_manual_search_0_exec(self, parameters):
-        self.registered_metamodel[self.current_model] = set(self.split_response(self.responses.pop(0))).pop()
+        self.registered_metamodel[self.current_model] = set(self.split_response(self.responses.pop(0))).pop().split(", ")[0]
     
     
     def _initialized_behaviour_going_manual_search_0_guard(self, parameters):
     def _initialized_behaviour_going_manual_search_0_guard(self, parameters):
         return self.expect_response_partial('Success: ')
         return self.expect_response_partial('Success: ')