Преглед изворни кода

Fixed even more bugs: matching and rewriting seems to work in with simple cases

Yentl Van Tendeloo пре 8 година
родитељ
комит
bf71a8f624

BIN
bootstrap/bootstrap.m.gz


+ 10 - 0
bootstrap/primitives.alc

@@ -265,3 +265,13 @@ Element function dict_copy(d : Element):
 
 	return result!
 
+Element function set_to_list(s : Element):
+	Element result
+	Element tmp
+
+	result = create_node()
+	tmp = set_copy(s)
+	while (read_nr_out(tmp) > 0):
+		list_append(result, set_pop(tmp))
+
+	return result!

+ 70 - 19
bootstrap/transform.alc

@@ -62,13 +62,10 @@ Element function get_possible_bindings(host_model : Element, LHS_model : Element
 	String typename
 	String original_typename
 
-	log("FIND BINDING")
 	options = create_node()
 
 	typename = reverseKeyLookup(LHS_model["metamodel"]["model"], dict_read_node(LHS_model["type_mapping"], LHS_model["model"][current_element]))
 	original_typename = string_substr(typename, 4, string_len(typename))
-	log("Found type: " + typename)
-	log("Original type: " + original_typename)
 
 	if (is_edge(LHS_model["model"][current_element])):
 		// Is an edge, so check for already bound source/target
@@ -77,20 +74,15 @@ Element function get_possible_bindings(host_model : Element, LHS_model : Element
 
 		if (bool_and(set_in(dict_keys(map), src_label), set_in(dict_keys(map), dst_label))):
 			// Source and destination are bound
-			log("MERGE")
 			options = allOutgoingAssociationInstances(host_model, map[src_label], original_typename)
-			log("SRC: " + set_to_string(allOutgoingAssociationInstances(host_model, map[src_label], original_typename)))
-			log("DST: " + set_to_string(allIncomingAssociationInstances(host_model, map[dst_label], original_typename)))
 			options = set_overlap(options, allIncomingAssociationInstances(host_model, map[dst_label], original_typename))
 
 		elif (set_in(dict_keys(map), src_label)):
 			// Source is bound
-			log("SOURCE")
 			options = allOutgoingAssociationInstances(host_model, map[src_label], original_typename)
 
 		elif (set_in(dict_keys(map), dst_label)):
 			// Destination is bound
-			log("DESTINATION")
 			options = allIncomingAssociationInstances(host_model, map[dst_label], original_typename)
 
 		else:
@@ -106,21 +98,17 @@ Element function get_possible_bindings(host_model : Element, LHS_model : Element
 	String option
 
 	filtered_options = create_node()
-	log("Checking options")
 	while (read_nr_out(options) > 0):
 		option = set_pop(options)
 		// Check for detecting same element twice
-		log("Option: " + cast_v2s(option))
 		if (bool_not(set_in(map, option))):
 			// Option is already present with another label, so skip this!
 
 			// Check for local constraints of element
 			if (element_eq(read_attribute(LHS_model, current_element, "constraint"), read_root())):
 				// No local constraints, so all is well
-				log("No constraints, so ignore")
 				set_add(filtered_options, option)
 			else:
-				log("Verify constraints first")
 				// Check local constraints and add only if positive
 				Element constraint_function
 				constraint_function = read_attribute(LHS_model, current_element, "constraint")
@@ -128,8 +116,6 @@ Element function get_possible_bindings(host_model : Element, LHS_model : Element
 				result = constraint_function(host_model, option)
 				if (result):
 					set_add(filtered_options, option)
-		else:
-			log("ERROR: already matched")
 
 	return filtered_options!
 
@@ -153,20 +139,16 @@ Element function match(host_model : Element, LHS_model : Element):
 	set_add(mappings, create_node())
 	while (bool_and(read_nr_out(schedule) > 0, read_nr_out(mappings) > 0)):
 		current_element = list_pop(schedule, 0)
-		log("Finding options for " + cast_v2s(read_attribute(LHS_model, current_element, "label")))
 		new_mappings = create_node()
 
 		while (read_nr_out(mappings) > 0):
 			map = set_pop(mappings)
-			log("In context " + dict_to_string(map))
 			options = get_possible_bindings(host_model, LHS_model, current_element, map)
-			log("Found options " + set_to_string(options))
 
 			while (read_nr_out(options) > 0):
 				option = set_pop(options)
 				new_map = dict_copy(map)
 				dict_add(new_map, read_attribute(LHS_model, current_element, "label"), option)
-				log(" --> adding mapping " + dict_to_string(new_map))
 				set_add(new_mappings, new_map)
 
 		mappings = new_mappings
@@ -174,7 +156,76 @@ Element function match(host_model : Element, LHS_model : Element):
 	return mappings!
 
 Void function rewrite(host_model : Element, RHS_model : Element, mapping : Element):
-	output("TODO: rewrite!")
+	// Rewrite the host model based on the mapping combined with the RHS
+	Element LHS_labels
+	Element RHS_labels
+	Element RHS_elements
+	Element remaining
+	String elem
+	String label
+	Element labels_to_remove
+	Element labels_to_add
+	String typename
+	String original_typename
+	String src
+	String dst
+	Element new_mapping
+	String new_name
+
+	LHS_labels = dict_keys(mapping)
+	RHS_labels = create_node()
+
+	RHS_elements = allInstances(RHS_model, "Post_Element")
+	while (read_nr_out(RHS_elements) > 0):
+		set_add(RHS_labels, read_attribute(RHS_model, set_pop(RHS_elements), "label"))
+
+	remaining = set_overlap(LHS_labels, RHS_labels)
+	while (read_nr_out(remaining) > 0):
+		elem = set_pop(remaining)
+		set_remove(LHS_labels, elem)
+		set_remove(RHS_labels, elem)
+	log("LHS labels: " + set_to_string(LHS_labels))
+	log("RHS labels: " + set_to_string(RHS_labels))
+
+	labels_to_remove = LHS_labels
+	labels_to_add = set_to_list(RHS_labels)
+	log("Labels to add: " + dict_to_string(labels_to_add))
+	log("Labels to remove: " + set_to_string(labels_to_remove))
+
+	new_mapping = dict_copy(mapping)
+	while (read_nr_out(labels_to_remove) > 0):
+		// Remove the elements linked to these labels
+		label = set_pop(labels_to_remove)
+		log("Remove element linked to label " + label)
+		log("   --> " + cast_v2s(mapping[label]))
+		model_delete_element(host_model, mapping[label])
+		dict_delete(new_mapping, label)
+
+	while (read_nr_out(labels_to_add) > 0):
+		// Add the elementsl inked to these labels
+		label = list_pop(labels_to_add, 0)
+		log("Add element linked to label " + label)
+		if (is_edge(RHS_model["model"][mapping[label]])):
+			// Edge
+			src = read_attribute(RHS_model, reverseKeyLookup(RHS_model["model"], read_edge_src(RHS_model["model"][mapping[label]])), "label")
+			dst = read_attribute(RHS_model, reverseKeyLookup(RHS_model["model"], read_edge_dst(RHS_model["model"][mapping[label]])), "label")
+			// First check whether both source and destination are already created
+			if (bool_and(dict_in(new_mapping, src), dict_in(new_mapping, dst))):
+				// Both are present, so we can make the link
+				typename = reverseKeyLookup(RHS_model["metamodel"]["model"], dict_read_node(RHS_model["type_mapping"], RHS_model["model"][mapping[label]]))
+				original_typename = string_substr(typename, 5, string_len(typename))
+				new_name = instantiate_link(host_model, original_typename, "", new_mapping[src], new_mapping[dst])
+				dict_add(new_mapping, label, new_name)
+			else:
+				// Delay this a bit, until all are bound
+				list_append(labels_to_add, label)
+		else:
+			// Node
+			// Create the node and add it
+			typename = reverseKeyLookup(RHS_model["metamodel"]["model"], dict_read_node(RHS_model["type_mapping"], RHS_model["model"][mapping[label]]))
+			original_typename = string_substr(typename, 5, string_len(typename))
+			new_name = instantiate_node(host_model, original_typename, "")
+			dict_add(new_mapping, label, new_name)
 
 	return!
 

+ 103 - 0
integration/code/ramified_petrinets.mvc

@@ -0,0 +1,103 @@
+SCD Pre_PetriNets {
+    // Add AL MM
+
+    Class LHS{
+        constraint : Expression {
+            target_upper_cardinality = 1
+        }
+        upper_cardinality = 1
+        lower_cardinality = 1
+    }
+    Class NAC{}
+    Class Pre_Element{
+        label : String {
+            target_lower_cardinality = 1
+            target_upper_cardinality = 1
+        }
+        constraint : Expression {
+            target_upper_cardinality = 1
+        }
+    }
+    Association (LHS, Pre_Element)
+    Association (NAC, Pre_Element){
+        target_lower_cardinality = 1
+    }
+
+    Class Pre_Place{}
+    Class Pre_Transition{}
+    Class Pre_Natural{}
+
+    Association Pre_P2T(Pre_Place, Pre_Transition) {}
+    Association Pre_T2P(Pre_Transition, Pre_Place) {}
+
+    Association Pre_Place_tokens(Pre_Place, Pre_Natural) {
+        name = "Pre_tokens"
+        target_upper_cardinality = 1
+    }
+    Association Pre_P2T_weight(Pre_P2T, Pre_Natural) {
+        name = "Pre_weight"
+        target_upper_cardinality = 1
+    }
+    Association Pre_T2P_weight(Pre_T2P, Pre_Natural) {
+        name = "Pre_weight"
+        target_upper_cardinality = 1
+    }
+
+    Inheritance (Pre_Place, Pre_Element) {}
+    Inheritance (Pre_Natural, Pre_Element) {}
+    Inheritance (Pre_Transition, Pre_Element) {}
+    Inheritance (Pre_P2T, Pre_Element) {}
+    Inheritance (Pre_Place_tokens, Pre_Element) {}
+    Inheritance (Pre_P2T_weight, Pre_Element) {}
+    Inheritance (Pre_T2P_weight, Pre_Element) {}
+}
+
+SCD Post_PetriNets{
+    // Add AL MM
+
+    Class RHS{
+        action : FunctionDefinition
+        upper_cardinality = 1
+        lower_cardinality = 1
+    }
+
+    Class Post_Element {
+        label : String {
+            target_lower_cardinality = 1
+            target_upper_cardinality = 1
+        }
+        value : Expression {
+            target_upper_cardinality = 1
+        }
+    }
+
+    Class Post_Place{}
+    Class Post_Transitions{}
+    Class Post_Natural{}
+
+    Association Post_P2T(Post_Place, Post_Transition) {}
+    Association Post_T2P(Post_Transition, Post_Place) {}
+
+    Association (Post_Place, Post_Natural) {
+        name = "Post_tokens"
+        target_upper_cardinality = 1
+    }
+
+    Association (Post_P2T, Post_Natural) {
+        name = "Post_weight"
+        target_upper_cardinality = 1
+    }
+
+    Association (Post_T2P, Post_Natural) {
+        name = "Post_weight"
+        target_upper_cardinality = 1
+    }
+
+    Inheritance (Post_Place, Post_Element) {}
+    Inheritance (Post_Natural, Post_Element) {}
+    Inheritance (Post_Transition, Post_Element) {}
+    Inheritance (Post_P2T, Post_Element) {}
+    Inheritance (Post_Place_tokens, Post_Element) {}
+    Inheritance (Post_P2T_weight, Post_Element) {}
+    Inheritance (Post_T2P_weight, Post_Element) {}
+}

+ 24 - 1
integration/test_pn_interface.py

@@ -562,13 +562,36 @@ Element function constraint(model : Element, name : String):
                 "instantiate", "LHS_contains", "", "lhs", "p",
                 "instantiate", "LHS_contains", "", "lhs", "t",
                 "instantiate", "LHS_contains", "", "lhs", "pt",
+                "instantiate", "LHS_contains", "", "lhs", "tokens",
+                "instantiate", "LHS_contains", "", "lhs", "p_tokens",
                 "attr_add", "tokens", "label", "0_tokens",
                 "attr_add", "p_tokens", "label", "1_p_tokens",
                 "attr_add", "p", "label", "2_p",
                 "attr_add", "t", "label", "3_t",
                 "attr_add", "pt", "label", "4_pt",
                 "exit",
-             "transform", "pn", "pn_LHS", "pn_LHS",
+             "new", "PetriNets_POST", "pn_RHS",
+                "instantiate", "RHS", "rhs",
+                "instantiate", "Post_Place", "p",
+                "instantiate", "Post_Place", "p2",
+                "instantiate", "Post_Transition", "t",
+                "instantiate", "Post_Natural", "tokens",
+                "instantiate", "Post_Place_tokens", "p_tokens", "p", "tokens",
+                "instantiate", "RHS_contains", "", "rhs", "p",
+                "instantiate", "RHS_contains", "", "rhs", "p2",
+                "instantiate", "RHS_contains", "", "rhs", "t",
+                "instantiate", "RHS_contains", "", "rhs", "p_tokens",
+                "instantiate", "RHS_contains", "", "rhs", "tokens",
+                "attr_add", "tokens", "label", "0_tokens",
+                "attr_add", "p_tokens", "label", "1_p_tokens",
+                "attr_add", "p", "label", "2_p",
+                "attr_add", "t", "label", "3_t",
+                "attr_add", "p2", "label", "5_p",
+                "exit",
+             "transform", "pn", "pn_LHS", "pn_RHS",
+             "load", "pn",
+                "list",
+                "exit",
                 ],
             None, "PO"))
 

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

@@ -101,3 +101,4 @@ String function set_to_string(set : Element)
 String function dict_to_string(dict : Element)
 Element function set_overlap(sa : Element, sb : Element)
 Element function dict_copy(dict : Element)
+Element function set_to_list(s : Element)

+ 1 - 0
interface/HUTN/includes/ramify.alh

@@ -0,0 +1 @@
+Element function ramify(model : Element)