topify.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. from uuid import UUID
  2. from transformation.rule import RuleMatcherRewriter
  3. from transformation.ramify import ramify
  4. from util.loader import load_rules
  5. from util.timer import Timer
  6. from concrete_syntax.textual_od.renderer import render_od
  7. import os
  8. THIS_DIR = os.path.dirname(__file__)
  9. class Topifier:
  10. def __init__(self, state):
  11. self.state = state
  12. # meta-meta-model
  13. self.scd_mmm = UUID(state.read_value(state.read_dict(state.read_root(), "SCD")))
  14. self.scd_mmm_ramified = ramify(state, self.scd_mmm)
  15. self.matcher_rewriter = RuleMatcherRewriter(state, self.scd_mmm, self.scd_mmm_ramified)
  16. # topification is implemented via model transformation
  17. self.rules = load_rules(state,
  18. lambda rule_name, kind: f"{THIS_DIR}/rules/r_{rule_name}_{kind}.od",
  19. self.scd_mmm_ramified, ["create_top", "create_inheritance"],
  20. check_conformance=False,
  21. )
  22. # Given a class diagram, extend it with a "Top"-type, i.e., an (abstract) supertype of all types. The set of instances of the "Top" is always the set of all objects in the diagram.
  23. def topify_cd(self, cd: UUID):
  24. with Timer("topify_cd"):
  25. # 1. Execute rule 'create_top' once
  26. rule = self.rules["create_top"]
  27. match_set = list(self.matcher_rewriter.match_rule(cd, rule.lhs, rule.nacs, "create_top"))
  28. if len(match_set) != 1:
  29. raise Exception(f"Expected rule 'create_top' to match only once, instead got {len(match_set)} matches")
  30. lhs_match = match_set[0]
  31. cd, rhs_match = self.matcher_rewriter.exec_rule(cd, rule.lhs, rule.rhs, lhs_match, "create_top")
  32. # 2. Execute rule 'create_inheritance' as many times as possible
  33. rule = self.rules["create_inheritance"]
  34. # for match in self.matcher_rewriter.match_rule(cd, rule.lhs, rule.nacs, "create_inheritance"):
  35. # self.matcher_rewriter.exec_rule(cd, rule.lhs, rule.rhs, match, "create_inheritance", in_place=True)
  36. # render_od(self.state, cd, self.scd_mmm)
  37. while True:
  38. iterator = self.matcher_rewriter.match_rule(cd, rule.lhs, rule.nacs, "create_inheritance")
  39. # find first match, and re-start matching
  40. try:
  41. lhs_match = iterator.__next__() # may throw StopIteration
  42. cd, rhs_match = self.matcher_rewriter.exec_rule(cd, rule.lhs, rule.rhs, lhs_match, "create_inheritance")
  43. except StopIteration:
  44. break # no more matches
  45. return cd