|
@@ -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)
|