include "primitives.alh" include "object_operations.alh" include "modelling.alh" Element function make_matching_schedule(LHS_model : Element): Element schedule Element workset Element all_elements Integer required_size String new_element Integer counter String next // Initialize schedule = create_node() workset = create_node() all_elements = allInstances(LHS_model, "Pre_Element") required_size = read_nr_out(all_elements) // Need to keep adding to the schedule while (read_nr_out(schedule) < required_size): // workset is empty, but we still need to add to the list // Therefore, we pick a random, unbound node, and add it to the workset new_element = set_pop(all_elements) log("Pick random: " + cast_v2s(new_element)) while (bool_or(set_in(schedule, new_element), is_edge(LHS_model["model"][new_element]))): log("Picked stupid: " + cast_v2s(new_element)) // Element is not usable, so pick another one new_element = set_pop(all_elements) log("Picked: " + cast_v2s(new_element)) set_add(workset, new_element) // Handle the workset while (read_nr_out(workset) > 0): // Still elements in the workset, so pop from these first next = set_pop(workset) log("Working on " + cast_v2s(next)) // Check if element might not be already used somewhere log("Check if already in schedule") if (bool_not(set_in(schedule, next))): log("NO") list_append(schedule, next) // If it is an edge, we should also add the target and source log("Edge?") if (is_edge(LHS_model["model"][next])): log("YES") // Add the target/source to the schedule set_add(workset, reverseKeyLookup(LHS_model["model"], read_edge_src(LHS_model["model"][next]))) set_add(workset, reverseKeyLookup(LHS_model["model"], read_edge_dst(LHS_model["model"][next]))) // Also add all outgoing links log("Recurse") counter = read_nr_out(LHS_model["model"][next]) while (counter > 0): log("Check") counter = counter - 1 if (set_in_node(LHS_model["model"], read_out(LHS_model["model"][next], counter))): log("ADD") set_add(workset, reverseKeyLookup(LHS_model["model"], read_out(LHS_model["model"][next], counter))) log("DONE") return schedule! Void function transform(host_model : Element, LHS_model : Element, RHS_model : Element): Element schedule schedule = make_matching_schedule(LHS_model) output("Got schedule") while (read_nr_out(schedule) > 0): output(list_pop(schedule, 0)) return!