Browse Source

Add test for cardinalities

Yentl Van Tendeloo 8 years ago
parent
commit
c709261d2f

File diff suppressed because it is too large
+ 69193 - 69045
bootstrap/bootstrap.m


+ 12 - 7
bootstrap/conformance_scd.alc

@@ -169,14 +169,15 @@ String function conformance_scd(model : Element):
 						if (dict_in(cardinalities[check_type], "tlc")):
 							// A lower cardinality was defined at the target
 							if (integer_gt(cardinalities[check_type]["tlc"], instances)):
-								return "Lower cardinality violation for outgoing edge at " + model_info(model, model_name)
+								String error
+								error = (("Lower cardinality violation for outgoing edge of type " + check_type) + " at ") + model_info(model, model_name)
+								return error
 						if (dict_in(cardinalities[check_type], "tuc")):
 							// An upper cardinality was defined at the target
 							if (integer_lt(cardinalities[check_type]["tuc"], instances)):
-								log("Instances: " + cast_i2s(instances))
-								log("Cardinalities: " + cast_i2s(cardinalities[check_type]["tuc"]))
-								log("Type: " + check_type)
-								return "Upper cardinality violation for outgoing edge at " + model_info(model, model_name)
+								String error
+								error = (("Upper cardinality violation for outgoing edge of type " + check_type) + " at ") + model_info(model, model_name)
+								return error
 
 			// Identical, but for outgoing, and thus for A in the figure
 			if (bool_not(dict_in(spi_cache, type_name))):
@@ -192,11 +193,15 @@ String function conformance_scd(model : Element):
 						if (dict_in(cardinalities[check_type], "slc")):
 							// A lower cardinality was defined at the source
 							if (integer_gt(cardinalities[check_type]["slc"], instances)):
-								return "Lower cardinality violation for incoming edge at " + model_info(model, model_name)
+								String error
+								error = (("Lower cardinality violation for incoming edge of type " + check_type) + " at ") + model_info(model, model_name)
+								return error
 						if (dict_in(cardinalities[check_type], "suc")):
 							// An upper cardinality was defined at the source
 							if (integer_lt(cardinalities[check_type]["suc"], instances)):
-								return "Upper cardinality violation for incoming edge at " + model_info(model, model_name)
+								String error
+								error = (("Upper cardinality violation for incoming edge of type " + check_type) + " at ") + model_info(model, model_name)
+								return error
 
 			Element constraint_function
 			constraint_function = read_attribute(metamodel, reverseKeyLookup(metamodel["model"], dict_read_node(typing, element)), "constraint")

+ 13 - 4
integration/code/several_petrinets.mvc

@@ -13,14 +13,23 @@ SCD PetriNets{
          $
     }
     Class Place{
-        tokens : Natural
+        tokens : Natural {
+            target_lower_cardinality = 1
+            target_upper_cardinality = 1
+            }
     }
     Class Transition{}
     Association P2T (Place, Transition) {
-        weight : Natural
+        weight : Natural {
+            target_lower_cardinality = 1
+            target_upper_cardinality = 1
+            }
     }
     Association T2P (Transition, Place) {
-        weight : Natural
+        weight : Natural {
+            target_lower_cardinality = 1
+            target_upper_cardinality = 1
+            }
     }
 }
 
@@ -126,7 +135,7 @@ PetriNets invalid_petrinet_6 {
         tokens = 3
     }
     Transition t1 {}
-    P2T (p1, t1) {}
+    P2T p2t (p1, t1) {}
     T2P (t1, p2) {
         weight = 2
     }

File diff suppressed because it is too large
+ 3 - 1
integration/test_constructors_models_compiled.py


+ 5 - 4
interface/HUTN/grammars/modelling.g

@@ -11,10 +11,11 @@ grammar{
 
     inheritance: COLON MODEL_ID (COMMA MODEL_ID)*;
 
-    model_attribute
-        : (MODEL_ID COLON MODEL_ID NEWLINE?)
-        | (MODEL_ID ASSIGN value NEWLINE?)
-        | (DOLLAR ANYTHING_EXCEPT_DOLLAR DOLLAR NEWLINE?);
+    model_attribute : (MODEL_ID COLON MODEL_ID (LCURLY NEWLINE? model_attr_instance* RCURLY)? NEWLINE?)
+                    | (model_attr_instance)
+                    | (DOLLAR ANYTHING_EXCEPT_DOLLAR DOLLAR NEWLINE?);
+
+    model_attr_instance: MODEL_ID ASSIGN value NEWLINE?;
 
     value
         : DEC_NUMBER

+ 17 - 5
interface/HUTN/hutn_compiler/model_visitor.py

@@ -82,17 +82,23 @@ class ModelVisitor(Visitor):
         children = tree.get_children("MODEL_ID")
         is_definition = bool(tree.get_children("COLON"))
         is_constraint = bool(tree.get_children("DOLLAR"))
-        is_assign = bool(tree.get_children("ASSIGN"))
+        is_assign = bool(tree.get_children("model_attr_instance"))
 
         if is_definition:
             attr_name = children[0].get_text()
             attr_type = children[1].get_text()
             self.constructors.extend(['"instantiate_link"', jsonstr(self.current_model), jsonstr("Association"), jsonstr(self.current_element + "_" + attr_name), jsonstr(self.current_element), jsonstr(attr_type)])
-            self.constructors.extend(['"instantiate_attribute"', jsonstr(self.current_model), jsonstr(self.current_element + "_" + attr_name), jsonstr("name"), jsonstr(attr_name)])
+            full_attribute_name = self.current_element + "_" + attr_name
+            self.constructors.extend(['"instantiate_attribute"', jsonstr(self.current_model), jsonstr(full_attribute_name), jsonstr("name"), jsonstr(attr_name)])
+            if is_assign:
+                # There are also some attributes to set!
+                old_element = self.current_element
+                self.current_element = full_attribute_name
+                for f in tree.get_children("model_attr_instance"):
+                    self.visit(f)
+                self.current_element = old_element
         elif is_assign:
-            attr_name = children[0].get_text()
-            attr_value = tree.get_children("value")[0]
-            self.constructors.extend(['"instantiate_attribute"', jsonstr(self.current_model), jsonstr(self.current_element), jsonstr(attr_name), jsonstr(attr_value.get_text()) if attr_value.head == "STRVALUE" else attr_value.get_text()])
+            self.visit(tree.get_children("model_attr_instance")[0])
         elif is_constraint:
             constraint = tree.get_children("ANYTHING_EXCEPT_DOLLAR")[0].get_text()
             whitespaces = len(constraint) - len(constraint.lstrip())
@@ -107,3 +113,9 @@ class ModelVisitor(Visitor):
                 f.flush()
             directory = os.path.realpath(__file__).rsplit(os.sep, 1)[0]
             self.constructors.extend(['"add_constraint"', jsonstr(self.current_model), jsonstr(self.current_element)] + do_compile(".constraint.alc", directory + "/../grammars/actionlanguage.g", "CS"))
+
+    def visit_model_attr_instance(self, tree):
+        children = tree.get_children("MODEL_ID")
+        attr_name = children[0].get_text()
+        attr_value = tree.get_children("value")[0]
+        self.constructors.extend(['"instantiate_attribute"', jsonstr(self.current_model), jsonstr(self.current_element), jsonstr(attr_name), jsonstr(attr_value.get_text()) if attr_value.head == "STRVALUE" else attr_value.get_text()])