topify.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  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. import os
  6. THIS_DIR = os.path.dirname(__file__)
  7. # Given a class diagram, extend it (in-place) 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.
  8. def topify_cd(state, cd: UUID):
  9. # meta-meta-model
  10. scd_mmm = UUID(state.read_value(state.read_dict(state.read_root(), "SCD")))
  11. scd_mmm_ramified = ramify(state, scd_mmm)
  12. matcher_rewriter = RuleMatcherRewriter(state, scd_mmm, scd_mmm_ramified)
  13. # topification is implemented via model transformation
  14. rules = load_rules(state,
  15. lambda rule_name, kind: f"{THIS_DIR}/rules/r_{rule_name}_{kind}.od",
  16. scd_mmm_ramified, ["create_top", "create_inheritance"])
  17. # 1. Execute rule 'create_top' once
  18. rule = rules["create_top"]
  19. match_set = list(matcher_rewriter.match_rule(cd, rule.lhs, rule.nacs, "create_top"))
  20. if len(match_set) != 1:
  21. raise Exception(f"Expected rule 'create_top' to match only once, instead got {len(match_set)} matches")
  22. lhs_match = match_set[0]
  23. cd, rhs_match = matcher_rewriter.exec_rule(cd, rule.lhs, rule.rhs, lhs_match, "create_top")
  24. # 2. Execute rule 'create_inheritance' as many times as possible
  25. rule = rules["create_inheritance"]
  26. while True:
  27. iterator = matcher_rewriter.match_rule(cd, rule.lhs, rule.nacs, "create_inheritance")
  28. # find first match, and re-start matching
  29. try:
  30. lhs_match = iterator.__next__() # may throw StopIteration
  31. cd, rhs_match = matcher_rewriter.exec_rule(cd, rule.lhs, rule.rhs, lhs_match, "create_inheritance")
  32. except StopIteration:
  33. break # no more matches
  34. return cd