diff --git a/core/context/generic.py b/core/context/generic.py new file mode 100644 index 0000000..ab91ba4 --- /dev/null +++ b/core/context/generic.py @@ -0,0 +1,82 @@ +from core.element import Element, String, Boolean +from state.base import State +from core.context.base import Context +from core.context.bottom import BottomContext + + +class GenericContext(Context): + def __init__(self, state: State, model: Element, metamodel: Element): + super().__init__(state, model, metamodel) + self.bottom = BottomContext(state, model) + + def __enter__(self): + pass + + def __exit__(self): + pass + + def _type_exists(self, type_name: String, instantiate_link: bool) -> bool: + metamodel_root = self.state.read_dict(self.metamodel.id, "Model") + type_element = self.state.read_dict(metamodel_root, type_name.value) + if type_element is None: + return False + else: + element_is_edge = self.state.read_edge(type_element) is not None + return element_is_edge == instantiate_link + + def instantiate(self, type_name: String, name: String): + if not self._type_exists(type_name, instantiate_link=False): + print(f"Attempting to instantiate element with invalid type: {type_name.value}") + else: + self.bottom.add_node(name) + self.retype_element(name, type_name) + + def instantiate_value(self, type_name: String, name: String, value: Element): + if not self._type_exists(type_name, instantiate_link=False): + print(f"Attempting to instantiate element with invalid type: {type_name.value}") + else: + self.bottom.add_value(name, value.value) + self.retype_element(name, type_name) + + def instantiate_link(self, type_name: String, name: String, source: String, target: String): + if not self._type_exists(type_name, instantiate_link=True): + print(f"Attempting to instantiate link with invalid type: {type_name.value}") + else: + self.bottom.add_edge(name, source, target) + self.retype_element(name, type_name) + + def delete_element(self, name: String): + self.bottom.delete_element(name) + + def verify(self): + pass # TODO: implement conformance check + + def list_elements(self): + model_root = self.state.read_dict(self.model.id, "Model") + unsorted = [] + for elem_edge in self.state.read_outgoing(model_root): + # get element name + label_edge, = self.state.read_outgoing(elem_edge) + _, label_node = self.state.read_edge(label_edge) + label = self.state.read_value(label_node) + type_node = self.state.read_dict(label_node, "Type") + type_name = self.state.read_value(type_node) + unsorted.append(f"{label} : {type_name}") + for i in sorted(unsorted): + print(i) + + def retype_element(self, name: String, type_name: String): + model_root = self.state.read_dict(self.model.id, "Model") + element_edge = self.state.read_dict_edge(model_root, name.value) + label_node_edge, = self.state.read_outgoing(element_edge) + _, label_node = self.state.read_edge(label_node_edge) + # create type name node + type_name_node = self.state.create_nodevalue(type_name.value) + if type_name_node is None: + print("Warning: Invalid type name, element not retyped.") + # remove any existing type node + existing = self.state.read_dict(label_node, "Type") + if existing is not None: + self.state.delete_node(existing) + # create new type node + self.state.create_dict(label_node, "Type", type_name_node)