muMLE/transformation/topify/topify.py

52 lines
No EOL
2.6 KiB
Python

from uuid import UUID
from transformation.rule import RuleMatcherRewriter
from transformation.ramify import ramify
from util.loader import load_rules
from util.timer import Timer
from concrete_syntax.textual_od.renderer import render_od
import os
THIS_DIR = os.path.dirname(__file__)
class Topifier:
def __init__(self, state):
self.state = state
# meta-meta-model
self.scd_mmm = UUID(state.read_value(state.read_dict(state.read_root(), "SCD")))
self.scd_mmm_ramified = ramify(state, self.scd_mmm)
self.matcher_rewriter = RuleMatcherRewriter(state, self.scd_mmm, self.scd_mmm_ramified)
# topification is implemented via model transformation
self.rules = load_rules(state,
lambda rule_name, kind: f"{THIS_DIR}/rules/r_{rule_name}_{kind}.od",
self.scd_mmm_ramified, ["create_top", "create_inheritance"],
check_conformance=False,
)
# 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.
def topify_cd(self, cd: UUID):
with Timer("topify_cd"):
# 1. Execute rule 'create_top' once
rule = self.rules["create_top"]
match_set = list(self.matcher_rewriter.match_rule(cd, rule.lhs, rule.nacs, "create_top"))
if len(match_set) != 1:
raise Exception(f"Expected rule 'create_top' to match only once, instead got {len(match_set)} matches")
lhs_match = match_set[0]
cd, rhs_match = self.matcher_rewriter.exec_rule(cd, rule.lhs, rule.rhs, lhs_match, "create_top")
# 2. Execute rule 'create_inheritance' as many times as possible
rule = self.rules["create_inheritance"]
# for match in self.matcher_rewriter.match_rule(cd, rule.lhs, rule.nacs, "create_inheritance"):
# self.matcher_rewriter.exec_rule(cd, rule.lhs, rule.rhs, match, "create_inheritance", in_place=True)
# render_od(self.state, cd, self.scd_mmm)
while True:
iterator = self.matcher_rewriter.match_rule(cd, rule.lhs, rule.nacs, "create_inheritance")
# find first match, and re-start matching
try:
lhs_match = iterator.__next__() # may throw StopIteration
cd, rhs_match = self.matcher_rewriter.exec_rule(cd, rule.lhs, rule.rhs, lhs_match, "create_inheritance")
except StopIteration:
break # no more matches
return cd