Clean slate
This commit is contained in:
parent
2e3576a1a8
commit
c64e348bf2
12 changed files with 0 additions and 860 deletions
|
|
@ -1,5 +0,0 @@
|
|||
from core.context.simple_class_diagrams import SCDContext
|
||||
|
||||
custom_contexts = {
|
||||
"SimpleClassDiagrams": SCDContext
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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]
|
||||
|
|
@ -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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue