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