Pārlūkot izejas kodu

Merge branch 'testing'

Yentl Van Tendeloo 7 gadi atpakaļ
vecāks
revīzija
b98e18cf73

+ 0 - 39
bootstrap/90_core_formalism.mvc

@@ -4,57 +4,18 @@ include "primitives.alh"
 SimpleClassDiagrams CoreFormalism {
     SimpleAttribute String {
         name = "String"
-        constraint = $
-            String function constraint(model : Element, name : String):
-                if (bool_not(is_physical_string(model["model"][name]))):
-                    return "String has no string value"!
-                else:
-                    return "OK"!
-            $
     }
 
     SimpleAttribute Permissions {
         name = "Permissions"
-        constraint = $
-            String function constraint(model : Element, name : String):
-                Element self
-                self = model["model"][name]
-                if (bool_not(is_physical_string(self))):
-                    return "Permissions has no string value"!
-                if (bool_not(string_len(self) == 3)):
-                    return "Permissions string is not of correct length"!
-                if (bool_or(cast_integer(string_get(self, 0)) < 0, cast_integer(string_get(self, 0)) > 2)):
-                    return "Owner permission is not in range [0, 2]"!
-                if (bool_or(cast_integer(string_get(self, 1)) < 0, cast_integer(string_get(self, 1)) > 2)):
-                    return "Group permission is not in range [0, 2]"!
-                if (bool_or(cast_integer(string_get(self, 2)) < 0, cast_integer(string_get(self, 2)) > 2)):
-                    return "Other permission is not in range [0, 2]"!
-                return "OK"!
-            $
     }
 
     SimpleAttribute Boolean {
         name = "Boolean"
-        constraint = $
-            String function constraint(model : Element, name : String):
-                if (bool_not(is_physical_boolean(model["model"][name]))):
-                    return "Boolean has no bool value"!
-                else:
-                    return "OK"!
-            $
     }
 
     SimpleAttribute Natural {
         name = "Natural"
-        constraint = $
-            String function constraint(model : Element, name : String):
-                if (bool_not(is_physical_int(model["model"][name]))):
-                    return "Natural has no integer value"!
-                elif (integer_lt(model["model"][name], 0)):
-                    return "Natural has negative value"!
-                else:
-                    return "OK"!
-            $
     }
 
     Class User {

+ 4 - 1
bootstrap/compiler.alc

@@ -33,7 +33,10 @@ Element function compile_code(code : String):
 	if (is_physical_string(list)):
 		return list!
 	else:
-		return construct_function_list(list)!
+		Element model
+		model = construct_function_list(list)
+		dict_add(model, "__text", code)
+		return model!
 
 Element function compile_model(code : String, metamodel : Element):
 	String port

+ 83 - 34
bootstrap/conformance_finding.alc

@@ -39,24 +39,35 @@ Boolean function find_type_mapping(model : Element):
 		Element elems
 		String elem
 
-		String node_source_element
-		String node_target_element
-		String edge_element
-
 		Element nodes
 		Element edges
 		nodes = allInstances(model["metamodel"], "Class")
 		edges = allInstances(model["metamodel"], "Association")
 
+		// Simple allocation: this seems like conformance bottom
 		if (bool_and(set_len(edges) == 1, set_len(nodes) == 1)):
-			// Simple allocation: this seems like conformance bottom
+			String node_source_element
+			String edge_element
+
 			node_source_element = set_pop(nodes)
-			node_target_element = node_source_element
 			edge_element = set_pop(edges)
 
-		elif (bool_and(set_len(edges) == 1, set_len(nodes) == 2)):
-			// Simple allocation: this seems like a type mapping
-			// Make sure to check that the edge goes from one node to the other!
+			elems = dict_keys(model["model"])
+			while (set_len(elems) > 0):
+				elem = set_pop(elems)
+				if (is_edge(model["model"][elem])):
+					retype(model, elem, edge_element)
+				else:
+					retype(model, elem, node_source_element)
+			return True!
+
+		// Simple allocation: this seems like a traceability model or so
+		// Make sure to check that the edge goes from one node to the other!
+		if (bool_and(set_len(edges) == 1, set_len(nodes) == 2)):
+			String node_target_element
+			String node_source_element
+			String edge_element
+
 			edge_element = set_pop(edges)
 			node_source_element = readAssociationSource(model["metamodel"], edge_element)
 			node_target_element = readAssociationDestination(model["metamodel"], edge_element)
@@ -65,32 +76,70 @@ Boolean function find_type_mapping(model : Element):
 				log("Could not automatically deduce mapping in a trivial way!")
 				return False!
 
-		else:
-			log("Could not automatically deduce mapping in a trivial way!")
-			return False!
-
-
-		// Now we have both an edge_element and node_element of the metamodel
-		// Now just trivially bind all elements!
-		elems = dict_keys(model["model"])
-		while (set_len(elems) > 0):
-			elem = set_pop(elems)
-
-			if (bool_and(is_edge(model["model"][elem]), read_nr_out(model["model"][elem]) == 0)):
-				// An edge, and there is always exactly one, so type
-				retype(model, elem, edge_element)
+			elems = dict_keys(model["model"])
+			while (set_len(elems) > 0):
+				elem = set_pop(elems)
 
-				// The source and target are ALWAYS typed as well!
-				retype(model, readAssociationSource(model, elem), node_source_element)
-				retype(model, readAssociationDestination(model, elem), node_target_element)
-			elif (node_source_element == node_target_element):
-				// A node, and we are sure that there is only one
-				if (is_edge(model["model"][elem])):
+				if (bool_and(is_edge(model["model"][elem]), read_nr_out(model["model"][elem]) == 0)):
+					// An edge, and there is always exactly one, so type
 					retype(model, elem, edge_element)
-				else:
-					retype(model, elem, node_source_element)
 
-	// 3) (optional) verify that the mapping is correct with conformance checking
-	// TODO
-	
+					// The source and target are ALWAYS typed as well!
+					retype(model, readAssociationSource(model, elem), node_source_element)
+					retype(model, readAssociationDestination(model, elem), node_target_element)
+
+			return True!
+
+		// Simple allocation: this seems like a dictionary model or so
+		if (bool_and(set_len(edges) == 2, set_len(nodes) == 3)):
+			String main_edge
+			String small_edge
+			main_edge = set_pop(edges)
+			small_edge = set_pop(edges)
+
+			if (readAssociationSource(model["metamodel"], main_edge) == small_edge):
+				// Switch both
+				log("Switch")
+				String tmp
+				tmp = main_edge
+				main_edge = small_edge
+				small_edge = tmp
+
+			if (readAssociationSource(model["metamodel"], small_edge) == main_edge):
+				log("Dictionary working...")
+				String origin
+				String value
+				String key
+				String middle_edge
+				origin = readAssociationSource(model["metamodel"], main_edge)
+				value = readAssociationDestination(model["metamodel"], main_edge)
+				key = readAssociationDestination(model["metamodel"], small_edge)
+
+				if (bool_and(bool_and(origin != value, origin != key), value != key)):
+					// All three nodes are different, meaning that we are complete and have identified a simple mapping!
+
+					elems = dict_keys(model["model"])
+					while (set_len(elems) > 0):
+						elem = set_pop(elems)
+						if (bool_and(is_edge(model["model"][elem]), read_nr_out(model["model"][elem]) == 0)):
+							// An edge with no outgoing links, meaning that it is the small_edge
+							retype(model, elem, small_edge)
+
+							// Source is main_edge and target is key
+							middle_edge = readAssociationSource(model, elem)
+							retype(model, middle_edge, main_edge)
+							retype(model, readAssociationDestination(model, elem), key)
+
+							// The main_edge goes from root to the value
+							retype(model, readAssociationSource(model, middle_edge), origin)
+							retype(model, readAssociationDestination(model, middle_edge), value)
+
+				return True!
+
+		log("Could not automatically deduce mapping in a trivial way!")
+		log("Model: " + set_to_string(dict_keys(model["model"])))
+		log("TM: " + set_to_string(dict_keys(tm)))
+		log("DIFF: " + set_to_string(set_difference(dict_keys(model["model"]), dict_keys(tm))))
+		return False!
+
 	return True!

+ 3 - 3
bootstrap/conformance_scd.alc

@@ -264,13 +264,13 @@ String function conformance_scd(model : Element):
 			if (attr_value < list_len(allInstances(model, metamodel_element))):
 				return "Upper cardinality violated for class: " + metamodel_element!
 
-	// Check all ComplexAttributes recursively
+	// Check all ActionLanguage recursively
 	Element all_complex_types
 	Element complex_instances
 	String complex_instance
 	String complex_type
 	String result
-	all_complex_types = allInstances(model["metamodel"]["metamodel"], "ComplexAttribute")
+	all_complex_types = allInstances(model["metamodel"]["metamodel"], "ActionLanguage")
 	while (set_len(all_complex_types) > 0):
 		complex_type = set_pop(all_complex_types)
 		complex_instances = allInstances(model, complex_type)
@@ -282,7 +282,7 @@ String function conformance_scd(model : Element):
 			result = check_location_conformance(model["model"][complex_instance], complex_type)
 
 			if (result != "OK"):
-				return "Complex attribute doesn't match for: " + complex_instance + "\n Message: " + result!
+				return "ActionLanguage attribute doesn't match for: " + complex_instance + "\n Message: " + result!
 
 	// Structure seems fine, now do global constraints
 	Element global_constraints

+ 17 - 9
bootstrap/core_algorithm.alc

@@ -101,7 +101,7 @@ Element function get_full_model(model_id : String, metamodel_id : String):
 	dict_add(m, "model", import_node(read_attribute(core, model_id, "location")))
 
 	// TODO for now this is restricted to the fixed semantics
-	// dict_add(m, "semantics", set_pop(allAssociationDestinations(core, choice, "semantics")))
+	// dict_add(m, "semantics", anAssociationDestination(core, choice, "semantics"))
 	dict_add(m, "semantics", get_entry_id("models/conformance_mv"))
 
 	if (metamodel_id == model_id):
@@ -144,7 +144,7 @@ Integer function get_relation_to_model(user_id : String, model_id : String):
 		return 0!
 	else:
 		String group_id
-		group_id = set_pop(allAssociationDestinations(core, model_id, "group"))
+		group_id = anAssociationDestination(core, model_id, "group")
 		if (set_in(allAssociationDestinations(core, user_id, "belongsTo"), group_id)):
 			// We are in the owning group
 			return 1!
@@ -1023,9 +1023,9 @@ Void function enact_PM(pm : Element, mapping : Element):
 						if (read_type(pm, next) == "Decision"):
 							// Got decision node, so expand immediately
 							if (result):
-								list_append(worklist, set_pop(allAssociationDestinations(pm, next, "Then")))
+								list_append(worklist, anAssociationDestination(pm, next, "Then"))
 							else:
-								list_append(worklist, set_pop(allAssociationDestinations(pm, next, "Else")))
+								list_append(worklist, anAssociationDestination(pm, next, "Else"))
 						else:
 							// Other node, so just append for further processing
 							list_append(worklist, next)
@@ -1043,6 +1043,12 @@ Void function enact_PM(pm : Element, mapping : Element):
 
 	return !
 
+String function cmd_AL_text(location : String):
+	if location == "":
+		return "Success: \n"!
+	else:
+		return "Success: " + cast_string(import_node(location + "/__text"))!
+
 String function cmd_help():
 	String result
 
@@ -1602,7 +1608,7 @@ String function cmd_model_overwrite(model_name : String, metamodel_name : String
 	model_id = get_entry_id(model_name)
 	if (model_id != ""):
 		if (allow_write(current_user_id, model_id)):
-			type_id = set_pop(allAssociationDestinations(core, model_id, "instanceOf"))
+			type_id = anAssociationDestination(core, model_id, "instanceOf")
 			if (allow_read(current_user_id, type_id)):
 				Element mm
 				mm = get_full_model(get_entry_id(metamodel_name), get_entry_id("formalisms/SimpleClassDiagrams"))
@@ -1633,7 +1639,7 @@ String function cmd_model_modify(model_name : String, metamodel_name : String):
 
 	if (model_id != ""):
 		if (allow_read(current_user_id, model_id)):
-			type_id = set_pop(allAssociationDestinations(core, model_id, "instanceOf"))
+			type_id = anAssociationDestination(core, model_id, "instanceOf")
 			if (allow_read(current_user_id, type_id)):
 				Element new_model
 				new_model = get_full_model(model_id, get_entry_id(metamodel_name))
@@ -1720,8 +1726,8 @@ String function cmd_model_list_full(location : String):
 			while (set_len(models) > 0):
 				m = set_pop(models)
 				permissions = read_attribute(core, m, "permissions")
-				owner = read_attribute(core, set_pop(allAssociationDestinations(core, m, "owner")), "name")
-				group = read_attribute(core, set_pop(allAssociationDestinations(core, m, "group")), "name")
+				owner = read_attribute(core, anAssociationDestination(core, m, "owner"), "name")
+				group = read_attribute(core, anAssociationDestination(core, m, "group"), "name")
 				if (is_nominal_instance(core, m, "Folder")):
 					name = get_filename(read_attribute(core, m, "name")) + "/"
 				else:
@@ -2348,7 +2354,7 @@ String function cmd_model_types(model_name : String):
 		types = allOutgoingAssociationInstances(core, model_id, "instanceOf")
 		while (set_len(types) > 0):
 			type_link = set_pop(types)
-			result = result + full_name(readAssociationDestination(core, type_link)) + ", " + full_name(set_pop(allAssociationDestinations(core, type_link, "typing"))) + ", " + full_name(set_pop(allAssociationDestinations(core, type_link, "semantics")))+ "\n"
+			result = result + cast_string(full_name(readAssociationDestination(core, type_link))) + ", " + cast_string(full_name(anAssociationDestination(core, type_link, "typing"))) + ", " + cast_string(full_name(anAssociationDestination(core, type_link, "semantics"))) + "\n"
 
 		return result!
 	else:
@@ -2497,6 +2503,8 @@ Void function user_function_skip_init(user_id : String):
 			cmd = "FAIL"
 		elif (cmd == "model_types"):
 			output(cmd_model_types(single_input("Model name?")))
+		elif (cmd == "AL_text"):
+			output(cmd_AL_text(single_input("Code location?")))
 		else:
 			output("Unknown command: " + cmd)
 

+ 7 - 7
bootstrap/metamodels.alt

@@ -109,8 +109,8 @@ Element function initialize_SCD(location : String):
 	instantiate_attribute(scd, "attr_optional", "optional", False)
 	instantiate_attribute(scd, "attr_name", "optional", False)
 
-	instantiate_node(scd, "Class", "ComplexAttribute")
-	instantiate_link(scd, "Inheritance", "", "ComplexAttribute", "Attribute")
+	instantiate_node(scd, "Class", "ActionLanguage")
+	instantiate_link(scd, "Inheritance", "", "ActionLanguage", "Attribute")
 
 	model_define_attribute(scd, "Class", "lower_cardinality", True, "Natural")
 	model_define_attribute(scd, "Class", "upper_cardinality", True, "Natural")
@@ -118,9 +118,9 @@ Element function initialize_SCD(location : String):
 	model_define_attribute(scd, "Association", "target_lower_cardinality", True, "Natural")
 	model_define_attribute(scd, "Association", "source_upper_cardinality", True, "Natural")
 	model_define_attribute(scd, "Association", "target_upper_cardinality", True, "Natural")
-	model_define_attribute(scd, "ComplexAttribute", "type", False, "Location")
 
 	model_define_attribute(scd, "Class", "name", False, "String")
+	model_define_attribute(scd, "Class", "abstract", True, "Boolean")
 	model_define_attribute(scd, "SimpleAttribute", "name", False, "String")
 	model_define_attribute(scd, "Association", "name", False, "String")
 	instantiate_attribute(scd, "Class", "name", "Class")
@@ -138,9 +138,9 @@ Element function initialize_SCD(location : String):
 	initialize_AL(location, al_location)
 
 	// Define additional attributes that define functions
-	instantiate_node(scd, "ComplexAttribute", "ActionLanguage")
-	instantiate_attribute(scd, "ActionLanguage", "type", al_location)
-	model_define_attribute(scd, "Element", "constraint", True, "ActionLanguage")
+	instantiate_node(scd, "ActionLanguage", "ActionCode")
+	instantiate_attribute(scd, "ActionCode", "name", "ActionCode")
+	model_define_attribute(scd, "Element", "constraint", True, "ActionCode")
 
 	// Define some constraints
 	//instantiate_attribute_code(scd, "Natural", "constraint", constraint_Natural)
@@ -150,7 +150,7 @@ Element function initialize_SCD(location : String):
 	//instantiate_attribute_code(scd, "ActionLanguage", "constraint", constraint_ActionLanguage)
 
 	instantiate_node(scd, "Class", "GlobalConstraint")
-	model_define_attribute(scd, "GlobalConstraint", "global_constraint", False, "ActionLanguage")
+	model_define_attribute(scd, "GlobalConstraint", "global_constraint", False, "ActionCode")
 	instantiate_attribute(scd, "GlobalConstraint", "name", "GlobalConstraint")
 
 	dict_overwrite(scd, "types", get_type_mapping(scd))

+ 13 - 50
bootstrap/mini_modify.alc

@@ -12,51 +12,6 @@ include "utils.alh"
 
 Boolean verbose = True
 
-String function pretty_print(model : Element):
-	Element keys_m
-	String type
-	String v_m
-	Element attr_list
-	Element attr_keys
-	String attr_key
-	String result
-
-	result = ""
-	keys_m = dict_keys(model["model"])
-
-	while (set_len(keys_m) > 0):
-		v_m = set_pop(keys_m)
-		type = read_type(model["metamodel"], read_type(model, v_m))
-
-		if (bool_or(type == "Class", type == "Association")):
-			result = result + "  " + v_m + " : " + read_type(model, v_m)
-			result = result + "\n"
-			if (type == "Association"):
-				result = result + "    " + reverseKeyLookup(model["model"], read_edge_src(model["model"][v_m])) + " --> " + reverseKeyLookup(model["model"], read_edge_dst(model["model"][v_m]))
-				result = result + "\n"
-
-			// Defines attributes
-			attr_list = getInstantiatableAttributes(model, v_m, "AttributeLink")
-			attr_keys = dict_keys(attr_list)
-			while (set_len(attr_keys) > 0):
-				attr_key = set_pop(attr_keys)
-				result = result + "      " + attr_key + " : " + cast_value(attr_list[attr_key])
-				result = result + "\n"
-
-			// Has attributes
-			attr_list = getAttributeList(model, v_m)
-			attr_keys = dict_keys(attr_list)
-			while (set_len(attr_keys) > 0):
-				attr_key = set_pop(attr_keys)
-				if (element_eq(read_attribute(model, v_m, attr_key), read_root())):
-					result = result + "      " + cast_string(attr_key) + " : " + cast_string(attr_list[attr_key]) + " = (undefined)"
-				else:
-					result = result + "      " + cast_string(attr_key) + " : " + cast_string(attr_list[attr_key]) + " = " + cast_value(read_attribute(model, v_m, attr_key))
-				result = result + "\n"
-		else:
-			log("Skip instance: " + type)
-	return result!
-
 String function cmd_help_m(write : Boolean):
 	String result
 	result = ""
@@ -178,7 +133,9 @@ String function cmd_attr_add_code(write : Boolean, model : Element, element_name
 			if (set_in(dict_keys(attrs), attr_name)):
 				output("Waiting for code constructors...")
 				Element compiled
+				log("Wait...")
 				compiled = compile_code(input())
+				log("Compiled!")
 				if (is_physical_string(compiled)):
 					return "Compilation error: " + cast_string(compiled)!
 
@@ -407,6 +364,7 @@ String function cmd_read_attrs(model : Element, element_name : String):
 	Element attr_list
 	Element attr_keys
 	String attr_key
+	String attr
 
 	result = "Success: "
 	if (dict_in(model["model"], element_name)):
@@ -414,7 +372,14 @@ String function cmd_read_attrs(model : Element, element_name : String):
 		attr_keys = dict_keys(attr_list)
 		while (0 < set_len(attr_keys)):
 			attr_key = set_pop(attr_keys)
-			result = string_join(result, attr_key) + " : " + cast_value(attr_list[attr_key]) + " = " + cast_value(read_attribute(model, element_name, attr_key)) + "\n"
+			attr = read_attribute(model, element_name, attr_key)
+			if (read_type(model["metamodel"], attr_list[attr_key]) == "ActionLanguage"):
+				if (element_eq(attr, read_root())):
+					result = result + attr_key + " : " + cast_value(attr_list[attr_key]) + " = {\"AL\": \"\"}\n"
+				else:
+					result = result + attr_key + " : " + cast_value(attr_list[attr_key]) + " = {\"AL\": " + cast_value(attr) + "}\n"
+			else:
+				result = result + attr_key + " : " + cast_value(attr_list[attr_key]) + " = " + cast_value(attr) + "\n"
 		return result!
 	else:
 		return "Element not found: " + element_name!
@@ -432,9 +397,9 @@ String function cmd_read_defined_attrs(model : Element, element_name : String):
 		while (0 < set_len(attr_keys)):
 			attr_key = set_pop(attr_keys)
 			if (value_eq(read_attribute(model, reverseKeyLookup(model["model"], dict_read_edge(model["model"][element_name], attr_key)), "optional"), True)):
-				result = string_join(result, attr_key) + " ?: " + cast_value(attr_list[attr_key]) + "\n"
+				result = string_join(result, attr_key) + " ?: " + cast_string(attr_list[attr_key]) + "\n"
 			else:
-				result = string_join(result, attr_key) + " : " + cast_value(attr_list[attr_key]) + "\n"
+				result = string_join(result, attr_key) + " : " + cast_string(attr_list[attr_key]) + "\n"
 		return result!
 	else:
 		return "Element not found: " + element_name!
@@ -530,8 +495,6 @@ Boolean function modify(model : Element, write : Boolean):
 			output(cmd_attr_optional(write, model, single_input("Name?"), single_input("Attribute name?"), input()))
 		elif (cmd == "delete"):
 			output(cmd_delete(write, model, single_input("Name?")))
-		elif (cmd == "nice_list"):
-			output(pretty_print(model))
 		elif (cmd == "list"):
 			output(cmd_list(model))
 		elif (cmd == "list_full"):

+ 1 - 0
bootstrap/modelling.alc

@@ -6,6 +6,7 @@ include "metamodels.alh"
 include "library.alh"
 include "typing.alh"
 include "utils.alh"
+include "core_algorithm.alh"
 
 Element global_models = ?
 

+ 30 - 0
bootstrap/object_operations.alc

@@ -200,6 +200,21 @@ String function readAssociationSource(model : Element, name : String):
 String function readAssociationDestination(model : Element, name : String):
 	return reverseKeyLookup(model["model"], read_edge_dst(model["model"][name]))!
 
+String function anAssociationDestination(model : Element, name : String, association_type : String):
+	Element tmp
+	Element result
+	String val
+
+	result = set_create()
+	tmp = allOutgoingAssociationInstances(model, name, association_type)
+
+	while (set_len(tmp) > 0):
+		val = readAssociationDestination(model, set_pop(tmp))
+		if (val != ""):
+			return val!
+
+	return ""!
+
 Element function allAssociationDestinations(model : Element, name : String, association_type : String):
 	Element tmp
 	Element result
@@ -215,6 +230,21 @@ Element function allAssociationDestinations(model : Element, name : String, asso
 
 	return result!
 
+String function anAssociationOrigin(model : Element, name : String, association_type : String):
+	Element tmp
+	Element result
+	String val
+
+	result = set_create()
+	tmp = allIncomingAssociationInstances(model, name, association_type)
+
+	while (set_len(tmp) > 0):
+		val = readAssociationSource(model, set_pop(tmp))
+		if (val != ""):
+			return val!
+
+	return ""!
+
 Element function allAssociationOrigins(model : Element, name : String, association_type : String):
 	Element tmp
 	Element result

+ 1 - 14
bootstrap/pm.mvc

@@ -8,17 +8,11 @@ SimpleClassDiagrams ProcessModel {
     }
     SimpleAttribute MvCName {
         name = "MvCName"
-        constraint = $
-            String function constraint(model : Element, name : String):
-                if (bool_not(is_physical_string(model["model"][name]))):
-                    return "MvCName has no string value"!
-                else:
-                    return "OK"!
-            $
     }
 
     Class Activity {
         name = "Activity"
+        abstract = True
     }
     Class Start : Activity {
         name = "Start"
@@ -37,13 +31,6 @@ SimpleClassDiagrams ProcessModel {
     }
     Class Decision : Activity {
         name = "Decision"
-        constraint = $
-            String function constraint(model : Element, name : String):
-                if (read_nr_out(allOutgoingAssociationInstances(model, name, "Next")) == 0):
-                    return "OK"!
-                else:
-                    return "Decision node cannot have a normal 'Next' link"!
-            $
     }
 
     Class Exec : Activity {

+ 12 - 14
bootstrap/ramify.alc

@@ -31,20 +31,18 @@ Element function ramify(model : Element):
 	instantiate_node(new_model, "SimpleAttribute", "Location")
 	instantiate_attribute(new_model, "Location", "constraint", constraint_Location)
 
-	instantiate_node(new_model, "ComplexAttribute", "ActionLanguage")
-	instantiate_attribute(new_model, "ActionLanguage", "constraint", constraint_ActionLanguage)
-	model_define_attribute(new_model, "ActionLanguage", "type", False, "Location")
+	instantiate_node(new_model, "ActionLanguage", "ActionCode")
 
 	// Add some default elements
 	//	Class LHS_Root {
-	//		constraint? : ActionLanguage
+	//		constraint? : ActionCode
 	//		upper_cardinality = 1
 	//		lower_cardinality = 1
 	//	}
 	instantiate_node(new_model, "Class", "LHS_Root")
 	instantiate_attribute(new_model, "LHS_Root", "lower_cardinality", 1)
 	instantiate_attribute(new_model, "LHS_Root", "upper_cardinality", 1)
-	model_define_attribute(new_model, "LHS_Root", "constraint", True, "ActionLanguage")
+	model_define_attribute(new_model, "LHS_Root", "constraint", True, "ActionCode")
 
 	//  Class LHS : LHS_Root {}
 	instantiate_node(new_model, "Class", "LHS")
@@ -58,17 +56,17 @@ Element function ramify(model : Element):
 
 	//	Class PreElement {
 	//		label : String
-	//		constraint? : ActionLanguage
+	//		constraint? : ActionCode
 	//	}
 	instantiate_node(new_model, "Class", "PreElement")
 	model_define_attribute(new_model, "PreElement", "label", False, "String")
-	model_define_attribute(new_model, "PreElement", "constraint", True, "ActionLanguage")
+	model_define_attribute(new_model, "PreElement", "constraint", True, "ActionCode")
 
 	// Association LHS_contains (LHS_Root, PreElement) {}
 	instantiate_link(new_model, "Association", "LHS_contains", "LHS_Root", "PreElement")
 
 	//	Class RHS {
-	//		action? : ActionLanguage
+	//		action? : ActionCode
 	//		upper_cardinality = 1
 	//		lower_cardinality = 1
 	//	}
@@ -76,16 +74,16 @@ Element function ramify(model : Element):
 	instantiate_attribute(new_model, "RHS", "lower_cardinality", 1)
 	instantiate_attribute(new_model, "RHS", "upper_cardinality", 1)
 	instantiate_attribute(new_model, "RHS", "name", "RHS")
-	model_define_attribute(new_model, "RHS", "action", True, "ActionLanguage")
+	model_define_attribute(new_model, "RHS", "action", True, "ActionCode")
 
 	//	Class PostElement {
 	//		label : String
-	//		action? : ActionLanguage
+	//		action? : ActionCode
 	//	}
 	instantiate_node(new_model, "Class", "PostElement")
 	model_define_attribute(new_model, "PostElement", "label", False, "String")
-	model_define_attribute(new_model, "PostElement", "action", True, "ActionLanguage")
-	model_define_attribute(new_model, "PostElement", "__id__", True, "ActionLanguage")
+	model_define_attribute(new_model, "PostElement", "action", True, "ActionCode")
+	model_define_attribute(new_model, "PostElement", "__id__", True, "ActionCode")
 
 	// Association RHS_contains (RHS, PostElement) {}
 	instantiate_link(new_model, "Association", "RHS_contains", "RHS", "PostElement")
@@ -154,8 +152,8 @@ Element function ramify(model : Element):
 				if (is_nominal_instance(model, old_source, "Element")):
 					// If the attribute is one used in the conformance check, we should mask it
 					// Add the attribute in the new model, altering its name and making it optional
-					model_define_attribute(new_model, "Pre_" + old_source, "constraint_" + attr_name, True, "ActionLanguage")
-					model_define_attribute(new_model, "Post_" + old_source, "value_" + attr_name, True, "ActionLanguage")
+					model_define_attribute(new_model, "Pre_" + old_source, "constraint_" + attr_name, True, "ActionCode")
+					model_define_attribute(new_model, "Post_" + old_source, "value_" + attr_name, True, "ActionCode")
 			else:
 				// Queue for later
 				list_append(keys, key)

+ 0 - 3
bootstrap/transform.alc

@@ -545,8 +545,6 @@ Boolean function transform_atomic(host_model : Element, schedule_model : Element
 	Element mappings
 	Element mapping
 
-	//log("Executing rule: " + current)
-
 	mappings = full_match(host_model, schedule_model, current, True)
 
 	//log("Executing rule: " + current)
@@ -560,7 +558,6 @@ Boolean function transform_atomic(host_model : Element, schedule_model : Element
 		//log("Rewrite OK")
 		return True!
 	else:
-		log("Rewrite failed")
 		return False!
 
 Boolean function transform_forall(host_model : Element, schedule_model : Element, current : String):

+ 3 - 1
bootstrap/type_mapping.mvc

@@ -3,7 +3,9 @@ import models/SimpleClassDiagrams as SCD
 SCD type_mapping {
     Class Instance {}
     Class Type {}
-    Association TypeLink (Instance, Type) {}
+    Class Root {}
+    Association TypeLink (Root, Type) {}
+    Association InstanceLink (TypeLink, Instance) {}
 }
 
 export type_mapping to models/TypeMapping

+ 28 - 110
bootstrap/typing.alc

@@ -3,106 +3,11 @@ include "utils.alh"
 
 Element function get_type_mapping(model : Element):
 	// Deserialize dictionary as model
-	Element tm_model
-	tm_model = dict_create()
-
-	Element m
-	Element mm
-	Element edge
-	Element keys
-	String key
-	String m_name
-	String mm_name
-
-	Element m_model
-	Element mm_model
-	Element tm
-	m_model = model["model"]
-	mm_model = model["metamodel"]["model"]
-	tm = model["type_mapping"]
-
-	keys = dict_keys(model["type_mapping"])
-
-	while (set_len(keys) > 0):
-		key = set_pop(keys)
-		m = m_model[key]
-		mm = mm_model[tm[key]]
-		edge = create_edge(m, mm)
-
-		m_name = "instance_" + key
-		mm_name = "type_" + cast_string(tm[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)
-
-	return tm_model!
+	return model["type_mapping"]!
 
 Void function set_type_mapping(model : Element, type_mapping_model : Element):
 	// Serialize model to dictionary
-	Element type_mapping
-	Element keys
-	String key
-	String source_name
-	String destination_name
-	String tmp_source_name
-	String tmp_destination_name
-	Element lookups
-	String value
-	String src_id
-	String dst_id
-	Element mm_model
-	Element m_model
-	m_model = model["model"]
-	mm_model = model["metamodel"]["model"]
-
-	type_mapping = dict_create()
-	keys = dict_keys(type_mapping_model)
-
-	Element reverse_mapping
-	reverse_mapping = dict_create()
-
-	while (set_len(keys) > 0):
-		key = set_pop(keys)
-		value = cast_id(type_mapping_model[key])
-
-		if (bool_not(dict_in(reverse_mapping, value))):
-			dict_add(reverse_mapping, value, set_create())
-		set_add(reverse_mapping[value], key)
-
-	keys = dict_keys(type_mapping_model)
-	while (set_len(keys) > 0):
-		key = set_pop(keys)
-		if (is_edge(type_mapping_model[key])):
-			src_id = cast_id(read_edge_src(type_mapping_model[key]))
-			if (bool_not(dict_in(reverse_mapping, src_id))):
-				continue!
-			lookups = set_copy(reverse_mapping[src_id])
-			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!
-
-			dst_id = cast_id(read_edge_dst(type_mapping_model[key]))
-			if (bool_not(dict_in(reverse_mapping, dst_id))):
-				continue!
-			lookups = set_copy(reverse_mapping[dst_id])
-			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(bool_and(dict_in(m_model, source_name), dict_in(mm_model, destination_name)), read_nr_out(type_mapping_model[key]) == 0)):
-				// Element is in neither model or metamodel
-				// Must be a typing link!
-				// So add it
-				dict_add_fast(type_mapping, source_name, destination_name)
-
-	dict_overwrite(model, "type_mapping", type_mapping)
+	dict_overwrite(model, "type_mapping", type_mapping_model)
 	return!
 
 Element function elements_typed_by(model : Element, type_name : String):
@@ -121,14 +26,14 @@ Element function elements_typed_by(model : Element, type_name : String):
 	return result!
 
 Element function get_type_mapping_as_dict(model : Element):
-	return model["type_mapping"]!
+	return model["type_mapping"]["root"]!
 
 String function read_type(model : Element, name : String):
 	String result
 	Element tm
 	if (dict_in(model["model"], name)):
-		if (dict_in(model["type_mapping"], name)):
-			result = model["type_mapping"][name]
+		if (dict_in(model["type_mapping"]["root"], name)):
+			result = model["type_mapping"]["root"][name]
 			if (dict_in(model["metamodel"]["model"], result)):
 				return result!
 			else:
@@ -140,21 +45,34 @@ String function read_type(model : Element, name : String):
 
 Void function retype(model : Element, element : String, type : String):
 	// Retype a model, deleting any previous type the element had
-	// The type string is evaluated in the metamodel previously specified
-	dict_overwrite(model["type_mapping"], element, type)
+	Element tm
+	tm = model["type_mapping"]
+
+	remove_type(model, element)
+
+	// Create new elements
+	Element type_link
+	Element type_elem
+	Element instance_link
+	Element instance_elem
+	type_elem = create_value(type)
+	instance_elem = create_value(element)
+	type_link = create_edge(tm["root"], type_elem)
+	instance_link = create_edge(type_link, instance_elem)
+	dict_add(tm, cast_id(type_elem), type_elem)
+	dict_add(tm, cast_id(instance_elem), instance_elem)
+	dict_add(tm, cast_id(type_link), type_link)
+	dict_add(tm, cast_id(instance_link), instance_link)
 	return!
 
 Void function new_type_mapping(model : Element):
 	dict_overwrite(model, "type_mapping", dict_create())
+	dict_add(model["type_mapping"], "root", create_node())
 	return !
 
 Void function remove_type(model : Element, name : String):
-	if (dict_in(model["type_mapping"], name)):
-		dict_delete(model["type_mapping"], name)
-	
-	String elem
-	elem = cast_id(model["model"][name])
-	if (dict_in(model["type_mapping"], elem)):
-		dict_delete(model["type_mapping"], elem)
-
+	Element value
+	value = dict_read_edge(model["type_mapping"]["root"], name)
+	if (element_neq(value, read_root())):
+		delete_element(value)
 	return !

+ 20 - 11
bootstrap/utils.alc

@@ -12,6 +12,8 @@ String function JSON_print(model : Element):
 	Element attr_keys
 	Boolean first
 	Element attr_value
+	String type_attr
+	Element attrs
 
 	result = "["
 	keys_m = dict_keys(model["model"])
@@ -28,27 +30,34 @@ String function JSON_print(model : Element):
 				first = False
 
 			result = result + "{"
-			result = result + "\"id\": \"" + v_m + "\""
-			result = result + "," + "\"type\": \"" + read_type(model, v_m) + "\""
+			result = result + "\"__id\": \"" + v_m + "\""
+			result = result + "," + "\"__type\": \"" + read_type(model, v_m) + "\""
 			if (type == "Association"):
 				result = result + ", \"__source\": \"" + reverseKeyLookup(model["model"], read_edge_src(model["model"][v_m])) + "\""
 				result = result + ", \"__target\": \"" + reverseKeyLookup(model["model"], read_edge_dst(model["model"][v_m])) + "\""
 
 			// Has attributes
-			attr_keys = dict_keys(getAttributeList(model, v_m))
+			attrs = getAttributeList(model, v_m)
+			attr_keys = dict_keys(attrs)
 			while (0 < set_len(attr_keys)):
 				attr_key = set_pop(attr_keys)
 				attr_value = read_attribute(model, v_m, attr_key)
-				if (element_eq(attr_value, read_root())):
-					result = result + ", \"" + attr_key + "\": null"
+				if (read_type(model["metamodel"], attrs[attr_key]) == "ActionLanguage"):
+					if (element_eq(attr_value, read_root())):
+						result = result + ", \"" + attr_key + "\": {\"AL\": \"\"}"
+					else:
+						result = result + ", \"" + attr_key + "\": {\"AL\": " + cast_value(attr_value) + "}"
 				else:
-					if (is_physical_boolean(attr_value)):
-						if (attr_value):
-							result = result + ", \"" + attr_key + "\": true"
-						else:
-							result = result + ", \"" + attr_key + "\": false"
+					if (element_eq(attr_value, read_root())):
+						result = result + ", \"" + attr_key + "\": null"
 					else:
-						result = result + ", \"" + attr_key + "\": " + cast_value(attr_value)
+						if (is_physical_boolean(attr_value)):
+							if (attr_value):
+								result = result + ", \"" + attr_key + "\": true"
+							else:
+								result = result + ", \"" + attr_key + "\": false"
+						else:
+							result = result + ", \"" + attr_key + "\": " + cast_value(attr_value)
 
 			result = result + "}"
 	result = result + "]"

+ 2 - 2
examples/live_modelling_CTCBD.py

@@ -19,7 +19,7 @@ transformation_add_MANUAL({"Design": "formalisms/CTCBD/Design_MM"}, {"Design": "
 def trace_D2P(model):
     instantiate(model, "Association", ("Design/Block", "PartialRuntime/Block"), ID="D2P_block")
 
-transformation_add_MT({"Design": "formalisms/CTCBD/Design_MM", "PartialRuntime": "formalisms/DTCBD/PartialRuntime_MM"}, {"PartialRuntime": "formalisms/DTCBD/PartialRuntime_MM"}, "models/CTCBD/toRuntime", open("models/CTCBD/transformations/to_partial_runtime.mvc", 'r').read(), trace_D2P)
+transformation_add_MT({"Design": "formalisms/CTCBD/Design_MM"}, {"PartialRuntime": "formalisms/DTCBD/PartialRuntime_MM"}, "models/CTCBD/toRuntime", open("models/CTCBD/transformations/to_partial_runtime.mvc", 'r').read(), trace_D2P)
 
 def trace_P2F(model):
     instantiate(model, "Association", ("PartialRuntime/Block", "FullRuntime/Block"), ID="P2F_block")
@@ -34,7 +34,7 @@ def modify_model(model):
     elements = element_list_nice(model)
     for e in elements:
         if e.get("value", None) == 10.0:
-            attr_assign(model, e["id"], "value", 100.0)
+            attr_assign(model, e["__id"], "value", 100.0)
             break
     else:
         while 1:

+ 2 - 2
examples/live_modelling_DTCBD.py

@@ -35,8 +35,8 @@ def modify_model(model):
         if e.get("value", None) == 2.0:
             while 1:
                 time.sleep(1)
-        elif e.get("type", None) == "Design/AdditionBlock":
-            adder = e["id"]
+        elif e.get("__type", None) == "Design/AdditionBlock":
+            adder = e["__id"]
             links = read_outgoing(model, adder, "Design/Link")
             destinations = [read_association_destination(model, link) for link in links]
     else:

+ 3 - 3
examples/live_modelling_FSA.py

@@ -33,7 +33,7 @@ def edit_FSA(model):
     elements = element_list_nice(model)
     for e in elements:
         if e.get("name", None) == "idle":
-            delete_element(model, e["id"])
+            delete_element(model, e["__id"])
             break
     else:
         while 1:
@@ -42,7 +42,7 @@ def edit_FSA(model):
     # Removed, so set a new element as initial
     for e in elements:
         if e.get("name", None) == "armed":
-            attr_assign(model, e["id"], "initial", True)
+            attr_assign(model, e["__id"], "initial", True)
             break
 
-process_execute("models/live_modelling_FSA", {"design_model": "models/FSA_model"}, {"models/FSA/edit": modify_model})
+process_execute("models/live_modelling_FSA", {"design_model": "models/FSA_model"}, {"models/FSA/edit": edit_FSA})

+ 1 - 0
interface/HUTN/hutn_compiler/model_bootstrap_visitor.py

@@ -182,6 +182,7 @@ class ModelBootstrapVisitor(Visitor):
             self.code += '\tinstantiate_attribute(%s, "%s", "%s", %s)\n' % (self.current_model, self.current_element[-1], attr_name, attr_value)
         elif tree.get_children("DOLLAR"):
             # Coded attribute
+            raise Exception("Code is no longer allowed in bootstrap files, as the HUTN parser is not initialized yet")
             #self.constructors.extend(["instantiate_attribute_code", self.current_model, self.current_element[-1], attr_name])
             #self.constructors.extend(constructors_compile(tree.get_children("ANYTHING_EXCEPT_DOLLAR")[0].get_text()))
             code = tree.get_children("ANYTHING_EXCEPT_DOLLAR")[0].get_text()

+ 2 - 0
interface/HUTN/includes/object_operations.alh

@@ -12,3 +12,5 @@ String function readAssociationDestination(model : Element, name : String)
 Element function allAssociationDestinations(model : Element, name : String, association_type : String)
 Element function allAssociationOrigins(model : Element, name : String, association_type : String)
 Element function allowedAssociationsBetween(model : Element, src : String, dst : String)
+String function anAssociationDestination(model : Element, name : String, association_type : String)
+String function anAssociationOrigin(model : Element, name : String, association_type : String)

+ 55 - 13
kernel/modelverse_kernel/compiled.py

@@ -5,6 +5,7 @@ def get_superclasses(a, b, **remainder):
         b['value'], = yield [("RV", [b['id']])]
     model_dict, tm_dict = yield [("RD", [a['id'], "model"]), 
                                  ("RD", [a['id'], "type_mapping"])]
+    tm_dict, = yield [("RD", [tm_dict, "root"])]
 
     worklist = set([b['value']])
     found = set([])
@@ -96,16 +97,16 @@ def reverseKeyLookup(a, b, **remainder):
         yield [("RETURN", [{'value': ""}])]
 
     options = set(edges_out) & set(edges_in)
-    if options:
-        # Select one option randomly
+    # Select one option randomly
+    while options:
         edge = options.pop()
         out_edges, = yield [("RO", [edge])]
         # Select one option randomly
-        out_edge = out_edges.pop()
-        e, = yield [("RE", [out_edge])]
-        yield [("RETURN", [{'id': e[1]}])]
-    else:
-        yield [("RETURN", [{'value': ""}])]
+        if out_edges:
+            out_edge = out_edges.pop()
+            e, = yield [("RE", [out_edge])]
+            yield [("RETURN", [{'id': e[1]}])]
+    yield [("RETURN", [{'value': ""}])]
 
 def instantiated_name(a, b, **remainder):
     if "id" not in a:
@@ -311,12 +312,13 @@ def list_pop_final(a, **remainder):
     yield [("RETURN", [{'id': result}])]
 
 def instantiate_node(a, b, c, **remainder):
+    if "value" not in b:
+        b['value'], = yield [("RV", [b['id']])]
+
     if "value" not in c:
         c['value'], = yield [("RV", [c['id']])]
-    if "id" not in b:
-        b['id'], = yield [("CNV", [b['value']])]
-
-    node, dict_entry, typing = \
+        
+    node, dict_entry, tm = \
         yield [("CN", []),
                ("RD", [a['id'], "model"]),
                ("RD", [a['id'], "type_mapping"]),
@@ -329,8 +331,19 @@ def instantiate_node(a, b, c, **remainder):
         name = c['value']
         name_node = c
 
-    yield [("CD", [dict_entry, name, node])]
-    yield [("CD", [typing, name, b['id']])]
+    _, root = yield [("CD", [dict_entry, name, node]),
+                     ("RD", [tm, "root"])]
+
+    # Create new type links
+    type_elem, instance_elem = yield [("CNV", [b['value']]), ("CNV", [name])]
+    type_link, = yield [("CE", [root, type_elem])]
+    instance_link, = yield [("CE", [type_link, instance_elem])]
+
+    # Add them to the model
+    yield  [("CD", [tm, str(type_elem), type_elem]),
+            ("CD", [tm, str(instance_elem), instance_elem]),
+            ("CD", [tm, str(type_link), type_link]),
+            ("CD", [tm, str(instance_link), instance_link])]
 
     yield [("RETURN", [name_node])]
 
@@ -392,6 +405,7 @@ def read_type(a, b, **remainder):
         b['value'], = yield [("RV", [b['id']])]
 
     model, type_mapping, metamodel = yield [("RD", [a['id'], 'model']), ("RD", [a['id'], 'type_mapping']), ("RD", [a['id'], 'metamodel'])]
+    type_mapping, = yield [("RD", [type_mapping, "root"])]
     metamodel, in_model, type_value = yield [("RD", [metamodel, 'model']), ("RD", [model, b['value']]), ("RD", [type_mapping, b['value']])]
 
     if in_model is None:
@@ -405,3 +419,31 @@ def read_type(a, b, **remainder):
             yield [("RETURN", [{'value': ""}])]
         else:
             yield [("RETURN", [{'value': type_value}])]
+
+def retype(a, b, c, **remainder):
+    if "value" not in b:
+        b['value'], = yield [("RV", [b['id']])]
+    if "value" not in c:
+        c['value'], = yield [("RV", [c['id']])]
+
+    tm, = yield [("RD", [a["id"], "type_mapping"])]
+    root, = yield [("RD", [tm, "root"])]
+
+    # remove_type
+    val, = yield [("RD", [root, b["value"]])]
+    if val is not None:
+        # Key exists, so remove
+        yield [("DN", [val])]
+
+    # Create new type links
+    type_elem, instance_elem = yield [("CNV", [c['value']]), ("CNV", [b['value']])]
+    type_link, = yield [("CE", [root, type_elem])]
+    instance_link, = yield [("CE", [type_link, instance_elem])]
+
+    # Add them to the model
+    yield  [("CD", [tm, str(type_elem), type_elem]),
+            ("CD", [tm, str(instance_elem), instance_elem]),
+            ("CD", [tm, str(type_link), type_link]), 
+            ("CD", [tm, str(instance_link), instance_link])]
+
+    yield [("RETURN", [None])]

+ 4 - 0
kernel/modelverse_kernel/primitives.py

@@ -306,8 +306,12 @@ def is_physical_action(a, **remainder):
     yield [("RETURN", [{'value': isinstance(a['value'], dict) and a['value']["value"] in ["if", "while", "assign", "call", "break", "continue", "return", "resolve", "access", "constant", "global", "declare"]}])]
 
 def is_physical_none(a, **remainder):
+    if a['id'] is None:
+        yield [("RETURN", [{"value": True}])]
     if "value" not in a:
         a['value'], = yield [("RV", [a['id']])]
+    elif a['value'] is None:
+        yield [("RETURN", [{"value": True}])]
     yield [("RETURN", [{'value': isinstance(a['value'], dict) and a['value']["value"] == "none"}])]
 
 def create_node(**remainder):

+ 0 - 3
models/CTCBD/PM_live_modelling.mvc

@@ -77,9 +77,6 @@ Produces (edit, design_model) {
 Consumes (toRuntime, design_model) {
     name = "Design"
 }
-Consumes (toRuntime, partial_runtime_model) {
-    name = "PartialRuntime"
-}
 Consumes (toRuntime, traceability_D2P) {
     name = "__traceability"
 }

+ 0 - 2
models/CTCBD/transformations/to_partial_runtime.mvc

@@ -66,7 +66,6 @@ Composite schedule {
                             String function new_id(model : Element, mapping : Element):
                                 String result
                                 result = cast_string(list_read(string_split(mapping["1"], "/"), 1)) + "_" + cast_string(list_read(string_split(mapping["2"], "/"), 1)) + "_D1"
-                                log("Generate new delayblock with ID " + result)
                                 return result!
                          $
             }
@@ -76,7 +75,6 @@ Composite schedule {
                             String function new_id(model : Element, mapping : Element):
                                 String result
                                 result = cast_string(list_read(string_split(mapping["1"], "/"), 1)) + "_" + cast_string(list_read(string_split(mapping["2"], "/"), 1)) + "_D2"
-                                log("Generate new delayblock with ID " + result)
                                 return result!
                          $
             }

+ 13 - 9
models/Conformance/AToMPM.alc

@@ -16,17 +16,21 @@ Boolean function main(model : Element):
 	Element classes
 	classes = allInstances(model, "metamodel/Class")
 
-	Element links
-	String link
 	Element type_mapping
-	type_mapping = dict_create()
-
 	Element instances
 	String instance
-	instances = allInstances(model, "type_mapping/Instance")
-	while (set_len(instances) > 0):
-		instance = set_pop(instances)
-		dict_add(type_mapping, "model/" + string_replace(instance, "type_mapping/instance_", ""), "metamodel/" + string_replace(set_pop(allAssociationDestinations(model, instance, "type_mapping/TypeLink")), "type_mapping/type_", ""))
+	type_mapping = model["model"][set_pop(allInstances(model, "type_mapping/Root"))]
+
+	Element new_type_mapping
+	Element keys
+	String key
+	new_type_mapping = dict_create()
+	keys = dict_keys(type_mapping)
+	while (set_len(keys) > 0):
+		key = set_pop(keys)
+		dict_add(new_type_mapping, "model/" + key, "metamodel/" + cast_string(type_mapping[key]))
+
+	type_mapping = new_type_mapping
 	
 	// Check if each attribute is there, and satisfies the constraints
 	instances = dict_keys(type_mapping)
@@ -36,7 +40,7 @@ Boolean function main(model : Element):
 			// Got an instance of a Class
 			String type
 			Element inherits_from
-			type = type_mapping[instance]
+			type = cast_string(type_mapping[instance])
 
 			Element outgoing_links
 			String outgoing_link

+ 14 - 10
models/Conformance/MetaDepth.alc

@@ -16,18 +16,22 @@ Boolean function main(model : Element):
 	Element classes
 	classes = allInstances(model, "metamodel/Class")
 
-	Element links
-	String link
 	Element type_mapping
-	type_mapping = dict_create()
+    Element instances
+    String instance
+    type_mapping = model["model"][set_pop(allInstances(model, "type_mapping/Root"))]
+
+	Element new_type_mapping
+    Element keys
+    String key
+    new_type_mapping = dict_create()
+    keys = dict_keys(type_mapping)
+    while (set_len(keys) > 0):
+        key = set_pop(keys)
+        dict_add(new_type_mapping, "model/" + key, "metamodel/" + cast_string(type_mapping[key]))
+
+    type_mapping = new_type_mapping
 
-	Element instances
-	String instance
-	instances = allInstances(model, "type_mapping/Instance")
-	while (set_len(instances) > 0):
-		instance = set_pop(instances)
-		dict_add(type_mapping, "model/" + string_replace(instance, "type_mapping/instance_", ""), "metamodel/" + string_replace(set_pop(allAssociationDestinations(model, instance, "type_mapping/TypeLink")), "type_mapping/type_", ""))
-	
 	// Check if each attribute is there, and satisfies the constraints
 	instances = dict_keys(type_mapping)
 	while (set_len(instances) > 0):

+ 0 - 39
models/DTCBD/transformations/simulate.alc

@@ -8,7 +8,6 @@ include "mini_modify.alh"
 include "utils.alh"
 
 Boolean function main(model : Element):
-	log("Start DTCBD simulation!")
 	String cmd
 	Boolean running
 	Element schedule_init
@@ -19,7 +18,6 @@ Boolean function main(model : Element):
 	String time
 	time = set_pop(allInstances(model, "FullRuntime/Time"))
 	current_time = read_attribute(model, time, "current_time")
-	log("Fetching time now: " + cast_value(current_time))
 
 	schedule_init = create_schedule(model)
 	schedule_run = read_root()
@@ -43,7 +41,6 @@ Boolean function main(model : Element):
 		current_time = step_simulation(model, schedule, current_time, inputs)
 
 	instantiate_attribute(model, time, "current_time", current_time)
-	log("CLOSE")
 	output("CLOSE")
 	return True!
 
@@ -59,7 +56,6 @@ Element function create_schedule(model : Element):
 	successors = set_create()
 	while (set_len(nodes) > 0):
 		element_name = set_pop(nodes)
-		log("Block " + element_name + " : " + read_type(model, element_name))
 
 		if (is_nominal_instance(model, element_name, "FullRuntime/ICBlock")):
 			if (bool_not(is_physical_float(read_attribute(model, element_name, "last_in")))):
@@ -73,19 +69,9 @@ Element function create_schedule(model : Element):
 			String source
 			source = readAssociationSource(model, set_pop(incoming_links))
 			list_append(successors, create_tuple(source, element_name))
-			log("Found edge: " + source + " --> " + element_name)
 
 	Element values
 	values = create_node()
-	//dict_add(values, "model", model)
-	//dict_add(values, "S", create_node())
-	//dict_add(values, "index", 0)
-	//dict_add(values, "indices", create_node())
-	//dict_add(values, "lowlink", create_node())
-	//dict_add(values, "onStack", create_node())
-	//dict_add(values, "successors", successors)
-	//dict_add(values, "predecessors", predecessors)
-	//dict_add(values, "SCC", create_node())
 
 	dict_add(values, "edges", successors)
 	dict_add(values, "nodes", allInstances(model, "FullRuntime/Block"))
@@ -94,39 +80,21 @@ Element function create_schedule(model : Element):
 	dict_add(values, "visited_topSort", set_create())
 	dict_add(values, "unvisited_strongComp", set_create())
 
-	log("Toposort")
-	//nodes = get_topolist(values)
-	//while (list_len(nodes) > 0):
-	//	log("Strong connect")
-	//	strongconnect(list_pop_final(nodes), values)
-
 	dict_overwrite(values, "SCC", strongComp(values))
 
-	//nodes = allInstances(model, "FullRuntime/Block")
-	//while (set_len(nodes) > 0):
-	//	strongconnect(set_pop(nodes), values)
-
-	log("OK")
-
 	return values["SCC"]!
 
 Void function topSort(values : Element):
 	Element nodes_copy
 	String node
 
-	// for node in graph:
-	//     node.visited = False
 	dict_overwrite(values, "visited_topSort", set_create())
 
-	// for node in graph:
-	//     if not node.visited:
-	//          dfsLabelling(node)
 	nodes_copy = set_copy(values["nodes"])
 	while (set_len(nodes_copy) > 0):
 		node = set_pop(nodes_copy)
 		if (bool_not(set_in(values["visited_topSort"], node))):
 			dfsLabelling(values, node)
-	log("Order: " + dict_to_string(values["orderNumber"]))
 
 	return!
 
@@ -238,7 +206,6 @@ Element function strongComp(values : Element):
 
 		component = dfsCollect(values, start_node)
 		list_append(sccs, component)
-		log("Got strong component: " + list_to_string(component))
 
 	return sccs!
 
@@ -329,7 +296,6 @@ Void function strongconnect(v : String, values : Element):
 			list_append(scc, w)
 		// output the current strongly connected component
 		list_insert(values["SCC"], scc, 0)
-		log("Found new SCC: " + list_to_string(scc))
 	return!
 
 Boolean function solve_scc(model : Element, scc : Element):
@@ -423,9 +389,6 @@ Boolean function solve_scc(model : Element, scc : Element):
 
 		i = i + 1
 
-	// Constructed a complete matrix, so we can start!
-	log(matrix2string(m))
-
 	// Solve matrix now
 	eliminateGaussJordan(m)
 
@@ -471,7 +434,6 @@ Float function step_simulation(model : Element, schedule : Element, time : Float
 
 		if (list_len(scc) > 1):
 			if (bool_not(solve_scc(model, scc))):
-				log("ALGEBRAIC_LOOP")
 				output("ALGEBRAIC_LOOP")
 				return time!
 		else:
@@ -479,7 +441,6 @@ Float function step_simulation(model : Element, schedule : Element, time : Float
 
 			// Execute "block"
 			blocktype = read_type(model, block)
-			//log("Execute block " + block + " : " + blocktype)
 			incoming = set_copy(inputs[block])
 			if (blocktype == "FullRuntime/ConstantBlock"):
 				signal = cast_float(read_attribute(model, block, "value"))

+ 2 - 2
models/ParallelDEVS/metamodels/PDEVS.mvc

@@ -1,4 +1,4 @@
-ComplexAttribute ActionCode {}
+ActionLanguage ActionCode {}
 SimpleAttribute String {}
 
 Class BaseDEVSBlock {
@@ -32,4 +32,4 @@ Class OutputPort: Port {}
 
 Association DEVSBlockToPort(BaseDEVSBlock, Port) {}
 Association DEVSInstanceToPort(DEVSInstance, Port) {}
-Association Channel (Port, Port) {}
+Association Channel (Port, Port) {}

+ 0 - 0
services/DEVS/models/.keepme


+ 23 - 22
unit/test_all.py

@@ -383,29 +383,29 @@ class TestModelverse(unittest.TestCase):
 
         got = element_list_nice("test/PetriNet")
         expected = \
-            [{'id': 'Natural', 'type': 'SimpleAttribute', 'constraint': None, 'name': 'Natural'},
-             {'id': 'String', 'type': 'SimpleAttribute', 'constraint': None, 'name': 'String'},
-             {'id': 'Place', 'type': 'Class', 'lower_cardinality': None, 'upper_cardinality': None, 'constraint': None, 'name': 'Place'},
-             {'id': 'Place_tokens', 'type': 'AttributeLink', '__source': 'Place', '__target': 'Natural', 'name': 'tokens', 'optional': False, 'constraint': None},
-             {'id': 'Place_name', 'type': 'AttributeLink', '__source': 'Place', '__target': 'String', 'name': 'name', 'optional': False, 'constraint': None},
-             {'id': 'Transition', 'type': 'Class', 'lower_cardinality': None, 'upper_cardinality': None, 'constraint': None, 'name': 'Transition'},
-             {'id': 'Transition_name', 'type': 'AttributeLink', '__source': 'Transition', '__target': 'String', 'name': 'name', 'optional': False, 'constraint': None},
-             {'id': 'P2T', 'type': 'Association', '__source': 'Place', '__target': 'Transition', 'source_lower_cardinality': None, 'target_lower_cardinality': None, 'source_upper_cardinality': None, 'target_upper_cardinality': None, 'constraint': None, 'name': 'P2T'},
-             {'id': 'P2T_weight', 'type': 'AttributeLink', '__source': 'P2T', '__target': 'Natural', 'name': 'weight', 'optional': False, 'constraint': None},
-             {'id': 'T2P', 'type': 'Association', '__source': 'Transition', '__target': 'Place', 'source_lower_cardinality': None, 'target_lower_cardinality': None, 'source_upper_cardinality': None, 'target_upper_cardinality': None, 'constraint': None, 'name': 'T2P'},
-             {'id': 'T2P_weight', 'type': 'AttributeLink', '__source': 'T2P', '__target': 'Natural', 'name': 'weight', 'optional': False, 'constraint': None}
+            [{'__id': 'Natural', '__type': 'SimpleAttribute', 'constraint': {'AL': ''}, 'name': 'Natural'},
+             {'__id': 'String', '__type': 'SimpleAttribute', 'constraint': {'AL': ''}, 'name': 'String'},
+             {'__id': 'Place', '__type': 'Class', 'lower_cardinality': None, 'upper_cardinality': None, 'constraint': {'AL': ''}, 'name': 'Place', 'abstract': None},
+             {'__id': 'Place_tokens', '__type': 'AttributeLink', '__source': 'Place', '__target': 'Natural', 'name': 'tokens', 'optional': False, 'constraint': {'AL': ''}},
+             {'__id': 'Place_name', '__type': 'AttributeLink', '__source': 'Place', '__target': 'String', 'name': 'name', 'optional': False, 'constraint': {'AL': ''}},
+             {'__id': 'Transition', '__type': 'Class', 'lower_cardinality': None, 'upper_cardinality': None, 'constraint': {'AL': ''}, 'name': 'Transition', 'abstract': None},
+             {'__id': 'Transition_name', '__type': 'AttributeLink', '__source': 'Transition', '__target': 'String', 'name': 'name', 'optional': False, 'constraint': {'AL': ''}},
+             {'__id': 'P2T', '__type': 'Association', '__source': 'Place', '__target': 'Transition', 'source_lower_cardinality': None, 'target_lower_cardinality': None, 'source_upper_cardinality': None, 'target_upper_cardinality': None, 'constraint': {'AL': ''}, 'name': 'P2T'},
+             {'__id': 'P2T_weight', '__type': 'AttributeLink', '__source': 'P2T', '__target': 'Natural', 'name': 'weight', 'optional': False, 'constraint': {'AL': ''}},
+             {'__id': 'T2P', '__type': 'Association', '__source': 'Transition', '__target': 'Place', 'source_lower_cardinality': None, 'target_lower_cardinality': None, 'source_upper_cardinality': None, 'target_upper_cardinality': None, 'constraint': {'AL': ''}, 'name': 'T2P'},
+             {'__id': 'T2P_weight', '__type': 'AttributeLink', '__source': 'T2P', '__target': 'Natural', 'name': 'weight', 'optional': False, 'constraint': {'AL': ''}},
             ]
         compare_unordered_lists(got, expected)
 
         got = element_list_nice("test/my_pn")
         expected = \
-            [{'id': 'p1', 'type': 'Place', 'tokens': 1, 'name': 'p1'},
-             {'id': 'p2', 'type': 'Place', 'tokens': 2, 'name': 'p2'},
-             {'id': 'p3', 'type': 'Place', 'tokens': 3, 'name': 'p3'},
-             {'id': 't1', 'type': 'Transition', 'name': 't1'},
-             {'id': '__0', 'type': 'P2T', '__source': 'p1', '__target': 't1', 'weight': 1},
-             {'id': '__1', 'type': 'P2T', '__source': 'p2', '__target': 't1', 'weight': 1},
-             {'id': '__2', 'type': 'T2P', '__source': 't1', '__target': 'p3', 'weight': 2}
+            [{'__id': 'p1', '__type': 'Place', 'tokens': 1, 'name': 'p1'},
+             {'__id': 'p2', '__type': 'Place', 'tokens': 2, 'name': 'p2'},
+             {'__id': 'p3', '__type': 'Place', 'tokens': 3, 'name': 'p3'},
+             {'__id': 't1', '__type': 'Transition', 'name': 't1'},
+             {'__id': '__0', '__type': 'P2T', '__source': 'p1', '__target': 't1', 'weight': 1},
+             {'__id': '__1', '__type': 'P2T', '__source': 'p2', '__target': 't1', 'weight': 1},
+             {'__id': '__2', '__type': 'T2P', '__source': 't1', '__target': 'p3', 'weight': 2}
             ]
         compare_unordered_lists(got, expected)
 
@@ -415,8 +415,9 @@ class TestModelverse(unittest.TestCase):
         count_nodes = 0
         count_edges = 0
         for entry in element_list_nice("test/PetriNet"):
-            assert entry["type"] in ["Node", "Edge"]
-            if entry["type"] == "Node":
+            print(entry)
+            assert entry["__type"] in ["Node", "Edge"]
+            if entry["__type"] == "Node":
                 assert len(entry) == 2
                 count_nodes += 1
             else:
@@ -428,8 +429,8 @@ class TestModelverse(unittest.TestCase):
         count_nodes = 0
         count_edges = 0
         for entry in element_list_nice("test/my_pn"):
-            assert entry["type"] in ["Node", "Edge"]
-            if entry["type"] == "Node":
+            assert entry["__type"] in ["Node", "Edge"]
+            if entry["__type"] == "Node":
                 assert len(entry) == 2
                 count_nodes += 1
             else:

+ 46 - 8
wrappers/classes/modelverse.xml

@@ -138,6 +138,9 @@
                             <parameter expr='urlencode({"op": "set_input", "data": json.dumps(value), "taskname": self.taskname})'/>
                             <parameter expr='None'/>
                         </raise>
+                        <script>
+                            #print("Request: " + str(value))
+                        </script>
                     </transition>
 
                     <transition event="request" cond="not isinstance(value, type([]))" target=".">
@@ -146,6 +149,9 @@
                             <parameter expr='urlencode({"op": "set_input", "value": json.dumps(value), "taskname": self.taskname})'/>
                             <parameter expr='None'/>
                         </raise>
+                        <script>
+                            #print("Request: " + str(value))
+                        </script>
                     </transition>
 
                     <transition event="request_raw" target=".">
@@ -375,6 +381,20 @@
                         </transition>
                     </state>
 
+                    <state id="AL_text">
+                        <onentry>
+                            <raise event="request">
+                                <parameter expr="['AL_text', self.parameters[0]]"/>
+                            </raise>
+                        </onentry>
+
+                        <transition cond="self.expect_response_partial('Success: ', pop=False)" target="../../wait_for_action/history">
+                            <raise event="result">
+                                <parameter expr="'\n'.join(self.split_response(self.responses.pop(0)))"/>
+                            </raise>
+                        </transition>
+                    </state>
+
                     <state id="model_list_full">
                         <onentry>
                             <raise event="request">
@@ -416,6 +436,7 @@
                         <transition target="../../wait_for_action/history">
                             <script>
                                 self.registered_metamodel[self.parameters[0]] = self.parameters[1]
+                                #print("Alter context of " + str(self.parameters[0]) + " to " + str(self.parameters[1]))
                             </script>
                         </transition>
                     </state>
@@ -1035,8 +1056,11 @@
                         <transition cond="self.expect_response_partial('Success: ', pop=False)" target="../../wait_for_action/history">
                             <script>
                                 response = self.responses.pop(0).split(": ", 1)[1].strip()
-                                values = {line.split(" : ", 1)[0]: line.split(" : ", 1)[1] for line in response.split("\n")}
-                                values = {key: json.loads(values[key].split(" = ", 1)[1]) for key in values}
+                                if "\n" in response:
+                                    values = {line.split(" : ", 1)[0]: line.split(" : ", 1)[1] for line in response.split("\n")}
+                                    values = {key: json.loads(values[key].split(" = ", 1)[1]) for key in values}
+                                else:
+                                    values = {}
                             </script>
                             <raise event="result">
                                 <parameter expr="values"/>
@@ -1118,15 +1142,23 @@
                     <state id="attr_assign_code">
                         <onentry>
                             <raise event="request">
-                                <parameter expr="['attr_add_code', self.parameters[1], self.parameters[2], self.parameters[3]]"/>
+                                <parameter expr="['attr_add_code', self.parameters[1], self.parameters[2]]"/>
                             </raise>
                         </onentry>
 
-                        <transition cond="self.expect_response('Success')" target="../../wait_for_action/history">
-                            <raise event="result">
-                                <parameter expr="None"/>
-                            </raise>
-                        </transition>
+                        <state id="sent">
+                            <transition cond="self.expect_response('Waiting for code constructors...')" target=".">
+                                <raise event="request">
+                                    <parameter expr="[self.parameters[3]]"/>
+                                </raise>
+                            </transition>
+
+                            <transition cond="self.expect_response('Success')" target="../../../wait_for_action/history">
+                                <raise event="result">
+                                    <parameter expr="None"/>
+                                </raise>
+                            </transition>
+                        </state>
                     </state>
 
                     <state id="attr_delete">
@@ -1576,6 +1608,12 @@
                             </script>
                         </transition>
 
+                        <transition cond="self.expect_action('AL_text')" target="../../operations/AL_text">
+                            <script>
+                                self.load_action()
+                            </script>
+                        </transition>
+
                         <transition cond="self.expect_action('verify')" target="../../operations/verify">
                             <script>
                                 self.load_action()

+ 4 - 0
wrappers/modelverse.py

@@ -443,6 +443,10 @@ def attr_delete(model_name, ID, attr):
     INPUT("attr_delete", [model_name, ID, attr])
     return OUTPUT()
 
+def AL_text(code_location):
+    INPUT("AL_text", [code_location])
+    return OUTPUT()
+
 def read_outgoing(model_name, ID, typename):
     INPUT("read_outgoing", [model_name, ID, typename])
     return OUTPUT()

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 233 - 181
wrappers/modelverse_SCCD.py