Browse Source

Add code for actual rule application

Yentl Van Tendeloo 7 years ago
parent
commit
579fa773d1
1 changed files with 101 additions and 1 deletions
  1. 101 1
      kernel/rules/to_python.alc

+ 101 - 1
kernel/rules/to_python.alc

@@ -20,6 +20,7 @@ Boolean function main(model : Element):
 	String value
 	Element explored
 	Element remainder_to_explore
+	String attr
 
 	explored = set_create()
 	result = "root, = yield [('RR', [])]\n"
@@ -115,7 +116,106 @@ Boolean function main(model : Element):
 					else:
 						result = result + " and " + string_replace(node, "/", "_") + "_V " + sign + " " + value
 
-		result = result + "): pass # Execute rule " + string_replace(rule, "/", "_") + "\n"
+		result = result + "):\n"
+		result = result + "\t# Execute rule " + rule + "\n"
+
+		// We know all the nodes that we already have (in variable "explored")
+		// Still have to match all "match" and "delete" elements
+		// For "match", it is exactly the same as before
+		// For "delete" edges, we match using "RD" and "RDE"
+		nodes = allAssociationDestinations(model, rule, "Rules/contains")
+		Element create_edges
+		create_edges = set_create()
+		explored = set_create()
+		while (set_len(nodes) > 0):
+			node = set_pop(nodes)
+			if (read_type(model, node) == "Rules/Root"):
+				// Found the root of this rule, so start exploring again
+			
+				// Keep following outgoing edges to find matching nodes
+				to_explore = set_create()
+				remainder_to_explore = set_create()
+				set_add(to_explore, node)
+
+				while (set_len(to_explore) > 0):
+					// Still explore more!
+					node = set_pop(to_explore)
+					source = string_replace(node, "/", "_")
+
+					edges = allOutgoingAssociationInstances(model, node, "Rules/MatchEdge")
+					while (set_len(edges) > 0):
+						edge = set_pop(edges)
+						new_node = readAssociationDestination(model, edge)
+
+						name = read_attribute(model, edge, "value")
+						destination = string_replace(new_node, "/", "_")
+
+						if (element_eq(name, read_root())):
+							String node_key
+							node_key = string_replace(set_pop(allAssociationDestinations(model, edge, "")), "/", "_")
+							if (set_in(explored, node_key)):
+								result = result + "\t" + destination + ", = yield [('RDN', [" + source + ", " + node_key + "])]\n"
+							else:
+								set_add(remainder_to_explore, node)
+								continue!
+
+							if (read_type(model, edge) == "Rules/DeleteEdge"):
+								// Delete edge
+								result = result + "\t" + destination + "_DEL, = yield [('RDNE', [" + source + ", " + node_key + "])]\n"
+								result = result + "\tyield [('DE', [" + destination + "_DEL])]\n"
+						else:
+							if (set_in(explored, destination)):
+								// Already visited this one in another way, so try to merge!
+								String rand
+								rand = random_string(10)
+								result = result + "\t" + rand + ", = yield [('RD', [" + source + ", " + name + "])]\n"
+								result = result + "\t" + "if " + rand + " != " + destination + ":\n"
+								// If the values don't agree, this is not a correct match, and we say that this element remains unmatched (i.e., assign None)
+								result = result + "\t" + "\t" + destination + " = None\n"
+							else:
+								// First visit to this element, so just assign
+								result = result + "\t" + destination + ", = yield [('RD', [" + source + ", " + name + "])]\n"
+								set_add(explored, destination)
+
+								String value
+								value = read_attribute(model, new_node, "value")
+								if (element_neq(value, read_root())):
+									// Match node has a value we should compare as well!
+									// Read out the value from the Modelverse
+									result = result + "\t" + destination + "_V, = yield [('RV', [" + destination + "])]\n"
+
+								set_add(to_explore, new_node)
+
+							if (read_type(model, edge) == "Rules/DeleteEdge"):
+								// Delete edge
+								result = result + "\t" + destination + "_DEL, = yield [('RDE', [" + source + ", " + name + "])]\n"
+								result = result + "\tyield [('DE', [" + destination + "_DEL])]\n"
+
+					if (bool_and(set_len(to_explore) == 0, set_len(remainder_to_explore) > 0)):
+						to_explore = remainder_to_explore
+						remainder_to_explore = set_create()
+			elif (read_type(model, node) == "Rules/Create"):
+				// A node that we should create: do that already, as otherwise we might have to sort
+				String attr
+				attr = read_attribute(model, node, "value")
+				if (element_eq(attr, read_root())):
+					// Create empty node
+					result = result + "\t" + string_replace(node, "/", "_") + ", = yield [('CN', [])]\n"
+				else:
+					// Create value node
+					result = result + "\t" + string_replace(node, "/", "_") + ", = yield [('CNV', [" + cast_string(attr) + "])]\n"
+			elif (read_type(model, node) == "Rules/CreateEdge"):
+				// Encounter a create edge, so alreade record this for later
+				set_add(create_edges, node)
+
+		// Now create all the new edges, given that we assume everything to be matched
+		while (set_len(create_edges) > 0):
+			edge = set_pop(create_edges)
+			attr = read_attribute(model, edge, "value")
+			if (element_neq(attr, read_root())):
+				result = result + "\t" + string_replace(edge, "/", "_") + ", = yield [('CD', [" + string_replace(readAssociationSource(model, edge), "/", "_") + ", " + attr + ", " + string_replace(readAssociationDestination(model, edge), "/", "_") + "])]\n"
+			else:
+				result = result + "\t" + string_replace(edge, "/", "_") + ", = yield [('CE', [" + string_replace(readAssociationSource(model, edge), "/", "_") + ", " + string_replace(readAssociationDestination(model, edge), "/", "_") + "])]\n"
 
 	log("Got result:")
 	log(result)