123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- 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
- Element full_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")
- full_all_elements = set_copy(all_elements)
- 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)
- while (bool_or(set_in(schedule, new_element), is_edge(LHS_model["model"][new_element]))):
- // Element is not usable, so pick another one
- new_element = set_pop(all_elements)
- 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)
- // Check if element might not be already used somewhere
- if (bool_not(set_in(schedule, next))):
- if (set_in(full_all_elements, next)):
- list_append(schedule, next)
- // If it is an edge, we should also add the target and source
- if (is_edge(LHS_model["model"][next])):
- // 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
- counter = read_nr_out(LHS_model["model"][next])
- while (counter > 0):
- counter = counter - 1
- if (set_in_node(LHS_model["model"], read_out(LHS_model["model"][next], counter))):
- set_add(workset, reverseKeyLookup(LHS_model["model"], read_out(LHS_model["model"][next], counter)))
- return schedule!
- Element function get_possible_bindings(host_model : Element, LHS_model : Element, current_element : String, map : Element):
- Element options
- output("FIND BINDING")
- options = create_node()
- return options!
- Element function match(host_model : Element, LHS_model : Element):
- // Match the LHS_model to the host_model, returning all possible mappings from LHS_model elements to host_model elements
- // Make the schedule first
- Element schedule
- schedule = make_matching_schedule(LHS_model)
- // Now follow the schedule, incrementally building all mappings
- Element mappings
- Element new_mappings
- Element new_map
- String current_element
- Element map
- String option
- Element options
- mappings = create_node()
- set_add(mappings, create_node())
- while (bool_and(read_nr_out(schedule) > 0, read_nr_out(mappings) > 0)):
- current_element = list_pop(schedule, 0)
- log("Finding options for " + current_element)
- new_mappings = create_node()
- while (read_nr_out(mappings) > 0):
- map = set_pop(mappings)
- log("In context " + set_to_string(map))
- options = get_possible_bindings(host_model, LHS_model, current_element, map)
- log("Found options " + set_to_string(options))
- while (read_nr_out(options) > 0):
- option = set_pop(options)
- new_map = set_copy(map)
- dict_add(new_map, current_element, option)
- log(" --> adding mapping " + set_to_string(new_map))
- set_add(new_mappings, new_map)
- mappings = new_mappings
- return mappings!
- Void function rewrite(host_model : Element, RHS_model : Element, mapping : Element):
- output("TODO: rewrite!")
- return!
- Void function transform(host_model : Element, LHS_model : Element, RHS_model : Element):
- Element mapping
- Element mappings
- // Get all possible mappings
- mappings = match(host_model, LHS_model)
- // Select one such mapping and rewrite it
- if (read_nr_out(mappings) > 0):
- // Mapping found, so can rewrite it
- mapping = set_pop(mappings)
- rewrite(host_model, RHS_model, mapping)
- else:
- output("No mapping found!")
- return!
|