Browse Source

Change inheritance hierarchy in SimpleClassDiagrams to allow for correct
inheritance links at lower levels

Yentl Van Tendeloo 3 years ago
parent
commit
730f7e18e1
3 changed files with 50 additions and 17 deletions
  1. 13 0
      bootstrap/conformance_finding.alc
  2. 3 4
      bootstrap/metamodels.alt
  3. 34 13
      unit/test_all.py

+ 13 - 0
bootstrap/conformance_finding.alc

@@ -44,6 +44,19 @@ Boolean function find_type_mapping(model : Element):
 		nodes = allInstances(model["metamodel"], "Class")
 		edges = allInstances(model["metamodel"], "Association")
 
+		// Filter out classes from the associations
+		Element new_nodes
+		String node
+		new_nodes = set_create()
+		while (set_len(nodes) > 0):
+			node = set_pop(nodes)
+			if (bool_not(is_edge(model["metamodel"]["model"][node]))):
+				set_add(new_nodes, node)
+		nodes = new_nodes
+
+		log("Nodes: " + set_to_string(nodes))
+		log("Edges: " + set_to_string(edges))
+
 		// Simple allocation: this seems like conformance bottom
 		if (bool_and(set_len(edges) == 1, set_len(nodes) == 1)):
 			String node_source_element

+ 3 - 4
bootstrap/metamodels.alt

@@ -71,14 +71,14 @@ Element function initialize_SCD(location : String):
 	model_add_node(scd, "String")
 	model_add_value(scd, "name_value", "name")
 	model_add_edge(scd, "Association", "Class", "Class")
-	model_add_edge(scd, "Inheritance", "Element", "Element")
-	model_add_edge(scd, "AttributeLink", "Element", "Attribute")
+	model_add_edge(scd, "Inheritance", "Class", "Class")
+	model_add_edge(scd, "AttributeLink", "Class", "Attribute")
 	model_add_edge(scd, "attr_name", "AttributeLink", "String")
 	model_add_edge(scd, "attr_name_name", "attr_name", "name_value")
 	model_add_edge(scd, "class_inh_element", "Class", "Element")
 	model_add_edge(scd, "attribute_inh_element", "Attribute", "Element")
 	model_add_edge(scd, "simple_inh_attribute", "SimpleAttribute", "Attribute")
-	model_add_edge(scd, "association_inh_element", "Association", "Element")
+	model_add_edge(scd, "association_inh_element", "Association", "Class")
 	model_add_edge(scd, "attributelink_inh_element", "AttributeLink", "Element")
 
 	// Retype to self
@@ -125,7 +125,6 @@ Element function initialize_SCD(location : String):
 	model_define_attribute(scd, "Class", "name", False, "String")
 	model_define_attribute(scd, "Class", "abstract", True, "Boolean")
 	model_define_attribute(scd, "SimpleAttribute", "name", False, "String")
-	model_define_attribute(scd, "Association", "name", False, "String")
 	instantiate_attribute(scd, "String", "name", "String")
 	instantiate_attribute(scd, "Element", "name", "Element")
 	instantiate_attribute(scd, "Element", "abstract", True)

+ 34 - 13
unit/test_all.py

@@ -470,7 +470,7 @@ class TestModelverse(unittest.TestCase):
             Class B : A {}
             Association C (A, B) {}
             """)
-        assert all_instances("users/user/test/a", "Class") == set(["A", "B"])
+        assert all_instances("users/user/test/a", "Class") == set(["A", "B", "C"])
         assert all_instances("users/user/test/a", "Association") == set(["C"])
 
         # Test non-existing type
@@ -773,8 +773,8 @@ class TestModelverse(unittest.TestCase):
         assert {"__id": "String", "__type": "SimpleAttribute", "constraint": {"AL": ""}, "name": "string"} in lst
         assert {"__id": "place", "name": "Place", "__type": "Class", "constraint": {"AL": ""}, "lower_cardinality": None, "upper_cardinality": None, "abstract": None} in lst
         assert {"__id": "transition", "name": "Transition", "__type": "Class", "constraint": {"AL": ""}, "lower_cardinality": None, "upper_cardinality": None, "abstract": None} in lst
-        assert {"__id": "p2t", "name": "P2T", "__type": "Association", "__source": "place", "__target": "transition", "constraint": {"AL": ""}, "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None} in lst
-        assert {"__id": "t2p", "name": "T2P", "__type": "Association", "__source": "transition", "__target": "place", "constraint": {"AL": ""}, "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None} in lst
+        assert {"__id": "p2t", "name": "P2T", "__type": "Association", "__source": "place", "__target": "transition", "constraint": {"AL": ""}, "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None, "abstract": None, "lower_cardinality": None, "upper_cardinality": None} in lst
+        assert {"__id": "t2p", "name": "T2P", "__type": "Association", "__source": "transition", "__target": "place", "constraint": {"AL": ""}, "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None, "abstract": None, "lower_cardinality": None, "upper_cardinality": None} in lst
         assert {"__id": "place_name", "__type": "AttributeLink", "__source": "place", "__target": "String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
         assert {"__id": "place_capacity", "__type": "AttributeLink", "__source": "place", "__target": "Natural", "name": "capacity", "optional": False, "constraint": {"AL": ""}} in lst
         assert {"__id": "transition_name", "__type": "AttributeLink", "__source": "transition", "__target": "String", "name": "name", "optional": False, "constraint": {"AL": ""}} in lst
@@ -914,8 +914,8 @@ class TestModelverse(unittest.TestCase):
         assert read_attrs("users/user/test/a", "String") == {"constraint": {"AL": ""}, "name": "string"}
         assert read_attrs("users/user/test/a", "Place") == {"constraint": {"AL": ""}, "name": "Place", "abstract": None, "lower_cardinality": None, "upper_cardinality": None}
         assert read_attrs("users/user/test/a", "Transition") == {"constraint": {"AL": ""}, "name": "Transition", "abstract": None, "lower_cardinality": None, "upper_cardinality": None}
-        assert read_attrs("users/user/test/a", "P2T") == {"constraint": {"AL": ""}, "name": "P2T", "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None}
-        assert read_attrs("users/user/test/a", "T2P") == {"constraint": {"AL": ""}, "name": "T2P", "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None}
+        assert read_attrs("users/user/test/a", "P2T") == {"constraint": {"AL": ""}, "name": "P2T", "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None, "abstract": None, "lower_cardinality": None, "upper_cardinality": None}
+        assert read_attrs("users/user/test/a", "T2P") == {"constraint": {"AL": ""}, "name": "T2P", "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None, "abstract": None, "lower_cardinality": None, "upper_cardinality": None}
 
         model_add("users/user/test/b", "users/user/test/a", """
             Place p1 {
@@ -1004,11 +1004,11 @@ class TestModelverse(unittest.TestCase):
         assert attr_assign("users/user/test/a", "Place", "lower_cardinality", 4) == None
         assert read_attrs("users/user/test/a", "Place") == {"constraint": {"AL": ""}, "name": "NewPlace", "abstract": False, "lower_cardinality": 4, "upper_cardinality": None}
 
-        assert read_attrs("users/user/test/a", "P2T") == {"constraint": {"AL": ""}, "name": "P2T", "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None}
+        assert read_attrs("users/user/test/a", "P2T") == {"constraint": {"AL": ""}, "name": "P2T", "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None, "abstract": None, "lower_cardinality": None, "upper_cardinality": None}
         assert attr_assign("users/user/test/a", "P2T", "name", "PPP") == None
         assert attr_assign("users/user/test/a", "P2T", "source_lower_cardinality", 1) == None
         assert attr_assign("users/user/test/a", "P2T", "target_upper_cardinality", 10) == None
-        assert read_attrs("users/user/test/a", "P2T") == {"constraint": {"AL": ""}, "name": "PPP", "source_lower_cardinality": 1, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": 10}
+        assert read_attrs("users/user/test/a", "P2T") == {"constraint": {"AL": ""}, "name": "PPP", "source_lower_cardinality": 1, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": 10, "abstract": None, "lower_cardinality": None, "upper_cardinality": None}
 
         model_add("users/user/test/b", "users/user/test/a", """
             Place p1 {
@@ -1116,11 +1116,11 @@ class TestModelverse(unittest.TestCase):
         assert attr_delete("users/user/test/a", "Place", "lower_cardinality") == None
         assert read_attrs("users/user/test/a", "Place") == {"constraint": {"AL": ""}, "name": None, "abstract": None, "lower_cardinality": None, "upper_cardinality": None}
 
-        assert read_attrs("users/user/test/a", "P2T") == {"constraint": {"AL": ""}, "name": "P2T", "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None}
+        assert read_attrs("users/user/test/a", "P2T") == {"constraint": {"AL": ""}, "name": "P2T", "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None, "abstract": None, "lower_cardinality": None, "upper_cardinality": None}
         assert attr_delete("users/user/test/a", "P2T", "name") == None
         assert attr_delete("users/user/test/a", "P2T", "source_lower_cardinality") == None
         assert attr_delete("users/user/test/a", "P2T", "target_upper_cardinality") == None
-        assert read_attrs("users/user/test/a", "P2T") == {"constraint": {"AL": ""}, "name": None, "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None}
+        assert read_attrs("users/user/test/a", "P2T") == {"constraint": {"AL": ""}, "name": None, "source_lower_cardinality": None, "source_upper_cardinality": None, "target_lower_cardinality": None, "target_upper_cardinality": None, "abstract": None, "lower_cardinality": None, "upper_cardinality": None}
 
         model_add("users/user/test/b", "users/user/test/a", """
             Place p1 {
@@ -1814,6 +1814,29 @@ class TestModelverse(unittest.TestCase):
         # No write permissions, but can query
         assert read_association_destination("formalisms/SimpleClassDiagrams", "Association") == "Class"
 
+    def test_op_connections_between(self):
+        model_add("users/user/test/a", "formalisms/SimpleClassDiagrams", """
+            SimpleAttribute String {}
+            Class A {
+                name1 : String
+                name2 : String
+            }
+            Class B {}
+            Association C (A, B) {}
+            Association D (A, B) {}
+            Association E (A, A) {}
+            Association F (C, B) {}
+            Association G (E, F) {}
+            """)
+
+        # Test normal operation
+        assert connections_between("users/user/test/a", "A", "A") == set(["Association", "Inheritance"])
+        assert connections_between("users/user/test/a", "A", "B") == set(["Association", "Inheritance"])
+        assert connections_between("users/user/test/a", "A", "C") == set(["Association", "Inheritance"])
+
+        # Test none allowed
+        assert connections_between("users/user/test/a", "A_name1", "A_name2") == set([])
+        
     """
     def test_op_model_render(self):
     def test_op_transformation_between(self):
@@ -1836,8 +1859,6 @@ class TestModelverse(unittest.TestCase):
     def test_op_group_list(self):
     def test_op_conformance_delete(self):
     def test_op_conformance_add(self):
-    def test_op_read_association_destination(self):
-    def test_op_conections_between(self):
     def test_op_define_attribute(self):
     """
 
@@ -2083,9 +2104,9 @@ class TestModelverse(unittest.TestCase):
              {'__id': 'Place_name', '__type': 'AttributeLink', '__source': 'Place', '__target': 'String', 'name': 'name', 'optional': False, 'constraint': {'AL': ''}},
              {'__id': 'Transition', '__type': 'Class', 'lower_cardinality': None, 'upper_cardinality': None, 'constraint': {'AL': ''}, 'name': 'Transition', 'abstract': None},
              {'__id': 'Transition_name', '__type': 'AttributeLink', '__source': 'Transition', '__target': 'String', 'name': 'name', 'optional': False, 'constraint': {'AL': ''}},
-             {'__id': 'P2T', '__type': 'Association', '__source': 'Place', '__target': 'Transition', 'source_lower_cardinality': None, 'target_lower_cardinality': None, 'source_upper_cardinality': None, 'target_upper_cardinality': None, 'constraint': {'AL': ''}, 'name': 'P2T'},
+             {'__id': 'P2T', '__type': 'Association', '__source': 'Place', '__target': 'Transition', 'source_lower_cardinality': None, 'target_lower_cardinality': None, 'source_upper_cardinality': None, 'target_upper_cardinality': None, 'constraint': {'AL': ''}, 'name': 'P2T', "abstract": None, "lower_cardinality": None, "upper_cardinality": None},
              {'__id': 'P2T_weight', '__type': 'AttributeLink', '__source': 'P2T', '__target': 'Natural', 'name': 'weight', 'optional': False, 'constraint': {'AL': ''}},
-             {'__id': 'T2P', '__type': 'Association', '__source': 'Transition', '__target': 'Place', 'source_lower_cardinality': None, 'target_lower_cardinality': None, 'source_upper_cardinality': None, 'target_upper_cardinality': None, 'constraint': {'AL': ''}, 'name': 'T2P'},
+             {'__id': 'T2P', '__type': 'Association', '__source': 'Transition', '__target': 'Place', 'source_lower_cardinality': None, 'target_lower_cardinality': None, 'source_upper_cardinality': None, 'target_upper_cardinality': None, 'constraint': {'AL': ''}, 'name': 'T2P', "abstract": None, "lower_cardinality": None, "upper_cardinality": None},
              {'__id': 'T2P_weight', '__type': 'AttributeLink', '__source': 'T2P', '__target': 'Natural', 'name': 'weight', 'optional': False, 'constraint': {'AL': ''}},
             ]
         compare_unordered_lists(got, expected)