Clean slate

This commit is contained in:
Andrei Bondarenko 2021-07-24 20:52:36 +02:00
parent 2e3576a1a8
commit c64e348bf2
12 changed files with 0 additions and 860 deletions

View file

View file

@ -1,5 +0,0 @@
from core.context.simple_class_diagrams import SCDContext
custom_contexts = {
"SimpleClassDiagrams": SCDContext
}

View file

@ -1,63 +0,0 @@
from abc import ABC, abstractmethod
from state.base import State
from core.element import Element, String
class Context(ABC):
def __init__(self, state: State, model: Element, metamodel: Element):
self.state = state
self.model = model
self.metamodel = metamodel
@abstractmethod
def __enter__(self):
pass
@abstractmethod
def __exit__(self):
pass
@abstractmethod
def exposed_methods(self):
pass
@abstractmethod
def instantiate(self, type_name: String, instance_name: String):
pass
@abstractmethod
def instantiate_value(self, type_name: String, instance_name: String, value: Element):
pass
@abstractmethod
def instantiate_link(self, type_name: String, name: String, source: String, target: String):
pass
@abstractmethod
def delete_element(self, name: String):
pass
@abstractmethod
def verify(self):
pass
@abstractmethod
def list_elements(self):
pass
def list_types(self):
# can be implemented here since we assume that metamodel
# is always in graph fo, i.e. in the MV-state graph.
unsorted = []
model_root = self.state.read_dict(self.metamodel.id, "Model")
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)
# find element type
elem_type_node = self.state.read_dict(label_node, "Type")
elem_type = self.state.read_value(elem_type_node)
unsorted.append(f"{label} : {elem_type if elem_type is not None else '_'}")
for i in sorted(unsorted):
print(i)

View file

@ -1,107 +0,0 @@
from state.base import INTEGER, FLOAT, BOOLEAN, STRING, TYPE, State
from core.element import Element, String
class BottomContext:
def __init__(self, state: State, model: Element):
self.state = state
self.model = model
def __enter__(self):
return self
def __exit__(self):
pass
def add_node(self, name: String):
model_root = self.state.read_dict(self.model.id, "Model")
# create model element
element = self.state.create_node()
# connect to model root
self.state.create_dict(model_root, name.value, element)
# confirm that element has been added to the model
element_found = self.state.read_dict(model_root, name.value)
if element_found is None:
self.state.delete_node(element)
print(f"Warning: Invalid name {name.value}, element not created.")
return
def add_value(self, name: String, value: Element):
model_root = self.state.read_dict(self.model.id, "Model")
# create model element
element = self.state.create_nodevalue(value.value)
if element is None:
print("Warning: Invalid value, value node not created.")
return
# connect to model root
self.state.create_dict(model_root, name.value, element)
# confirm that element has been added to the model
element_found = self.state.read_dict(model_root, name.value)
if element_found is None:
self.state.delete_node(element)
print(f"Warning: Invalid name {name.value}, element not created.")
return
def add_edge(self, name: String, source: String, target: String):
model_root = self.state.read_dict(self.model.id, "Model")
source_element = self.state.read_dict(model_root, source.value)
if source_element is None:
print(f"Warning: Unknown source element {source.value}, edge not created.")
return
target_element = self.state.read_dict(model_root, target.value)
if target_element is None:
print(f"Warning: Unknown target element {target.value}, edge not created.")
return
# create model element
element = self.state.create_edge(source_element, target_element)
# connect to model root
self.state.create_dict(model_root, name.value, element)
# confirm that element has been added to the model
element_found = self.state.read_dict(model_root, name.value)
if element_found is None:
self.state.delete_edge(element)
print(f"Warning: Invalid name {name.value}, element not created.")
def delete_element(self, name: String):
model_root = self.state.read_dict(self.model.id, "Model")
element = self.state.read_dict(model_root, name.value)
# could be both a node or an edge
self.state.delete_node(element)
self.state.delete_edge(element)
def list_elements(self):
def is_edge(element: str) -> bool:
edge = self.state.read_edge(element)
return edge is not None
def value_type(value) -> str:
mapping = {
int: INTEGER,
float: FLOAT,
str: STRING,
bool: BOOLEAN,
tuple: TYPE
}
return mapping[type(value)][0]
unsorted = []
model_root = self.state.read_dict(self.model.id, "Model")
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)
# find element bottom type
_, elem = self.state.read_edge(elem_edge)
if is_edge(elem):
bottom_type = "Edge"
else:
# is_node
elem_value = self.state.read_value(elem)
if elem_value is None:
bottom_type = "Node"
else:
bottom_type = value_type
unsorted.append(f"{label} : {bottom_type}")
for i in sorted(unsorted):
print(i)

View file

@ -1,98 +0,0 @@
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 exposed_methods(self):
yield from [
self.instantiate,
self.instantiate_value,
self.instantiate_link,
self.retype_element,
self.delete_element,
self.list_elements,
self.list_types,
self.verify,
]
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) != (None, 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)
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)
if element_edge is None:
print(f"Error: Element with name {name.value} not found.")
return
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("Error: 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)

View file

@ -1,121 +0,0 @@
from core.element import Element, String, Integer, Boolean
from state.base import State
from core.context.generic import GenericContext
class SCDContext(GenericContext):
def __init__(self, state: State, model: Element, metamodel: Element):
super().__init__(state, model, metamodel)
def exposed_methods(self):
yield from super().exposed_methods()
yield from [
self.create_class,
self.create_class_attribute,
self.create_association,
self.create_inheritance
]
def create_class(self, name: String, lower_cardinality: Integer = Element(), upper_cardinality: Integer = Element()):
self.instantiate(Element(value="Class"), name)
if lower_cardinality.value is not None:
self.instantiate_value(
Element(value="Class_lower_cardinality"),
Element(value=name.value + ".lower_cardinality"),
lower_cardinality
)
self.instantiate_link(
Element(value="Class_lower_cardinality_link"),
Element(value=name.value + ".lower_cardinality_link"),
name,
Element(value=name.value + ".lower_cardinality")
)
if upper_cardinality.value is not None:
self.instantiate_value(
Element(value="Class_upper_cardinality"),
Element(value=name.value + ".upper_cardinality"),
upper_cardinality
)
self.instantiate_link(
Element(value="Class_upper_cardinality_link"),
Element(value=name.value + ".upper_cardinality_link"),
name,
Element(value=name.value + ".upper_cardinality")
)
def create_class_attribute(self, class_name: String, name: String, optional: Boolean = Element(value=False)):
# create attribute
element_name = Element(value=f"{class_name.value}_{name.value}")
element_link_name = Element(value=f"{class_name.value}_{name.value}_link")
self.instantiate(Element(value="Attribute"), element_name)
self.instantiate_link(Element(value="AttributeLink"), element_link_name, class_name, element_name)
# set attribute's attributes
attr_name_name = Element(value=f"{class_name.value}_{name.value}.name")
attr_optional_name = Element(value=f"{class_name.value}_{name.value}.optional")
attr_name_link_name = Element(value=f"{class_name.value}_{name.value}.name_link")
attr_optional_link_name = Element(value=f"{class_name.value}_{name.value}.optional_link")
self.instantiate_value(Element(value="Attribute_name"), attr_name_name, name)
self.instantiate_value(Element(value="Attribute_optional"), attr_optional_name, optional)
self.instantiate_link(Element(value="Attribute_name_link"), attr_name_link_name, element_name, attr_name_name)
self.instantiate_link(Element(value="Attribute_optional_link"), attr_optional_link_name, element_name, attr_optional_name)
def create_association(self, source_class_name: String, target_class_name: String, name: String,
source_lower_cardinality: Integer = Element(), target_lower_cardinality: Integer = Element(),
source_upper_cardinality: Integer = Element(), target_upper_cardinality: Integer = Element()
):
self.instantiate_link(Element(value="Association"), name, source_class_name, target_class_name)
if source_lower_cardinality.value is not None:
self.instantiate_value(
Element(value="Association_source_lower_cardinality"),
Element(value=name.value + ".source_lower_cardinality"),
source_lower_cardinality
)
self.instantiate_link(
Element(value="Association_source_lower_cardinality_link"),
Element(value=name.value + ".source_lower_cardinality_link"),
name,
Element(value=name.value + ".source_lower_cardinality")
)
if source_upper_cardinality.value is not None:
self.instantiate_value(
Element(value="Association_source_upper_cardinality"),
Element(value=name.value + ".source_upper_cardinality"),
source_upper_cardinality
)
self.instantiate_link(
Element(value="Association_source_upper_cardinality_link"),
Element(value=name.value + ".source_upper_cardinality_link"),
name,
Element(value=name.value + ".source_upper_cardinality")
)
if target_lower_cardinality.value is not None:
self.instantiate_value(
Element(value="Association_target_lower_cardinality"),
Element(value=name.value + ".target_lower_cardinality"),
target_lower_cardinality
)
self.instantiate_link(
Element(value="Association_target_lower_cardinality_link"),
Element(value=name.value + ".target_lower_cardinality_link"),
name,
Element(value=name.value + ".target_lower_cardinality")
)
if target_upper_cardinality.value is not None:
self.instantiate_value(
Element(value="Association_target_upper_cardinality"),
Element(value=name.value + ".target_upper_cardinality"),
target_upper_cardinality
)
self.instantiate_link(
Element(value="Association_target_upper_cardinality_link"),
Element(value=name.value + ".target_upper_cardinality_link"),
name,
Element(value=name.value + ".target_upper_cardinality")
)
def create_inheritance(self, parent_class_name: String, child_class_name: String):
self.instantiate_link(
Element(value="Inheritance"),
Element(value=f"{child_class_name.value}_inherits_from_{parent_class_name.value}"),
child_class_name,
parent_class_name)

View file

@ -1,34 +0,0 @@
from dataclasses import dataclass
from typing import TypeVar, Generic, Optional, Literal
from state.base import INTEGER, FLOAT, BOOLEAN, STRING, TYPE
# Some typing information for Python static type checkers
bottom_type = Literal[INTEGER, FLOAT, BOOLEAN, STRING, TYPE]
T = TypeVar('T', int, float, bool, str, bottom_type)
@dataclass
class Element(Generic[T]):
"""
An Element can represent one of following two things, based on the value of its attributes:
* An element (node or edge) in the State (id is not None). In this case the value can be None because it hasn't
yet been read OR because the element doesn't have a value.
* A value for which a node has not yet been materialized in the State (id is None, value is not None).
If you are familiar with the Modelverse Kernel, this class serves a function similar to the {id: ..., value: ...}
dict that is used there.
"""
id: Optional[str] = None
value: Optional[T] = None
def is_none(self) -> bool:
return self.id is None and self.value is None
String = Element[str]
Integer = Element[int]
Float = Element[float]
Boolean = Element[bool]
Type = Element[bottom_type]

View file

@ -1,88 +0,0 @@
from state.base import State
from core.element import Element, String
class Manager:
def __init__(self, state: State):
self.state = state
def exposed_methods(self):
yield from [
self.new_model,
self.get_model,
self.rename_model,
self.retype_model,
self.delete_model,
self.list_models,
]
def new_model(self, name: String, type_model_name: String) -> Element:
root = self.state.read_root()
mm_bottom = self.state.read_dict(root, type_model_name.value)
if mm_bottom is None:
print(f"Error: Invalid type model name {type_model_name.value}. Model not created.")
return Element()
bottom = self.state.create_nodevalue(name.value)
if bottom is None:
print(f"Error: Invalid model name {name.value}. Model not created.")
return Element()
self.state.create_dict(root, name.value, bottom)
self.state.create_dict(bottom, "Model", self.state.create_node())
self.state.create_dict(bottom, "Metamodel", mm_bottom)
return Element(id=bottom)
def get_model(self, name: String) -> Element:
root = self.state.read_root()
model = self.state.read_dict(root, name.value)
if model is None:
print(f"Error: Cannot find model with name {name.value}.")
return Element()
return Element(id=model)
def rename_model(self, name: String, new_name: String):
root = self.state.read_root()
name_used = self.state.read_dict_edge(root, new_name.value)
if name_used:
print(f"Error: Model with name {new_name.value} already exists. Please use another name.")
return
mode_edge = self.state.read_dict_edge(root, name.value)
if mode_edge is None:
print(f"Error: Cannot find model with name {name.value}.")
return
_, model_node = self.state.read_edge(mode_edge)
self.state.create_dict(root, new_name.value, model_node)
created = self.state.read_dict_edge(root, new_name.value)
if created is None:
print(f"Error: Invalid model name {new_name.value}. Model not renamed.")
else:
self.state.delete_edge(mode_edge)
def delete_model(self, name: String):
root = self.state.read_root()
model = self.state.read_dict(root, name.value)
if model is None:
print(f"Error: No model found for name {name.value}.")
else:
self.state.delete_node(model)
def list_models(self):
unsorted = []
for edge in self.state.read_outgoing(self.state.read_root()):
_, model = self.state.read_edge(edge)
metamodel = self.state.read_dict(model, "Metamodel")
unsorted.append(f"{self.state.read_value(model)} : {self.state.read_value(metamodel)}")
for x in sorted(unsorted):
print(x)
def retype_model(self, model_name: String, metamodel_name: String):
root = self.state.read_root()
model = self.state.read_dict(root, model_name.value)
if model is None:
print(f"Error: Cannot find model with name {model_name.value}.")
metamodel = self.state.read_dict(root, metamodel_name.value)
if metamodel is None:
print(f"Error: Cannot find model with name {metamodel_name.value}.")
metamodel_edge = self.state.read_dict_edge(model, "Metamodel")
if metamodel_edge is not None:
self.state.delete_edge(metamodel_edge)
self.state.create_dict(model, "Metamodel", metamodel)