Browse Source

Added model transformation test with models defined in the HUTN

Yentl Van Tendeloo 8 years ago
parent
commit
413fa05e8d
3 changed files with 397 additions and 105 deletions
  1. 3 0
      integration/code/pn_interface.alc
  2. 383 103
      integration/test_pn_interface.py
  3. 11 2
      integration/utils.py

+ 3 - 0
integration/code/pn_interface.alc

@@ -320,6 +320,7 @@ Element function main():
 			output("  rename -- Rename a previously made model")
 			output("  delete -- Delete a previously made model")
 			output("  list   -- Show a list of all stored models")
+			output("  upload -- Upload a model using the model constructor commands")
 			output("  ramify -- RAMify a previously made model")
 			output("  help   -- Show a list of possible commands")
 		elif (command == "new"):
@@ -336,6 +337,8 @@ Element function main():
 					model_loaded(my_model)
 			else:
 				output("Unknown metamodel; aborting")
+		elif (command == "upload"):
+			construct_model()
 		elif (command == "load"):
 			output("Model to load?")
 			name = input()

+ 383 - 103
integration/test_pn_interface.py

@@ -1,6 +1,6 @@
 import unittest
 
-from utils import run_file, get_constructor
+from utils import run_file, get_constructor, get_model_constructor
 
 set_inheritance = [
         "Which link in the metamodel is the inheritance link?",
@@ -401,59 +401,59 @@ include "primitives.alh"
 include "object_operations.alh"
 
 Element function constraint(model : Element, name : String):
-\tElement associations
-\tElement back_associations
-\tElement association
-\tString destination
-\tassociations = allOutgoingAssociationInstances(model, name, "tile_left")
-\twhile (0 < list_len(associations)):
-\t\tassociation = set_pop(associations)
-\t\tdestination = readAssociationDestination(model, association)
-\t\tback_associations = allOutgoingAssociationInstances(model, destination, "tile_right")
-\t\tif (list_len(back_associations) < 1):
-\t\t\treturn "Left link does not have a right link back"!
-\t\telse:
-\t\t\tassociation = set_pop(back_associations)
-\t\t\tdestination = readAssociationDestination(model, association)
-\t\t\tif (destination != name):
-\t\t\t\treturn "Right link does not have a left link back to the same tile"!
-\tassociations = allOutgoingAssociationInstances(model, name, "tile_right")
-\twhile (0 < list_len(associations)):
-\t\tassociation = set_pop(associations)
-\t\tdestination = readAssociationDestination(model, association)
-\t\tback_associations = allOutgoingAssociationInstances(model, destination, "tile_left")
-\t\tif (list_len(back_associations) < 1):
-\t\t\treturn "Right link does not have a left link back"!
-\t\telse:
-\t\t\tassociation = set_pop(back_associations)
-\t\t\tdestination = readAssociationDestination(model, association)
-\t\t\tif (destination != name):
-\t\t\t\treturn "Right link does not have a left link back to the same tile"!
-\tassociations = allOutgoingAssociationInstances(model, name, "tile_top")
-\twhile (0 < list_len(associations)):
-\t\tassociation = set_pop(associations)
-\t\tdestination = readAssociationDestination(model, association)
-\t\tback_associations = allOutgoingAssociationInstances(model, destination, "tile_bottom")
-\t\tif (list_len(back_associations) < 1):
-\t\t\treturn "Top link does not have a bottom link back"!
-\t\telse:
-\t\t\tassociation = set_pop(back_associations)
-\t\t\tdestination = readAssociationDestination(model, association)
-\t\t\tif (destination != name):
-\t\t\t\treturn "Top link does not have a bottom link back to the same tile"!
-\tassociations = allOutgoingAssociationInstances(model, name, "tile_bottom")
-\twhile (0 < list_len(associations)):
-\t\tassociation = set_pop(associations)
-\t\tdestination = readAssociationDestination(model, association)
-\t\tback_associations = allOutgoingAssociationInstances(model, destination, "tile_top")
-\t\tif (list_len(back_associations) < 1):
-\t\t\treturn "Bottom link does not have a top link back"!
-\t\telse:
-\t\t\tassociation = set_pop(back_associations)
-\t\t\tdestination = readAssociationDestination(model, association)
-\t\t\tif (destination != name):
-\t\t\t\treturn "Bottom link does not have a top link back to the same tile"!
-\treturn "OK"!
+	Element associations
+	Element back_associations
+	Element association
+	String destination
+	associations = allOutgoingAssociationInstances(model, name, "tile_left")
+	while (0 < list_len(associations)):
+		association = set_pop(associations)
+		destination = readAssociationDestination(model, association)
+		back_associations = allOutgoingAssociationInstances(model, destination, "tile_right")
+		if (list_len(back_associations) < 1):
+			return "Left link does not have a right link back"!
+		else:
+			association = set_pop(back_associations)
+			destination = readAssociationDestination(model, association)
+			if (destination != name):
+				return "Right link does not have a left link back to the same tile"!
+	associations = allOutgoingAssociationInstances(model, name, "tile_right")
+	while (0 < list_len(associations)):
+		association = set_pop(associations)
+		destination = readAssociationDestination(model, association)
+		back_associations = allOutgoingAssociationInstances(model, destination, "tile_left")
+		if (list_len(back_associations) < 1):
+			return "Right link does not have a left link back"!
+		else:
+			association = set_pop(back_associations)
+			destination = readAssociationDestination(model, association)
+			if (destination != name):
+				return "Right link does not have a left link back to the same tile"!
+	associations = allOutgoingAssociationInstances(model, name, "tile_top")
+	while (0 < list_len(associations)):
+		association = set_pop(associations)
+		destination = readAssociationDestination(model, association)
+		back_associations = allOutgoingAssociationInstances(model, destination, "tile_bottom")
+		if (list_len(back_associations) < 1):
+			return "Top link does not have a bottom link back"!
+		else:
+			association = set_pop(back_associations)
+			destination = readAssociationDestination(model, association)
+			if (destination != name):
+				return "Top link does not have a bottom link back to the same tile"!
+	associations = allOutgoingAssociationInstances(model, name, "tile_bottom")
+	while (0 < list_len(associations)):
+		association = set_pop(associations)
+		destination = readAssociationDestination(model, association)
+		back_associations = allOutgoingAssociationInstances(model, destination, "tile_top")
+		if (list_len(back_associations) < 1):
+			return "Bottom link does not have a top link back"!
+		else:
+			association = set_pop(back_associations)
+			destination = readAssociationDestination(model, association)
+			if (destination != name):
+				return "Bottom link does not have a top link back to the same tile"!
+	return "OK"!
             """
 
         constructors = get_constructor(constraint_code)
@@ -545,20 +545,20 @@ include "primitives.alh"
 include "modelling.alh"
 include "object_operations.alh"
 Boolean function constraint(host_model : Element, name : String):
-\t// Make sure that all places have enough tokens
-\tElement links
-\tString link
-\tString place
-\tlinks = allIncomingAssociationInstances(host_model, name, "P2T")
-\twhile (read_nr_out(links) > 0):
-\t\tlink = set_pop(links)
-\t\tplace = readAssociationSource(host_model, link)
-\t\tlog("Check link " + link)
-\t\tlog("Check place " + place)
-\t\tif (integer_lt(read_attribute(host_model, place, "tokens"), read_attribute(host_model, link, "weight"))):
-\t\t\t// Not enough tokens for this weight
-\t\t\treturn False!
-\treturn True!
+	// Make sure that all places have enough tokens
+	Element links
+	String link
+	String place
+	links = allIncomingAssociationInstances(host_model, name, "P2T")
+	while (read_nr_out(links) > 0):
+		link = set_pop(links)
+		place = readAssociationSource(host_model, link)
+		log("Check link " + link)
+		log("Check place " + place)
+		if (integer_lt(read_attribute(host_model, place, "tokens"), read_attribute(host_model, link, "weight"))):
+			// Not enough tokens for this weight
+			return False!
+	return True!
             """
 
         code_mark_action = \
@@ -566,9 +566,9 @@ Boolean function constraint(host_model : Element, name : String):
 include "primitives.alh"
 include "modelling.alh"
 Void function action(host_model : Element, name : String, mapping : Element):
-\tunset_attribute(host_model, name, "executing")
-\tinstantiate_attribute(host_model, name, "executing", True)
-\treturn!
+	unset_attribute(host_model, name, "executing")
+	instantiate_attribute(host_model, name, "executing", True)
+	return!
             """
 
         code_consume_transition_constraint = \
@@ -576,8 +576,8 @@ Void function action(host_model : Element, name : String, mapping : Element):
 include "primitives.alh"
 include "modelling.alh"
 Boolean function constraint(host_model : Element, name : String):
-\t// Check if this node is executing currently
-\treturn value_eq(read_attribute(host_model, name, "executing"), True)!
+	// Check if this node is executing currently
+	return value_eq(read_attribute(host_model, name, "executing"), True)!
             """
 
         code_consume_place_constraint = \
@@ -585,8 +585,8 @@ Boolean function constraint(host_model : Element, name : String):
 include "primitives.alh"
 include "modelling.alh"
 Boolean function constraint(host_model : Element, name : String):
-\t// Check if this node is executing currently
-\treturn value_eq(read_attribute(host_model, name, "executed"), False)!
+	// Check if this node is executing currently
+	return value_eq(read_attribute(host_model, name, "executed"), False)!
             """
 
         code_consume_place_action = \
@@ -594,15 +594,15 @@ Boolean function constraint(host_model : Element, name : String):
 include "primitives.alh"
 include "modelling.alh"
 Void function action(host_model : Element, name : String, mapping : Element):
-\tInteger tokens
-\tInteger weight
-\ttokens = read_attribute(host_model, name, "tokens")
-\tweight = read_attribute(host_model, mapping["2"], "weight")
-\tunset_attribute(host_model, name, "tokens")
-\tinstantiate_attribute(host_model, name, "tokens", tokens - weight)
-\tunset_attribute(host_model, name, "executed")
-\tinstantiate_attribute(host_model, name, "executed", True)
-\treturn!
+	Integer tokens
+	Integer weight
+	tokens = read_attribute(host_model, name, "tokens")
+	weight = read_attribute(host_model, mapping["2"], "weight")
+	unset_attribute(host_model, name, "tokens")
+	instantiate_attribute(host_model, name, "tokens", tokens - weight)
+	unset_attribute(host_model, name, "executed")
+	instantiate_attribute(host_model, name, "executed", True)
+	return!
             """
 
         code_produce_place_action = \
@@ -610,15 +610,15 @@ Void function action(host_model : Element, name : String, mapping : Element):
 include "primitives.alh"
 include "modelling.alh"
 Void function action(host_model : Element, name : String, mapping : Element):
-\tInteger tokens
-\tInteger weight
-\ttokens = read_attribute(host_model, name, "tokens")
-\tweight = read_attribute(host_model, mapping["2"], "weight")
-\tunset_attribute(host_model, name, "tokens")
-\tinstantiate_attribute(host_model, name, "tokens", tokens + weight)
-\tunset_attribute(host_model, name, "executed")
-\tinstantiate_attribute(host_model, name, "executed", True)
-\treturn!
+	Integer tokens
+	Integer weight
+	tokens = read_attribute(host_model, name, "tokens")
+	weight = read_attribute(host_model, mapping["2"], "weight")
+	unset_attribute(host_model, name, "tokens")
+	instantiate_attribute(host_model, name, "tokens", tokens + weight)
+	unset_attribute(host_model, name, "executed")
+	instantiate_attribute(host_model, name, "executed", True)
+	return!
             """
 
         code_unmark_transition_constraint = \
@@ -626,8 +626,8 @@ Void function action(host_model : Element, name : String, mapping : Element):
 include "primitives.alh"
 include "modelling.alh"
 Boolean function constraint(host_model : Element, name : String):
-\t// Check if this node is executing currently
-\treturn value_eq(read_attribute(host_model, name, "executing"), True)!
+	// Check if this node is executing currently
+	return value_eq(read_attribute(host_model, name, "executing"), True)!
             """
 
         code_unmark_place_constraint = \
@@ -635,8 +635,8 @@ Boolean function constraint(host_model : Element, name : String):
 include "primitives.alh"
 include "modelling.alh"
 Boolean function constraint(host_model : Element, name : String):
-\t// Check if this node is executing currently
-\treturn value_eq(read_attribute(host_model, name, "executed"), True)!
+	// Check if this node is executing currently
+	return value_eq(read_attribute(host_model, name, "executed"), True)!
             """
 
         code_unmark_transition_action = \
@@ -644,9 +644,9 @@ Boolean function constraint(host_model : Element, name : String):
 include "primitives.alh"
 include "modelling.alh"
 Void function action(host_model : Element, name : String, mapping : Element):
-\tunset_attribute(host_model, name, "executing")
-\tinstantiate_attribute(host_model, name, "executing", False)
-\treturn!
+	unset_attribute(host_model, name, "executing")
+	instantiate_attribute(host_model, name, "executing", False)
+	return!
             """
 
         code_unmark_place_action = \
@@ -654,9 +654,9 @@ Void function action(host_model : Element, name : String, mapping : Element):
 include "primitives.alh"
 include "modelling.alh"
 Void function action(host_model : Element, name : String, mapping : Element):
-\tunset_attribute(host_model, name, "executed")
-\tinstantiate_attribute(host_model, name, "executed", False)
-\treturn!
+	unset_attribute(host_model, name, "executed")
+	instantiate_attribute(host_model, name, "executed", False)
+	return!
             """
 
         constructor_mark_constraint = get_constructor(code_mark_constraint)
@@ -866,3 +866,283 @@ Void function action(host_model : Element, name : String, mapping : Element):
                 "exit",
                 ],
             None, "PO"))
+
+    def test_po_pn_interface_model_transform_pn(self):
+        PN_runtime = \
+            """
+            import models/SimpleClassDiagrams as SimpleClassDiagrams
+
+            SimpleClassDiagrams (Inheritance) PetriNets_Runtime{
+                Class Natural {}
+                Class Boolean {}
+                Class Place {
+                    tokens : Natural
+                    executed : Boolean
+                }
+                Class Transition {
+                    executing : Boolean
+                }
+                Association P2T (Place, Transition) {
+                    weight : Natural
+                }
+                Association T2P (Transition, Place) {
+                    weight : Natural
+                }
+
+            export PetriNets_Runtime to models/PetriNets_Runtime
+            """
+
+        PN_model = \
+            """
+            import models/PetriNets_Runtime as PetriNets_Runtime
+
+            PetriNets_Runtime pn {
+                Place p1 {
+                    tokens = 1
+                    executed = False
+                }
+                Place p2 {
+                    tokens = 2
+                    executed = False
+                }
+                Transition t1 {
+                    executing = False
+                }
+            }
+
+            export pn to models/pn
+            """
+
+        schedule_model = \
+            """
+            import models/PetriNets_Runtime_Schedule as PN_Transform
+
+            PN_Transform s {
+                Composite schedule {
+                    Failure failure {}
+                    Success success {}
+                    Atomic mark {
+                        LHS {
+                            Pre_Transition {
+                                label = "1"
+                                constraint = 
+                                    $
+                                    include "primitives.alh"
+                                    include "modelling.alh"
+                                    include "object_operations.alh"
+                                    Boolean function constraint(host_model : Element, name : String):
+                                        // Make sure that all places have enough tokens
+                                        Element links
+                                        String link
+                                        String place
+                                        links = allIncomingAssociationInstances(host_model, name, "P2T")
+                                        while (read_nr_out(links) > 0):
+                                            link = set_pop(links)
+                                                    place = readAssociationSource(host_model, link)
+                                                    log("Check link " + link)
+                                                    log("Check place " + place)
+                                                    if (integer_lt(read_attribute(host_model, place, "tokens"), read_attribute(host_model, link, "weight"))):
+                                                            // Not enough tokens for this weight
+                                                            return False!
+                                            return True!
+                                    $
+                            }
+                        }
+                        RHS {
+                            Post_Transition {
+                                label = "1"
+                                action = 
+                                    $
+                                    include "primitives.alh"
+                                    include "modelling.alh"
+                                    Void function action(host_model : Element, name : String, mapping : Element):
+                                            unset_attribute(host_model, name, "executing")
+                                            instantiate_attribute(host_model, name, "executing", True)
+                                            return!
+                                    $
+                            }
+                        }
+                    Atomic consume {
+                        LHS {
+                            Pre_Transition {
+                                label = "0"
+                                constraint = 
+                                    $
+                                    include "primitives.alh"
+                                    include "modelling.alh"
+                                    Boolean function constraint(host_model : Element, name : String):
+                                            // Check if this node is executing currently
+                                            return value_eq(read_attribute(host_model, name, "executing"), True)!
+                                    $
+                            }
+                            Pre_Place {
+                                label = "1"
+                                constraint = 
+                                    $
+                                    include "primitives.alh"
+                                    include "modelling.alh"
+                                    Boolean function constraint(host_model : Element, name : String):
+                                            // Check if this node is executing currently
+                                            return value_eq(read_attribute(host_model, name, "executed"), False)!
+                                    $
+                            }
+                            Pre_P2T {
+                                label = "2"
+                            }
+                        RHS {
+                            Post_Transition {
+                                label = "0"
+                            }
+                            Post_Place {
+                                label = "1"
+                                action = 
+                                    $
+                                    include "primitives.alh"
+                                    include "modelling.alh"
+                                    Void function action(host_model : Element, name : String, mapping : Element):
+                                            Integer tokens
+                                            Integer weight
+                                            tokens = read_attribute(host_model, name, "tokens")
+                                            weight = read_attribute(host_model, mapping["2"], "weight")
+                                            unset_attribute(host_model, name, "tokens")
+                                            instantiate_attribute(host_model, name, "tokens", tokens - weight)
+                                            unset_attribute(host_model, name, "executed")
+                                            instantiate_attribute(host_model, name, "executed", True)
+                                            return!
+                                    $
+                            }
+                            Post_P2T {
+                                label = "2"
+                            }
+                        }
+                    Atomic produce {
+                        LHS {
+                            Pre_Transition {
+                                label = "0"
+                                constraint = 
+                                    $
+                                    include "primitives.alh"
+                                    include "modelling.alh"
+                                    Boolean function constraint(host_model : Element, name : String):
+                                            // Check if this node is executing currently
+                                            return value_eq(read_attribute(host_model, name, "executing"), True)!
+                                    $
+                            }
+                            Pre_Place {
+                                label = "1"
+                                constraint = 
+                                    $
+                                    include "primitives.alh"
+                                    include "modelling.alh"
+                                    Boolean function constraint(host_model : Element, name : String):
+                                            // Check if this node is executing currently
+                                            return value_eq(read_attribute(host_model, name, "executed"), False)!
+                                    $
+                            }
+                            Pre_T2P {
+                                label = "2"
+                            }
+                        RHS {
+                            Post_Transition {
+                                label = "0"
+                            }
+                            Post_Place {
+                                label = "1"
+                                action = 
+                                    $
+                                    include "primitives.alh"
+                                    include "modelling.alh"
+                                    Void function action(host_model : Element, name : String, mapping : Element):
+                                            Integer tokens
+                                            Integer weight
+                                            tokens = read_attribute(host_model, name, "tokens")
+                                            weight = read_attribute(host_model, mapping["2"], "weight")
+                                            unset_attribute(host_model, name, "tokens")
+                                            instantiate_attribute(host_model, name, "tokens", tokens + weight)
+                                            unset_attribute(host_model, name, "executed")
+                                            instantiate_attribute(host_model, name, "executed", True)
+                                            return!
+                                    $
+                            }
+                            Post_T2P {
+                                label = "2"
+                            }
+                        }
+                    Atomic unmark_transition {
+                        LHS {
+                            Pre_Transition {
+                                label = "0"
+                                constraint = 
+                                    $
+                                    include "primitives.alh"
+                                    include "modelling.alh"
+                                    Boolean function constraint(host_model : Element, name : String):
+                                            // Check if this node is executing currently
+                                            return value_eq(read_attribute(host_model, name, "executing"), True)!
+                                    $
+                            }
+                        }
+                        RHS {
+                            Post_Transition {
+                                label = "0"
+                                value = $$
+                            }
+                        }
+                    Atomic unmark_place:
+                        LHS {
+                            Pre_Place {
+                                label = "0"
+                                constraint = 
+                                    $
+                                    include "primitives.alh"
+                                    include "modelling.alh"
+                                    Boolean function constraint(host_model : Element, name : String):
+                                            // Check if this node is executing currently
+                                            return value_eq(read_attribute(host_model, name, "executed"), True)!
+                                    $
+                            }
+                        }
+                        RHS {
+                            Post_Place {
+                                label = "0"
+                                value = 
+                                    $
+                                    include "primitives.alh"
+                                    include "modelling.alh"
+                                    Void function action(host_model : Element, name : String, mapping : Element):
+                                            unset_attribute(host_model, name, "executed")
+                                            instantiate_attribute(host_model, name, "executed", False)
+                                            return!
+                                    $
+                            }
+                        }
+                    }
+                    OnSuccess (mark, consume) {}
+                    OnFailure (mark, failure) {}
+                    OnSuccess (consume, consume) {}
+                    OnFailure (consume, produce) {}
+                    OnSuccess (produce, produce) {}
+                    OnFailure (produce, unmark_transition) {}
+                    OnSuccess (unmark_transition, unmark_place) {}
+                    OnFailure (unmark_transition, failure) {}
+                    OnSuccess (unmark_place, unmark_place) {}
+                    OnFailure (unmark_place, success) {}
+                    initial = mark
+            """
+
+        self.assertTrue(run_file(all_files,
+            ["upload", 
+            ] + get_model_constructor(PN_runtime) + [
+            ] + get_model_constructor(PN_model) + [
+             "ramify", "PetriNets_runtime",
+            ] + get_model_constructor(schedule_model) + [
+             "transform", "pn", "pn_simulate",
+             "load", "pn",
+                "list",
+                "verify",
+                "read", "t1",
+                "read", "p1",
+                "read", "p2",
+                "exit",
+            ],
+          None, "PO"))

+ 11 - 2
integration/utils.py

@@ -271,10 +271,19 @@ def run_barebone(parameters, expected, interface="0", timeout=False, wait=False,
         kill(proc)
 
 def get_constructor(code):
-    with open("__constraint.al", "w") as f:
+    with open("__constraint.alc", "w") as f:
         f.write(code)
         f.flush()
 
-    constructors = do_compile("__constraint.al", "interface/HUTN/grammars/actionlanguage.g", "CS")
+    constructors = do_compile("__constraint.alc", "interface/HUTN/grammars/actionlanguage.g", "CS")
+
+    return constructors
+
+def get_model_constructor(code):
+    with open("__model.mvc", "w") as f:
+        f.write(code)
+        f.flush()
+
+    constructors = do_compile("__model.mvc", "interface/HUTN/grammars/actionlanguage.g", "M")
 
     return constructors