2 Commits 4300783416 ... d7ba998cd7

Author SHA1 Message Date
  Andrei Bondarenko d7ba998cd7 Simple prompt implemented 2 years ago
  Andrei Bondarenko 65886dc694 Moved SCD bootstrap to separate file 2 years ago

+ 0 - 0
bootstrap/__init__.py


+ 204 - 0
bootstrap/simple_class_diagrams.py

@@ -0,0 +1,204 @@
+from core.element import Element
+from state.base import State, STRING, INTEGER, BOOLEAN, TYPE
+from core.context.generic import GenericContext
+
+
+def bootstrap_scd(state: State) -> Element:
+    ctx = GenericContext(state, Element(), Element())
+
+    scd = state.create_nodevalue("SimpleClassDiagrams")
+    state.create_dict(state.read_root(), "SimpleClassDiagrams", scd)
+    state.create_dict(scd, "Model", state.create_node())
+    state.create_dict(scd, "Metamodel", scd)
+    ctx.__init__(state, Element(id=scd), Element(id=scd))
+
+    # Classes --> elements that will be typed by Class
+    ctx.bottom.add_node(Element(value="Element"))
+    ctx.bottom.add_node(Element(value="Class"))
+    ctx.bottom.add_value(Element(value="Attribute"), Element(value=TYPE))
+
+    # Associations --> elements that will be typed by Association
+    ctx.bottom.add_edge(Element(value="Association"), Element(value="Class"), Element(value="Class"))
+    ctx.bottom.add_edge(Element(value="Inheritance"), Element(value="Element"), Element(value="Element"))
+    ctx.bottom.add_edge(Element(value="AttributeLink"), Element(value="Element"), Element(value="Attribute"))
+
+    # Attributes --> elements that will be typed by Attribute
+    ctx.bottom.add_value(Element(value="Class_lower_cardinality"), Element(value=INTEGER))
+    ctx.bottom.add_value(Element(value="Class_upper_cardinality"), Element(value=INTEGER))
+
+    ctx.bottom.add_value(Element(value="Association_source_lower_cardinality"), Element(value=INTEGER))
+    ctx.bottom.add_value(Element(value="Association_source_upper_cardinality"), Element(value=INTEGER))
+    ctx.bottom.add_value(Element(value="Association_target_lower_cardinality"), Element(value=INTEGER))
+    ctx.bottom.add_value(Element(value="Association_target_upper_cardinality"), Element(value=INTEGER))
+
+    ctx.bottom.add_value(Element(value="Attribute_name"), Element(value=STRING))
+    ctx.bottom.add_value(Element(value="Attribute_optional"), Element(value=BOOLEAN))
+
+    # Attribute instances --> elements that will be typed by one of the Attributes defined above
+    ctx.bottom.add_value(Element(value="Attribute_name.name"), Element(value="name"))
+    ctx.bottom.add_value(Element(value="Attribute_name.optional"), Element(value=False))
+    ctx.bottom.add_value(Element(value="Attribute_optional.name"), Element(value="optional"))
+    ctx.bottom.add_value(Element(value="Attribute_optional.optional"), Element(value=False))
+
+    ctx.bottom.add_value(Element(value="Class_lower_cardinality.name"), Element(value="lower_cardinality"))
+    ctx.bottom.add_value(Element(value="Class_lower_cardinality.optional"), Element(value=True))
+    ctx.bottom.add_value(Element(value="Class_upper_cardinality.name"), Element(value="upper_cardinality"))
+    ctx.bottom.add_value(Element(value="Class_upper_cardinality.optional"), Element(value=True))
+
+    ctx.bottom.add_value(Element(value="Association_source_lower_cardinality.name"),
+                         Element(value="source_lower_cardinality"))
+    ctx.bottom.add_value(Element(value="Association_source_lower_cardinality.optional"), Element(value=True))
+    ctx.bottom.add_value(Element(value="Association_source_upper_cardinality.name"),
+                         Element(value="source_upper_cardinality"))
+    ctx.bottom.add_value(Element(value="Association_source_upper_cardinality.optional"), Element(value=True))
+
+    ctx.bottom.add_value(Element(value="Association_target_lower_cardinality.name"),
+                         Element(value="target_lower_cardinality"))
+    ctx.bottom.add_value(Element(value="Association_target_lower_cardinality.optional"), Element(value=True))
+    ctx.bottom.add_value(Element(value="Association_target_upper_cardinality.name"),
+                         Element(value="target_upper_cardinality"))
+    ctx.bottom.add_value(Element(value="Association_target_upper_cardinality.optional"), Element(value=True))
+
+    # Inheritance instances --> elements that will be typed by Inheritance
+    ctx.bottom.add_edge(Element(value="class_inh_element"), Element(value="Class"), Element(value="Element"))
+    ctx.bottom.add_edge(Element(value="attribute_inh_element"), Element(value="Attribute"), Element(value="Element"))
+    ctx.bottom.add_edge(Element(value="association_inh_element"), Element(value="Association"),
+                        Element(value="Element"))
+    ctx.bottom.add_edge(Element(value="attributelink_inh_element"), Element(value="AttributeLink"),
+                        Element(value="Element"))
+
+    # AttributeLinks --> elements that will be typed by AttributeLink
+    ctx.bottom.add_edge(Element(value="Class_attr01"), Element(value="Class"),
+                        Element(value="Class_lower_cardinality"))
+    ctx.bottom.add_edge(Element(value="Class_attr02"), Element(value="Class"),
+                        Element(value="Class_upper_cardinality"))
+
+    ctx.bottom.add_edge(Element(value="Association_attr01"), Element(value="Association"),
+                        Element(value="Association_source_lower_cardinality"))
+    ctx.bottom.add_edge(Element(value="Association_attr02"), Element(value="Association"),
+                        Element(value="Association_source_upper_cardinality"))
+    ctx.bottom.add_edge(Element(value="Association_attr03"), Element(value="Association"),
+                        Element(value="Association_target_lower_cardinality"))
+    ctx.bottom.add_edge(Element(value="Association_attr04"), Element(value="Association"),
+                        Element(value="Association_target_upper_cardinality"))
+
+    ctx.bottom.add_edge(Element(value="Attribute_name_link"), Element(value="Attribute"),
+                        Element(value="Attribute_name"))
+    ctx.bottom.add_edge(Element(value="Attribute_optional_link"), Element(value="Attribute"),
+                        Element(value="Attribute_optional"))
+
+    # AttributeLink instances --> elements that will be typed by one of the AttributeLink defined above
+    ctx.bottom.add_edge(Element(value="Attribute_name_link_01"), Element(value="Attribute_name"),
+                        Element(value="Attribute_name.name"))
+    ctx.bottom.add_edge(Element(value="Attribute_optional_link_01"), Element(value="Attribute_name"),
+                        Element(value="Attribute_name.optional"))
+    ctx.bottom.add_edge(Element(value="Attribute_name_link_02"), Element(value="Attribute_optional"),
+                        Element(value="Attribute_optional.name"))
+    ctx.bottom.add_edge(Element(value="Attribute_optional_link_02"), Element(value="Attribute_optional"),
+                        Element(value="Attribute_optional.optional"))
+
+    ctx.bottom.add_edge(Element(value="Attribute_name_link_03"), Element(value="Class_lower_cardinality"),
+                        Element(value="Class_lower_cardinality.name"))
+    ctx.bottom.add_edge(Element(value="Attribute_optional_link_03"), Element(value="Class_lower_cardinality"),
+                        Element(value="Class_lower_cardinality.optional"))
+    ctx.bottom.add_edge(Element(value="Attribute_name_link_04"), Element(value="Class_upper_cardinality"),
+                        Element(value="Class_upper_cardinality.name"))
+    ctx.bottom.add_edge(Element(value="Attribute_optional_link_04"), Element(value="Class_upper_cardinality"),
+                        Element(value="Class_upper_cardinality.optional"))
+
+    ctx.bottom.add_edge(Element(value="Attribute_name_link_05"), Element(value="Association_source_lower_cardinality"),
+                        Element(value="Association_source_lower_cardinality.name"))
+    ctx.bottom.add_edge(Element(value="Attribute_optional_link_05"),
+                        Element(value="Association_source_lower_cardinality"),
+                        Element(value="Association_source_lower_cardinality.optional"))
+    ctx.bottom.add_edge(Element(value="Attribute_name_link_06"), Element(value="Association_source_upper_cardinality"),
+                        Element(value="Association_source_upper_cardinality.name"))
+    ctx.bottom.add_edge(Element(value="Attribute_optional_link_06"),
+                        Element(value="Association_source_upper_cardinality"),
+                        Element(value="Association_source_upper_cardinality.optional"))
+
+    ctx.bottom.add_edge(Element(value="Attribute_name_link_07"), Element(value="Association_target_lower_cardinality"),
+                        Element(value="Association_target_lower_cardinality.name"))
+    ctx.bottom.add_edge(Element(value="Attribute_optional_link_07"),
+                        Element(value="Association_target_lower_cardinality"),
+                        Element(value="Association_target_lower_cardinality.optional"))
+    ctx.bottom.add_edge(Element(value="Attribute_name_link_08"), Element(value="Association_target_upper_cardinality"),
+                        Element(value="Association_target_upper_cardinality.name"))
+    ctx.bottom.add_edge(Element(value="Attribute_optional_link_08"),
+                        Element(value="Association_target_upper_cardinality"),
+                        Element(value="Association_target_upper_cardinality.optional"))
+
+    """
+    Retype the elements of the model.
+    This way we make the model "metacircular".
+    """
+    ctx.retype_element(Element(value="Element"), Element(value="Class"))
+    ctx.retype_element(Element(value="Class"), Element(value="Class"))
+    ctx.retype_element(Element(value="Attribute"), Element(value="Class"))
+
+    ctx.retype_element(Element(value="Association"), Element(value="Association"))
+    ctx.retype_element(Element(value="Inheritance"), Element(value="Association"))
+    ctx.retype_element(Element(value="AttributeLink"), Element(value="Association"))
+
+    ctx.retype_element(Element(value="Class_lower_cardinality"), Element(value="Attribute"))
+    ctx.retype_element(Element(value="Class_upper_cardinality"), Element(value="Attribute"))
+    ctx.retype_element(Element(value="Association_source_lower_cardinality"), Element(value="Attribute"))
+    ctx.retype_element(Element(value="Association_source_upper_cardinality"), Element(value="Attribute"))
+    ctx.retype_element(Element(value="Association_target_lower_cardinality"), Element(value="Attribute"))
+    ctx.retype_element(Element(value="Association_target_upper_cardinality"), Element(value="Attribute"))
+    ctx.retype_element(Element(value="Attribute_name"), Element(value="Attribute"))
+    ctx.retype_element(Element(value="Attribute_optional"), Element(value="Attribute"))
+
+    ctx.retype_element(Element(value="Class_attr01"), Element(value="AttributeLink"))
+    ctx.retype_element(Element(value="Class_attr02"), Element(value="AttributeLink"))
+    ctx.retype_element(Element(value="Association_attr01"), Element(value="AttributeLink"))
+    ctx.retype_element(Element(value="Association_attr02"), Element(value="AttributeLink"))
+    ctx.retype_element(Element(value="Association_attr03"), Element(value="AttributeLink"))
+    ctx.retype_element(Element(value="Association_attr04"), Element(value="AttributeLink"))
+    ctx.retype_element(Element(value="Attribute_name_link"), Element(value="AttributeLink"))
+    ctx.retype_element(Element(value="Attribute_optional_link"), Element(value="AttributeLink"))
+
+    ctx.retype_element(Element(value="class_inh_element"), Element(value="Inheritance"))
+    ctx.retype_element(Element(value="attribute_inh_element"), Element(value="Inheritance"))
+    ctx.retype_element(Element(value="association_inh_element"), Element(value="Inheritance"))
+    ctx.retype_element(Element(value="attributelink_inh_element"), Element(value="Inheritance"))
+
+    ctx.retype_element(Element(value="Attribute_name.name"), Element(value="Attribute_name"))
+    ctx.retype_element(Element(value="Attribute_name.optional"), Element(value="Attribute_optional"))
+    ctx.retype_element(Element(value="Attribute_optional.name"), Element(value="Attribute_name"))
+    ctx.retype_element(Element(value="Attribute_optional.optional"), Element(value="Attribute_optional"))
+    ctx.retype_element(Element(value="Class_lower_cardinality.name"), Element(value="Attribute_name"))
+    ctx.retype_element(Element(value="Class_lower_cardinality.optional"), Element(value="Attribute_optional"))
+    ctx.retype_element(Element(value="Class_upper_cardinality.name"), Element(value="Attribute_name"))
+    ctx.retype_element(Element(value="Class_upper_cardinality.optional"), Element(value="Attribute_optional"))
+    ctx.retype_element(Element(value="Association_source_lower_cardinality.name"), Element(value="Attribute_name"))
+    ctx.retype_element(Element(value="Association_source_lower_cardinality.optional"),
+                       Element(value="Attribute_optional"))
+    ctx.retype_element(Element(value="Association_source_upper_cardinality.name"), Element(value="Attribute_name"))
+    ctx.retype_element(Element(value="Association_source_upper_cardinality.optional"),
+                       Element(value="Attribute_optional"))
+    ctx.retype_element(Element(value="Association_target_lower_cardinality.name"), Element(value="Attribute_name"))
+    ctx.retype_element(Element(value="Association_target_lower_cardinality.optional"),
+                       Element(value="Attribute_optional"))
+    ctx.retype_element(Element(value="Association_target_upper_cardinality.name"), Element(value="Attribute_name"))
+    ctx.retype_element(Element(value="Association_target_upper_cardinality.optional"),
+                       Element(value="Attribute_optional"))
+
+    ctx.retype_element(Element(value="Attribute_name_link_01"), Element(value="Attribute_name_link"))
+    ctx.retype_element(Element(value="Attribute_optional_link_01"), Element(value="Attribute_optional_link"))
+    ctx.retype_element(Element(value="Attribute_name_link_02"), Element(value="Attribute_name_link"))
+    ctx.retype_element(Element(value="Attribute_optional_link_02"), Element(value="Attribute_optional_link"))
+    ctx.retype_element(Element(value="Attribute_name_link_03"), Element(value="Attribute_name_link"))
+    ctx.retype_element(Element(value="Attribute_optional_link_03"), Element(value="Attribute_optional_link"))
+    ctx.retype_element(Element(value="Attribute_name_link_04"), Element(value="Attribute_name_link"))
+    ctx.retype_element(Element(value="Attribute_optional_link_04"), Element(value="Attribute_optional_link"))
+    ctx.retype_element(Element(value="Attribute_name_link_05"), Element(value="Attribute_name_link"))
+    ctx.retype_element(Element(value="Attribute_optional_link_05"), Element(value="Attribute_optional_link"))
+    ctx.retype_element(Element(value="Attribute_name_link_06"), Element(value="Attribute_name_link"))
+    ctx.retype_element(Element(value="Attribute_optional_link_06"), Element(value="Attribute_optional_link"))
+    ctx.retype_element(Element(value="Attribute_name_link_07"), Element(value="Attribute_name_link"))
+    ctx.retype_element(Element(value="Attribute_optional_link_07"), Element(value="Attribute_optional_link"))
+    ctx.retype_element(Element(value="Attribute_name_link_08"), Element(value="Attribute_name_link"))
+    ctx.retype_element(Element(value="Attribute_optional_link_08"), Element(value="Attribute_optional_link"))
+
+    return Element(id=scd)

+ 4 - 0
core/context/base.py

@@ -17,6 +17,10 @@ class Context(ABC):
     def __exit__(self):
         pass
 
+    @abstractmethod
+    def exposed_methods(self):
+        pass
+
     @abstractmethod
     def instantiate(self, type_name: String, instance_name: String):
         pass

+ 13 - 1
core/context/generic.py

@@ -5,6 +5,7 @@ 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)
@@ -15,13 +16,24 @@ class GenericContext(Context):
     def __exit__(self):
         pass
 
+    def exposed_methods(self):
+        yield from [
+            self.instantiate,
+            self.instantiate_value,
+            self.instantiate_link,
+            self.retype_element,
+            self.list_elements,
+            self.delete_element,
+            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) is not None
+            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):

+ 25 - 185
core/context/simple_class_diagrams.py

@@ -1,5 +1,5 @@
-from core.element import Element
-from state.base import State, STRING, INTEGER, BOOLEAN, TYPE
+from core.element import Element, String, Integer, Boolean
+from state.base import State
 from core.context.generic import GenericContext
 
 
@@ -7,186 +7,26 @@ class SCDContext(GenericContext):
     def __init__(self, state: State, model: Element, metamodel: Element):
         super().__init__(state, model, metamodel)
 
-    def _bootstrap_scd(self) -> Element:
-
-        scd = self.state.create_nodevalue("SimpleClassDiagrams")
-        self.state.create_dict(self.state.read_root(), "SimpleClassDiagrams", scd)
-        self.state.create_dict(scd, "Model", self.state.create_node())
-        self.state.create_dict(scd, "Metamodel", scd)
-        super().__init__(self.state, Element(id=scd), Element(id=scd))
-
-        # Classes --> elements that will be typed by Class
-        self.bottom.add_node(Element(value="Element"))
-        self.bottom.add_node(Element(value="Class"))
-        self.bottom.add_value(Element(value="Attribute"), Element(value=TYPE))
-
-        # Associations --> elements that will be typed by Association
-        self.bottom.add_edge(Element(value="Association"), Element(value="Class"), Element(value="Class"))
-        self.bottom.add_edge(Element(value="Inheritance"), Element(value="Element"), Element(value="Element"))
-        self.bottom.add_edge(Element(value="AttributeLink"), Element(value="Element"), Element(value="Attribute"))
-
-        # Attributes --> elements that will be typed by Attribute
-        self.bottom.add_value(Element(value="Class_lower_cardinality"), Element(value=INTEGER))
-        self.bottom.add_value(Element(value="Class_upper_cardinality"), Element(value=INTEGER))
-
-        self.bottom.add_value(Element(value="Association_source_lower_cardinality"), Element(value=INTEGER))
-        self.bottom.add_value(Element(value="Association_source_upper_cardinality"), Element(value=INTEGER))
-        self.bottom.add_value(Element(value="Association_target_lower_cardinality"), Element(value=INTEGER))
-        self.bottom.add_value(Element(value="Association_target_upper_cardinality"), Element(value=INTEGER))
-
-        self.bottom.add_value(Element(value="Attribute_name"), Element(value=STRING))
-        self.bottom.add_value(Element(value="Attribute_optional"), Element(value=BOOLEAN))
-
-        # Attribute instances --> elements that will be typed by one of the Attributes defined above
-        self.bottom.add_value(Element(value="Attribute_name.name"), Element(value="name"))
-        self.bottom.add_value(Element(value="Attribute_name.optional"), Element(value=False))
-        self.bottom.add_value(Element(value="Attribute_optional.name"), Element(value="optional"))
-        self.bottom.add_value(Element(value="Attribute_optional.optional"), Element(value=False))
-
-        self.bottom.add_value(Element(value="Class_lower_cardinality.name"), Element(value="lower_cardinality"))
-        self.bottom.add_value(Element(value="Class_lower_cardinality.optional"), Element(value=True))
-        self.bottom.add_value(Element(value="Class_upper_cardinality.name"), Element(value="upper_cardinality"))
-        self.bottom.add_value(Element(value="Class_upper_cardinality.optional"), Element(value=True))
-
-        self.bottom.add_value(Element(value="Association_source_lower_cardinality.name"), Element(value="source_lower_cardinality"))
-        self.bottom.add_value(Element(value="Association_source_lower_cardinality.optional"), Element(value=True))
-        self.bottom.add_value(Element(value="Association_source_upper_cardinality.name"), Element(value="source_upper_cardinality"))
-        self.bottom.add_value(Element(value="Association_source_upper_cardinality.optional"), Element(value=True))
-
-        self.bottom.add_value(Element(value="Association_target_lower_cardinality.name"), Element(value="target_lower_cardinality"))
-        self.bottom.add_value(Element(value="Association_target_lower_cardinality.optional"), Element(value=True))
-        self.bottom.add_value(Element(value="Association_target_upper_cardinality.name"), Element(value="target_upper_cardinality"))
-        self.bottom.add_value(Element(value="Association_target_upper_cardinality.optional"), Element(value=True))
-
-        # Inheritance instances --> elements that will be typed by Inheritance
-        self.bottom.add_edge(Element(value="class_inh_element"), Element(value="Class"), Element(value="Element"))
-        self.bottom.add_edge(Element(value="attribute_inh_element"), Element(value="Attribute"), Element(value="Element"))
-        self.bottom.add_edge(Element(value="association_inh_element"), Element(value="Association"), Element(value="Element"))
-        self.bottom.add_edge(Element(value="attributelink_inh_element"), Element(value="AttributeLink"), Element(value="Element"))
-
-        # AttributeLinks --> elements that will be typed by AttributeLink
-        self.bottom.add_edge(Element(value="Class_attr01"), Element(value="Class"), Element(value="Class_lower_cardinality"))
-        self.bottom.add_edge(Element(value="Class_attr02"), Element(value="Class"), Element(value="Class_upper_cardinality"))
-
-        self.bottom.add_edge(Element(value="Association_attr01"), Element(value="Association"), Element(value="Association_source_lower_cardinality"))
-        self.bottom.add_edge(Element(value="Association_attr02"), Element(value="Association"), Element(value="Association_source_upper_cardinality"))
-        self.bottom.add_edge(Element(value="Association_attr03"), Element(value="Association"), Element(value="Association_target_lower_cardinality"))
-        self.bottom.add_edge(Element(value="Association_attr04"), Element(value="Association"), Element(value="Association_target_upper_cardinality"))
-
-        self.bottom.add_edge(Element(value="Attribute_name_link"), Element(value="Attribute"), Element(value="Attribute_name"))
-        self.bottom.add_edge(Element(value="Attribute_optional_link"), Element(value="Attribute"), Element(value="Attribute_optional"))
-
-        # AttributeLink instances --> elements that will be typed by one of the AttributeLink defined above
-        self.bottom.add_edge(Element(value="Attribute_name_link_01"), Element(value="Attribute_name"), Element(value="Attribute_name.name"))
-        self.bottom.add_edge(Element(value="Attribute_optional_link_01"), Element(value="Attribute_name"), Element(value="Attribute_name.optional"))
-        self.bottom.add_edge(Element(value="Attribute_name_link_02"), Element(value="Attribute_optional"), Element(value="Attribute_optional.name"))
-        self.bottom.add_edge(Element(value="Attribute_optional_link_02"), Element(value="Attribute_optional"), Element(value="Attribute_optional.optional"))
-
-        self.bottom.add_edge(Element(value="Attribute_name_link_03"), Element(value="Class_lower_cardinality"), Element(value="Class_lower_cardinality.name"))
-        self.bottom.add_edge(Element(value="Attribute_optional_link_03"), Element(value="Class_lower_cardinality"), Element(value="Class_lower_cardinality.optional"))
-        self.bottom.add_edge(Element(value="Attribute_name_link_04"), Element(value="Class_upper_cardinality"), Element(value="Class_upper_cardinality.name"))
-        self.bottom.add_edge(Element(value="Attribute_optional_link_04"), Element(value="Class_upper_cardinality"), Element(value="Class_upper_cardinality.optional"))
-
-        self.bottom.add_edge(Element(value="Attribute_name_link_05"), Element(value="Association_source_lower_cardinality"), Element(value="Association_source_lower_cardinality.name"))
-        self.bottom.add_edge(Element(value="Attribute_optional_link_05"), Element(value="Association_source_lower_cardinality"), Element(value="Association_source_lower_cardinality.optional"))
-        self.bottom.add_edge(Element(value="Attribute_name_link_06"), Element(value="Association_source_upper_cardinality"), Element(value="Association_source_upper_cardinality.name"))
-        self.bottom.add_edge(Element(value="Attribute_optional_link_06"), Element(value="Association_source_upper_cardinality"), Element(value="Association_source_upper_cardinality.optional"))
-
-        self.bottom.add_edge(Element(value="Attribute_name_link_07"), Element(value="Association_target_lower_cardinality"), Element(value="Association_target_lower_cardinality.name"))
-        self.bottom.add_edge(Element(value="Attribute_optional_link_07"), Element(value="Association_target_lower_cardinality"), Element(value="Association_target_lower_cardinality.optional"))
-        self.bottom.add_edge(Element(value="Attribute_name_link_08"), Element(value="Association_target_upper_cardinality"), Element(value="Association_target_upper_cardinality.name"))
-        self.bottom.add_edge(Element(value="Attribute_optional_link_08"), Element(value="Association_target_upper_cardinality"), Element(value="Association_target_upper_cardinality.optional"))
-
-        """
-        Retype the elements of the model.
-        This way we make the model "metacircular".
-        """
-        self.retype_element(Element(value="Element"), Element(value="Class"))
-        self.retype_element(Element(value="Class"), Element(value="Class"))
-        self.retype_element(Element(value="Attribute"), Element(value="Class"))
-
-        self.retype_element(Element(value="Association"), Element(value="Association"))
-        self.retype_element(Element(value="Inheritance"), Element(value="Association"))
-        self.retype_element(Element(value="AttributeLink"), Element(value="Association"))
-
-        self.retype_element(Element(value="Class_lower_cardinality"), Element(value="Attribute"))
-        self.retype_element(Element(value="Class_upper_cardinality"), Element(value="Attribute"))
-        self.retype_element(Element(value="Association_source_lower_cardinality"), Element(value="Attribute"))
-        self.retype_element(Element(value="Association_source_upper_cardinality"), Element(value="Attribute"))
-        self.retype_element(Element(value="Association_target_lower_cardinality"), Element(value="Attribute"))
-        self.retype_element(Element(value="Association_target_upper_cardinality"), Element(value="Attribute"))
-        self.retype_element(Element(value="Attribute_name"), Element(value="Attribute"))
-        self.retype_element(Element(value="Attribute_optional"), Element(value="Attribute"))
-
-        self.retype_element(Element(value="Class_attr01"), Element(value="AttributeLink"))
-        self.retype_element(Element(value="Class_attr02"), Element(value="AttributeLink"))
-        self.retype_element(Element(value="Association_attr01"), Element(value="AttributeLink"))
-        self.retype_element(Element(value="Association_attr02"), Element(value="AttributeLink"))
-        self.retype_element(Element(value="Association_attr03"), Element(value="AttributeLink"))
-        self.retype_element(Element(value="Association_attr04"), Element(value="AttributeLink"))
-        self.retype_element(Element(value="Attribute_name_link"), Element(value="AttributeLink"))
-        self.retype_element(Element(value="Attribute_optional_link"), Element(value="AttributeLink"))
-
-        self.retype_element(Element(value="class_inh_element"), Element(value="Inheritance"))
-        self.retype_element(Element(value="attribute_inh_element"), Element(value="Inheritance"))
-        self.retype_element(Element(value="association_inh_element"), Element(value="Inheritance"))
-        self.retype_element(Element(value="attributelink_inh_element"), Element(value="Inheritance"))
-
-        self.retype_element(Element(value="Attribute_name.name"), Element(value="Attribute_name"))
-        self.retype_element(Element(value="Attribute_name.optional"),Element(value="Attribute_optional"))
-        self.retype_element(Element(value="Attribute_optional.name"), Element(value="Attribute_name"))
-        self.retype_element(Element(value="Attribute_optional.optional"), Element(value="Attribute_optional"))
-        self.retype_element(Element(value="Class_lower_cardinality.name"), Element(value="Attribute_name"))
-        self.retype_element(Element(value="Class_lower_cardinality.optional"), Element(value="Attribute_optional"))
-        self.retype_element(Element(value="Class_upper_cardinality.name"), Element(value="Attribute_name"))
-        self.retype_element(Element(value="Class_upper_cardinality.optional"), Element(value="Attribute_optional"))
-        self.retype_element(Element(value="Association_source_lower_cardinality.name"), Element(value="Attribute_name"))
-        self.retype_element(Element(value="Association_source_lower_cardinality.optional"), Element(value="Attribute_optional"))
-        self.retype_element(Element(value="Association_source_upper_cardinality.name"), Element(value="Attribute_name"))
-        self.retype_element(Element(value="Association_source_upper_cardinality.optional"), Element(value="Attribute_optional"))
-        self.retype_element(Element(value="Association_target_lower_cardinality.name"), Element(value="Attribute_name"))
-        self.retype_element(Element(value="Association_target_lower_cardinality.optional"), Element(value="Attribute_optional"))
-        self.retype_element(Element(value="Association_target_upper_cardinality.name"), Element(value="Attribute_name"))
-        self.retype_element(Element(value="Association_target_upper_cardinality.optional"), Element(value="Attribute_optional"))
-
-        self.retype_element(Element(value="Attribute_name_link_01"), Element(value="Attribute_name_link"))
-        self.retype_element(Element(value="Attribute_optional_link_01"), Element(value="Attribute_optional_link"))
-        self.retype_element(Element(value="Attribute_name_link_02"), Element(value="Attribute_name_link"))
-        self.retype_element(Element(value="Attribute_optional_link_02"), Element(value="Attribute_optional_link"))
-        self.retype_element(Element(value="Attribute_name_link_03"), Element(value="Attribute_name_link"))
-        self.retype_element(Element(value="Attribute_optional_link_03"), Element(value="Attribute_optional_link"))
-        self.retype_element(Element(value="Attribute_name_link_04"), Element(value="Attribute_name_link"))
-        self.retype_element(Element(value="Attribute_optional_link_04"), Element(value="Attribute_optional_link"))
-        self.retype_element(Element(value="Attribute_name_link_05"), Element(value="Attribute_name_link"))
-        self.retype_element(Element(value="Attribute_optional_link_05"), Element(value="Attribute_optional_link"))
-        self.retype_element(Element(value="Attribute_name_link_06"), Element(value="Attribute_name_link"))
-        self.retype_element(Element(value="Attribute_optional_link_06"), Element(value="Attribute_optional_link"))
-        self.retype_element(Element(value="Attribute_name_link_07"), Element(value="Attribute_name_link"))
-        self.retype_element(Element(value="Attribute_optional_link_07"), Element(value="Attribute_optional_link"))
-        self.retype_element(Element(value="Attribute_name_link_08"), Element(value="Attribute_name_link"))
-        self.retype_element(Element(value="Attribute_optional_link_08"), Element(value="Attribute_optional_link"))
-
-        return Element(id=scd)
-
-
-def main():
-    from state.devstate import DevState
-
-    s = DevState()
-    scd = SCDContext(s, Element(), Element())
-    bootstrap = scd._bootstrap_scd()
-    model = s.read_dict(bootstrap.id, "Model")
-    x = []
-    for e in s.read_outgoing(model):
-        label_node_edge, = s.read_outgoing(e)
-        _, label_node = s.read_edge(label_node_edge)
-        type_node = s.read_dict(label_node, "Type")
-        x.append(f"{s.read_value(label_node)} : {s.read_value(type_node)}")
-    for t in sorted(x):
-        print(t)
-
-    # s.dump("out/scd.dot", "out/scd.png")
-
-
-if __name__ == '__main__':
-    main()
+    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()):
+        pass
+
+    def create_class_attribute(self, class_name: String, name: String, optional: Boolean = Element(value=False)):
+        pass
+
+    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()
+                           ):
+        pass
+
+    def create_inheritance(self, parent_class_name: String, child_class_name: String):
+        pass

+ 10 - 0
core/manager.py

@@ -6,6 +6,16 @@ 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)

+ 121 - 0
main.py

@@ -0,0 +1,121 @@
+from core.element import Element
+from core.manager import Manager
+from core.context.bottom import BottomContext
+from core.context.generic import GenericContext
+from core.context import custom_contexts
+from state.devstate import DevState
+from bootstrap.simple_class_diagrams import bootstrap_scd
+
+import inspect
+from ast import literal_eval
+import sys
+import signal
+signal.signal(signal.SIGINT, signal.default_int_handler)
+
+
+def params(method):
+    annotations = {
+        "core.element.Element[str]": "String",
+        "core.element.Element[int]": "Integer",
+        "core.element.Element[float]": "Float",
+        "core.element.Element[bool]": "Boolean"
+    }
+    sign = inspect.signature(method)
+    for param in sign.parameters.values():
+        param_type = annotations.get(str(param.annotation), "Element")
+        if param.default is param.empty:
+            yield param.name, param_type
+        else:
+            yield param.name, param_type, param.default
+
+
+def input_args(method):
+    args = []
+    for param_tuple in params(method):
+        if len(param_tuple) == 3:
+            param_name, param_type, param_default = param_tuple
+            arg = input(f"{param_type} {param_name} (default = {param_default.value})? ")
+            if arg == '':
+                arg = param_default.value
+        else:
+            param_name, param_type = param_tuple
+            while True:
+                arg = input(f"{param_type} {param_name}? ")
+                if arg == '':
+                    print("This arguments is non-optional, please provide a value.")
+                else:
+                    break
+        if arg is None:
+            arg = Element()
+        elif param_type in {"Boolean", "Integer", "Float"}:
+            arg = Element(value=literal_eval(arg))
+        else:
+            arg = Element(value=arg)
+        args.append(arg)
+    return args
+
+
+def model_management_loop(manager: Manager):
+    try:
+        print("\nCurrently no model is loaded. Following model management operations are available:")
+        for m in manager.exposed_methods():
+            print(f"\t* {m.__name__}")
+        while True:
+            command = input("\nPlease enter a command: ")
+            try:
+                method = next(m for m in manager.exposed_methods() if m.__name__ == command)
+                user_args = input_args(method)
+                model = method(*user_args)
+                if model is not None and not model.is_none():
+                    metamodel = Element(id=manager.state.read_dict(model.id, "Metamodel"))
+                    modelling_loop(manager, model, metamodel)
+                    break
+            except StopIteration:
+                print("Invalid command, please try again.")
+    except KeyboardInterrupt:
+        print("\nBye!")
+        sys.exit()
+
+
+def modelling_loop(manager: Manager, model: Element, metamodel: Element):
+    model_name = manager.state.read_value(model.id)
+    metamodel_name = manager.state.read_value(metamodel.id)
+    if metamodel.is_none():
+        context = BottomContext(manager.state, model)
+        print(f"No metamodel found. Model {model_name} has been loaded in context Bottom.")
+    else:
+        context = custom_contexts.get(metamodel_name, GenericContext)(manager.state, model, metamodel)
+        print(type(context))
+        print(f"Model {model_name} has been loaded in context {metamodel_name}.")
+    print(f"To return to the model management interface press CTRL + C.")
+    print(f"The following operations are available in this context:")
+    for m in context.exposed_methods():
+        print(f"\t* {m.__name__}")
+    try:
+        while True:
+            command = input("\nPlease enter a command: ")
+            try:
+                method = next(m for m in context.exposed_methods() if m.__name__ == command)
+                user_args = input_args(method)
+                model = method(*user_args)
+                if model is not None and not model.is_none():
+                    metamodel = Element(id=manager.state.read_dict(model.id, "Metamodel"))
+                    modelling_loop(manager, model, metamodel)
+                    break
+            except StopIteration:
+                print("Invalid command, please try again.")
+    except KeyboardInterrupt:
+        pass
+
+
+if __name__ == '__main__':
+    state = DevState()
+    bootstrap_scd(state)
+
+    man = Manager(state)
+    print("Welcome to MV2!")
+    while True:
+        model_management_loop(man)
+
+
+