transform.alc 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. include "primitives.alh"
  2. include "object_operations.alh"
  3. include "modelling.alh"
  4. Element function make_matching_schedule(LHS_model : Element):
  5. Element schedule
  6. Element workset
  7. Element all_elements
  8. Element full_all_elements
  9. Integer required_size
  10. String new_element
  11. Integer counter
  12. String next
  13. // Initialize
  14. schedule = create_node()
  15. workset = create_node()
  16. all_elements = allInstances(LHS_model, "Pre_Element")
  17. full_all_elements = set_copy(all_elements)
  18. required_size = read_nr_out(all_elements)
  19. // Need to keep adding to the schedule
  20. while (read_nr_out(schedule) < required_size):
  21. // workset is empty, but we still need to add to the list
  22. // Therefore, we pick a random, unbound node, and add it to the workset
  23. new_element = set_pop(all_elements)
  24. while (bool_or(set_in(schedule, new_element), is_edge(LHS_model["model"][new_element]))):
  25. // Element is not usable, so pick another one
  26. new_element = set_pop(all_elements)
  27. set_add(workset, new_element)
  28. // Handle the workset
  29. while (read_nr_out(workset) > 0):
  30. // Still elements in the workset, so pop from these first
  31. next = set_pop(workset)
  32. // Check if element might not be already used somewhere
  33. if (bool_not(set_in(schedule, next))):
  34. if (set_in(full_all_elements, next)):
  35. list_append(schedule, next)
  36. // If it is an edge, we should also add the target and source
  37. if (is_edge(LHS_model["model"][next])):
  38. // Add the target/source to the schedule
  39. set_add(workset, reverseKeyLookup(LHS_model["model"], read_edge_src(LHS_model["model"][next])))
  40. set_add(workset, reverseKeyLookup(LHS_model["model"], read_edge_dst(LHS_model["model"][next])))
  41. // Also add all outgoing links
  42. counter = read_nr_out(LHS_model["model"][next])
  43. while (counter > 0):
  44. counter = counter - 1
  45. if (set_in_node(LHS_model["model"], read_out(LHS_model["model"][next], counter))):
  46. set_add(workset, reverseKeyLookup(LHS_model["model"], read_out(LHS_model["model"][next], counter)))
  47. return schedule!
  48. Element function get_possible_bindings(host_model : Element, LHS_model : Element, current_element : String, map : Element):
  49. Element options
  50. output("FIND BINDING")
  51. options = create_node()
  52. return options!
  53. Element function match(host_model : Element, LHS_model : Element):
  54. // Match the LHS_model to the host_model, returning all possible mappings from LHS_model elements to host_model elements
  55. // Make the schedule first
  56. Element schedule
  57. schedule = make_matching_schedule(LHS_model)
  58. // Now follow the schedule, incrementally building all mappings
  59. Element mappings
  60. Element new_mappings
  61. Element new_map
  62. String current_element
  63. Element map
  64. String option
  65. Element options
  66. mappings = create_node()
  67. set_add(mappings, create_node())
  68. while (bool_and(read_nr_out(schedule) > 0, read_nr_out(mappings) > 0)):
  69. current_element = list_pop(schedule, 0)
  70. log("Finding options for " + current_element)
  71. new_mappings = create_node()
  72. while (read_nr_out(mappings) > 0):
  73. map = set_pop(mappings)
  74. log("In context " + set_to_string(map))
  75. options = get_possible_bindings(host_model, LHS_model, current_element, map)
  76. log("Found options " + set_to_string(options))
  77. while (read_nr_out(options) > 0):
  78. option = set_pop(options)
  79. new_map = set_copy(map)
  80. dict_add(new_map, current_element, option)
  81. log(" --> adding mapping " + set_to_string(new_map))
  82. set_add(new_mappings, new_map)
  83. mappings = new_mappings
  84. return mappings!
  85. Void function rewrite(host_model : Element, RHS_model : Element, mapping : Element):
  86. output("TODO: rewrite!")
  87. return!
  88. Void function transform(host_model : Element, LHS_model : Element, RHS_model : Element):
  89. Element mapping
  90. Element mappings
  91. // Get all possible mappings
  92. mappings = match(host_model, LHS_model)
  93. // Select one such mapping and rewrite it
  94. if (read_nr_out(mappings) > 0):
  95. // Mapping found, so can rewrite it
  96. mapping = set_pop(mappings)
  97. rewrite(host_model, RHS_model, mapping)
  98. else:
  99. output("No mapping found!")
  100. return!