RAMification adds 'name' attribute, giving control over the names of created objects
This commit is contained in:
parent
7c01b126c2
commit
da4f1718ce
8 changed files with 64 additions and 32 deletions
|
|
@ -24,10 +24,13 @@ def render_petri_net(od: ODAPI):
|
||||||
dot += "node[fontname=Arial,fontsize=10];\n"
|
dot += "node[fontname=Arial,fontsize=10];\n"
|
||||||
dot += "subgraph places {"
|
dot += "subgraph places {"
|
||||||
dot += " node [shape=circle,fixedsize=true,label=\"\", height=.35,width=.35];"
|
dot += " node [shape=circle,fixedsize=true,label=\"\", height=.35,width=.35];"
|
||||||
for _, place_state in od.get_all_instances("PNPlaceState"):
|
for _, place in od.get_all_instances("PNPlace"):
|
||||||
place = od.get_target(od.get_outgoing(place_state, "pn_of")[0])
|
|
||||||
place_name = od.get_name(place)
|
place_name = od.get_name(place)
|
||||||
num_tokens = od.get_slot_value(place_state, "numTokens")
|
try:
|
||||||
|
place_state = od.get_source(od.get_incoming(place, "pn_of")[0])
|
||||||
|
num_tokens = od.get_slot_value(place_state, "numTokens")
|
||||||
|
except IndexError:
|
||||||
|
num_tokens = 0
|
||||||
dot += f" {place_name} [label=\"{place_name}\\n\\n{render_tokens(num_tokens)}\\n\\n\"];\n"
|
dot += f" {place_name} [label=\"{place_name}\\n\\n{render_tokens(num_tokens)}\\n\\n\"];\n"
|
||||||
dot += "}\n"
|
dot += "}\n"
|
||||||
dot += "subgraph transitions {"
|
dot += "subgraph transitions {"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
# Auto-generated by /home/maestro/repos/MV2/examples/semantics/translational/regenerate_mm.py
|
# Auto-generated by /home/maestro/repos/MV2/examples/semantics/translational/regenerate_mm.py.
|
||||||
|
|
||||||
# PlantUML visualization: https://deemz.org/plantuml/pdf/hPT1Zzem48Nl-HKMnqeWqcG1HLKFkuUg5nO9f1wHSSPiHB2HOofLxVxtsYOWTXKfByWSkCtdcNdFuqaYQjuqRFJ2JrnKzi-BLeqrl5AMZHXlsBJzRJl-_2-ZajZVXB7chJfT8QnWFvMbFPdaFMaFM2rNDHUqjjmIYgQdW5RduqOVI3LTt5_Q7CYi2SwNn1Lw2Usa3afJPexudl2Txvomx9uXppMCuTqOVJO2pKMcym2vgbfhSM3fP9A2uLaUccEh8tMrvPcCVHlI6pcRNzpXOiw-qsjhAhNlA7EZJoXpaT_N66o5XlBqFlJcdK4bySKz8xG43fNteJz8aU5M6pHyD_jG-79Zk6egMsa54yfEZwsMxjuh4fRlQhWF8k_sQwKEA88-oD7cuCePf8Uy3A2Z_asbSzYprZLnzSaW0uZvT7gREsitrJe7H3lEOA88XIQzrVWfyEtVUDpF_4fvFyxV5GZdvtXCd9CMmBdh2EAuZDWx_mW0sRbPYcO75EkV2KnPvx-eoieighBfF2ekYsjZoMCQ1L9sGB42A1OsYd-AWEm8lsJznORX2E9cCOsIPpcWh7-KmEnsPLGfPDJnwLRVg0DgDujxAu1f34lXNqVePSpOA6MJ2NFBx7ZytJsz8sohBfW6y_N8W9xwSxu0V1zLC6w0zyH_UTmEIE43tCvOCC7LwyalYuZBd2qUACID2NVERGL3wdaQBaXOXGfsKbj8ayL3cYoy9dk_NLTYMxjz55b55e-S5CIfceis_iEclsibFUI2e4xxVVqg_mC=
|
# Merged run-time meta-models of 'Petri Net' and 'Port' formalisms.
|
||||||
|
# An abstract 'Top'-class (superclass of everything else), and a 'generic_link'-association (which can connect everything with everything) have also been added.
|
||||||
|
|
||||||
|
# PlantUML visualization: https://deemz.org/plantuml/pdf/hPTDZzem48Rl-HKMnqgWa0sKeAg7tKFL2ui4KezeuXWs8jYHOofLxVxtZiE7s5KatY3dm8bvF3Flp7WSoOgQHWnUg2PPkZylHZVEKgcT60XgH7p-DXq__alZMIh-Ha8qRsLzWOYv-AcTsYaRlKVd0vQBPKLIhHmv1QFp5gsFXxNPAzrqSNyPkrTsfM1_i-G2FPbsKdkvcMLCV8yezvcJJjmojiSAnL3SZJ57As5VygA5N5IjZDoByMWq1iqBQfFZoeFgIikpikwjJsx6SN6g3hOv-aold2trhYFCjQbHPaAtCRPbXPgcNszDhxNJAwHKtJBQbA2caycjwG-bbILdB6mkFmI-M5lIJUbAer72zAcpnfOBxdkjfAEyWlCmfUvwBVKUHSm-o77sWSFffGUT1j31_5O5LzYpCPKY_Qb0-X6lSsV5KwrpG9p76KhCapRGwEu__HJuzcyulCzCPtGVvti5m_4S3ubZQKFYqcqCuBYxGUycav1Iy9q2u7WqWzwbGExyhGFYA0zQA5aM59SNGN55sAuWeExmGe6KxT5aKo3O7eMIAi2x6TnaKB0yQq5SZ1JA5C_TKzWc2pe-UVKDEb4cCcWP8-EpXnHvWjoChCLWB4OZmSliSFYThzu1jbNFXTbY_dfaYuxzELy0lhUQ2x98VldbSJrW31_0E-DSIDAljLyMWGxrPV508DpNVCvr1GFEuUTPVq7yAZGNjTv0cYGFQP9uJNP-koxbfk9z5DaTr2CdjUAKpKaR_x01ifO-KWLfgyxvVVsw_Gy=
|
||||||
|
|
||||||
|
|
||||||
CapacityConstraint:Class
|
CapacityConstraint:Class
|
||||||
|
|
@ -74,16 +77,17 @@ operatingCapacities:GlobalConstraint {
|
||||||
```;
|
```;
|
||||||
}
|
}
|
||||||
WorkerSet_numWorkers:AttributeLink (WorkerSet -> Integer) {
|
WorkerSet_numWorkers:AttributeLink (WorkerSet -> Integer) {
|
||||||
|
constraint = `get_value(get_target(this)) >= 0`;
|
||||||
optional = False;
|
optional = False;
|
||||||
name = "numWorkers";
|
name = "numWorkers";
|
||||||
constraint = `get_value(get_target(this)) >= 0`;
|
|
||||||
}
|
}
|
||||||
PlaceState_numShips:AttributeLink (PlaceState -> Integer) {
|
PlaceState_numShips:AttributeLink (PlaceState -> Integer) {
|
||||||
|
optional = False;
|
||||||
name = "numShips";
|
name = "numShips";
|
||||||
constraint = `get_value(get_target(this)) >= 0`;
|
constraint = `get_value(get_target(this)) >= 0`;
|
||||||
optional = False;
|
|
||||||
}
|
}
|
||||||
ConnectionState_moved:AttributeLink (ConnectionState -> Boolean) {
|
ConnectionState_moved:AttributeLink (ConnectionState -> Boolean) {
|
||||||
|
name = "moved";
|
||||||
constraint = ```
|
constraint = ```
|
||||||
result = True
|
result = True
|
||||||
all_successors_moved = True
|
all_successors_moved = True
|
||||||
|
|
@ -101,26 +105,25 @@ ConnectionState_moved:AttributeLink (ConnectionState -> Boolean) {
|
||||||
result
|
result
|
||||||
```;
|
```;
|
||||||
optional = False;
|
optional = False;
|
||||||
name = "moved";
|
|
||||||
}
|
}
|
||||||
BerthState_status:AttributeLink (BerthState -> String) {
|
BerthState_status:AttributeLink (BerthState -> String) {
|
||||||
|
name = "status";
|
||||||
constraint = ```
|
constraint = ```
|
||||||
(
|
(
|
||||||
get_value(get_target(this)) in { "empty", "unserved", "served" }
|
get_value(get_target(this)) in { "empty", "unserved", "served" }
|
||||||
)
|
)
|
||||||
```;
|
```;
|
||||||
optional = False;
|
optional = False;
|
||||||
name = "status";
|
|
||||||
}
|
}
|
||||||
PNPlaceState_numTokens:AttributeLink (PNPlaceState -> Integer) {
|
PNPlaceState_numTokens:AttributeLink (PNPlaceState -> Integer) {
|
||||||
constraint = `"numTokens cannot be negative" if get_value(get_target(this)) < 0 else None`;
|
|
||||||
optional = False;
|
optional = False;
|
||||||
name = "numTokens";
|
name = "numTokens";
|
||||||
|
constraint = `"numTokens cannot be negative" if get_value(get_target(this)) < 0 else None`;
|
||||||
}
|
}
|
||||||
Clock_time:AttributeLink (Clock -> Integer) {
|
Clock_time:AttributeLink (Clock -> Integer) {
|
||||||
|
name = "time";
|
||||||
constraint = `get_value(get_target(this)) >= 0`;
|
constraint = `get_value(get_target(this)) >= 0`;
|
||||||
optional = False;
|
optional = False;
|
||||||
name = "time";
|
|
||||||
}
|
}
|
||||||
CapacityConstraint_shipCapacity:AttributeLink (CapacityConstraint -> Integer) {
|
CapacityConstraint_shipCapacity:AttributeLink (CapacityConstraint -> Integer) {
|
||||||
constraint = `get_value(get_target(this)) >= 0`;
|
constraint = `get_value(get_target(this)) >= 0`;
|
||||||
|
|
@ -128,10 +131,10 @@ CapacityConstraint_shipCapacity:AttributeLink (CapacityConstraint -> Integer) {
|
||||||
name = "shipCapacity";
|
name = "shipCapacity";
|
||||||
}
|
}
|
||||||
of:Association (State -> Stateful) {
|
of:Association (State -> Stateful) {
|
||||||
|
target_lower_cardinality = 1;
|
||||||
source_upper_cardinality = 1;
|
source_upper_cardinality = 1;
|
||||||
source_lower_cardinality = 1;
|
source_lower_cardinality = 1;
|
||||||
target_upper_cardinality = 1;
|
target_upper_cardinality = 1;
|
||||||
target_lower_cardinality = 1;
|
|
||||||
}
|
}
|
||||||
arc:Association (PNConnectable -> PNConnectable)
|
arc:Association (PNConnectable -> PNConnectable)
|
||||||
canOperate:Association (WorkerSet -> Berth) {
|
canOperate:Association (WorkerSet -> Berth) {
|
||||||
|
|
@ -139,10 +142,10 @@ canOperate:Association (WorkerSet -> Berth) {
|
||||||
}
|
}
|
||||||
connection:Association (Source -> Sink)
|
connection:Association (Source -> Sink)
|
||||||
pn_of:Association (PNPlaceState -> PNPlace) {
|
pn_of:Association (PNPlaceState -> PNPlace) {
|
||||||
source_lower_cardinality = 1;
|
|
||||||
target_upper_cardinality = 1;
|
target_upper_cardinality = 1;
|
||||||
target_lower_cardinality = 1;
|
target_lower_cardinality = 1;
|
||||||
source_upper_cardinality = 1;
|
source_upper_cardinality = 1;
|
||||||
|
source_lower_cardinality = 1;
|
||||||
}
|
}
|
||||||
generic_link:Association (Top -> Top)
|
generic_link:Association (Top -> Top)
|
||||||
isOperating:Association (WorkerSetState -> Berth) {
|
isOperating:Association (WorkerSetState -> Berth) {
|
||||||
|
|
@ -171,6 +174,7 @@ capacityOf:Association (CapacityConstraint -> Place) {
|
||||||
:Inheritance (connection -> Stateful)
|
:Inheritance (connection -> Stateful)
|
||||||
:Inheritance (CapacityConstraint -> Top)
|
:Inheritance (CapacityConstraint -> Top)
|
||||||
:Inheritance (Sink -> Top)
|
:Inheritance (Sink -> Top)
|
||||||
|
:Inheritance (generic_link -> Top)
|
||||||
:Inheritance (Berth -> Place)
|
:Inheritance (Berth -> Place)
|
||||||
:Inheritance (WorkerSet -> Stateful)
|
:Inheritance (WorkerSet -> Stateful)
|
||||||
:Inheritance (Place -> Source)
|
:Inheritance (Place -> Source)
|
||||||
|
|
@ -184,7 +188,6 @@ capacityOf:Association (CapacityConstraint -> Place) {
|
||||||
:Inheritance (WorkerSetState -> State)
|
:Inheritance (WorkerSetState -> State)
|
||||||
:Inheritance (Place -> Sink)
|
:Inheritance (Place -> Sink)
|
||||||
:Inheritance (BerthState -> PlaceState)
|
:Inheritance (BerthState -> PlaceState)
|
||||||
:Inheritance (generic_link -> Top)
|
|
||||||
:Inheritance (PNTransition -> PNConnectable)
|
:Inheritance (PNTransition -> PNConnectable)
|
||||||
:Inheritance (ConnectionState -> State)
|
:Inheritance (ConnectionState -> State)
|
||||||
:Inheritance (PNPlaceState -> Top)
|
:Inheritance (PNPlaceState -> Top)
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,9 @@ if __name__ == "__main__":
|
||||||
filename = THIS_DIR+"/merged_mm.od"
|
filename = THIS_DIR+"/merged_mm.od"
|
||||||
|
|
||||||
with open(filename, "w") as file:
|
with open(filename, "w") as file:
|
||||||
file.write(f"# Auto-generated by {__file__}\n\n")
|
file.write(f"# Auto-generated by {__file__}.\n\n")
|
||||||
|
file.write(f"# Merged run-time meta-models of 'Petri Net' and 'Port' formalisms.\n")
|
||||||
|
file.write(f"# An abstract 'Top'-class (superclass of everything else), and a 'generic_link'-association (which can connect everything with everything) have also been added.\n\n")
|
||||||
file.write(f"# PlantUML visualization: {plantuml_url}\n\n")
|
file.write(f"# PlantUML visualization: {plantuml_url}\n\n")
|
||||||
file.write(txt)
|
file.write(txt)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -273,11 +273,15 @@ def match_od(state, host_m, host_mm, pattern_m, pattern_mm, pivot={}):
|
||||||
if pattern_odapi.get_type_name(pattern_el) == "GlobalCondition":
|
if pattern_odapi.get_type_name(pattern_el) == "GlobalCondition":
|
||||||
return False
|
return False
|
||||||
# Super-cheap and unreliable way of filtering out the 'condition'-attribute, added to every class:
|
# Super-cheap and unreliable way of filtering out the 'condition'-attribute, added to every class:
|
||||||
return not (pattern_el_name.endswith("condition")
|
return ((not pattern_el_name.endswith("condition")
|
||||||
# as an extra safety measure, if the user defined her own 'condition' attribute, RAMification turned this into 'RAM_condition', and we can detect this
|
# as an extra safety measure, if the user defined her own 'condition' attribute, RAMification turned this into 'RAM_condition', and we can detect this
|
||||||
# of course this breaks if the class name already ended with 'RAM', but let's hope that never happens
|
# of course this breaks if the class name already ended with 'RAM', but let's hope that never happens
|
||||||
# also, we are assuming the default "RAM_" prefix is used, but the user can change this...
|
# also, we are assuming the default "RAM_" prefix is used, but the user can change this...
|
||||||
and not pattern_el_name.endswith("RAM_condition"))
|
or pattern_el_name.endswith("RAM_condition"))
|
||||||
|
and (
|
||||||
|
not pattern_el_name.endswith("name")
|
||||||
|
or pattern_el_name.endswith("RAM_name") # same thing here as with the condition, explained above.
|
||||||
|
))
|
||||||
|
|
||||||
g_names, guest = model_to_graph(state, pattern_m, pattern_mm,
|
g_names, guest = model_to_graph(state, pattern_m, pattern_mm,
|
||||||
_filter=is_matchable)
|
_filter=is_matchable)
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,9 @@ def ramify(state: State, model: UUID, prefix = "RAM_") -> UUID:
|
||||||
# In RHS, this is just a piece of action code
|
# In RHS, this is just a piece of action code
|
||||||
ramified_scd._create_attribute_link(prefix+class_name, actioncode_modelref, "condition", optional=True)
|
ramified_scd._create_attribute_link(prefix+class_name, actioncode_modelref, "condition", optional=True)
|
||||||
|
|
||||||
|
# Optional: specify name of object to create
|
||||||
|
ramified_scd._create_attribute_link(prefix+class_name, actioncode_modelref, "name", optional=True)
|
||||||
|
|
||||||
already_ramified.add(class_name)
|
already_ramified.add(class_name)
|
||||||
|
|
||||||
glob_cond = ramified_scd.create_class("GlobalCondition", abstract=None)
|
glob_cond = ramified_scd.create_class("GlobalCondition", abstract=None)
|
||||||
|
|
@ -97,6 +100,9 @@ def ramify(state: State, model: UUID, prefix = "RAM_") -> UUID:
|
||||||
# Additional constraint that can be specified
|
# Additional constraint that can be specified
|
||||||
ramified_scd._create_attribute_link(prefix+assoc_name, actioncode_modelref, "condition", optional=True)
|
ramified_scd._create_attribute_link(prefix+assoc_name, actioncode_modelref, "condition", optional=True)
|
||||||
|
|
||||||
|
# Optional: specify name of link to create
|
||||||
|
ramified_scd._create_attribute_link(prefix+assoc_name, actioncode_modelref, "name", optional=True)
|
||||||
|
|
||||||
already_ramified.add(assoc_name)
|
already_ramified.add(assoc_name)
|
||||||
|
|
||||||
# Associations can also have attributes...
|
# Associations can also have attributes...
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,12 @@ def rewrite(state, lhs_m: UUID, rhs_m: UUID, pattern_mm: UUID, lhs_match: dict,
|
||||||
bottom = Bottom(state)
|
bottom = Bottom(state)
|
||||||
|
|
||||||
# Need to come up with a new, unique name when creating new element in host-model:
|
# Need to come up with a new, unique name when creating new element in host-model:
|
||||||
def first_available_name(prefix: str):
|
def first_available_name(suggested_name: str):
|
||||||
|
if len(bottom.read_outgoing_elements(host_m, suggested_name)) == 0:
|
||||||
|
return suggested_name # already unique :)
|
||||||
i = 0
|
i = 0
|
||||||
while True:
|
while True:
|
||||||
name = prefix + str(i)
|
name = suggested_name + str(i)
|
||||||
if len(bottom.read_outgoing_elements(host_m, name)) == 0:
|
if len(bottom.read_outgoing_elements(host_m, name)) == 0:
|
||||||
return name # found unique name
|
return name # found unique name
|
||||||
i += 1
|
i += 1
|
||||||
|
|
@ -56,7 +58,10 @@ def rewrite(state, lhs_m: UUID, rhs_m: UUID, pattern_mm: UUID, lhs_match: dict,
|
||||||
lhs_keys = lhs_match.keys()
|
lhs_keys = lhs_match.keys()
|
||||||
rhs_keys = set(k for k in bottom.read_keys(rhs_m)
|
rhs_keys = set(k for k in bottom.read_keys(rhs_m)
|
||||||
# extremely dirty - should think of a better way
|
# extremely dirty - should think of a better way
|
||||||
if "GlobalCondition" not in k and not k.endswith("_condition") and not k.endswith(".condition"))
|
if "GlobalCondition" not in k and not k.endswith("_condition") and not k.endswith(".condition")
|
||||||
|
and (not k.endswith("_name") or k.endswith("RAM_name")) and (not k.endswith(".name")))
|
||||||
|
|
||||||
|
print('filtered out:', set(k for k in bottom.read_keys(rhs_m) if k.endswith(".name") or k.endswith("_name")))
|
||||||
|
|
||||||
common = lhs_keys & rhs_keys
|
common = lhs_keys & rhs_keys
|
||||||
to_delete = lhs_keys - common
|
to_delete = lhs_keys - common
|
||||||
|
|
@ -75,6 +80,16 @@ def rewrite(state, lhs_m: UUID, rhs_m: UUID, pattern_mm: UUID, lhs_match: dict,
|
||||||
for rhs_name in remaining_to_create:
|
for rhs_name in remaining_to_create:
|
||||||
# Determine the type of the thing to create
|
# Determine the type of the thing to create
|
||||||
rhs_obj = rhs_odapi.get(rhs_name)
|
rhs_obj = rhs_odapi.get(rhs_name)
|
||||||
|
# what to name our new object?
|
||||||
|
try:
|
||||||
|
name_expr = rhs_odapi.get_slot_value(rhs_obj, "name")
|
||||||
|
except:
|
||||||
|
name_expr = f'"{rhs_name}"' # <- if the 'name' slot doesnt exist, use the pattern element name
|
||||||
|
suggested_name = exec_then_eval(name_expr,
|
||||||
|
_globals={
|
||||||
|
**bind_api(host_odapi),
|
||||||
|
'matched': matched_callback,
|
||||||
|
})
|
||||||
rhs_type = rhs_odapi.get_type(rhs_obj)
|
rhs_type = rhs_odapi.get_type(rhs_obj)
|
||||||
host_type = ramify.get_original_type(bottom, rhs_type)
|
host_type = ramify.get_original_type(bottom, rhs_type)
|
||||||
# for debugging:
|
# for debugging:
|
||||||
|
|
@ -100,13 +115,13 @@ def rewrite(state, lhs_m: UUID, rhs_m: UUID, pattern_mm: UUID, lhs_match: dict,
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if od.is_typed_by(bottom, rhs_type, class_type):
|
if od.is_typed_by(bottom, rhs_type, class_type):
|
||||||
obj_name = first_available_name(rhs_name)
|
obj_name = first_available_name(suggested_name)
|
||||||
host_od._create_object(obj_name, host_type)
|
host_od._create_object(obj_name, host_type)
|
||||||
host_odapi._ODAPI__recompute_mappings()
|
host_odapi._ODAPI__recompute_mappings()
|
||||||
rhs_match[rhs_name] = obj_name
|
rhs_match[rhs_name] = obj_name
|
||||||
elif od.is_typed_by(bottom, rhs_type, assoc_type):
|
elif od.is_typed_by(bottom, rhs_type, assoc_type):
|
||||||
_, _, host_src, host_tgt = get_src_tgt()
|
_, _, host_src, host_tgt = get_src_tgt()
|
||||||
link_name = first_available_name(rhs_name)
|
link_name = first_available_name(suggested_name)
|
||||||
host_od._create_link(link_name, host_type, host_src, host_tgt)
|
host_od._create_link(link_name, host_type, host_src, host_tgt)
|
||||||
host_odapi._ODAPI__recompute_mappings()
|
host_odapi._ODAPI__recompute_mappings()
|
||||||
rhs_match[rhs_name] = link_name
|
rhs_match[rhs_name] = link_name
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
# We create the 'Top'-class with a GlobalCondition, because that's the only way we can control the name of the object to be created.
|
# We create the 'Top'-class with a GlobalCondition, because that's the only way we can control the name of the object to be created.
|
||||||
|
|
||||||
:GlobalCondition {
|
Top:RAM_Class {
|
||||||
condition = ```
|
RAM_abstract = `True`;
|
||||||
top = create_object("Top", "Class")
|
|
||||||
set_slot_value(top, "abstract", True)
|
|
||||||
lnk = create_link("generic_link", "Association", top, top)
|
|
||||||
# lnk also inherits top:
|
|
||||||
create_link(None, "Inheritance", lnk, top)
|
|
||||||
```;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generic_link:RAM_Association (Top -> Top)
|
||||||
|
|
||||||
|
:RAM_Inheritance (generic_link -> Top)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import os.path
|
import os.path
|
||||||
from framework.conformance import Conformance, render_conformance_check_result
|
from framework.conformance import Conformance, render_conformance_check_result
|
||||||
from concrete_syntax.textual_od import parser
|
from concrete_syntax.textual_od import parser
|
||||||
|
from concrete_syntax.common import indent
|
||||||
from transformation.rule import Rule
|
from transformation.rule import Rule
|
||||||
|
|
||||||
# parse model and check conformance
|
# parse model and check conformance
|
||||||
|
|
@ -77,6 +78,6 @@ def load_rules(state, get_filename, rt_mm_ramified, rule_names, check_conformanc
|
||||||
|
|
||||||
rules[rule_name] = Rule(*(parse(kind) for kind in KINDS))
|
rules[rule_name] = Rule(*(parse(kind) for kind in KINDS))
|
||||||
|
|
||||||
print("Rules loaded:\n" + '\n'.join(files_read))
|
print("Rules loaded:\n" + indent('\n'.join(files_read), 4))
|
||||||
|
|
||||||
return rules
|
return rules
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue