Browse Source

Initial RRD support for rule generation

Yentl Van Tendeloo 7 years ago
parent
commit
96fff1b2a5
4 changed files with 98 additions and 57 deletions
  1. 1 1
      kernel/rules/MvK_rules.mvc
  2. 95 54
      kernel/rules/to_python.alc
  3. 1 1
      services/HUTN/main.py
  4. 1 1
      wrappers/modelverse_SCCD.py

+ 1 - 1
kernel/rules/MvK_rules.mvc

@@ -1730,7 +1730,7 @@ Rule Output_Init_N26 {
     Create N26_5 {}
     Match N26_6 {}
     Match N26_7 {}
-    Match N26_8 {
+    Create N26_8 {
         value = "'output'"
     }
 

+ 95 - 54
kernel/rules/to_python.alc

@@ -126,8 +126,13 @@ Boolean function main(model : Element):
 		// 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
+		Element all_nodes
+
+		log("Matching rule " + rule)
+		nodes = allAssociationDestinations(model, rule, "Rules/contains")
+		all_nodes = set_overlap(nodes, allInstances(model, "Rules/Match"))
+
 		create_edges = set_create()
 		explored = set_create()
 		while (set_len(nodes) > 0):
@@ -140,63 +145,99 @@ Boolean function main(model : Element):
 				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, "/", "_")
+				while (set_len(explored) < set_len(all_nodes)):
+					while (set_len(to_explore) > 0):
+						// Still explore more!
+						node = set_pop(to_explore)
+						log("Explore " + node)
+						set_add(explored, node)
+						source = string_replace(node, "/", "_")
 
-					edges = allOutgoingAssociationInstances(model, node, "Rules/MatchEdge")
-					while (set_len(edges) > 0):
-						edge = set_pop(edges)
-						new_node = readAssociationDestination(model, edge)
+						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, "/", "_")
+							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 (element_eq(name, read_root())):
+								String node_key
+								node_key = set_pop(allAssociationDestinations(model, edge, ""))
+								if (set_in(explored, node_key)):
+									result = result + "\t" + destination + ", = yield [('RDN', [" + source + ", " + string_replace(node_key, "/", "_") + "])]\n"
+									set_add(to_explore, new_node)
+								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"
+								if (read_type(model, edge) == "Rules/DeleteEdge"):
+									// Delete edge
+									result = result + "\t" + destination + "_DEL, = yield [('RDNE', [" + source + ", " + string_replace(node_key, "/", "_") + "])]\n"
+									result = result + "\tyield [('DE', [" + destination + "_DEL])]\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()
+								if (set_in(explored, new_node)):
+									// 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"
+
+									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()
+
+					// Check for nodes that are unexplored, but seemingly not reachable from the root directly
+					Element remaining
+					String check_elem
+					Boolean found
+					if (set_len(explored) < set_len(all_nodes)):
+						// Find all unexplored nodes
+						remaining = set_difference(all_nodes, explored)
+						log("Remain unexplored: " + set_to_string(remaining))
+						while (set_len(remaining) > 0):
+							check_elem = set_pop(remaining)
+
+							edges = allOutgoingAssociationInstances(model, check_elem, "Rules/MatchEdge")
+							found = False
+							while (set_len(edges) > 0):
+								edge = set_pop(edges)
+								new_node = readAssociationDestination(model, edge)
+								name = read_attribute(model, edge, "value")
+								if (set_in(explored, new_node)):
+									// We already explored this node, so we can do a RRD from this place!
+									if (bool_not(found)):
+										result = result + "\tmatched = []\n"
+									result = result + "\t_tmp, = yield [('RRD', [" + string_replace(new_node, "/", "_") + ", " + name + "])]\n"
+									result = result + "\tmatched.append(_tmp)\n"
+									found = True
+
+							// Iterated over all edges, so check how many we found!
+							if (found):
+								set_add(to_explore, check_elem)
+								set_add(explored, check_elem)
+								// Found at least one match, so we try to find an overlapping node
+								result = result + "\t" + string_replace(check_elem, "/", "_") + " = self.set_overlap(matched)[0]\n"
+
 			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
@@ -222,7 +263,7 @@ Boolean function main(model : Element):
 
 	result = result + "else:\n"
 	result = result + "\t# no rules were applicable, so idle for some time\n"
-	result = result + "\tTODO
+	result = result + "\tpass #TODO\n"
 
 	log("Got result:")
 	log(result)

+ 1 - 1
services/HUTN/main.py

@@ -22,7 +22,7 @@ def clean_code(code):
     code_fragments = [i[initial_tabs:] for i in code_fragments]
     code_fragments.append("")
     code = "\n".join(code_fragments)
-    return code
+    return code.encode('ascii', 'replace')
 
 def compile_service(port):
     start = time.time()

+ 1 - 1
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)
 
-Date:   Fri Nov 24 13:38:48 2017
+Date:   Mon Nov 27 10:48:12 2017
 
 Model author: Yentl Van Tendeloo
 Model name:   MvK Server