Yentl Van Tendeloo 9 лет назад
Родитель
Сommit
6e79d39a3b
62 измененных файлов с 3021 добавлено и 1243 удалено
  1. 1 0
      .gitattributes
  2. 0 7
      .gitignore
  3. 1 8
      README.md
  4. 4 5
      bootstrap/bootstrap.py
  5. 12 7
      bootstrap/conformance_scd.alc
  6. 13 2
      bootstrap/constructors.alc
  7. 5 2
      bootstrap/library.alc
  8. 26 16
      bootstrap/modelling.alc
  9. 10 3
      bootstrap/random.alc
  10. 19 0
      integration/code/my_petrinet.mvc
  11. 34 0
      integration/code/my_petrinet_with_MM.mvc
  12. 43 0
      integration/code/my_petrinet_with_MM_and_constraints.mvc
  13. 17 0
      integration/code/petrinets.mvc
  14. 27 0
      integration/code/petrinets_constraints.mvc
  15. 1 106
      integration/code/pn_interface.alc
  16. 149 0
      integration/code/pn_semantics.alc
  17. 127 0
      integration/code/rpgame.mvc
  18. 95 0
      integration/code/rpgame_semantics.alc
  19. 166 0
      integration/code/several_petrinets.mvc
  20. 21 0
      integration/code/simpleclassdiagrams.mvc
  21. 33 0
      integration/my_petrinet_with_MM_and_constraints.mvc
  22. 210 214
      integration/test_constructors_models.py
  23. 95 0
      integration/test_constructors_models_compiled.py
  24. 4 37
      integration/test_pn_interface.py
  25. 52 0
      interface/HUTN/grammars/modelling.g
  26. 3 1
      interface/HUTN/hutn_compiler/bootstrap_visitor.py
  27. 4 0
      interface/HUTN/hutn_compiler/compiler.py
  28. 39 0
      interface/HUTN/hutn_compiler/model_object_visitor.py
  29. 126 0
      interface/HUTN/hutn_compiler/model_visitor.py
  30. 0 1
      interface/HUTN/hutn_compiler/primitives_object_visitor.py
  31. 8 6
      interface/HUTN/hutn_compiler/primitives_visitor.py
  32. 7 0
      interface/HUTN/test/constructor_compilation_action_language/util.py
  33. 7 0
      interface/HUTN/test/grammar_action_language/util.py
  34. 167 155
      interface/HUTN/test/graph_compilation_action_language/expected/factorial
  35. 199 187
      interface/HUTN/test/graph_compilation_action_language/expected/fibonacci
  36. 417 385
      interface/HUTN/test/graph_compilation_action_language/expected/fibonacci_smart
  37. 19 21
      interface/HUTN/test/graph_compilation_action_language/expected/global
  38. 92 76
      interface/HUTN/test/graph_compilation_action_language/expected/include
  39. 7 0
      interface/HUTN/test/graph_compilation_action_language/util.py
  40. 19 0
      interface/HUTN/test/modelling_language/code/my_petrinet.mvc
  41. 33 0
      interface/HUTN/test/modelling_language/code/my_petrinet_with_MM.mvc
  42. 17 0
      interface/HUTN/test/modelling_language/code/petrinets.mvc
  43. 27 0
      interface/HUTN/test/modelling_language/code/petrinets_constraints.mvc
  44. 21 0
      interface/HUTN/test/modelling_language/code/simpleclassdiagrams.mvc
  45. 1 0
      interface/HUTN/test/modelling_language/expected/my_petrinet
  46. 1 0
      interface/HUTN/test/modelling_language/expected/my_petrinet_with_MM
  47. 1 0
      interface/HUTN/test/modelling_language/expected/petrinets
  48. 1 0
      interface/HUTN/test/modelling_language/expected/petrinets_constraints
  49. 1 0
      interface/HUTN/test/modelling_language/expected/simpleclassdiagrams
  50. 33 0
      interface/HUTN/test/modelling_language/test_compile.py
  51. 7 0
      interface/HUTN/test/modelling_language/util.py
  52. 1 1
      interface/HUTN/test/util.py
  53. 56 0
      kernel/modelverse_kernel/compiled.py
  54. 4 0
      kernel/modelverse_kernel/main.py
  55. 1 1
      kernel/modelverse_kernel/primitives.py
  56. 120 0
      kernel/test/functions/utils.py
  57. 120 0
      kernel/test/instructions/utils.py
  58. 120 0
      kernel/test/primitives/utils.py
  59. 120 0
      kernel/test/rules/utils.py
  60. 2 2
      scripts/compile.py
  61. 54 0
      scripts/execute_model.py
  62. 1 0
      scripts/fix_files.py

+ 1 - 0
.gitattributes

@@ -0,0 +1 @@
+*.m binary

+ 0 - 7
.gitignore

@@ -4,11 +4,4 @@
 .cache
 *.swp
 __pycache__
-interface/HUTN/test/grammar_action_language/util.py
-interface/HUTN/test/graph_compilation_action_language/util.py
-interface/HUTN/test/constructor_compilation_action_language/util.py
-kernel/test/functions/utils.py
-kernel/test/instructions/utils.py
-kernel/test/primitives/utils.py
-kernel/test/rules/utils.py
 hybrid_server/server.py

+ 1 - 8
README.md

@@ -4,14 +4,7 @@ Installation
 Installing the Modelverse is unnecessary, as it is mere Python code and doesn't use installation scripts.
 All scripts which are generally useful are found in the 'scripts' directory, and are written in OS-independent Python code.
 
-There will be three things that you need to do only once:
-
-    1. Make copies of test files, by executing `scripts/fix_files.py`
-    2. Generate a bootstrap file, by executing `scripts/generate_bootstrap.py`
-    3. Install the [SCCD compiler and runtime](https://msdl.uantwerpen.be/git/simon/SCCD)
-
-That is it!
-You will only have to recreate a bootstrap file if you modify any of the code in the bootstrap folder, which is likely not a good idea unless you know what you are doing!.
+You will, however, need to install a dependency: the [SCCD compiler and runtime](https://msdl.uantwerpen.be/git/simon/SCCD).
 
 Starting up the Modelverse
 ==========================

+ 4 - 5
bootstrap/bootstrap.py

@@ -154,27 +154,26 @@ def bootstrap():
     include "primitives.alc"
     include "compilation_manager.alc"
     include "constructors.alc"
-    include "object_operations.alc"
     include "library.alc"
+    include "object_operations.alc"
     include "conformance_scd.alc"
     include "modelling.alc"
+    include "metamodels.alc"
 
     Void function __main():
     \tInteger interface
     \twhile (True):
-    \t\tlog("User interface select")
     \t\tinterface = input()
     \t\tif (interface == 0):
-    \t\t\tlog("DO deserialize")
     \t\t\texec(deserialize(input()))
     \t\telif (interface == 1):
-    \t\t\tlog("User entered constructors")
     \t\t\texec(construct_unknown())
     \t\telif (interface == 2):
-    \t\t\tlog("Done signalled")
     \t\t\toutput("DONE")
     \t\telif (interface == 3):
     \t\t\tcompilation_manager()
+    \t\telif (interface == 4):
+    \t\t\tconstruct_model()
     \t\telse:
     \t\t\tlog("Unsupported interface!")
     '''

+ 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 - 2
bootstrap/constructors.alc

@@ -23,6 +23,7 @@ Action function construct_global():
 	String declared_element
 	String op
 
+	log("Construct global")
 	this_element = create_value(!global)
 	declared_element = input()
 	dict_add(this_element, "var", declared_element)
@@ -37,12 +38,22 @@ Action function construct_global():
 	dict_add(assign, "var", resolve)
 	dict_add(resolve, "var", declared_element)
 	op = input()
-	value = create_value(!constant)
 	if (op == "deref"):
+		value = create_value(!constant)
 		dict_add(value, "node", import_node(input()))
 	elif (op == "empty"):
-		dict_add(value, "node", create_node())
+		log("EMPTY")
+		value = create_value(!call)
+		Element res
+		Element acc
+		res = create_value(!resolve)
+		acc = create_value(!access)
+		dict_add(value, "func", acc)
+		dict_add(acc, "var", res)
+		dict_add(res, "var", "create_node")
+		log("Created create_node call")
 	elif (op == "const"):
+		value = create_value(!constant)
 		dict_add(value, "node", input())
 	dict_add(assign, "value", value)
 

+ 5 - 2
bootstrap/library.alc

@@ -31,7 +31,10 @@ Element function import_node(model_name : String):
 	Element current
 	current = dict_read(read_root(), "__hierarchy")
 	while (counter_i < length):
-		current = current[splitted[counter_i]]
-		counter_i = counter_i + 1
+		if dict_in(current, splitted[counter_i]):
+			current = current[splitted[counter_i]]
+			counter_i = counter_i + 1
+		else:
+			return read_root()
 
 	return current

+ 26 - 16
bootstrap/modelling.alc

@@ -3,6 +3,7 @@ include "io.alh"
 include "object_operations.alh"
 include "constructors.alh"
 include "metamodels.alh"
+include "library.alh"
 
 Element global_models = ?
 
@@ -171,7 +172,7 @@ Void function instantiate_attribute(model : Element, element : String, attribute
 		log("Could not find attribute!")
 		return
 		
-	attr_name = model_add_value(model, "", value)
+	attr_name = model_add_value(model, (element + ".") + attribute_name, value)
 	retype(model, attr_name, reverseKeyLookup(model["metamodel"]["model"], read_edge_dst(model["metamodel"]["model"][attr_type])))
 	instantiate_link(model, attr_type, "", element, attr_name)
 
@@ -373,38 +374,47 @@ Void function construct_model():
 		if (command == "instantiate_bottom"):
 			Element m
 			m = instantiate_bottom()
-			set_add(global_models, m)
-			output(m)
+			dict_add(global_models, input(), m)
 		elif (command == "add_node"):
-			model_add_node(input(), input())
+			model_add_node(global_models[input()], input())
 		elif (command == "add_value"):
-			model_add_value(input(), input(), input())
+			model_add_value(global_models[input()], input(), input())
 		elif (command == "add_edge"):
-			model_add_edge(input(), input(), input(), input())
+			model_add_edge(global_models[input()], input(), input(), input())
 		elif (command == "exit"):
 			return
 		elif (command == "retype_model"):
-			retype_model(input(), input())
+			retype_model(global_models[input()], global_models[input()])
 		elif (command == "retype"):
-			retype(input(), input(), input())
+			retype(global_models[input()], input(), input())
 		elif (command == "instantiate_model"):
 			Element m
-			m = instantiate_model(input())
-			set_add(global_models, m)
-			output(m)
+			m = instantiate_model(global_models[input()])
+			dict_add(global_models, input(), m)
 		elif (command == "instantiate_node"):
-			instantiate_node(input(), input(), input())
+			instantiate_node(global_models[input()], input(), input())
 		elif (command == "instantiate_attribute"):
-			instantiate_attribute(input(), input(), input(), input())
+			instantiate_attribute(global_models[input()], input(), input(), input())
 		elif (command == "instantiate_link"):
-			instantiate_link(input(), input(), input(), input(), input())
+			instantiate_link(global_models[input()], input(), input(), input(), input())
 		elif (command == "define_inheritance"):
-			define_inheritance(input(), input())
+			define_inheritance(global_models[input()], input())
 		elif (command == "add_constraint"):
-			add_constraint(input(), input(), construct_function())
+			add_constraint(global_models[input()], input(), construct_function())
 		elif (command == "initialize_SCD"):
 			initialize_SCD(input())
 		elif (command == "initialize_bottom"):
 			initialize_bottom(input())
+		elif (command == "export_node"):
+			String local_name
+			String location
+			local_name = input()
+			location = input()
+			export_node(location, global_models[local_name])
+		elif (command == "import_node"):
+			Element m
+			m = import_node(input())
+			log("Imported node " + cast_e2s(m))
+			dict_add(global_models, input(), m)
 		else:
 			log("Modelling error: did not understand command " + command)

+ 10 - 3
bootstrap/random.alc

@@ -17,10 +17,17 @@ Float function random():
 	seed = integer_modulo(a * seed + c, m)
 
 	// The seed is the new value
-	return seed / m
+	log("Return random " + cast_f2s(float_division(seed, m)))
+	return float_division(seed, m)
 
 Integer function random_interval(a : Integer, b : Integer):
-	return cast_f2i(random() * (b - a) + a)
+	if (a == b):
+		return a
+	else:
+		return cast_f2i(random() * (b - a + 1) + a)
 
 Element function random_choice(list : Element):
-	return read_edge_dst(read_out(list, random_interval(0, read_nr_out(list) - 1)))
+	if (list_len(list) == 0):
+		return read_root()
+	else:
+		return read_edge_dst(read_out(list, random_interval(0, read_nr_out(list) - 1)))

+ 19 - 0
integration/code/my_petrinet.mvc

@@ -0,0 +1,19 @@
+import models/PetriNets as PetriNets
+
+PetriNets my_petrinet {
+    Place p1 {
+        tokens = 1
+    }
+    Place p2 {
+        tokens = 3
+    }
+    Transition t1 {}
+    P2T (p1, t1) {
+        weight = 1
+    }
+    T2P (t1, p2) {
+        weight = 2
+    }
+}
+
+export my_petrinet to models/my_petrinet

+ 34 - 0
integration/code/my_petrinet_with_MM.mvc

@@ -0,0 +1,34 @@
+import models/SimpleClassDiagrams as SCD
+include "primitives.alh"
+
+SCD PetriNets{
+    Class Natural {}
+    Class Place{
+        tokens : Natural
+    }
+    Class Transition{}
+    Association P2T (Place, Transition) {
+        weight : Natural
+    }
+    Association T2P (Transition, Place) {
+        weight : Natural
+    }
+}
+
+PetriNets my_petrinet {
+    Place p1 {
+        tokens = 1
+    }
+    Place p2 {
+        tokens = 3
+    }
+    Transition t1 {}
+    P2T (p1, t1) {
+        weight = 1
+    }
+    T2P (t1, p2) {
+        weight = 2
+    }
+}
+
+export my_petrinet to models/my_petrinet

+ 43 - 0
integration/code/my_petrinet_with_MM_and_constraints.mvc

@@ -0,0 +1,43 @@
+import models/SimpleClassDiagrams as SCD
+include "primitives.alh"
+
+SCD PetriNets{
+    Class Natural {
+        $
+            if (bool_not(is_physical_int(self))):
+                return "Natural has no integer value"
+            elif (integer_lt(self, 0)):
+                return "Natural does not have a positive or zero value"
+            else:
+                return "OK"
+         $
+    }
+    Class Place{
+        tokens : Natural
+    }
+    Class Transition{}
+    Association P2T (Place, Transition) {
+        weight : Natural
+    }
+    Association T2P (Transition, Place) {
+        weight : Natural
+    }
+}
+
+PetriNets my_petrinet {
+    Place p1 {
+        tokens = 1
+    }
+    Place p2 {
+        tokens = 3
+    }
+    Transition t1 {}
+    P2T (p1, t1) {
+        weight = 1
+    }
+    T2P (t1, p2) {
+        weight = 2
+    }
+}
+
+export my_petrinet to models/my_petrinet

+ 17 - 0
integration/code/petrinets.mvc

@@ -0,0 +1,17 @@
+import models/SimpleClassDiagrams as SCD
+
+SCD PetriNets{
+    Class Natural {}
+    Class Place{
+        tokens : Natural
+    }
+    Class Transition{}
+    Association P2T (Place, Transition) {
+        weight : Natural
+    }
+    Association T2P (Transition, Place) {
+        weight : Natural
+    }
+}
+
+export PetriNets to models/PetriNets

+ 27 - 0
integration/code/petrinets_constraints.mvc

@@ -0,0 +1,27 @@
+import models/SimpleClassDiagrams as SCD
+include "primitives.alh"
+
+SCD PetriNets{
+    Class Natural {
+        $
+            if (bool_not(is_physical_int(self))):
+                return "Natural has no integer value"
+            elif (integer_lt(self, 0)):
+                return "Natural does not have a positive or zero value"
+            else:
+                return "OK"
+         $
+    }
+    Class Place{
+        tokens : Natural
+    }
+    Class Transition{}
+    Association P2T (Place, Transition) {
+        weight : Natural
+    }
+    Association T2P (Transition, Place) {
+        weight : Natural
+    }
+}
+
+export PetriNets to models/PetriNets

+ 1 - 106
integration/code/pn_interface.alc

@@ -8,95 +8,6 @@ include "metamodels.alh"
 include "modelling.alh"
 include "compilation_manager.alh"
 
-Element function pn_operations():
-	Element ops
-	ops = create_node()
-	dict_add(ops, "fire", petrinet_fire)
-	dict_add(ops, "enabled", petrinet_enabled)
-	return ops
-
-Element function petrinet_enabled(model : Element):
-	Element set_enabled
-	set_enabled = petrinet_enabled_set(model)
-	output("Enabled transitions:")
-	while (0 < read_nr_out(set_enabled)):
-		output(set_pop(set_enabled))
-	return model
-
-Element function petrinet_enabled_set(model : Element):
-	Element all_transitions
-	Element enabled_transitions
-	String under_study
-	Element in_arcs
-	String arc_under_study
-	Boolean enabled
-
-	all_transitions = allInstances(model, "Transition")
-	enabled_transitions = create_node()
-
-	while (0 < read_nr_out(all_transitions)):
-		under_study = set_pop(all_transitions)
-		enabled = True
-
-		// Find all incoming transitions
-		in_arcs = allIncomingAssociationInstances(model, under_study, "P2T")
-
-		while (0 < read_nr_out(in_arcs)):
-			arc_under_study = set_pop(in_arcs)
-
-			Integer present_tokens
-			Integer required_tokens
-			required_tokens = read_attribute(model, arc_under_study, "weight")
-			log("Weight: " + cast_i2s(required_tokens))
-			present_tokens = read_attribute(model, reverseKeyLookup(model["model"], read_edge_src(model["model"][arc_under_study])), "tokens")
-			log("Tokens: " + cast_i2s(present_tokens))
-			if (present_tokens < required_tokens):
-				// Less tokens than required, so disable the transition completely
-				enabled = False
-
-		if (enabled):
-			set_add(enabled_transitions, under_study)
-
-	log("Got all enabled transitions!")
-	return enabled_transitions
-
-Element function petrinet_fire(model : Element):
-	output("Transition to fire?")
-	String transition
-	transition = input()
-	if (dict_in(model["model"], transition)):
-		if (set_in(petrinet_enabled_set(model), transition)):
-			Element workset
-			String working_place
-			String working_arc
-			Integer new_value
-
-			// Consume tokens
-			workset = allIncomingAssociationInstances(model, transition, "P2T")
-			while (0 < read_nr_out(workset)):
-				working_arc = set_pop(workset)
-				working_place = reverseKeyLookup(model["model"], read_edge_src(model["model"][working_arc]))
-				new_value = integer_subtraction(read_attribute(model, working_place, "tokens"), read_attribute(model, working_arc, "weight"))
-				unset_attribute(model, working_place, "tokens")
-				instantiate_attribute(model, working_place, "tokens", new_value)
-				output((("  " + working_place) + ": ") + cast_i2s(read_attribute(model, working_place, "tokens")))
-
-			// Add tokens
-			workset = allOutgoingAssociationInstances(model, transition, "T2P")
-			while (0 < read_nr_out(workset)):
-				working_arc = set_pop(workset)
-				working_place = reverseKeyLookup(model["model"], read_edge_dst(model["model"][working_arc]))
-				new_value = integer_addition(read_attribute(model, working_place, "tokens"), read_attribute(model, working_arc, "weight"))
-				unset_attribute(model, working_place, "tokens")
-				instantiate_attribute(model, working_place, "tokens", new_value)
-				output((("  " + working_place) + ": ") + cast_i2s(read_attribute(model, working_place, "tokens")))
-			output("Transition fired!")
-		else:
-			output("Cannot fire if not enabled; aborting")
-	else:
-		output("Unknown transition; aborting")
-	return model
-	
 Element function model_loaded(model : Element):
 	String cmd
 
@@ -137,14 +48,6 @@ Element function model_loaded(model : Element):
 			output("  retype      -- Change the type of an element")
 			output("  switch      -- Switch between conformance bottom and the linguistic metamodel")
 			output("  exit        -- Unload the model and go back to the loading prompt")
-			if (bool_not(bottom)):
-				output("Model-specific operations:")
-				Element specific_ops
-				specific_ops = dict_keys(pn_operations())
-				String specific_op
-				while (0 < dict_len(specific_ops)):
-					specific_op = set_pop(specific_ops)
-					output("  " + specific_op)
 		elif (cmd == "exit"):
 			return model
 		elif (cmd == "instantiate"):
@@ -370,16 +273,11 @@ Element function model_loaded(model : Element):
 			else:
 				// We already switched the models and such, so we are already done!
 				output("Switching to linguistic metamodel!")
-		elif (bool_and(dict_in(pn_operations(), cmd), bool_not(bottom))):
-			// A model-specific operation, so execute that one
-			Element specific_op
-			specific_op = dict_read(pn_operations(), cmd)
-			specific_op(model)
 		else:
 			output("Unknown command: " + cast_v2s(cmd))
 			output("Use command 'help' to get a list of available commands")
 
-Element function initial_prompt():
+Element function main():
 	output("Welcome to the Model Management Interface, running live on the Modelverse!")
 	output("Use 'help' command for a list of possible commands")
 	String command
@@ -463,6 +361,3 @@ Element function initial_prompt():
 			output("Back in model manager!")
 		else:
 			output("Command not recognized, use 'help' for a list of possible commands")
-
-Void function main():
-	initial_prompt()

+ 149 - 0
integration/code/pn_semantics.alc

@@ -0,0 +1,149 @@
+include "primitives.alh"
+include "modelling.alh"
+include "object_operations.alh"
+include "library.alh"
+include "conformance_scd.alh"
+
+Void function petrinet_enabled(model : Element):
+	Element set_enabled
+	set_enabled = petrinet_enabled_set(model)
+	output("Enabled transitions:")
+	while (0 < read_nr_out(set_enabled)):
+		output(set_pop(set_enabled))
+	return
+
+Element function petrinet_enabled_set(model : Element):
+	Element all_transitions
+	Element enabled_transitions
+	String under_study
+	Element in_arcs
+	String arc_under_study
+	Boolean enabled
+
+	all_transitions = allInstances(model, "Transition")
+	enabled_transitions = create_node()
+
+	while (0 < read_nr_out(all_transitions)):
+		under_study = set_pop(all_transitions)
+		enabled = True
+
+		// Find all incoming transitions
+		in_arcs = allIncomingAssociationInstances(model, under_study, "P2T")
+
+		while (0 < read_nr_out(in_arcs)):
+			arc_under_study = set_pop(in_arcs)
+
+			Integer present_tokens
+			Integer required_tokens
+			required_tokens = read_attribute(model, arc_under_study, "weight")
+			log("Weight: " + cast_i2s(required_tokens))
+			present_tokens = read_attribute(model, reverseKeyLookup(model["model"], read_edge_src(model["model"][arc_under_study])), "tokens")
+			log("Tokens: " + cast_i2s(present_tokens))
+			if (present_tokens < required_tokens):
+				// Less tokens than required, so disable the transition completely
+				enabled = False
+
+		if (enabled):
+			set_add(enabled_transitions, under_study)
+
+	log("Got all enabled transitions!")
+	return enabled_transitions
+
+Void function petrinet_fire(model : Element):
+	output("Transition to fire?")
+	String transition
+	transition = input()
+	if (dict_in(model["model"], transition)):
+		if (set_in(petrinet_enabled_set(model), transition)):
+			Element workset
+			String working_place
+			String working_arc
+			Integer new_value
+
+			// Consume tokens
+			workset = allIncomingAssociationInstances(model, transition, "P2T")
+			while (0 < read_nr_out(workset)):
+				working_arc = set_pop(workset)
+				working_place = reverseKeyLookup(model["model"], read_edge_src(model["model"][working_arc]))
+				new_value = integer_subtraction(read_attribute(model, working_place, "tokens"), read_attribute(model, working_arc, "weight"))
+				unset_attribute(model, working_place, "tokens")
+				instantiate_attribute(model, working_place, "tokens", new_value)
+				output((("  " + working_place) + ": ") + cast_i2s(read_attribute(model, working_place, "tokens")))
+
+			// Add tokens
+			workset = allOutgoingAssociationInstances(model, transition, "T2P")
+			while (0 < read_nr_out(workset)):
+				working_arc = set_pop(workset)
+				working_place = reverseKeyLookup(model["model"], read_edge_dst(model["model"][working_arc]))
+				new_value = integer_addition(read_attribute(model, working_place, "tokens"), read_attribute(model, working_arc, "weight"))
+				unset_attribute(model, working_place, "tokens")
+				instantiate_attribute(model, working_place, "tokens", new_value)
+				output((("  " + working_place) + ": ") + cast_i2s(read_attribute(model, working_place, "tokens")))
+			output("Transition fired!")
+		else:
+			output("Cannot fire if not enabled; aborting")
+	else:
+		output("Unknown transition; aborting")
+	return
+
+Void function petrinet_list(model : Element):
+	Element keys 
+	Element typemap
+	Element place
+	String name
+
+	keys = dict_keys(model["model"])
+	typemap = model["type_mapping"]
+	place = model["metamodel"]["model"]["Place"]
+
+	while (list_len(keys) > 0):
+		name = set_pop(keys)
+		if (element_eq(dict_read_node(typemap, model["model"][name]), place)):
+			// Found a place
+			output((name + ": ") + cast_i2s(read_attribute(model, name, "tokens")))
+	return
+
+Void function main():
+	Element model
+	String verify_result
+
+	while (True):
+		output("Which model do you want to execute with petri net semantics?")
+		model = import_node(input())
+
+		if (element_eq(model, read_root())):
+			output("Could not find model; aborting")
+		elif (element_neq(model["metamodel"], import_node("models/PetriNets"))):
+			output("Not a PetriNets model; aborting")
+		else:
+			verify_result = conformance_scd(model)
+			if (verify_result == "OK"):
+				output("Model OK!")
+				execute_petrinet(model)
+			else:
+				output("Non-conforming model: " + verify_result)
+
+Void function execute_petrinet(model : Element):
+	String cmd
+	while (True):
+		output("Which operation do you want to execute?")
+		cmd = input()
+
+		if (cmd == "help"):
+			output("Supported operations:")
+			output("  help    -- this information")
+			output("  enabled -- list the enabled transitions")
+			output("  fire    -- fire a transition")
+			output("  list    -- list the state of the petrinet")
+			output("  exit    -- select another model")
+		elif (cmd == "enabled"):
+			petrinet_enabled(model)
+		elif (cmd == "fire"):
+			petrinet_fire(model)
+		elif (cmd == "list"):
+			petrinet_list(model)
+		elif (cmd == "exit"):
+			return
+		else:
+			output("Did not understand command!")
+			output("Use 'help' for a list of available options")

+ 127 - 0
integration/code/rpgame.mvc

@@ -0,0 +1,127 @@
+import models/SimpleClassDiagrams as SCD
+include "primitives.alh"
+include "object_operations.alh"
+
+SCD RPGame{
+    Class Tile {
+        $
+        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"
+        $
+    }
+    Association tile_left (Tile, Tile){
+        source_upper_cardinality = 1
+        target_upper_cardinality = 1
+    }
+    Association tile_right (Tile, Tile){
+        source_upper_cardinality = 1
+        target_upper_cardinality = 1
+    }
+    Association tile_top (Tile, Tile){
+        source_upper_cardinality = 1
+        target_upper_cardinality = 1
+    }
+    Association tile_bottom (Tile, Tile){
+        source_upper_cardinality = 1
+        target_upper_cardinality = 1
+    }
+    Class Scene {}
+    Association Scene_has_tiles (Scene, Tile){
+        source_lower_cardinality = 1
+        source_upper_cardinality = 1
+        target_lower_cardinality = 1
+    }
+    Class Item {}
+    Association Item_on_tile (Item, Tile){
+        source_upper_cardinality = 1
+        target_lower_cardinality = 1
+        target_upper_cardinality = 1
+    }
+    Class Goal : Item {}
+    Class Character {}
+    Association Character_on_tile (Character, Tile){
+        source_upper_cardinality = 1
+        target_lower_cardinality = 1
+        target_upper_cardinality = 1
+    }
+    Class Hero : Character {}
+}
+
+export RPGame to models/RPGame
+
+RPGame my_game {
+    Scene scene {}
+    Hero link {}
+    Goal goal {}
+    Tile tile_00 {}
+    Tile tile_01 {}
+    Tile tile_10 {}
+    Tile tile_11 {}
+    Scene_has_tiles (scene, tile_00) {}
+    Scene_has_tiles (scene, tile_01) {}
+    Scene_has_tiles (scene, tile_10) {}
+    Scene_has_tiles (scene, tile_11) {}
+    Character_on_tile (link, tile_00) {}
+    Item_on_tile (goal, tile_11) {}
+    tile_left (tile_01, tile_00) {}
+    tile_right (tile_00, tile_01) {}
+    tile_left (tile_11, tile_10) {}
+    tile_right (tile_10, tile_11) {}
+    tile_top (tile_10, tile_00) {}
+    tile_bottom (tile_00, tile_10) {}
+    tile_top (tile_11, tile_01) {}
+    tile_bottom (tile_01, tile_11) {}
+}
+
+export my_game to models/my_game

+ 95 - 0
integration/code/rpgame_semantics.alc

@@ -0,0 +1,95 @@
+include "primitives.alh"
+include "modelling.alh"
+include "object_operations.alh"
+include "library.alh"
+include "conformance_scd.alh"
+include "random.alh"
+
+Void function main():
+	Element model
+	String verify_result
+
+	while (True):
+		output("Which model do you want to execute with RPGame semantics?")
+		model = import_node(input())
+
+		if (element_eq(model, read_root())):
+			output("Could not find model; aborting")
+		elif (element_neq(model["metamodel"], import_node("models/RPGame"))):
+			log("Got metamodel: " + cast_e2s(model["metamodel"]))
+			log("Expected metamodel: " + cast_e2s(import_node("models/RPGame")))
+			output("Not a RPGame model; aborting")
+		else:
+			verify_result = conformance_scd(model)
+			if (verify_result == "OK"):
+				output("Model OK!")
+				execute_rpgame(model)
+			else:
+				output("Non-conforming model: " + verify_result)
+
+String function getHeroTile(model : Element, hero : String):
+	return set_pop(followAssociation(model, hero, "Character_on_tile"))
+
+String function getGoalTile(model : Element, goal : String):
+	return set_pop(followAssociation(model, goal, "Item_on_tile"))
+
+Void function setHeroTile(model : Element, hero : String, tile : String):
+	Element assocs
+
+	assocs = allOutgoingAssociationInstances(model, hero, "Character_on_tile")
+	while (0 < list_len(assocs)):
+		model_delete_element(model, set_pop(assocs))
+
+	instantiate_link(model, "Character_on_tile", "", hero, tile)
+
+	return
+
+Element function getConnectedTiles(model : Element, tile : String):
+	Element left
+	Element right
+	Element top
+	Element bottom
+	Element result
+
+	result = create_node()
+	left = followAssociation(model, tile, "tile_left")
+	right = followAssociation(model, tile, "tile_right")
+	top = followAssociation(model, tile, "tile_top")
+	bottom = followAssociation(model, tile, "tile_bottom")
+
+	while (dict_len(left) > 0):
+		set_add(result, set_pop(left))
+	while (dict_len(right) > 0):
+		set_add(result, set_pop(right))
+	while (dict_len(top) > 0):
+		set_add(result, set_pop(top))
+	while (dict_len(bottom) > 0):
+		set_add(result, set_pop(bottom))
+
+	return result
+
+Void function execute_rpgame(model : Element):
+	String hero
+	String goal
+	String hero_tile
+	String goal_tile
+
+	log("Executing model!")
+
+	// Make the assumption that only a single hero and goal exist
+	hero = set_pop(allInstances(model, "Hero"))
+	goal = set_pop(allInstances(model, "Goal"))
+
+	log("Got all tiles")
+	goal_tile = getGoalTile(model, goal)
+	log("Got goal tile: " + goal_tile)
+	hero_tile = getHeroTile(model, hero)
+	log("Got hero tile: " + hero_tile)
+
+	log("Keep executing")
+	while (hero_tile != goal_tile):
+		output((("Hero: " + hero_tile) + " -- Goal: ") + goal_tile)
+		hero_tile = random_choice(getConnectedTiles(model, hero_tile))
+		setHeroTile(model, hero, hero_tile)
+	output("Hero reached goal!")
+	return

+ 166 - 0
integration/code/several_petrinets.mvc

@@ -0,0 +1,166 @@
+import models/SimpleClassDiagrams as SCD
+include "primitives.alh"
+
+SCD PetriNets{
+    Class Natural {
+        $
+            if (bool_not(is_physical_int(self))):
+                return "Natural has no integer value at " + name
+            elif (integer_lt(self, 0)):
+                return "Natural does not have a positive or zero value at " + name
+            else:
+                return "OK"
+         $
+    }
+    Class Place{
+        tokens : Natural {
+            target_lower_cardinality = 1
+            target_upper_cardinality = 1
+            }
+    }
+    Class Transition{}
+    Association P2T (Place, Transition) {
+        weight : Natural {
+            target_lower_cardinality = 1
+            target_upper_cardinality = 1
+            }
+    }
+    Association T2P (Transition, Place) {
+        weight : Natural {
+            target_lower_cardinality = 1
+            target_upper_cardinality = 1
+            }
+    }
+}
+
+PetriNets valid_petrinet {
+    Place p1 {
+        tokens = 1
+    }
+    Place p2 {
+        tokens = 3
+    }
+    Transition t1 {}
+    P2T (p1, t1) {
+        weight = 1
+    }
+    T2P (t1, p2) {
+        weight = 2
+    }
+}
+
+PetriNets invalid_petrinet_1 {
+    Place p1 {
+        tokens = -1
+    }
+    Place p2 {
+        tokens = 3
+    }
+    Transition t1 {}
+    P2T (p1, t1) {
+        weight = 1
+    }
+    T2P (t1, p2) {
+        weight = 2
+    }
+}
+
+PetriNets invalid_petrinet_2 {
+    Place p1 {
+        tokens = 1
+    }
+    Place p2 {
+        tokens = 3
+    }
+    Transition t1 {}
+    P2T p2t(p1, t1) {
+        weight = -1
+    }
+    T2P (t1, p2) {
+        weight = 2
+    }
+}
+
+PetriNets invalid_petrinet_3 {
+    Place p1 {
+        tokens = 1
+    }
+    Place p2 {
+        tokens = 3
+    }
+    Transition t1 {}
+    P2T wrong_p2t (p1, p2) {
+        weight = 1
+    }
+    T2P (t1, p2) {
+        weight = 2
+    }
+}
+
+PetriNets invalid_petrinet_4 {
+    Place p1 {
+        tokens = 1
+    }
+    Place p2 {
+        tokens = 3
+    }
+    Transition t1 {}
+    P2T (p1, t1) {
+        weight = 1
+    }
+    T2P wrong_t2p(p1, p2) {
+        weight = 2
+    }
+}
+
+PetriNets invalid_petrinet_5 {
+    Place p1 {}
+    Place p2 {
+        tokens = 3
+    }
+    Transition t1 {}
+    P2T (p1, t1) {
+        weight = 1
+    }
+    T2P (t1, p2) {
+        weight = 2
+    }
+}
+
+PetriNets invalid_petrinet_6 {
+    Place p1 {
+        tokens = 1
+    }
+    Place p2 {
+        tokens = 3
+    }
+    Transition t1 {}
+    P2T p2t (p1, t1) {}
+    T2P (t1, p2) {
+        weight = 2
+    }
+}
+
+PetriNets invalid_petrinet_7 {
+    Place p1 {
+        tokens = "abc"
+    }
+    Place p2 {
+        tokens = 3
+    }
+    Transition t1 {}
+    P2T (p1, t1) {}
+    T2P (t1, p2) {
+        weight = 2
+    }
+}
+
+export PetriNets to models/PetriNets
+export valid_petrinet to models/valid_petrinet
+export invalid_petrinet_1 to models/invalid_petrinet_1
+export invalid_petrinet_2 to models/invalid_petrinet_2
+export invalid_petrinet_3 to models/invalid_petrinet_3
+export invalid_petrinet_4 to models/invalid_petrinet_4
+export invalid_petrinet_5 to models/invalid_petrinet_5
+export invalid_petrinet_6 to models/invalid_petrinet_6
+export invalid_petrinet_7 to models/invalid_petrinet_7

+ 21 - 0
integration/code/simpleclassdiagrams.mvc

@@ -0,0 +1,21 @@
+import /formalisms/SimpleClassDiagrams as SCD
+
+SCD SimpleClassDiagrams{
+    Class Any {}
+    Class Natural {}
+    Class String {}
+    Class Class{
+        lower_cardinality : Natural
+        upper_cardinality : Natural
+    }
+    Association Association (Class, Class){
+        name : String
+        source_lower_cardinality : Natural
+        source_upper_cardinality : Natural
+        target_lower_cardinality : Natural
+        target_upper_cardinality : Natural
+    }
+    Association Inheritance (Class, Class){}
+    Inheritance assoc_inh_class (Association, Class) {}
+    Inheritance class_inh_any (Class, Any) {}
+}

+ 33 - 0
integration/my_petrinet_with_MM_and_constraints.mvc

@@ -0,0 +1,33 @@
+import models/SimpleClassDiagrams as SCD
+
+SCD PetriNets{
+    Class Natural {}
+    Class Place{
+        tokens : Natural
+    }
+    Class Transition{}
+    Association P2T (Place, Transition) {
+        weight : Natural
+    }
+    Association T2P (Transition, Place) {
+        weight : Natural
+    }
+}
+
+PetriNets my_petrinet {
+    Place p1 {
+        tokens = 1
+    }
+    Place p2 {
+        tokens = 3
+    }
+    Transition t1 {}
+    P2T (p1, t1) {
+        weight = 1
+    }
+    T2P (t1, p2) {
+        weight = 2
+    }
+}
+
+export my_petrinet to models/my_petrinet

+ 210 - 214
integration/test_constructors_models.py

@@ -4,187 +4,179 @@ import os
 
 from utils import execute, kill, run_file, run_barebone
 
-def flatten(lst):
-    new_lst = []
-    for f in lst:
-        if isinstance(f, (list, tuple)):
-            new_lst.extend(flatten(f))
-        else:
-            new_lst.append(f)
-    return new_lst
-
 bottom = [
         '"model"',
-        '"instantiate_bottom"', 1,
-        '"add_node"', 1, '"Class"',
-        '"add_node"', 1, '"Any"',
-        '"add_node"', 1, '"String"',
-        '"add_value"', 1, '"name"', '"name"',
-        '"add_edge"', 1, '"Association"', '"Class"', '"Any"',
-        '"add_edge"', 1, '"Inheritance"', '"Class"', '"Class"',
-        '"add_edge"', 1, '"Association_attribute"', '"Association"', '"String"',
-        '"add_edge"', 1, '"Association_name"', '"Association_attribute"', '"name"',
-        '"add_edge"', 1, '"assoc_inh_class"', '"Association"', '"Class"',
-        '"add_edge"', 1, '"class_inh_any"', '"Class"', '"Any"',
-        '"add_edge"', 1, '"string_inh_any"', '"String"', '"Any"',
-        '"retype_model"', 1, 1,
-        '"define_inheritance"', 1, '"Inheritance"',
-        '"retype"', 1, '"Class"', '"Class"',
-        '"retype"', 1, '"Any"', '"Class"',
-        '"retype"', 1, '"String"', '"Class"',
-        '"retype"', 1, '"name"', '"String"',
-        '"retype"', 1, '"Association"', '"Association"',
-        '"retype"', 1, '"Inheritance"', '"Association"',
-        '"retype"', 1, '"Association_attribute"', '"Association"',
-        '"retype"', 1, '"Association_name"', '"Association_attribute"',
-        '"retype"', 1, '"assoc_inh_class"', '"Inheritance"',
-        '"retype"', 1, '"class_inh_any"', '"Inheritance"',
-        '"retype"', 1, '"string_inh_any"', '"Inheritance"',
+        '"instantiate_bottom"', '"1"',
+        '"add_node"', '"1"', '"Class"',
+        '"add_node"', '"1"', '"Any"',
+        '"add_node"', '"1"', '"String"',
+        '"add_value"', '"1"', '"name"', '"name"',
+        '"add_edge"', '"1"', '"Association"', '"Class"', '"Any"',
+        '"add_edge"', '"1"', '"Inheritance"', '"Class"', '"Class"',
+        '"add_edge"', '"1"', '"Association_attribute"', '"Association"', '"String"',
+        '"add_edge"', '"1"', '"Association_name"', '"Association_attribute"', '"name"',
+        '"add_edge"', '"1"', '"assoc_inh_class"', '"Association"', '"Class"',
+        '"add_edge"', '"1"', '"class_inh_any"', '"Class"', '"Any"',
+        '"add_edge"', '"1"', '"string_inh_any"', '"String"', '"Any"',
+        '"retype_model"', '"1"', '"1"',
+        '"define_inheritance"', '"1"', '"Inheritance"',
+        '"retype"', '"1"', '"Class"', '"Class"',
+        '"retype"', '"1"', '"Any"', '"Class"',
+        '"retype"', '"1"', '"String"', '"Class"',
+        '"retype"', '"1"', '"name"', '"String"',
+        '"retype"', '"1"', '"Association"', '"Association"',
+        '"retype"', '"1"', '"Inheritance"', '"Association"',
+        '"retype"', '"1"', '"Association_attribute"', '"Association"',
+        '"retype"', '"1"', '"Association_name"', '"Association_attribute"',
+        '"retype"', '"1"', '"assoc_inh_class"', '"Inheritance"',
+        '"retype"', '"1"', '"class_inh_any"', '"Inheritance"',
+        '"retype"', '"1"', '"string_inh_any"', '"Inheritance"',
+        '"export_node"', '"1"', '"models/SimpleClassDiagrams"',
         '"exit"',
     ]
 
 action_language = [
         '"model"',
-        '"instantiate_node"', 1, '"Class"', '"Action"',
-        '"instantiate_node"', 1, '"Class"', '"Statement"',
-        '"instantiate_node"', 1, '"Class"', '"Expression"',
-        '"instantiate_node"', 1, '"Class"', '"funcdef"',
-        '"instantiate_node"', 1, '"Class"', '"param"',
-        '"instantiate_node"', 1, '"Class"', '"if"',
-        '"instantiate_node"', 1, '"Class"', '"break"',
-        '"instantiate_node"', 1, '"Class"', '"while"',
-        '"instantiate_node"', 1, '"Class"', '"continue"',
-        '"instantiate_node"', 1, '"Class"', '"assign"',
-        '"instantiate_node"', 1, '"Class"', '"return"',
-        '"instantiate_node"', 1, '"Class"', '"output"',
-        '"instantiate_node"', 1, '"Class"', '"declare"',
-        '"instantiate_node"', 1, '"Class"', '"global"',
-        '"instantiate_node"', 1, '"Class"', '"access"',
-        '"instantiate_node"', 1, '"Class"', '"constant"',
-        '"instantiate_node"', 1, '"Class"', '"input"',
-        '"instantiate_node"', 1, '"Class"', '"resolve"',
-        '"instantiate_node"', 1, '"Class"', '"call"',
-        '"instantiate_link"', 1, '"Association"', '"dict_link"', '"Action"', '"Any"',
-        '"instantiate_link"', 1, '"Association"', '"to_str"', '"dict_link"', '"String"',
-        '"instantiate_attribute"', 1, '"to_str"', '"name"', '"name"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"Action"', '"Any"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"funcdef"', '"Action"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"param"', '"Action"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"Statement"', '"Action"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"Expression"', '"Action"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"resolve"', '"Statement"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"if"', '"Statement"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"break"', '"Statement"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"continue"', '"Statement"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"global"', '"Statement"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"while"', '"Statement"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"assign"', '"Statement"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"return"', '"Statement"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"call"', '"Statement"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"declare"', '"Statement"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"call"', '"Expression"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"access"', '"Expression"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"constant"', '"Expression"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"input"', '"Expression"',
-        '"instantiate_link"', 1, '"Association"', '"statement_next"', '"Statement"', '"Statement"',
-        '"instantiate_attribute"', 1, '"statement_next"', '"name"', '"next"',
-        '"instantiate_link"', 1, '"Association"', '"if_cond"', '"if"', '"Expression"',
-        '"instantiate_attribute"', 1, '"if_cond"', '"name"', '"cond"',
-        '"instantiate_link"', 1, '"Association"', '"if_then"', '"if"', '"Statement"',
-        '"instantiate_attribute"', 1, '"if_then"', '"name"', '"true"',
-        '"instantiate_link"', 1, '"Association"', '"if_else"', '"if"', '"Statement"',
-        '"instantiate_attribute"', 1, '"if_else"', '"name"', '"false"',
-        '"instantiate_link"', 1, '"Association"', '"while_cond"', '"while"', '"Expression"',
-        '"instantiate_attribute"', 1, '"while_cond"', '"name"', '"cond"',
-        '"instantiate_link"', 1, '"Association"', '"while_body"', '"while"', '"Statement"',
-        '"instantiate_attribute"', 1, '"while_body"', '"name"', '"body"',
-        '"instantiate_link"', 1, '"Association"', '"assign_var"', '"assign"', '"Any"',
-        '"instantiate_attribute"', 1, '"assign_var"', '"name"', '"var"',
-        '"instantiate_link"', 1, '"Association"', '"assign_value"', '"assign"', '"Expression"',
-        '"instantiate_attribute"', 1, '"assign_value"', '"name"', '"value"',
-        '"instantiate_link"', 1, '"Association"', '"break_while"', '"break"', '"while"',
-        '"instantiate_attribute"', 1, '"break_while"', '"name"', '"while"',
-        '"instantiate_link"', 1, '"Association"', '"continue_while"', '"continue"', '"while"',
-        '"instantiate_attribute"', 1, '"continue_while"', '"name"', '"while"',
-        '"instantiate_link"', 1, '"Association"', '"return_value"', '"return"', '"Expression"',
-        '"instantiate_attribute"', 1, '"return_value"', '"name"', '"value"',
-        '"instantiate_link"', 1, '"Association"', '"resolve_var"', '"resolve"', '"Any"',
-        '"instantiate_attribute"', 1, '"resolve_var"', '"name"', '"var"',
-        '"instantiate_link"', 1, '"Association"', '"access_var"', '"access"', '"Any"',
-        '"instantiate_attribute"', 1, '"access_var"', '"name"', '"var"',
-        '"instantiate_link"', 1, '"Association"', '"constant_node"', '"constant"', '"Any"',
-        '"instantiate_attribute"', 1, '"constant_node"', '"name"', '"node"',
-        '"instantiate_link"', 1, '"Association"', '"output_node"', '"output"', '"Expression"',
-        '"instantiate_attribute"', 1, '"output_node"', '"name"', '"node"',
-        '"instantiate_link"', 1, '"Association"', '"global_var"', '"global"', '"String"',
-        '"instantiate_attribute"', 1, '"global_var"', '"name"', '"var"',
-        '"instantiate_link"', 1, '"Association"', '"param_name"', '"param"', '"String"',
-        '"instantiate_attribute"', 1, '"param_name"', '"name"', '"name"',
-        '"instantiate_link"', 1, '"Association"', '"param_value"', '"param"', '"Expression"',
-        '"instantiate_attribute"', 1, '"param_value"', '"name"', '"value"',
-        '"instantiate_link"', 1, '"Association"', '"param_next_param"', '"param"', '"param"',
-        '"instantiate_attribute"', 1, '"param_next_param"', '"name"', '"next_param"',
-        '"instantiate_link"', 1, '"Association"', '"funcdef_body"', '"funcdef"', '"Statement"',
-        '"instantiate_attribute"', 1, '"funcdef_body"', '"name"', '"body"',
-        '"instantiate_link"', 1, '"Association"', '"call_func"', '"call"', '"Expression"',
-        '"instantiate_attribute"', 1, '"call_func"', '"name"', '"func"',
-        '"instantiate_link"', 1, '"Association"', '"call_params"', '"call"', '"param"',
-        '"instantiate_attribute"', 1, '"call_params"', '"name"', '"params"',
-        '"instantiate_link"', 1, '"Association"', '"call_last_param"', '"call"', '"param"',
-        '"instantiate_attribute"', 1, '"call_last_param"', '"name"', '"last_param"',
+        '"instantiate_node"', '"1"', '"Class"', '"Action"',
+        '"instantiate_node"', '"1"', '"Class"', '"Statement"',
+        '"instantiate_node"', '"1"', '"Class"', '"Expression"',
+        '"instantiate_node"', '"1"', '"Class"', '"funcdef"',
+        '"instantiate_node"', '"1"', '"Class"', '"param"',
+        '"instantiate_node"', '"1"', '"Class"', '"if"',
+        '"instantiate_node"', '"1"', '"Class"', '"break"',
+        '"instantiate_node"', '"1"', '"Class"', '"while"',
+        '"instantiate_node"', '"1"', '"Class"', '"continue"',
+        '"instantiate_node"', '"1"', '"Class"', '"assign"',
+        '"instantiate_node"', '"1"', '"Class"', '"return"',
+        '"instantiate_node"', '"1"', '"Class"', '"output"',
+        '"instantiate_node"', '"1"', '"Class"', '"declare"',
+        '"instantiate_node"', '"1"', '"Class"', '"global"',
+        '"instantiate_node"', '"1"', '"Class"', '"access"',
+        '"instantiate_node"', '"1"', '"Class"', '"constant"',
+        '"instantiate_node"', '"1"', '"Class"', '"input"',
+        '"instantiate_node"', '"1"', '"Class"', '"resolve"',
+        '"instantiate_node"', '"1"', '"Class"', '"call"',
+        '"instantiate_link"', '"1"', '"Association"', '"dict_link"', '"Action"', '"Any"',
+        '"instantiate_link"', '"1"', '"Association"', '"to_str"', '"dict_link"', '"String"',
+        '"instantiate_attribute"', '"1"', '"to_str"', '"name"', '"name"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"Action"', '"Any"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"funcdef"', '"Action"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"param"', '"Action"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"Statement"', '"Action"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"Expression"', '"Action"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"resolve"', '"Statement"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"if"', '"Statement"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"break"', '"Statement"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"continue"', '"Statement"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"global"', '"Statement"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"while"', '"Statement"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"assign"', '"Statement"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"return"', '"Statement"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"call"', '"Statement"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"declare"', '"Statement"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"call"', '"Expression"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"access"', '"Expression"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"constant"', '"Expression"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"input"', '"Expression"',
+        '"instantiate_link"', '"1"', '"Association"', '"statement_next"', '"Statement"', '"Statement"',
+        '"instantiate_attribute"', '"1"', '"statement_next"', '"name"', '"next"',
+        '"instantiate_link"', '"1"', '"Association"', '"if_cond"', '"if"', '"Expression"',
+        '"instantiate_attribute"', '"1"', '"if_cond"', '"name"', '"cond"',
+        '"instantiate_link"', '"1"', '"Association"', '"if_then"', '"if"', '"Statement"',
+        '"instantiate_attribute"', '"1"', '"if_then"', '"name"', '"true"',
+        '"instantiate_link"', '"1"', '"Association"', '"if_else"', '"if"', '"Statement"',
+        '"instantiate_attribute"', '"1"', '"if_else"', '"name"', '"false"',
+        '"instantiate_link"', '"1"', '"Association"', '"while_cond"', '"while"', '"Expression"',
+        '"instantiate_attribute"', '"1"', '"while_cond"', '"name"', '"cond"',
+        '"instantiate_link"', '"1"', '"Association"', '"while_body"', '"while"', '"Statement"',
+        '"instantiate_attribute"', '"1"', '"while_body"', '"name"', '"body"',
+        '"instantiate_link"', '"1"', '"Association"', '"assign_var"', '"assign"', '"Any"',
+        '"instantiate_attribute"', '"1"', '"assign_var"', '"name"', '"var"',
+        '"instantiate_link"', '"1"', '"Association"', '"assign_value"', '"assign"', '"Expression"',
+        '"instantiate_attribute"', '"1"', '"assign_value"', '"name"', '"value"',
+        '"instantiate_link"', '"1"', '"Association"', '"break_while"', '"break"', '"while"',
+        '"instantiate_attribute"', '"1"', '"break_while"', '"name"', '"while"',
+        '"instantiate_link"', '"1"', '"Association"', '"continue_while"', '"continue"', '"while"',
+        '"instantiate_attribute"', '"1"', '"continue_while"', '"name"', '"while"',
+        '"instantiate_link"', '"1"', '"Association"', '"return_value"', '"return"', '"Expression"',
+        '"instantiate_attribute"', '"1"', '"return_value"', '"name"', '"value"',
+        '"instantiate_link"', '"1"', '"Association"', '"resolve_var"', '"resolve"', '"Any"',
+        '"instantiate_attribute"', '"1"', '"resolve_var"', '"name"', '"var"',
+        '"instantiate_link"', '"1"', '"Association"', '"access_var"', '"access"', '"Any"',
+        '"instantiate_attribute"', '"1"', '"access_var"', '"name"', '"var"',
+        '"instantiate_link"', '"1"', '"Association"', '"constant_node"', '"constant"', '"Any"',
+        '"instantiate_attribute"', '"1"', '"constant_node"', '"name"', '"node"',
+        '"instantiate_link"', '"1"', '"Association"', '"output_node"', '"output"', '"Expression"',
+        '"instantiate_attribute"', '"1"', '"output_node"', '"name"', '"node"',
+        '"instantiate_link"', '"1"', '"Association"', '"global_var"', '"global"', '"String"',
+        '"instantiate_attribute"', '"1"', '"global_var"', '"name"', '"var"',
+        '"instantiate_link"', '"1"', '"Association"', '"param_name"', '"param"', '"String"',
+        '"instantiate_attribute"', '"1"', '"param_name"', '"name"', '"name"',
+        '"instantiate_link"', '"1"', '"Association"', '"param_value"', '"param"', '"Expression"',
+        '"instantiate_attribute"', '"1"', '"param_value"', '"name"', '"value"',
+        '"instantiate_link"', '"1"', '"Association"', '"param_next_param"', '"param"', '"param"',
+        '"instantiate_attribute"', '"1"', '"param_next_param"', '"name"', '"next_param"',
+        '"instantiate_link"', '"1"', '"Association"', '"funcdef_body"', '"funcdef"', '"Statement"',
+        '"instantiate_attribute"', '"1"', '"funcdef_body"', '"name"', '"body"',
+        '"instantiate_link"', '"1"', '"Association"', '"call_func"', '"call"', '"Expression"',
+        '"instantiate_attribute"', '"1"', '"call_func"', '"name"', '"func"',
+        '"instantiate_link"', '"1"', '"Association"', '"call_params"', '"call"', '"param"',
+        '"instantiate_attribute"', '"1"', '"call_params"', '"name"', '"params"',
+        '"instantiate_link"', '"1"', '"Association"', '"call_last_param"', '"call"', '"param"',
+        '"instantiate_attribute"', '"1"', '"call_last_param"', '"name"', '"last_param"',
 
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"statement_next"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"if_cond"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"if_then"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"if_else"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"while_cond"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"while_body"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"assign_var"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"assign_value"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"break_while"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"continue_while"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"return_value"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"resolve_var"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"access_var"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"constant_node"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"output_node"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"global_var"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"param_name"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"param_value"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"param_next_param"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"funcdef_body"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"call_func"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"call_params"', '"dict_link"',
-        '"instantiate_link"', 1, '"Inheritance"', '""', '"call_last_param"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"statement_next"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"if_cond"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"if_then"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"if_else"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"while_cond"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"while_body"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"assign_var"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"assign_value"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"break_while"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"continue_while"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"return_value"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"resolve_var"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"access_var"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"constant_node"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"output_node"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"global_var"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"param_name"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"param_value"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"param_next_param"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"funcdef_body"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"call_func"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"call_params"', '"dict_link"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '""', '"call_last_param"', '"dict_link"',
 
-        '"instantiate_link"', 1, '"Association"', '"constraint"', '"Class"', '"funcdef"',
-        '"instantiate_attribute"', 1, '"constraint"', '"name"', '"constraint"',
+        '"instantiate_link"', '"1"', '"Association"', '"constraint"', '"Class"', '"funcdef"',
+        '"instantiate_attribute"', '"1"', '"constraint"', '"name"', '"constraint"',
         '"exit"',
     ]
 
 bottom_attributes = [
         '"model"',
-        '"instantiate_node"', 1, '"Class"', '"Integer"',
-        '"instantiate_link"', 1, '"Inheritance"', '"integer_inh_any"', '"Integer"', '"Any"',
-        '"instantiate_link"', 1, '"Association"', '"lc"', '"Class"', '"Integer"',
-        '"instantiate_attribute"', 1, '"lc"', '"name"', '"lower_cardinality"',
-        '"instantiate_link"', 1, '"Association"', '"uc"', '"Class"', '"Integer"',
-        '"instantiate_attribute"', 1, '"uc"', '"name"', '"upper_cardinality"',
-        '"instantiate_link"', 1, '"Association"', '"slc"', '"Association"', '"Integer"',
-        '"instantiate_attribute"', 1, '"slc"', '"name"', '"source_lower_cardinality"',
-        '"instantiate_link"', 1, '"Association"', '"suc"', '"Association"', '"Integer"',
-        '"instantiate_attribute"', 1, '"suc"', '"name"', '"source_upper_cardinality"',
-        '"instantiate_link"', 1, '"Association"', '"tlc"', '"Association"', '"Integer"',
-        '"instantiate_attribute"', 1, '"tlc"', '"name"', '"target_lower_cardinality"',
-        '"instantiate_link"', 1, '"Association"', '"tuc"', '"Association"', '"Integer"',
-        '"instantiate_attribute"', 1, '"tuc"', '"name"', '"target_upper_cardinality"',
+        '"instantiate_node"', '"1"', '"Class"', '"Integer"',
+        '"instantiate_link"', '"1"', '"Inheritance"', '"integer_inh_any"', '"Integer"', '"Any"',
+        '"instantiate_link"', '"1"', '"Association"', '"lc"', '"Class"', '"Integer"',
+        '"instantiate_attribute"', '"1"', '"lc"', '"name"', '"lower_cardinality"',
+        '"instantiate_link"', '"1"', '"Association"', '"uc"', '"Class"', '"Integer"',
+        '"instantiate_attribute"', '"1"', '"uc"', '"name"', '"upper_cardinality"',
+        '"instantiate_link"', '"1"', '"Association"', '"slc"', '"Association"', '"Integer"',
+        '"instantiate_attribute"', '"1"', '"slc"', '"name"', '"source_lower_cardinality"',
+        '"instantiate_link"', '"1"', '"Association"', '"suc"', '"Association"', '"Integer"',
+        '"instantiate_attribute"', '"1"', '"suc"', '"name"', '"source_upper_cardinality"',
+        '"instantiate_link"', '"1"', '"Association"', '"tlc"', '"Association"', '"Integer"',
+        '"instantiate_attribute"', '"1"', '"tlc"', '"name"', '"target_lower_cardinality"',
+        '"instantiate_link"', '"1"', '"Association"', '"tuc"', '"Association"', '"Integer"',
+        '"instantiate_attribute"', '"1"', '"tuc"', '"name"', '"target_upper_cardinality"',
         '"exit"',
     ]
 
 def add_constraints(model):
     return [
             '"model"',
-            '"add_constraint"', model, '"Integer"',
+            '"add_constraint"', '"%s"' % model, '"Integer"',
                 '"funcdef"',
                 '"constraint"',
                 '2', '"%s"' % (model*100), '"%s"' % (model*100+1),
@@ -218,62 +210,66 @@ def add_constraints(model):
 
 instantiate_scd = [
         '"model"',
-        '"instantiate_model"', 1, 2,
-        '"define_inheritance"', 2, '"Inheritance"',
-        '"instantiate_node"', 2, '"Class"', '"Place"',
-        '"instantiate_node"', 2, '"Class"', '"Transition"',
-        '"instantiate_node"', 2, '"Class"', '"Integer"',
-        '"instantiate_link"', 2, '"Association"', '"P2T"', '"Place"', '"Transition"',
-        '"instantiate_link"', 2, '"Association"', '"T2P"', '"Transition"', '"Place"',
-        '"instantiate_link"', 2, '"Association"', '"Place_tokens"', '"Place"', '"Integer"',
-        '"instantiate_attribute"', 2, '"Place_tokens"', '"name"', '"tokens"',
-        '"instantiate_link"', 2, '"Association"', '"P2T_weight"', '"P2T"', '"Integer"',
-        '"instantiate_attribute"', 2, '"P2T_weight"', '"name"', '"weight"',
-        '"instantiate_link"', 2, '"Association"', '"T2P_weight"', '"T2P"', '"Integer"',
-        '"instantiate_attribute"', 2, '"T2P_weight"', '"name"', '"weight"',
+        '"instantiate_model"', '"1"', '"2"',
+        '"define_inheritance"', '"2"', '"Inheritance"',
+        '"instantiate_node"', '"2"', '"Class"', '"Place"',
+        '"instantiate_node"', '"2"', '"Class"', '"Transition"',
+        '"instantiate_node"', '"2"', '"Class"', '"Integer"',
+        '"instantiate_link"', '"2"', '"Association"', '"P2T"', '"Place"', '"Transition"',
+        '"instantiate_link"', '"2"', '"Association"', '"T2P"', '"Transition"', '"Place"',
+        '"instantiate_link"', '"2"', '"Association"', '"Place_tokens"', '"Place"', '"Integer"',
+        '"instantiate_attribute"', '"2"', '"Place_tokens"', '"name"', '"tokens"',
+        '"instantiate_link"', '"2"', '"Association"', '"P2T_weight"', '"P2T"', '"Integer"',
+        '"instantiate_attribute"', '"2"', '"P2T_weight"', '"name"', '"weight"',
+        '"instantiate_link"', '"2"', '"Association"', '"T2P_weight"', '"T2P"', '"Integer"',
+        '"instantiate_attribute"', '"2"', '"T2P_weight"', '"name"', '"weight"',
+        '"export_node"', '"2"', '"models/PetriNets"',
         '"exit"',
     ]
 
 instantiate_pn = [
         '"model"',
-        '"instantiate_model"', 2, 3,
-        '"instantiate_node"', 3, '"Place"', '"p1"',
-        '"instantiate_node"', 3, '"Place"', '"p2"',
-        '"instantiate_node"', 3, '"Transition"', '"t1"',
-        '"instantiate_node"', 3, '"Transition"', '"t2"',
-        '"instantiate_link"', 3, '"P2T"', '"p1_t1"', '"p1"', '"t1"',
-        '"instantiate_link"', 3, '"T2P"', '"t1_p2"', '"t1"', '"p2"',
-        '"instantiate_link"', 3, '"P2T"', '"p2_t2"', '"p2"', '"t2"',
-        '"instantiate_link"', 3, '"T2P"', '"t2_p1"', '"t2"', '"p1"',
-        '"instantiate_attribute"', 3, '"p1_t1"', '"weight"', '1',
-        '"instantiate_attribute"', 3, '"t1_p2"', '"weight"', '2',
-        '"instantiate_attribute"', 3, '"p2_t2"', '"weight"', '3',
-        '"instantiate_attribute"', 3, '"t2_p1"', '"weight"', '4',
-        '"instantiate_attribute"', 3, '"p1"', '"tokens"', '5',
-        '"instantiate_attribute"', 3, '"p2"', '"tokens"', '6',
+        '"instantiate_model"', '"2"', '"3"',
+        '"instantiate_node"', '"3"', '"Place"', '"p1"',
+        '"instantiate_node"', '"3"', '"Place"', '"p2"',
+        '"instantiate_node"', '"3"', '"Transition"', '"t1"',
+        '"instantiate_node"', '"3"', '"Transition"', '"t2"',
+        '"instantiate_link"', '"3"', '"P2T"', '"p1_t1"', '"p1"', '"t1"',
+        '"instantiate_link"', '"3"', '"T2P"', '"t1_p2"', '"t1"', '"p2"',
+        '"instantiate_link"', '"3"', '"P2T"', '"p2_t2"', '"p2"', '"t2"',
+        '"instantiate_link"', '"3"', '"T2P"', '"t2_p1"', '"t2"', '"p1"',
+        '"instantiate_attribute"', '"3"', '"p1_t1"', '"weight"', '1',
+        '"instantiate_attribute"', '"3"', '"t1_p2"', '"weight"', '2',
+        '"instantiate_attribute"', '"3"', '"p2_t2"', '"weight"', '3',
+        '"instantiate_attribute"', '"3"', '"t2_p1"', '"weight"', '4',
+        '"instantiate_attribute"', '"3"', '"p1"', '"tokens"', '5',
+        '"instantiate_attribute"', '"3"', '"p2"', '"tokens"', '6',
+        '"export_node"', '"3"', '"models/PN_instance"',
         '"exit"',
     ]
 
 instantiate_example = [
         '"model"',
-        '"instantiate_model"', 1, 2,
-        '"define_inheritance"', 2, '"Inheritance"',
-        '"instantiate_node"', 2, '"Class"', '"A"',
-        '"instantiate_node"', 2, '"Class"', '"B"',
-        '"instantiate_node"', 2, '"Class"', '"C"',
-        '"instantiate_link"', 2, '"Inheritance"', '"b_inherits_a"', '"B"', '"A"',
-        '"instantiate_link"', 2, '"Association"', '"A_tokens"', '"A"', '"B"',
-        '"instantiate_attribute"', 2, '"A_tokens"', '"name"', '"tokens"',
-        '"instantiate_link"', 2, '"Association"', '"C_tokens"', '"C"', '"B"',
-        '"instantiate_attribute"', 2, '"C_tokens"', '"name"', '"tokens"',
+        '"instantiate_model"', '"1"', '"2"',
+        '"define_inheritance"', '"2"', '"Inheritance"',
+        '"instantiate_node"', '"2"', '"Class"', '"A"',
+        '"instantiate_node"', '"2"', '"Class"', '"B"',
+        '"instantiate_node"', '"2"', '"Class"', '"C"',
+        '"instantiate_link"', '"2"', '"Inheritance"', '"b_inherits_a"', '"B"', '"A"',
+        '"instantiate_link"', '"2"', '"Association"', '"A_tokens"', '"A"', '"B"',
+        '"instantiate_attribute"', '"2"', '"A_tokens"', '"name"', '"tokens"',
+        '"instantiate_link"', '"2"', '"Association"', '"C_tokens"', '"C"', '"B"',
+        '"instantiate_attribute"', '"2"', '"C_tokens"', '"name"', '"tokens"',
+        '"export_node"', '"2"', '"models/example_MM"',
         '"exit"',
         '"model"',
-        '"instantiate_model"', 2, 3,
-        '"instantiate_node"', 3, '"A"', '"a"',
-        '"instantiate_attribute"', 3, '"a"', '"tokens"', '"b"',
-        '"instantiate_node"', 3, '"B"', '"b"',
-        '"instantiate_node"', 3, '"C"', '"c"',
-        '"instantiate_attribute"', 3, '"c"', '"tokens"', '"b"',
+        '"instantiate_model"', '"2"', '"3"',
+        '"instantiate_node"', '"3"', '"A"', '"a"',
+        '"instantiate_attribute"', '"3"', '"a"', '"tokens"', '"b"',
+        '"instantiate_node"', '"3"', '"B"', '"b"',
+        '"instantiate_node"', '"3"', '"C"', '"c"',
+        '"instantiate_attribute"', '"3"', '"c"', '"tokens"', '"b"',
+        '"export_node"', '"3"', '"models/example_M"',
         '"exit"',
     ]
 
@@ -283,7 +279,7 @@ def conformance_call(operation, model, metamodel):
                 '"call"',
                     '"access"', '"resolve"', '"%s"' % operation,
                     '3',
-                    '"const"', 3,
+                    '"call"', '"access"', '"resolve"', '"import_node"', '1', '"const"', '"models/example_M"', 'false',
                     '"const"', '"%s"' % model,
                     '"const"', '"%s"' % metamodel,
                 'false',
@@ -318,38 +314,38 @@ def conformance_check(node):
                 '"call"',
                     '"access"', '"resolve"', '"conformance_scd"',
                     '1',
-                    '"const"', node,
+                    '"call"', '"access"', '"resolve"', '"import_node"', '1', '"const"', '"%s"' % (node), 'false',
                     'false',
                 'true',
             ]
 
 class TestConstructorsModels(unittest.TestCase):
     def test_constructors_instantiate_bottom(self):
-        commands = bottom + bottom_attributes + conformance_check(1) + ['"return"', 'false']
+        commands = bottom + bottom_attributes + conformance_check("models/SimpleClassDiagrams") + ['"return"', 'false']
         self.assertTrue(run_barebone(commands, ["OK"], 1))
 
     def test_constructors_action_language(self):
-        commands = bottom + action_language + bottom_attributes + conformance_check(1) + ['"return"', 'false']
+        commands = bottom + action_language + bottom_attributes + conformance_check("models/SimpleClassDiagrams") + ['"return"', 'false']
         self.assertTrue(run_barebone(commands, ["OK"], 1))
 
     def test_constructors_constraints(self):
-        commands = bottom + action_language + bottom_attributes + add_constraints(1) + conformance_check(1) + ['"return"', 'false']
+        commands = bottom + action_language + bottom_attributes + add_constraints(1) + conformance_check("models/SimpleClassDiagrams") + ['"return"', 'false']
         self.assertTrue(run_barebone(commands, ["OK"], 1))
 
     def test_constructors_constraints_executed(self):
-        commands = bottom + action_language + bottom_attributes + add_constraints(1) + instantiate_scd + add_constraints(2) + instantiate_pn + conformance_check(3) + ['"return"', 'false']
+        commands = bottom + action_language + bottom_attributes + add_constraints(1) + instantiate_scd + add_constraints(2) + instantiate_pn + conformance_check("models/PN_instance") + ['"return"', 'false']
         self.assertTrue(run_barebone(commands, ["OK"], 1))
 
     def test_constructors_instantiate_scd(self):
-        commands = bottom + bottom_attributes + instantiate_scd + conformance_check(2) + ['"return"', 'false']
+        commands = bottom + bottom_attributes + instantiate_scd + conformance_check("models/PetriNets") + ['"return"', 'false']
         self.assertTrue(run_barebone(commands, ["OK"], 1))
 
     def test_constructors_instantiate_pn(self):
-        commands = bottom + bottom_attributes + instantiate_scd + instantiate_pn + conformance_check(3) + ['"return"', 'false']
+        commands = bottom + bottom_attributes + instantiate_scd + instantiate_pn + conformance_check("models/PN_instance") + ['"return"', 'false']
         self.assertTrue(run_barebone(commands, ["OK"], 1))
 
     def test_constructors_instantiate_example(self):
-        commands = bottom + bottom_attributes + instantiate_example + conformance_check(2) + conformance_check(3) + ['"return"', 'false']
+        commands = bottom + bottom_attributes + instantiate_example + conformance_check("models/example_MM") + conformance_check("models/example_M") + ['"return"', 'false']
         self.assertTrue(run_barebone(commands, ["OK", "OK"], 1))
 
     def test_constructors_is_direct_instance(self):

+ 95 - 0
integration/test_constructors_models_compiled.py

@@ -0,0 +1,95 @@
+import unittest
+import sys
+import os
+
+from utils import execute, kill, run_file, run_barebone
+sys.path.append("interface/HUTN")
+from hutn_compiler.compiler import main as do_compile
+
+def model_compile(filename):
+    return do_compile(filename, "interface/HUTN/grammars/modelling.g", "M")
+
+def conformance_call(operation, model, metamodel):
+    return [
+            '"output"',
+                '"call"',
+                    '"access"', '"resolve"', '"%s"' % operation,
+                    '3',
+                    '"call"', '"access"', '"resolve"', '"import_node"', '1', '"const"', '"models/example_M"', 'false',
+                    '"const"', '"%s"' % model,
+                    '"const"', '"%s"' % metamodel,
+                'false',
+            'true',
+            ]
+
+def conformance_check(node):
+    return [
+            '"output"',
+                '"call"',
+                    '"access"', '"resolve"', '"conformance_scd"',
+                    '1',
+                    '"call"', '"access"', '"resolve"', '"import_node"', '1', '"const"', '"%s"' % (node), 'false',
+                    'false',
+                'true',
+            ]
+
+class TestConstructorsModelsCompiled(unittest.TestCase):
+    def test_constructors_petrinets(self):
+        commands = ['"initialize_SCD"', '"models/SimpleClassDiagrams"'] + \
+                   model_compile("integration/code/petrinets.mvc") + \
+                   ['"exit"', '1'] + conformance_check("models/PetriNets") + ['"return"', 'false']
+        self.assertTrue(run_barebone(commands, ["OK"], 4))
+
+    def test_constructors_petrinet_instance(self):
+        commands = ['"initialize_SCD"', '"models/SimpleClassDiagrams"'] + \
+                   model_compile("integration/code/petrinets.mvc") + \
+                   model_compile("integration/code/my_petrinet.mvc") + \
+                   ['"exit"', '1'] + conformance_check("models/my_petrinet") + ['"return"', 'false']
+        self.assertTrue(run_barebone(commands, ["OK"], 4))
+
+    def test_constructors_petrinet_full(self):
+        commands = ['"initialize_SCD"', '"models/SimpleClassDiagrams"'] + \
+                   model_compile("integration/code/my_petrinet_with_MM.mvc") + \
+                   ['"exit"', '1'] + conformance_check("models/my_petrinet") + ['"return"', 'false']
+        self.assertTrue(run_barebone(commands, ["OK"], 4))
+
+    def test_constructors_petrinets_constraints(self):
+        commands = ['"initialize_SCD"', '"models/SimpleClassDiagrams"'] + \
+                   model_compile("integration/code/petrinets_constraints.mvc") + \
+                   ['"exit"', '1'] + conformance_check("models/PetriNets") + ['"return"', 'false']
+        self.assertTrue(run_barebone(commands, ["OK"], 4))
+
+    def test_constructors_petrinet_instance_constraints(self):
+        commands = ['"initialize_SCD"', '"models/SimpleClassDiagrams"'] + \
+                   model_compile("integration/code/petrinets_constraints.mvc") + \
+                   model_compile("integration/code/my_petrinet.mvc") + \
+                   ['"exit"', '1'] + conformance_check("models/my_petrinet") + ['"return"', 'false']
+        self.assertTrue(run_barebone(commands, ["OK"], 4))
+
+    def test_constructors_petrinet_full_constraints(self):
+        commands = ['"initialize_SCD"', '"models/SimpleClassDiagrams"'] + \
+                   model_compile("integration/code/my_petrinet_with_MM_and_constraints.mvc") + \
+                   ['"exit"', '1'] + conformance_check("models/my_petrinet") + ['"return"', 'false']
+        self.assertTrue(run_barebone(commands, ["OK"], 4))
+
+    def test_constructors_petrinet_invalids(self):
+        commands = ['"initialize_SCD"', '"models/SimpleClassDiagrams"'] + \
+                   model_compile("integration/code/several_petrinets.mvc") + \
+                   ['"exit"', '1'] + \
+                   conformance_check("models/valid_petrinet") + \
+                   conformance_check("models/invalid_petrinet_1") + \
+                   conformance_check("models/invalid_petrinet_2") + \
+                   conformance_check("models/invalid_petrinet_3") + \
+                   conformance_check("models/invalid_petrinet_4") + \
+                   conformance_check("models/invalid_petrinet_5") + \
+                   conformance_check("models/invalid_petrinet_6") + \
+                   conformance_check("models/invalid_petrinet_7") + \
+                   ['"return"', 'false']
+        self.assertTrue(run_barebone(commands, ["OK", 
+                    "Natural does not have a positive or zero value at p1.tokens",
+                    "Natural does not have a positive or zero value at p2t.weight",
+                    "Destination of model edge not typed by source of type: wrong_p2t",
+                    "Source of model edge not typed by source of type: wrong_t2p",
+                    "Lower cardinality violation for outgoing edge of type Place_tokens at p1",
+                    "Lower cardinality violation for outgoing edge of type P2T_weight at p2t",
+                    "Natural has no integer value at p1.tokens"], 4))

+ 4 - 37
integration/test_pn_interface.py

@@ -81,15 +81,6 @@ def read_edge(name, t, src, dst, defs, attrs):
             ["Attributes:"] + \
             ([set(['  "%s" : "%s" = %s' % (m, mm, v) for m, mm, v in attrs])] if attrs else [])
 
-def enabled(enableds):
-    return ["Enabled transitions:"] + \
-            [set(enableds)]
-
-def fire(fired):
-    return ["Transition to fire?"] +  \
-            [set(["  %s: %s" % (p, v) for p, v in fired])] + \
-            ["Transition fired!"]
-
 delete =            ["Model to delete?", "Deleted!"]
 rename =            ["Old name?", "New name?", "Rename complete!"]
 attr_add =          ["Which model do you want to assign an attribute to?",
@@ -206,10 +197,10 @@ class TestPetrinetInterface(unittest.TestCase):
             init + new + loaded + \
                 instantiate_node + prompt + \
                 attr_add + prompt + \
-                list_model([("p1", "Place")]) + prompt + \
+                list_model([("p1", "Place"), ("p1.tokens", "Natural")]) + prompt + \
                 read_node("p1", "Place", [], [("tokens", "Natural", 5)]) + prompt + \
                 instantiate_node + prompt + \
-                list_model([("p1", "Place"), ("t1", "Transition")]) + prompt + \
+                list_model([("p1", "Place"), ("t1", "Transition"), ("p1.tokens", "Natural")]) + prompt + \
                 read_node("t1", "Transition", [], []) + prompt,
             mode))
 
@@ -236,30 +227,6 @@ class TestPetrinetInterface(unittest.TestCase):
                 read_edge("t2p", "T2P", "t1", "p2", [], [("weight", "Natural", 1)]) + prompt,
             mode))
 
-    def test_po_pn_interface_enabled(self):
-        self.pn_interface_enabled("PO")
-
-    def test_co_pn_interface_enabled(self):
-        self.pn_interface_enabled("CO")
-
-    def pn_interface_enabled(self, mode):
-        self.assertTrue(run_file(all_files,
-            do_instantiate_simple + ['"enabled"'],
-            did_instantiate_simple + enabled(["t1"]) + prompt,
-            mode))
-
-    def test_po_pn_interface_fire(self):
-        self.pn_interface_fire("PO")
-
-    def test_co_pn_interface_fire(self):
-        self.pn_interface_fire("CO")
-
-    def pn_interface_fire(self, mode):
-        self.assertTrue(run_file(all_files,
-            do_instantiate_simple + ['"fire"', '"t1"'],
-            did_instantiate_simple + fire([("p1", 3), ("p2", 1)]) + prompt,
-            mode))
-
     def test_po_pn_interface_verify_OK(self):
         self.pn_interface_verify_OK("PO")
 
@@ -352,7 +319,7 @@ class TestPetrinetInterface(unittest.TestCase):
     def pn_interface_verify_fail_attr_lower_cardinality(self, mode):
         self.assertTrue(run_file(all_files,
             do_instantiate_simple + ['"instantiate"', '"Place"', '"p999"', '"verify"'],
-            did_instantiate_simple + instantiate_node + prompt + ["Lower cardinality violation for outgoing edge at p999"] + prompt,
+            did_instantiate_simple + instantiate_node + prompt + ["Lower cardinality violation for outgoing edge of type Place_tokens at p999"] + prompt,
             mode))
 
     def test_po_pn_interface_verify_fail_attr_upper_cardinality(self):
@@ -364,7 +331,7 @@ class TestPetrinetInterface(unittest.TestCase):
     def pn_interface_verify_fail_attr_upper_cardinality(self, mode):
         self.assertTrue(run_file(all_files,
             do_instantiate_simple + ['"attr_add"', '"p1"', '"tokens"', '5', '"verify"'],
-            did_instantiate_simple + attr_add + prompt + ["Upper cardinality violation for outgoing edge at p1"] + prompt,
+            did_instantiate_simple + attr_add + prompt + ["Upper cardinality violation for outgoing edge of type Place_tokens at p1"] + prompt,
             mode))
 
     def test_po_pn_interface_verify_natural(self):

+ 52 - 0
interface/HUTN/grammars/modelling.g

@@ -0,0 +1,52 @@
+grammar{
+    start: (import | export | include_files | model | NEWLINE)+;
+
+    import: IMPORT MV_URL AS MODEL_ID;
+    export: EXPORT MODEL_ID TO MV_URL;
+    include_files: INCLUDE STRVALUE NEWLINE;
+
+    model: MODEL_ID MODEL_ID NEWLINE? LCURLY NEWLINE? (model_element)* RCURLY;
+
+    model_element: MODEL_ID MODEL_ID? inheritance? (LPAR MODEL_ID COMMA MODEL_ID RPAR)? NEWLINE? LCURLY NEWLINE? (model_attribute)* RCURLY NEWLINE?;
+
+    inheritance: COLON MODEL_ID (COMMA MODEL_ID)*;
+
+    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
+        | FLOAT_NUMBER
+        | TRUE
+        | FALSE
+        | STRVALUE;
+
+    tokens{
+        IMPORT: 'import';
+        AS: 'as';
+        MODEL_ID: '[a-zA-Z_][a-zA-Z_0-9]*';
+        MV_URL: '[a-zA-Z_0-9/]*';
+        LCURLY: '{';
+        RCURLY: '}';
+        NEWLINE: '(\r?\n)+';
+        DEC_NUMBER: '[+-]?(0|[1-9]\d*[lL]?)';
+        FLOAT_NUMBER: '[+-]?((\d+\.\d*|\.\d+)([eE][-+]?\d+)?|\d+[eE][-+]?\d+)';
+        STRVALUE: 'u?r?("(?!"").*?(?<!\\)(\\\\)*?"|\'(?!\'\').*?(?<!\\)(\\\\)*?\')';
+        TRUE: 'True';
+        FALSE: 'False';
+        ASSIGN: '=';
+        DOLLAR: '\$';
+        WS: '[ ]+' @Impl;
+        COLON : ':';
+        LPAR: '\(';
+        RPAR: '\)';
+        COMMA: ',';
+        EXPORT: 'export';
+        TO: 'to';
+        ANYTHING_EXCEPT_DOLLAR: '[^$]*';
+        INCLUDE: 'include';
+    }
+}

+ 3 - 1
interface/HUTN/hutn_compiler/bootstrap_visitor.py

@@ -6,6 +6,7 @@ class BootstrapVisitor(PrimitivesVisitor):
         PrimitivesVisitor.__init__(self, args)
 
     def dump(self):
+        link_id = 0
         call = self.value("call")
         access = self.value("access")
         resolve = self.value("resolve")
@@ -31,7 +32,8 @@ class BootstrapVisitor(PrimitivesVisitor):
                 source = "auto_%s" % source if isinstance(source, int) else source
                 target = "auto_%s" % target if isinstance(target, int) else target
                 # output.append("D %s,%s,%s\n" % (source, value, target))
-                linkname = "%s_%s_%s" % (source, abs(hash(value)), target)
+                linkname = "%s_%s_%s" % (source, link_id, target)
+                link_id += 1
                 output.append("Edge _%s_0(%s, %s)\n" % (linkname, source, target))
                 output.append("Node _%s_2(%s)\n" % (linkname, value))
                 output.append("Edge _%s_1(_%s_0, _%s_2)\n" % (linkname, linkname, linkname))

+ 4 - 0
interface/HUTN/hutn_compiler/compiler.py

@@ -143,6 +143,8 @@ def main(input_file, grammar_file, mode, args=[]):
     from primitives_object_visitor import PrimitivesObjectVisitor
     from constructors_visitor import ConstructorsVisitor
     from constructors_object_visitor import ConstructorsObjectVisitor
+    from model_visitor import ModelVisitor
+    from model_object_visitor import ModelObjectVisitor
 
     modes = {
         "N" : [],
@@ -154,6 +156,8 @@ def main(input_file, grammar_file, mode, args=[]):
         "BS" : [SemanticsVisitor, BootstrapVisitor],
         "CS" : [SemanticsVisitor, ConstructorsVisitor],
         "CO" : [SemanticsVisitor, ConstructorsObjectVisitor],
+        "M" : [ModelVisitor],
+        "MO" : [ModelObjectVisitor],
     }
     return do_compile(input_file, grammar_file, [v(args) for v in modes[mode]])
 

+ 39 - 0
interface/HUTN/hutn_compiler/model_object_visitor.py

@@ -0,0 +1,39 @@
+from model_visitor import ModelVisitor
+from compiler import main as do_compile
+import os
+import urllib2
+import urllib
+import json
+
+def jsonstr(s):
+    return '"%s"' % s
+
+def empty(s):
+    return None
+
+class ModelObjectVisitor(ModelVisitor):
+    def __init__(self, args):
+        ModelVisitor.__init__(self, args)
+        self.username = args[0]
+        self.obj_file = args[1]
+        self.real_file = args[2]
+        self.address = args[3]
+
+    def dump(self):
+        v = ModelVisitor.dump(self)
+        data = []
+        data.append(["V", '4'])
+        for i in v:
+            data.append(["V", i])
+        data.append(["V", '"exit"'])
+
+        # Wait for kernel to signal that it finished
+        data.append(["V", '2'])
+
+        urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "set_input", "data": json.dumps(data), "username": self.username}))).read()
+        v = urllib2.urlopen(urllib2.Request(self.address, urllib.urlencode({"op": "get_output", "username": self.username}))).read()
+        v = v.split("=", 2)[2]
+        if v == "DONE":
+            return True
+        else:
+            return False

+ 126 - 0
interface/HUTN/hutn_compiler/model_visitor.py

@@ -0,0 +1,126 @@
+from visitor import Visitor
+from compiler import main as do_compile
+import os
+
+def jsonstr(s):
+    return '"%s"' % s
+
+def empty(s):
+    return None
+
+class ModelVisitor(Visitor):
+    def __init__(self, args):
+        Visitor.__init__(self, args)
+        self.constructors = []
+        self.free_id = 0
+        self.name_maps = {}
+        self.current_model = None
+        self.current_element = None
+        self.includes = []
+
+    def dump(self):
+        return self.constructors
+
+    def __getattr__(self, attr):
+        if attr.startswith("visit_"):
+            return empty
+        else:
+            raise AttributeError()
+
+    def visit_start(self, tree):
+        for t in tree.get_tail():
+            self.visit(t)
+
+    def visit_include_files(self, tree):
+        self.includes.append(tree.get_children("STRVALUE")[0].get_text())
+
+    def visit_import(self, tree):
+        url = tree.get_children("MV_URL")[0]
+        target = tree.get_children("MODEL_ID")[0]
+        self.constructors.extend(['"import_node"', jsonstr(url.get_text()), jsonstr(target.get_text())])
+
+    def visit_export(self, tree):
+        url = tree.get_children("MV_URL")[0]
+        target = tree.get_children("MODEL_ID")[0]
+        self.constructors.extend(['"export_node"', jsonstr(target.get_text()), jsonstr(url.get_text())])
+
+    def visit_model(self, tree):
+        children = tree.get_children("MODEL_ID")
+        model_type = children[0].get_text()
+        model_name = children[1].get_text()
+        self.constructors.extend(['"instantiate_model"', jsonstr(model_type), jsonstr(model_name)])
+        self.constructors.extend(['"define_inheritance"', jsonstr(model_name), jsonstr("Inheritance")])
+        self.current_model = model_name
+        for element in tree.get_children("model_element"):
+            self.visit(element)
+
+    def visit_model_element(self, tree):
+        children = tree.get_children("MODEL_ID")
+        element_type = children[0].get_text()
+        if len(children) == 2 or len(children) == 4:
+            element_name = children[1].get_text()
+        else:
+            element_name = "__%s" % self.free_id
+            self.free_id += 1
+
+        if len(children) > 2:
+            # So we have a source and target; but aren't sure which is which, because the name is optional!
+            source_name = children[-2].get_text()
+            target_name = children[-1].get_text()
+            self.constructors.extend(['"instantiate_link"', jsonstr(self.current_model), jsonstr(element_type), jsonstr(element_name), jsonstr(source_name), jsonstr(target_name)])
+        else:
+            self.constructors.extend(['"instantiate_node"', jsonstr(self.current_model), jsonstr(element_type), jsonstr(element_name)])
+        self.current_element = element_name
+
+        if tree.get_children("inheritance"):
+            self.visit(tree.get_children("inheritance")[0])
+            
+        for attr in tree.get_children("model_attribute"):
+            self.visit(attr)
+
+    def visit_inheritance(self, tree):
+        for token in tree.get_children("MODEL_ID"):
+            superclass = token.get_text()
+            self.constructors.extend(['"instantiate_link"', jsonstr(self.current_model), jsonstr("Inheritance"), jsonstr("%s_inherits_from_%s" % (self.current_element, superclass)), jsonstr(self.current_element), jsonstr(superclass)])
+
+    def visit_model_attribute(self, tree):
+        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("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)])
+            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:
+            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())
+            constraint = "\n".join(["\t" + line[whitespaces-1:].replace("    ", "\t") for line in constraint.split("\n") if len(line.strip()) != 0])
+            constraint = "".join(["include %s\n" % i for i in self.includes]) + \
+                         "String function constraint(model : Element, name : String):\n" + \
+                         "\tElement self\n" + \
+                         '\tself = model["model"][name]\n' + \
+                         constraint + "\n"
+            with open(".constraint.alc", 'w') as f:
+                f.write(constraint)
+                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()])

+ 0 - 1
interface/HUTN/hutn_compiler/primitives_object_visitor.py

@@ -49,7 +49,6 @@ class PrimitivesObjectVisitor(PrimitivesVisitor):
                 print("[CACHED] %s" % simple_filename)
 
     def dump(self):
-        print("DUMP")
         v = PrimitivesVisitor.dump(self)
         data = []
 

+ 8 - 6
interface/HUTN/hutn_compiler/primitives_visitor.py

@@ -411,17 +411,19 @@ class PrimitivesVisitor(Visitor):
         assign = self.value("assign")
         self.dict(assign, "var", resolve)
 
-        const = self.value("constant")
-
         self.visit_atomvalue(tree.get_tail()[-1])
         value = self.get_primitive(tree.get_tail()[-1])
 
-        #TODO hack...
         if value is None:
-            value = self.node()
+            call = self.value("call")
+            access = self.value("access")
+            resolve = self.value("resolve")
+            self.dict(call, "func", access)
+            self.dict(access, "var", resolve)
+            self.dict(resolve, "var", self.value('"create_node"'))
+            value = call
 
-        self.dict(const, "node", value)
-        self.dict(assign, "value", const)
+        self.dict(assign, "value", value)
 
         self.set_primitive(tree, (declare, assign))
 

+ 7 - 0
interface/HUTN/test/constructor_compilation_action_language/util.py

@@ -0,0 +1,7 @@
+import os
+
+def get_code_path(filename):
+    return os.path.abspath(os.path.dirname(__file__)) + os.sep + "code" + os.sep + filename
+
+def get_expected_path(filename):
+    return os.path.abspath(os.path.dirname(__file__)) + os.sep + "expected" + os.sep + filename.rsplit(".", 1)[0]

+ 7 - 0
interface/HUTN/test/grammar_action_language/util.py

@@ -0,0 +1,7 @@
+import os
+
+def get_code_path(filename):
+    return os.path.abspath(os.path.dirname(__file__)) + os.sep + "code" + os.sep + filename
+
+def get_expected_path(filename):
+    return os.path.abspath(os.path.dirname(__file__)) + os.sep + "expected" + os.sep + filename.rsplit(".", 1)[0]

+ 167 - 155
interface/HUTN/test/graph_compilation_action_language/expected/factorial

@@ -1,185 +1,197 @@
 V auto_initial_IP(global)
 V auto_1(assign)
-V auto_10(constant)
-N auto_11
+V auto_10(call)
+V auto_11(access)
 V auto_12(resolve)
-V auto_13("integer_subtraction")
-V auto_14(constant)
-N auto_15
-V auto_16(resolve)
-V auto_17("integer_lte")
-V auto_18(constant)
-N auto_19
+V auto_13("create_node")
+V auto_14(resolve)
+V auto_15("integer_subtraction")
+V auto_16(call)
+V auto_17(access)
+V auto_18(resolve)
+V auto_19("create_node")
 V auto_2(global)
 V auto_20(resolve)
-V auto_21("integer_multiplication")
-V auto_22(constant)
-N auto_23
-V auto_24(while)
-V auto_25(output)
-V auto_26(call)
-V auto_27(access)
-V auto_28(resolve)
-V auto_29("factorial")
+V auto_21("integer_lte")
+V auto_22(call)
+V auto_23(access)
+V auto_24(resolve)
+V auto_25("create_node")
+V auto_26(resolve)
+V auto_27("integer_multiplication")
+V auto_28(constant)
+N auto_29
 V auto_3(assign)
-N auto_30
-V auto_31("a")
-V auto_32(input)
-V auto_33(constant)
-V auto_34(True)
-V auto_35(resolve)
-V auto_36("main")
-V auto_37(constant)
-N auto_38
-V auto_39(if)
+V auto_30(while)
+V auto_31(output)
+V auto_32(call)
+V auto_33(access)
+V auto_34(resolve)
+V auto_35("factorial")
+N auto_36
+V auto_37("a")
+V auto_38(input)
+V auto_39(constant)
 V auto_4(global)
-V auto_40(call)
-V auto_41(access)
-V auto_42(resolve)
-N auto_43
-V auto_44("b")
-V auto_45(constant)
-V auto_46(1)
-N auto_47
-V auto_48("a")
-V auto_49(access)
+V auto_40(True)
+V auto_41(resolve)
+V auto_42("main")
+V auto_43(constant)
+N auto_44
+V auto_45(if)
+V auto_46(call)
+V auto_47(access)
+V auto_48(resolve)
+N auto_49
 V auto_5(assign)
-V auto_50(resolve)
-N auto_51
-V auto_52("a")
-V auto_53(return)
-V auto_54(call)
+V auto_50("b")
+V auto_51(constant)
+V auto_52(1)
+N auto_53
+V auto_54("a")
 V auto_55(access)
 V auto_56(resolve)
 N auto_57
-V auto_58("b")
-V auto_59(call)
+V auto_58("a")
+V auto_59(return)
 V auto_6(global)
-V auto_60(access)
-V auto_61(resolve)
-N auto_62
-V auto_63("a")
-V auto_64(call)
-V auto_65(access)
-V auto_66(resolve)
-N auto_67
-V auto_68("b")
-V auto_69(constant)
+V auto_60(call)
+V auto_61(access)
+V auto_62(resolve)
+N auto_63
+V auto_64("b")
+V auto_65(call)
+V auto_66(access)
+V auto_67(resolve)
+N auto_68
+V auto_69("a")
 V auto_7(assign)
-V auto_70(1)
-N auto_71
-V auto_72("a")
-V auto_73(access)
-V auto_74(resolve)
-N auto_75
-V auto_76("a")
-V auto_77(access)
-V auto_78(resolve)
-V auto_79(return)
+V auto_70(call)
+V auto_71(access)
+V auto_72(resolve)
+N auto_73
+V auto_74("b")
+V auto_75(constant)
+V auto_76(1)
+N auto_77
+V auto_78("a")
+V auto_79(access)
 V auto_8(global)
-V auto_80(constant)
-V auto_81(1)
-N auto_82
-V auto_83(resolve)
+V auto_80(resolve)
+N auto_81
+V auto_82("a")
+V auto_83(access)
+V auto_84(resolve)
+V auto_85(return)
+V auto_86(constant)
+V auto_87(1)
+N auto_88
+V auto_89(resolve)
 V auto_9(assign)
 D auto_initial_IP,"next",auto_1
-D auto_initial_IP,"var",auto_29
+D auto_initial_IP,"var",auto_35
 D auto_1,"next",auto_2
-D auto_1,"value",auto_37
-D auto_1,"var",auto_83
-D auto_10,"node",auto_11
+D auto_1,"value",auto_43
+D auto_1,"var",auto_89
+D auto_10,"func",auto_11
+D auto_11,"var",auto_12
 D auto_12,"var",auto_13
-D auto_14,"node",auto_15
-D auto_16,"var",auto_17
-D auto_18,"node",auto_19
+D auto_14,"var",auto_15
+D auto_16,"func",auto_17
+D auto_17,"var",auto_18
+D auto_18,"var",auto_19
 D auto_2,"next",auto_3
-D auto_2,"var",auto_36
+D auto_2,"var",auto_42
 D auto_20,"var",auto_21
-D auto_22,"node",auto_23
-D auto_23,"body",auto_24
-D auto_24,"body",auto_25
-D auto_24,"cond",auto_33
-D auto_25,"value",auto_26
-D auto_26,"func",auto_27
-D auto_26,"last_param",auto_30
-D auto_26,"params",auto_30
-D auto_27,"var",auto_28
-D auto_28,"var",auto_29
+D auto_22,"func",auto_23
+D auto_23,"var",auto_24
+D auto_24,"var",auto_25
+D auto_26,"var",auto_27
+D auto_28,"node",auto_29
+D auto_29,"body",auto_30
 D auto_3,"next",auto_4
-D auto_3,"value",auto_22
-D auto_3,"var",auto_35
-D auto_30,"name",auto_31
-D auto_30,"value",auto_32
-D auto_33,"node",auto_34
-D auto_35,"var",auto_36
-D auto_37,"node",auto_38
-D auto_38,"body",auto_39
-D auto_38,"params",auto_82
-D auto_39,"cond",auto_40
-D auto_39,"else",auto_53
-D auto_39,"then",auto_79
+D auto_3,"value",auto_28
+D auto_3,"var",auto_41
+D auto_30,"body",auto_31
+D auto_30,"cond",auto_39
+D auto_31,"value",auto_32
+D auto_32,"func",auto_33
+D auto_32,"last_param",auto_36
+D auto_32,"params",auto_36
+D auto_33,"var",auto_34
+D auto_34,"var",auto_35
+D auto_36,"name",auto_37
+D auto_36,"value",auto_38
+D auto_39,"node",auto_40
 D auto_4,"next",auto_5
-D auto_4,"var",auto_21
-D auto_40,"func",auto_41
-D auto_40,"last_param",auto_43
-D auto_40,"params",auto_47
+D auto_4,"var",auto_27
 D auto_41,"var",auto_42
-D auto_42,"var",auto_17
-D auto_43,"name",auto_44
-D auto_43,"value",auto_45
-D auto_45,"node",auto_46
-D auto_47,"name",auto_48
-D auto_47,"next_param",auto_43
-D auto_47,"value",auto_49
-D auto_49,"var",auto_50
+D auto_43,"node",auto_44
+D auto_44,"body",auto_45
+D auto_44,"params",auto_88
+D auto_45,"cond",auto_46
+D auto_45,"else",auto_59
+D auto_45,"then",auto_85
+D auto_46,"func",auto_47
+D auto_46,"last_param",auto_49
+D auto_46,"params",auto_53
+D auto_47,"var",auto_48
+D auto_48,"var",auto_21
+D auto_49,"name",auto_50
+D auto_49,"value",auto_51
 D auto_5,"next",auto_6
-D auto_5,"value",auto_18
-D auto_5,"var",auto_20
-D auto_50,"var",auto_51
-D auto_51,"name",auto_52
-D auto_53,"value",auto_54
-D auto_54,"func",auto_55
-D auto_54,"last_param",auto_57
-D auto_54,"params",auto_75
+D auto_5,"value",auto_22
+D auto_5,"var",auto_26
+D auto_51,"node",auto_52
+D auto_53,"name",auto_54
+D auto_53,"next_param",auto_49
+D auto_53,"value",auto_55
 D auto_55,"var",auto_56
-D auto_56,"var",auto_21
+D auto_56,"var",auto_57
 D auto_57,"name",auto_58
-D auto_57,"value",auto_59
-D auto_59,"func",auto_60
-D auto_59,"last_param",auto_62
-D auto_59,"params",auto_62
+D auto_59,"value",auto_60
 D auto_6,"next",auto_7
-D auto_6,"var",auto_17
-D auto_60,"var",auto_61
-D auto_61,"var",auto_29
-D auto_62,"name",auto_63
-D auto_62,"value",auto_64
-D auto_64,"func",auto_65
-D auto_64,"last_param",auto_67
-D auto_64,"params",auto_71
-D auto_65,"var",auto_66
-D auto_66,"var",auto_13
-D auto_67,"name",auto_68
-D auto_67,"value",auto_69
-D auto_69,"node",auto_70
+D auto_6,"var",auto_21
+D auto_60,"func",auto_61
+D auto_60,"last_param",auto_63
+D auto_60,"params",auto_81
+D auto_61,"var",auto_62
+D auto_62,"var",auto_27
+D auto_63,"name",auto_64
+D auto_63,"value",auto_65
+D auto_65,"func",auto_66
+D auto_65,"last_param",auto_68
+D auto_65,"params",auto_68
+D auto_66,"var",auto_67
+D auto_67,"var",auto_35
+D auto_68,"name",auto_69
+D auto_68,"value",auto_70
 D auto_7,"next",auto_8
-D auto_7,"value",auto_14
-D auto_7,"var",auto_16
-D auto_71,"name",auto_72
-D auto_71,"next_param",auto_67
-D auto_71,"value",auto_73
-D auto_73,"var",auto_74
-D auto_74,"var",auto_51
-D auto_75,"name",auto_76
-D auto_75,"next_param",auto_57
-D auto_75,"value",auto_77
-D auto_77,"var",auto_78
-D auto_78,"var",auto_51
-D auto_79,"value",auto_80
+D auto_7,"value",auto_16
+D auto_7,"var",auto_20
+D auto_70,"func",auto_71
+D auto_70,"last_param",auto_73
+D auto_70,"params",auto_77
+D auto_71,"var",auto_72
+D auto_72,"var",auto_15
+D auto_73,"name",auto_74
+D auto_73,"value",auto_75
+D auto_75,"node",auto_76
+D auto_77,"name",auto_78
+D auto_77,"next_param",auto_73
+D auto_77,"value",auto_79
+D auto_79,"var",auto_80
 D auto_8,"next",auto_9
-D auto_8,"var",auto_13
-D auto_80,"node",auto_81
-D auto_82,"a",auto_51
-D auto_83,"var",auto_29
+D auto_8,"var",auto_15
+D auto_80,"var",auto_57
+D auto_81,"name",auto_82
+D auto_81,"next_param",auto_63
+D auto_81,"value",auto_83
+D auto_83,"var",auto_84
+D auto_84,"var",auto_57
+D auto_85,"value",auto_86
+D auto_86,"node",auto_87
+D auto_88,"a",auto_57
+D auto_89,"var",auto_35
 D auto_9,"value",auto_10
-D auto_9,"var",auto_12
+D auto_9,"var",auto_14

+ 199 - 187
interface/HUTN/test/graph_compilation_action_language/expected/fibonacci

@@ -1,217 +1,229 @@
 V auto_initial_IP(global)
 V auto_1(assign)
-V auto_10(constant)
-N auto_11
+V auto_10(call)
+V auto_100(constant)
+V auto_101(1)
+N auto_102
+V auto_103(resolve)
+V auto_11(access)
 V auto_12(resolve)
-V auto_13("integer_subtraction")
-V auto_14(constant)
-N auto_15
-V auto_16(resolve)
-V auto_17("integer_lte")
-V auto_18(constant)
-N auto_19
+V auto_13("create_node")
+V auto_14(resolve)
+V auto_15("integer_subtraction")
+V auto_16(call)
+V auto_17(access)
+V auto_18(resolve)
+V auto_19("create_node")
 V auto_2(global)
 V auto_20(resolve)
-V auto_21("integer_addition")
-V auto_22(constant)
-N auto_23
-V auto_24(while)
-V auto_25(output)
-V auto_26(call)
-V auto_27(access)
-V auto_28(resolve)
-V auto_29("fib")
+V auto_21("integer_lte")
+V auto_22(call)
+V auto_23(access)
+V auto_24(resolve)
+V auto_25("create_node")
+V auto_26(resolve)
+V auto_27("integer_addition")
+V auto_28(constant)
+N auto_29
 V auto_3(assign)
-N auto_30
-V auto_31("a")
-V auto_32(input)
-V auto_33(constant)
-V auto_34(True)
-V auto_35(resolve)
-V auto_36("main")
-V auto_37(constant)
-N auto_38
-V auto_39(if)
+V auto_30(while)
+V auto_31(output)
+V auto_32(call)
+V auto_33(access)
+V auto_34(resolve)
+V auto_35("fib")
+N auto_36
+V auto_37("a")
+V auto_38(input)
+V auto_39(constant)
 V auto_4(global)
-V auto_40(call)
-V auto_41(access)
-V auto_42(resolve)
-N auto_43
-V auto_44("b")
-V auto_45(constant)
-V auto_46(2)
-N auto_47
-V auto_48("a")
-V auto_49(access)
+V auto_40(True)
+V auto_41(resolve)
+V auto_42("main")
+V auto_43(constant)
+N auto_44
+V auto_45(if)
+V auto_46(call)
+V auto_47(access)
+V auto_48(resolve)
+N auto_49
 V auto_5(assign)
-V auto_50(resolve)
-N auto_51
-V auto_52("a")
-V auto_53(return)
-V auto_54(call)
+V auto_50("b")
+V auto_51(constant)
+V auto_52(2)
+N auto_53
+V auto_54("a")
 V auto_55(access)
 V auto_56(resolve)
 N auto_57
-V auto_58("b")
-V auto_59(call)
+V auto_58("a")
+V auto_59(return)
 V auto_6(global)
-V auto_60(access)
-V auto_61(resolve)
-N auto_62
-V auto_63("a")
-V auto_64(call)
-V auto_65(access)
-V auto_66(resolve)
-N auto_67
-V auto_68("b")
-V auto_69(constant)
+V auto_60(call)
+V auto_61(access)
+V auto_62(resolve)
+N auto_63
+V auto_64("b")
+V auto_65(call)
+V auto_66(access)
+V auto_67(resolve)
+N auto_68
+V auto_69("a")
 V auto_7(assign)
-V auto_70(2)
-N auto_71
-V auto_72("a")
-V auto_73(access)
-V auto_74(resolve)
-N auto_75
-V auto_76("a")
-V auto_77(call)
-V auto_78(access)
-V auto_79(resolve)
+V auto_70(call)
+V auto_71(access)
+V auto_72(resolve)
+N auto_73
+V auto_74("b")
+V auto_75(constant)
+V auto_76(2)
+N auto_77
+V auto_78("a")
+V auto_79(access)
 V auto_8(global)
-N auto_80
-V auto_81("a")
-V auto_82(call)
-V auto_83(access)
-V auto_84(resolve)
-N auto_85
-V auto_86("b")
-V auto_87(constant)
-V auto_88(1)
-N auto_89
+V auto_80(resolve)
+N auto_81
+V auto_82("a")
+V auto_83(call)
+V auto_84(access)
+V auto_85(resolve)
+N auto_86
+V auto_87("a")
+V auto_88(call)
+V auto_89(access)
 V auto_9(assign)
-V auto_90("a")
-V auto_91(access)
-V auto_92(resolve)
-V auto_93(return)
-V auto_94(constant)
-V auto_95(1)
-N auto_96
-V auto_97(resolve)
+V auto_90(resolve)
+N auto_91
+V auto_92("b")
+V auto_93(constant)
+V auto_94(1)
+N auto_95
+V auto_96("a")
+V auto_97(access)
+V auto_98(resolve)
+V auto_99(return)
 D auto_initial_IP,"next",auto_1
-D auto_initial_IP,"var",auto_29
+D auto_initial_IP,"var",auto_35
 D auto_1,"next",auto_2
-D auto_1,"value",auto_37
-D auto_1,"var",auto_97
-D auto_10,"node",auto_11
+D auto_1,"value",auto_43
+D auto_1,"var",auto_103
+D auto_10,"func",auto_11
+D auto_100,"node",auto_101
+D auto_102,"a",auto_57
+D auto_103,"var",auto_35
+D auto_11,"var",auto_12
 D auto_12,"var",auto_13
-D auto_14,"node",auto_15
-D auto_16,"var",auto_17
-D auto_18,"node",auto_19
+D auto_14,"var",auto_15
+D auto_16,"func",auto_17
+D auto_17,"var",auto_18
+D auto_18,"var",auto_19
 D auto_2,"next",auto_3
-D auto_2,"var",auto_36
+D auto_2,"var",auto_42
 D auto_20,"var",auto_21
-D auto_22,"node",auto_23
-D auto_23,"body",auto_24
-D auto_24,"body",auto_25
-D auto_24,"cond",auto_33
-D auto_25,"value",auto_26
-D auto_26,"func",auto_27
-D auto_26,"last_param",auto_30
-D auto_26,"params",auto_30
-D auto_27,"var",auto_28
-D auto_28,"var",auto_29
+D auto_22,"func",auto_23
+D auto_23,"var",auto_24
+D auto_24,"var",auto_25
+D auto_26,"var",auto_27
+D auto_28,"node",auto_29
+D auto_29,"body",auto_30
 D auto_3,"next",auto_4
-D auto_3,"value",auto_22
-D auto_3,"var",auto_35
-D auto_30,"name",auto_31
-D auto_30,"value",auto_32
-D auto_33,"node",auto_34
-D auto_35,"var",auto_36
-D auto_37,"node",auto_38
-D auto_38,"body",auto_39
-D auto_38,"params",auto_96
-D auto_39,"cond",auto_40
-D auto_39,"else",auto_53
-D auto_39,"then",auto_93
+D auto_3,"value",auto_28
+D auto_3,"var",auto_41
+D auto_30,"body",auto_31
+D auto_30,"cond",auto_39
+D auto_31,"value",auto_32
+D auto_32,"func",auto_33
+D auto_32,"last_param",auto_36
+D auto_32,"params",auto_36
+D auto_33,"var",auto_34
+D auto_34,"var",auto_35
+D auto_36,"name",auto_37
+D auto_36,"value",auto_38
+D auto_39,"node",auto_40
 D auto_4,"next",auto_5
-D auto_4,"var",auto_21
-D auto_40,"func",auto_41
-D auto_40,"last_param",auto_43
-D auto_40,"params",auto_47
+D auto_4,"var",auto_27
 D auto_41,"var",auto_42
-D auto_42,"var",auto_17
-D auto_43,"name",auto_44
-D auto_43,"value",auto_45
-D auto_45,"node",auto_46
-D auto_47,"name",auto_48
-D auto_47,"next_param",auto_43
-D auto_47,"value",auto_49
-D auto_49,"var",auto_50
+D auto_43,"node",auto_44
+D auto_44,"body",auto_45
+D auto_44,"params",auto_102
+D auto_45,"cond",auto_46
+D auto_45,"else",auto_59
+D auto_45,"then",auto_99
+D auto_46,"func",auto_47
+D auto_46,"last_param",auto_49
+D auto_46,"params",auto_53
+D auto_47,"var",auto_48
+D auto_48,"var",auto_21
+D auto_49,"name",auto_50
+D auto_49,"value",auto_51
 D auto_5,"next",auto_6
-D auto_5,"value",auto_18
-D auto_5,"var",auto_20
-D auto_50,"var",auto_51
-D auto_51,"name",auto_52
-D auto_53,"value",auto_54
-D auto_54,"func",auto_55
-D auto_54,"last_param",auto_57
-D auto_54,"params",auto_75
+D auto_5,"value",auto_22
+D auto_5,"var",auto_26
+D auto_51,"node",auto_52
+D auto_53,"name",auto_54
+D auto_53,"next_param",auto_49
+D auto_53,"value",auto_55
 D auto_55,"var",auto_56
-D auto_56,"var",auto_21
+D auto_56,"var",auto_57
 D auto_57,"name",auto_58
-D auto_57,"value",auto_59
-D auto_59,"func",auto_60
-D auto_59,"last_param",auto_62
-D auto_59,"params",auto_62
+D auto_59,"value",auto_60
 D auto_6,"next",auto_7
-D auto_6,"var",auto_17
-D auto_60,"var",auto_61
-D auto_61,"var",auto_29
-D auto_62,"name",auto_63
-D auto_62,"value",auto_64
-D auto_64,"func",auto_65
-D auto_64,"last_param",auto_67
-D auto_64,"params",auto_71
-D auto_65,"var",auto_66
-D auto_66,"var",auto_13
-D auto_67,"name",auto_68
-D auto_67,"value",auto_69
-D auto_69,"node",auto_70
+D auto_6,"var",auto_21
+D auto_60,"func",auto_61
+D auto_60,"last_param",auto_63
+D auto_60,"params",auto_81
+D auto_61,"var",auto_62
+D auto_62,"var",auto_27
+D auto_63,"name",auto_64
+D auto_63,"value",auto_65
+D auto_65,"func",auto_66
+D auto_65,"last_param",auto_68
+D auto_65,"params",auto_68
+D auto_66,"var",auto_67
+D auto_67,"var",auto_35
+D auto_68,"name",auto_69
+D auto_68,"value",auto_70
 D auto_7,"next",auto_8
-D auto_7,"value",auto_14
-D auto_7,"var",auto_16
-D auto_71,"name",auto_72
-D auto_71,"next_param",auto_67
-D auto_71,"value",auto_73
-D auto_73,"var",auto_74
-D auto_74,"var",auto_51
-D auto_75,"name",auto_76
-D auto_75,"next_param",auto_57
-D auto_75,"value",auto_77
-D auto_77,"func",auto_78
-D auto_77,"last_param",auto_80
-D auto_77,"params",auto_80
-D auto_78,"var",auto_79
-D auto_79,"var",auto_29
+D auto_7,"value",auto_16
+D auto_7,"var",auto_20
+D auto_70,"func",auto_71
+D auto_70,"last_param",auto_73
+D auto_70,"params",auto_77
+D auto_71,"var",auto_72
+D auto_72,"var",auto_15
+D auto_73,"name",auto_74
+D auto_73,"value",auto_75
+D auto_75,"node",auto_76
+D auto_77,"name",auto_78
+D auto_77,"next_param",auto_73
+D auto_77,"value",auto_79
+D auto_79,"var",auto_80
 D auto_8,"next",auto_9
-D auto_8,"var",auto_13
-D auto_80,"name",auto_81
-D auto_80,"value",auto_82
-D auto_82,"func",auto_83
-D auto_82,"last_param",auto_85
-D auto_82,"params",auto_89
-D auto_83,"var",auto_84
-D auto_84,"var",auto_13
-D auto_85,"name",auto_86
-D auto_85,"value",auto_87
-D auto_87,"node",auto_88
-D auto_89,"name",auto_90
-D auto_89,"next_param",auto_85
-D auto_89,"value",auto_91
+D auto_8,"var",auto_15
+D auto_80,"var",auto_57
+D auto_81,"name",auto_82
+D auto_81,"next_param",auto_63
+D auto_81,"value",auto_83
+D auto_83,"func",auto_84
+D auto_83,"last_param",auto_86
+D auto_83,"params",auto_86
+D auto_84,"var",auto_85
+D auto_85,"var",auto_35
+D auto_86,"name",auto_87
+D auto_86,"value",auto_88
+D auto_88,"func",auto_89
+D auto_88,"last_param",auto_91
+D auto_88,"params",auto_95
+D auto_89,"var",auto_90
 D auto_9,"value",auto_10
-D auto_9,"var",auto_12
-D auto_91,"var",auto_92
-D auto_92,"var",auto_51
-D auto_93,"value",auto_94
-D auto_94,"node",auto_95
-D auto_96,"a",auto_51
-D auto_97,"var",auto_29
+D auto_9,"var",auto_14
+D auto_90,"var",auto_15
+D auto_91,"name",auto_92
+D auto_91,"value",auto_93
+D auto_93,"node",auto_94
+D auto_95,"name",auto_96
+D auto_95,"next_param",auto_91
+D auto_95,"value",auto_97
+D auto_97,"var",auto_98
+D auto_98,"var",auto_57
+D auto_99,"value",auto_100

+ 417 - 385
interface/HUTN/test/graph_compilation_action_language/expected/fibonacci_smart

@@ -1,462 +1,494 @@
 V auto_initial_IP(global)
 V auto_1(assign)
 V auto_10(global)
-V auto_100(access)
-V auto_101(resolve)
-N auto_102
-V auto_103("b")
+N auto_100
+V auto_101("a")
+V auto_102(access)
+V auto_103(resolve)
 V auto_104(call)
 V auto_105(access)
 V auto_106(resolve)
-N auto_107
-V auto_108("b")
-V auto_109(call)
+V auto_107(resolve)
+V auto_108(resolve)
+V auto_109("main")
 V auto_11(assign)
-V auto_110(access)
-V auto_111(resolve)
-N auto_112
-V auto_113("b")
-V auto_114(call)
-V auto_115(access)
-V auto_116(resolve)
-N auto_117
-V auto_118("b")
-V auto_119(constant)
+V auto_110(constant)
+N auto_111
+V auto_112(declare)
+V auto_113(while)
+V auto_114(assign)
+V auto_115(call)
+V auto_116(access)
+V auto_117(resolve)
+N auto_118
+V auto_119("b")
 V auto_12(global)
-V auto_120(1)
-N auto_121
-V auto_122("a")
-V auto_123(access)
-V auto_124(resolve)
-N auto_125
-N auto_126
-V auto_127("a")
-V auto_128(access)
-V auto_129(resolve)
+V auto_120(call)
+V auto_121(access)
+V auto_122(resolve)
+N auto_123
+V auto_124("b")
+V auto_125(call)
+V auto_126(access)
+V auto_127(resolve)
+N auto_128
+V auto_129("b")
 V auto_13(assign)
-N auto_130
-V auto_131("a")
-V auto_132(call)
-V auto_133(access)
-V auto_134(resolve)
-N auto_135
-V auto_136("b")
-V auto_137(call)
-V auto_138(access)
-V auto_139(resolve)
+V auto_130(call)
+V auto_131(access)
+V auto_132(resolve)
+N auto_133
+V auto_134("b")
+V auto_135(constant)
+V auto_136(1)
+N auto_137
+V auto_138("a")
+V auto_139(access)
 V auto_14(global)
-N auto_140
-V auto_141("b")
-V auto_142(constant)
-V auto_143(2)
-N auto_144
-V auto_145("a")
-V auto_146(access)
-V auto_147(resolve)
-N auto_148
-V auto_149("a")
+V auto_140(resolve)
+N auto_141
+N auto_142
+V auto_143("a")
+V auto_144(access)
+V auto_145(resolve)
+N auto_146
+V auto_147("a")
+V auto_148(call)
+V auto_149(access)
 V auto_15(assign)
-V auto_150(access)
-V auto_151(resolve)
-N auto_152
-V auto_153("a")
+V auto_150(resolve)
+N auto_151
+V auto_152("b")
+V auto_153(call)
 V auto_154(access)
 V auto_155(resolve)
-V auto_156(call)
-V auto_157(access)
-V auto_158(resolve)
-N auto_159
+N auto_156
+V auto_157("b")
+V auto_158(constant)
+V auto_159(2)
 V auto_16(global)
-V auto_160("a")
-V auto_161(access)
-V auto_162(resolve)
+N auto_160
+V auto_161("a")
+V auto_162(access)
 V auto_163(resolve)
-V auto_164(call)
-V auto_165(access)
-V auto_166(resolve)
-N auto_167
-V auto_168("b")
-V auto_169(call)
+N auto_164
+V auto_165("a")
+V auto_166(access)
+V auto_167(resolve)
+N auto_168
+V auto_169("a")
 V auto_17(assign)
 V auto_170(access)
 V auto_171(resolve)
-N auto_172
-V auto_173("a")
-V auto_174(access)
-V auto_175(resolve)
-N auto_176
-V auto_177("a")
-V auto_178(access)
+V auto_172(call)
+V auto_173(access)
+V auto_174(resolve)
+N auto_175
+V auto_176("a")
+V auto_177(access)
+V auto_178(resolve)
 V auto_179(resolve)
 V auto_18(global)
-N auto_180
-V auto_181("a")
-V auto_182(return)
-V auto_183(call)
-V auto_184(access)
-V auto_185(resolve)
-N auto_186
-V auto_187("b")
-V auto_188(call)
-V auto_189(access)
+V auto_180(call)
+V auto_181(access)
+V auto_182(resolve)
+N auto_183
+V auto_184("b")
+V auto_185(call)
+V auto_186(access)
+V auto_187(resolve)
+N auto_188
+V auto_189("a")
 V auto_19(assign)
-V auto_190(resolve)
-N auto_191
-V auto_192("b")
-V auto_193(constant)
-V auto_194(1)
-N auto_195
-V auto_196("a")
-V auto_197(access)
-V auto_198(resolve)
-N auto_199
+V auto_190(access)
+V auto_191(resolve)
+N auto_192
+V auto_193("a")
+V auto_194(access)
+V auto_195(resolve)
+N auto_196
+V auto_197("a")
+V auto_198(return)
+V auto_199(call)
 V auto_2(global)
-V auto_20(constant)
-V auto_200("a")
-V auto_201(access)
-V auto_202(resolve)
-N auto_203
-V auto_204(resolve)
-N auto_21
+V auto_20(call)
+V auto_200(access)
+V auto_201(resolve)
+N auto_202
+V auto_203("b")
+V auto_204(call)
+V auto_205(access)
+V auto_206(resolve)
+N auto_207
+V auto_208("b")
+V auto_209(constant)
+V auto_21(access)
+V auto_210(1)
+N auto_211
+V auto_212("a")
+V auto_213(access)
+V auto_214(resolve)
+N auto_215
+V auto_216("a")
+V auto_217(access)
+V auto_218(resolve)
+N auto_219
 V auto_22(resolve)
-V auto_23("numbers")
-V auto_24(constant)
-N auto_25
-V auto_26(resolve)
-V auto_27("create_node")
-V auto_28(constant)
-N auto_29
+V auto_220(resolve)
+V auto_23("create_node")
+V auto_24(resolve)
+V auto_25("numbers")
+V auto_26(call)
+V auto_27(access)
+V auto_28(resolve)
+V auto_29("create_node")
 V auto_3(assign)
 V auto_30(resolve)
-V auto_31("dict_read")
-V auto_32(constant)
-N auto_33
+V auto_31("create_node")
+V auto_32(call)
+V auto_33(access)
 V auto_34(resolve)
-V auto_35("integer_subtraction")
-V auto_36(constant)
-N auto_37
-V auto_38(resolve)
-V auto_39("list_append")
+V auto_35("create_node")
+V auto_36(resolve)
+V auto_37("dict_read")
+V auto_38(call)
+V auto_39(access)
 V auto_4(global)
-V auto_40(constant)
-N auto_41
+V auto_40(resolve)
+V auto_41("create_node")
 V auto_42(resolve)
-V auto_43("list_len")
-V auto_44(constant)
-N auto_45
+V auto_43("integer_subtraction")
+V auto_44(call)
+V auto_45(access)
 V auto_46(resolve)
-V auto_47("integer_gt")
-V auto_48(constant)
-N auto_49
+V auto_47("create_node")
+V auto_48(resolve)
+V auto_49("list_append")
 V auto_5(assign)
-V auto_50(resolve)
-V auto_51("integer_addition")
-V auto_52(constant)
-N auto_53
-V auto_54(assign)
-V auto_55(call)
-V auto_56(access)
-V auto_57(resolve)
-N auto_58
-V auto_59("b")
+V auto_50(call)
+V auto_51(access)
+V auto_52(resolve)
+V auto_53("create_node")
+V auto_54(resolve)
+V auto_55("list_len")
+V auto_56(call)
+V auto_57(access)
+V auto_58(resolve)
+V auto_59("create_node")
 V auto_6(global)
-V auto_60(constant)
-V auto_61(1)
+V auto_60(resolve)
+V auto_61("integer_gt")
 V auto_62(call)
 V auto_63(access)
 V auto_64(resolve)
-N auto_65
-V auto_66("b")
-V auto_67(constant)
-V auto_68(1)
-V auto_69(while)
+V auto_65("create_node")
+V auto_66(resolve)
+V auto_67("integer_addition")
+V auto_68(constant)
+N auto_69
 V auto_7(assign)
-V auto_70(output)
+V auto_70(assign)
 V auto_71(call)
 V auto_72(access)
 V auto_73(resolve)
-V auto_74("fib")
-N auto_75
-V auto_76("a")
-V auto_77(input)
-V auto_78(constant)
-V auto_79(True)
+N auto_74
+V auto_75("b")
+V auto_76(constant)
+V auto_77(1)
+V auto_78(call)
+V auto_79(access)
 V auto_8(global)
-N auto_80
-V auto_81("a")
-V auto_82(access)
-V auto_83(resolve)
-N auto_84
-V auto_85("a")
-V auto_86(access)
-V auto_87(resolve)
-V auto_88(call)
-V auto_89(access)
+V auto_80(resolve)
+N auto_81
+V auto_82("b")
+V auto_83(constant)
+V auto_84(1)
+V auto_85(while)
+V auto_86(output)
+V auto_87(call)
+V auto_88(access)
+V auto_89(resolve)
 V auto_9(assign)
-V auto_90(resolve)
-V auto_91(resolve)
-V auto_92(resolve)
-V auto_93("main")
+V auto_90("fib")
+N auto_91
+V auto_92("a")
+V auto_93(input)
 V auto_94(constant)
-N auto_95
-V auto_96(declare)
-V auto_97(while)
-V auto_98(assign)
-V auto_99(call)
+V auto_95(True)
+N auto_96
+V auto_97("a")
+V auto_98(access)
+V auto_99(resolve)
 D auto_initial_IP,"next",auto_1
-D auto_initial_IP,"var",auto_74
+D auto_initial_IP,"var",auto_90
 D auto_1,"next",auto_2
-D auto_1,"value",auto_94
-D auto_1,"var",auto_204
+D auto_1,"value",auto_110
+D auto_1,"var",auto_220
 D auto_10,"next",auto_11
-D auto_10,"var",auto_39
-D auto_100,"var",auto_101
-D auto_101,"var",auto_39
-D auto_102,"name",auto_103
-D auto_102,"value",auto_104
+D auto_10,"var",auto_49
+D auto_100,"name",auto_101
+D auto_100,"next_param",auto_74
+D auto_100,"value",auto_102
+D auto_102,"var",auto_103
+D auto_103,"var",auto_25
 D auto_104,"func",auto_105
-D auto_104,"last_param",auto_107
-D auto_104,"params",auto_130
 D auto_105,"var",auto_106
-D auto_106,"var",auto_51
-D auto_107,"name",auto_108
-D auto_107,"value",auto_109
-D auto_109,"func",auto_110
-D auto_109,"last_param",auto_112
-D auto_109,"params",auto_126
+D auto_106,"var",auto_31
+D auto_107,"var",auto_25
+D auto_108,"var",auto_109
 D auto_11,"next",auto_12
-D auto_11,"value",auto_36
-D auto_11,"var",auto_38
-D auto_110,"var",auto_111
-D auto_111,"var",auto_31
-D auto_112,"name",auto_113
-D auto_112,"value",auto_114
-D auto_114,"func",auto_115
-D auto_114,"last_param",auto_117
-D auto_114,"params",auto_121
-D auto_115,"var",auto_116
-D auto_116,"var",auto_35
-D auto_117,"name",auto_118
-D auto_117,"value",auto_119
-D auto_119,"node",auto_120
+D auto_11,"value",auto_44
+D auto_11,"var",auto_48
+D auto_110,"node",auto_111
+D auto_111,"body",auto_112
+D auto_111,"params",auto_219
+D auto_112,"next",auto_113
+D auto_112,"var",auto_141
+D auto_113,"body",auto_114
+D auto_113,"cond",auto_180
+D auto_113,"next",auto_198
+D auto_114,"next",auto_115
+D auto_114,"value",auto_172
+D auto_114,"var",auto_179
+D auto_115,"func",auto_116
+D auto_115,"last_param",auto_118
+D auto_115,"params",auto_168
+D auto_116,"var",auto_117
+D auto_117,"var",auto_49
+D auto_118,"name",auto_119
+D auto_118,"value",auto_120
 D auto_12,"next",auto_13
-D auto_12,"var",auto_35
-D auto_121,"name",auto_122
-D auto_121,"next_param",auto_117
-D auto_121,"value",auto_123
-D auto_123,"var",auto_124
-D auto_124,"var",auto_125
-D auto_126,"name",auto_127
-D auto_126,"next_param",auto_112
-D auto_126,"value",auto_128
-D auto_128,"var",auto_129
-D auto_129,"var",auto_23
+D auto_12,"var",auto_43
+D auto_120,"func",auto_121
+D auto_120,"last_param",auto_123
+D auto_120,"params",auto_146
+D auto_121,"var",auto_122
+D auto_122,"var",auto_67
+D auto_123,"name",auto_124
+D auto_123,"value",auto_125
+D auto_125,"func",auto_126
+D auto_125,"last_param",auto_128
+D auto_125,"params",auto_142
+D auto_126,"var",auto_127
+D auto_127,"var",auto_37
+D auto_128,"name",auto_129
+D auto_128,"value",auto_130
 D auto_13,"next",auto_14
-D auto_13,"value",auto_32
-D auto_13,"var",auto_34
-D auto_130,"name",auto_131
-D auto_130,"next_param",auto_107
-D auto_130,"value",auto_132
-D auto_132,"func",auto_133
-D auto_132,"last_param",auto_135
-D auto_132,"params",auto_148
-D auto_133,"var",auto_134
-D auto_134,"var",auto_31
-D auto_135,"name",auto_136
-D auto_135,"value",auto_137
-D auto_137,"func",auto_138
-D auto_137,"last_param",auto_140
-D auto_137,"params",auto_144
-D auto_138,"var",auto_139
-D auto_139,"var",auto_35
+D auto_13,"value",auto_38
+D auto_13,"var",auto_42
+D auto_130,"func",auto_131
+D auto_130,"last_param",auto_133
+D auto_130,"params",auto_137
+D auto_131,"var",auto_132
+D auto_132,"var",auto_43
+D auto_133,"name",auto_134
+D auto_133,"value",auto_135
+D auto_135,"node",auto_136
+D auto_137,"name",auto_138
+D auto_137,"next_param",auto_133
+D auto_137,"value",auto_139
+D auto_139,"var",auto_140
 D auto_14,"next",auto_15
-D auto_14,"var",auto_31
-D auto_140,"name",auto_141
-D auto_140,"value",auto_142
-D auto_142,"node",auto_143
-D auto_144,"name",auto_145
-D auto_144,"next_param",auto_140
-D auto_144,"value",auto_146
-D auto_146,"var",auto_147
-D auto_147,"var",auto_125
-D auto_148,"name",auto_149
-D auto_148,"next_param",auto_135
-D auto_148,"value",auto_150
+D auto_14,"var",auto_37
+D auto_140,"var",auto_141
+D auto_142,"name",auto_143
+D auto_142,"next_param",auto_128
+D auto_142,"value",auto_144
+D auto_144,"var",auto_145
+D auto_145,"var",auto_25
+D auto_146,"name",auto_147
+D auto_146,"next_param",auto_123
+D auto_146,"value",auto_148
+D auto_148,"func",auto_149
+D auto_148,"last_param",auto_151
+D auto_148,"params",auto_164
+D auto_149,"var",auto_150
 D auto_15,"next",auto_16
-D auto_15,"value",auto_28
-D auto_15,"var",auto_30
-D auto_150,"var",auto_151
-D auto_151,"var",auto_23
-D auto_152,"name",auto_153
-D auto_152,"next_param",auto_102
-D auto_152,"value",auto_154
+D auto_15,"value",auto_32
+D auto_15,"var",auto_36
+D auto_150,"var",auto_37
+D auto_151,"name",auto_152
+D auto_151,"value",auto_153
+D auto_153,"func",auto_154
+D auto_153,"last_param",auto_156
+D auto_153,"params",auto_160
 D auto_154,"var",auto_155
-D auto_155,"var",auto_23
-D auto_156,"func",auto_157
-D auto_156,"last_param",auto_159
-D auto_156,"params",auto_159
-D auto_157,"var",auto_158
-D auto_158,"var",auto_43
-D auto_159,"name",auto_160
-D auto_159,"value",auto_161
+D auto_155,"var",auto_43
+D auto_156,"name",auto_157
+D auto_156,"value",auto_158
+D auto_158,"node",auto_159
 D auto_16,"next",auto_17
-D auto_16,"var",auto_27
-D auto_161,"var",auto_162
-D auto_162,"var",auto_23
-D auto_163,"var",auto_125
-D auto_164,"func",auto_165
-D auto_164,"last_param",auto_167
-D auto_164,"params",auto_176
-D auto_165,"var",auto_166
-D auto_166,"var",auto_47
-D auto_167,"name",auto_168
-D auto_167,"value",auto_169
-D auto_169,"func",auto_170
-D auto_169,"last_param",auto_172
-D auto_169,"params",auto_172
+D auto_16,"var",auto_31
+D auto_160,"name",auto_161
+D auto_160,"next_param",auto_156
+D auto_160,"value",auto_162
+D auto_162,"var",auto_163
+D auto_163,"var",auto_141
+D auto_164,"name",auto_165
+D auto_164,"next_param",auto_151
+D auto_164,"value",auto_166
+D auto_166,"var",auto_167
+D auto_167,"var",auto_25
+D auto_168,"name",auto_169
+D auto_168,"next_param",auto_118
+D auto_168,"value",auto_170
 D auto_17,"next",auto_18
-D auto_17,"value",auto_24
-D auto_17,"var",auto_26
+D auto_17,"value",auto_26
+D auto_17,"var",auto_30
 D auto_170,"var",auto_171
-D auto_171,"var",auto_43
-D auto_172,"name",auto_173
-D auto_172,"value",auto_174
-D auto_174,"var",auto_175
-D auto_175,"var",auto_23
-D auto_176,"name",auto_177
-D auto_176,"next_param",auto_167
-D auto_176,"value",auto_178
-D auto_178,"var",auto_179
-D auto_179,"var",auto_180
+D auto_171,"var",auto_25
+D auto_172,"func",auto_173
+D auto_172,"last_param",auto_175
+D auto_172,"params",auto_175
+D auto_173,"var",auto_174
+D auto_174,"var",auto_55
+D auto_175,"name",auto_176
+D auto_175,"value",auto_177
+D auto_177,"var",auto_178
+D auto_178,"var",auto_25
+D auto_179,"var",auto_141
 D auto_18,"next",auto_19
-D auto_18,"var",auto_23
-D auto_180,"name",auto_181
-D auto_182,"value",auto_183
-D auto_183,"func",auto_184
-D auto_183,"last_param",auto_186
-D auto_183,"params",auto_199
-D auto_184,"var",auto_185
-D auto_185,"var",auto_31
-D auto_186,"name",auto_187
-D auto_186,"value",auto_188
-D auto_188,"func",auto_189
-D auto_188,"last_param",auto_191
-D auto_188,"params",auto_195
-D auto_189,"var",auto_190
+D auto_18,"var",auto_25
+D auto_180,"func",auto_181
+D auto_180,"last_param",auto_183
+D auto_180,"params",auto_192
+D auto_181,"var",auto_182
+D auto_182,"var",auto_61
+D auto_183,"name",auto_184
+D auto_183,"value",auto_185
+D auto_185,"func",auto_186
+D auto_185,"last_param",auto_188
+D auto_185,"params",auto_188
+D auto_186,"var",auto_187
+D auto_187,"var",auto_55
+D auto_188,"name",auto_189
+D auto_188,"value",auto_190
 D auto_19,"value",auto_20
-D auto_19,"var",auto_22
-D auto_190,"var",auto_35
-D auto_191,"name",auto_192
-D auto_191,"value",auto_193
-D auto_193,"node",auto_194
-D auto_195,"name",auto_196
-D auto_195,"next_param",auto_191
-D auto_195,"value",auto_197
-D auto_197,"var",auto_198
-D auto_198,"var",auto_180
-D auto_199,"name",auto_200
-D auto_199,"next_param",auto_186
-D auto_199,"value",auto_201
+D auto_19,"var",auto_24
+D auto_190,"var",auto_191
+D auto_191,"var",auto_25
+D auto_192,"name",auto_193
+D auto_192,"next_param",auto_183
+D auto_192,"value",auto_194
+D auto_194,"var",auto_195
+D auto_195,"var",auto_196
+D auto_196,"name",auto_197
+D auto_198,"value",auto_199
+D auto_199,"func",auto_200
+D auto_199,"last_param",auto_202
+D auto_199,"params",auto_215
 D auto_2,"next",auto_3
-D auto_2,"var",auto_93
-D auto_20,"node",auto_21
-D auto_201,"var",auto_202
-D auto_202,"var",auto_23
-D auto_203,"a",auto_180
-D auto_204,"var",auto_74
+D auto_2,"var",auto_109
+D auto_20,"func",auto_21
+D auto_200,"var",auto_201
+D auto_201,"var",auto_37
+D auto_202,"name",auto_203
+D auto_202,"value",auto_204
+D auto_204,"func",auto_205
+D auto_204,"last_param",auto_207
+D auto_204,"params",auto_211
+D auto_205,"var",auto_206
+D auto_206,"var",auto_43
+D auto_207,"name",auto_208
+D auto_207,"value",auto_209
+D auto_209,"node",auto_210
+D auto_21,"var",auto_22
+D auto_211,"name",auto_212
+D auto_211,"next_param",auto_207
+D auto_211,"value",auto_213
+D auto_213,"var",auto_214
+D auto_214,"var",auto_196
+D auto_215,"name",auto_216
+D auto_215,"next_param",auto_202
+D auto_215,"value",auto_217
+D auto_217,"var",auto_218
+D auto_218,"var",auto_25
+D auto_219,"a",auto_196
 D auto_22,"var",auto_23
-D auto_24,"node",auto_25
-D auto_26,"var",auto_27
-D auto_28,"node",auto_29
+D auto_220,"var",auto_90
+D auto_24,"var",auto_25
+D auto_26,"func",auto_27
+D auto_27,"var",auto_28
+D auto_28,"var",auto_29
 D auto_3,"next",auto_4
-D auto_3,"value",auto_52
-D auto_3,"var",auto_92
+D auto_3,"value",auto_68
+D auto_3,"var",auto_108
 D auto_30,"var",auto_31
-D auto_32,"node",auto_33
+D auto_32,"func",auto_33
+D auto_33,"var",auto_34
 D auto_34,"var",auto_35
-D auto_36,"node",auto_37
-D auto_38,"var",auto_39
+D auto_36,"var",auto_37
+D auto_38,"func",auto_39
+D auto_39,"var",auto_40
 D auto_4,"next",auto_5
-D auto_4,"var",auto_51
-D auto_40,"node",auto_41
+D auto_4,"var",auto_67
+D auto_40,"var",auto_41
 D auto_42,"var",auto_43
-D auto_44,"node",auto_45
+D auto_44,"func",auto_45
+D auto_45,"var",auto_46
 D auto_46,"var",auto_47
-D auto_48,"node",auto_49
+D auto_48,"var",auto_49
 D auto_5,"next",auto_6
-D auto_5,"value",auto_48
-D auto_5,"var",auto_50
-D auto_50,"var",auto_51
-D auto_52,"node",auto_53
-D auto_53,"body",auto_54
-D auto_54,"next",auto_55
-D auto_54,"value",auto_88
-D auto_54,"var",auto_91
-D auto_55,"func",auto_56
-D auto_55,"last_param",auto_58
-D auto_55,"next",auto_62
-D auto_55,"params",auto_84
-D auto_56,"var",auto_57
-D auto_57,"var",auto_39
-D auto_58,"name",auto_59
-D auto_58,"value",auto_60
+D auto_5,"value",auto_62
+D auto_5,"var",auto_66
+D auto_50,"func",auto_51
+D auto_51,"var",auto_52
+D auto_52,"var",auto_53
+D auto_54,"var",auto_55
+D auto_56,"func",auto_57
+D auto_57,"var",auto_58
+D auto_58,"var",auto_59
 D auto_6,"next",auto_7
-D auto_6,"var",auto_47
-D auto_60,"node",auto_61
+D auto_6,"var",auto_61
+D auto_60,"var",auto_61
 D auto_62,"func",auto_63
-D auto_62,"last_param",auto_65
-D auto_62,"next",auto_69
-D auto_62,"params",auto_80
 D auto_63,"var",auto_64
-D auto_64,"var",auto_39
-D auto_65,"name",auto_66
-D auto_65,"value",auto_67
-D auto_67,"node",auto_68
+D auto_64,"var",auto_65
+D auto_66,"var",auto_67
+D auto_68,"node",auto_69
 D auto_69,"body",auto_70
-D auto_69,"cond",auto_78
 D auto_7,"next",auto_8
-D auto_7,"value",auto_44
-D auto_7,"var",auto_46
-D auto_70,"value",auto_71
+D auto_7,"value",auto_56
+D auto_7,"var",auto_60
+D auto_70,"next",auto_71
+D auto_70,"value",auto_104
+D auto_70,"var",auto_107
 D auto_71,"func",auto_72
-D auto_71,"last_param",auto_75
-D auto_71,"params",auto_75
+D auto_71,"last_param",auto_74
+D auto_71,"next",auto_78
+D auto_71,"params",auto_100
 D auto_72,"var",auto_73
-D auto_73,"var",auto_74
-D auto_75,"name",auto_76
-D auto_75,"value",auto_77
-D auto_78,"node",auto_79
+D auto_73,"var",auto_49
+D auto_74,"name",auto_75
+D auto_74,"value",auto_76
+D auto_76,"node",auto_77
+D auto_78,"func",auto_79
+D auto_78,"last_param",auto_81
+D auto_78,"next",auto_85
+D auto_78,"params",auto_96
+D auto_79,"var",auto_80
 D auto_8,"next",auto_9
-D auto_8,"var",auto_43
-D auto_80,"name",auto_81
-D auto_80,"next_param",auto_65
-D auto_80,"value",auto_82
-D auto_82,"var",auto_83
-D auto_83,"var",auto_23
-D auto_84,"name",auto_85
-D auto_84,"next_param",auto_58
-D auto_84,"value",auto_86
-D auto_86,"var",auto_87
-D auto_87,"var",auto_23
-D auto_88,"func",auto_89
+D auto_8,"var",auto_55
+D auto_80,"var",auto_49
+D auto_81,"name",auto_82
+D auto_81,"value",auto_83
+D auto_83,"node",auto_84
+D auto_85,"body",auto_86
+D auto_85,"cond",auto_94
+D auto_86,"value",auto_87
+D auto_87,"func",auto_88
+D auto_87,"last_param",auto_91
+D auto_87,"params",auto_91
+D auto_88,"var",auto_89
 D auto_89,"var",auto_90
 D auto_9,"next",auto_10
-D auto_9,"value",auto_40
-D auto_9,"var",auto_42
-D auto_90,"var",auto_27
-D auto_91,"var",auto_23
-D auto_92,"var",auto_93
+D auto_9,"value",auto_50
+D auto_9,"var",auto_54
+D auto_91,"name",auto_92
+D auto_91,"value",auto_93
 D auto_94,"node",auto_95
-D auto_95,"body",auto_96
-D auto_95,"params",auto_203
-D auto_96,"next",auto_97
-D auto_96,"var",auto_125
-D auto_97,"body",auto_98
-D auto_97,"cond",auto_164
-D auto_97,"next",auto_182
-D auto_98,"next",auto_99
-D auto_98,"value",auto_156
-D auto_98,"var",auto_163
-D auto_99,"func",auto_100
-D auto_99,"last_param",auto_102
-D auto_99,"params",auto_152
+D auto_96,"name",auto_97
+D auto_96,"next_param",auto_81
+D auto_96,"value",auto_98
+D auto_98,"var",auto_99
+D auto_99,"var",auto_25

+ 19 - 21
interface/HUTN/test/graph_compilation_action_language/expected/global

@@ -1,35 +1,33 @@
 V auto_initial_IP(global)
 V auto_1(assign)
-V auto_10("a")
-V auto_11(constant)
-N auto_12
-V auto_13(declare)
-N auto_14
-V auto_15(resolve)
-V auto_16("abc")
+V auto_10(constant)
+N auto_11
+V auto_12(declare)
+N auto_13
+V auto_14(resolve)
+V auto_15("abc")
 V auto_2(global)
 V auto_3(assign)
 V auto_4(global)
 V auto_5("b")
 V auto_6(constant)
-V auto_7(constant)
-V auto_8(1)
-V auto_9(resolve)
+V auto_7(1)
+V auto_8(resolve)
+V auto_9("a")
 D auto_initial_IP,"next",auto_1
-D auto_initial_IP,"var",auto_16
+D auto_initial_IP,"var",auto_15
 D auto_1,"next",auto_2
-D auto_1,"value",auto_11
-D auto_1,"var",auto_15
-D auto_11,"node",auto_12
-D auto_12,"body",auto_13
-D auto_13,"var",auto_14
-D auto_15,"var",auto_16
+D auto_1,"value",auto_10
+D auto_1,"var",auto_14
+D auto_10,"node",auto_11
+D auto_11,"body",auto_12
+D auto_12,"var",auto_13
+D auto_14,"var",auto_15
 D auto_2,"next",auto_3
-D auto_2,"var",auto_10
+D auto_2,"var",auto_9
 D auto_3,"next",auto_4
 D auto_3,"value",auto_6
-D auto_3,"var",auto_9
+D auto_3,"var",auto_8
 D auto_4,"var",auto_5
 D auto_6,"node",auto_7
-D auto_7,"node",auto_8
-D auto_9,"var",auto_10
+D auto_8,"var",auto_9

+ 92 - 76
interface/HUTN/test/graph_compilation_action_language/expected/include

@@ -1,112 +1,128 @@
 V auto_initial_IP(global)
 V auto_1(assign)
-V auto_10(constant)
-N auto_11
+V auto_10(call)
+V auto_11(access)
 V auto_12(resolve)
-V auto_13("float_subtraction")
-V auto_14(constant)
-N auto_15
-V auto_16(resolve)
-V auto_17("float_addition")
-V auto_18(constant)
-N auto_19
+V auto_13("create_node")
+V auto_14(resolve)
+V auto_15("float_subtraction")
+V auto_16(call)
+V auto_17(access)
+V auto_18(resolve)
+V auto_19("create_node")
 V auto_2(global)
 V auto_20(resolve)
-V auto_21("integer_subtraction")
-V auto_22(constant)
-N auto_23
+V auto_21("float_addition")
+V auto_22(call)
+V auto_23(access)
 V auto_24(resolve)
-V auto_25("integer_addition")
-V auto_26(constant)
-N auto_27
+V auto_25("create_node")
+V auto_26(resolve)
+V auto_27("integer_subtraction")
 V auto_28(call)
 V auto_29(access)
 V auto_3(assign)
 V auto_30(resolve)
-N auto_31
-V auto_32("b")
-V auto_33(constant)
-V auto_34(2)
-V auto_35(call)
-V auto_36(access)
-V auto_37(resolve)
-N auto_38
-V auto_39("b")
+V auto_31("create_node")
+V auto_32(resolve)
+V auto_33("integer_addition")
+V auto_34(constant)
+N auto_35
+V auto_36(call)
+V auto_37(access)
+V auto_38(resolve)
+N auto_39
 V auto_4(global)
-V auto_40(constant)
-V auto_41(4)
-N auto_42
-V auto_43("a")
-V auto_44(constant)
-V auto_45(3)
+V auto_40("b")
+V auto_41(constant)
+V auto_42(2)
+V auto_43(call)
+V auto_44(access)
+V auto_45(resolve)
 N auto_46
-V auto_47("a")
+V auto_47("b")
 V auto_48(constant)
-V auto_49(1)
+V auto_49(4)
 V auto_5(assign)
-V auto_50(resolve)
-V auto_51("main")
+N auto_50
+V auto_51("a")
+V auto_52(constant)
+V auto_53(3)
+N auto_54
+V auto_55("a")
+V auto_56(constant)
+V auto_57(1)
+V auto_58(resolve)
+V auto_59("main")
 V auto_6(global)
 V auto_7(assign)
 V auto_8(global)
 V auto_9(assign)
 D auto_initial_IP,"next",auto_1
-D auto_initial_IP,"var",auto_51
+D auto_initial_IP,"var",auto_59
 D auto_1,"next",auto_2
-D auto_1,"value",auto_26
-D auto_1,"var",auto_50
-D auto_10,"node",auto_11
+D auto_1,"value",auto_34
+D auto_1,"var",auto_58
+D auto_10,"func",auto_11
+D auto_11,"var",auto_12
 D auto_12,"var",auto_13
-D auto_14,"node",auto_15
-D auto_16,"var",auto_17
-D auto_18,"node",auto_19
+D auto_14,"var",auto_15
+D auto_16,"func",auto_17
+D auto_17,"var",auto_18
+D auto_18,"var",auto_19
 D auto_2,"next",auto_3
-D auto_2,"var",auto_25
+D auto_2,"var",auto_33
 D auto_20,"var",auto_21
-D auto_22,"node",auto_23
+D auto_22,"func",auto_23
+D auto_23,"var",auto_24
 D auto_24,"var",auto_25
-D auto_26,"node",auto_27
-D auto_27,"body",auto_28
+D auto_26,"var",auto_27
 D auto_28,"func",auto_29
-D auto_28,"last_param",auto_31
-D auto_28,"next",auto_35
-D auto_28,"params",auto_46
 D auto_29,"var",auto_30
 D auto_3,"next",auto_4
-D auto_3,"value",auto_22
-D auto_3,"var",auto_24
-D auto_30,"var",auto_25
-D auto_31,"name",auto_32
-D auto_31,"value",auto_33
-D auto_33,"node",auto_34
-D auto_35,"func",auto_36
-D auto_35,"last_param",auto_38
-D auto_35,"params",auto_42
-D auto_36,"var",auto_37
-D auto_37,"var",auto_17
-D auto_38,"name",auto_39
-D auto_38,"value",auto_40
+D auto_3,"value",auto_28
+D auto_3,"var",auto_32
+D auto_30,"var",auto_31
+D auto_32,"var",auto_33
+D auto_34,"node",auto_35
+D auto_35,"body",auto_36
+D auto_36,"func",auto_37
+D auto_36,"last_param",auto_39
+D auto_36,"next",auto_43
+D auto_36,"params",auto_54
+D auto_37,"var",auto_38
+D auto_38,"var",auto_33
+D auto_39,"name",auto_40
+D auto_39,"value",auto_41
 D auto_4,"next",auto_5
-D auto_4,"var",auto_21
-D auto_40,"node",auto_41
-D auto_42,"name",auto_43
-D auto_42,"next_param",auto_38
-D auto_42,"value",auto_44
-D auto_44,"node",auto_45
+D auto_4,"var",auto_27
+D auto_41,"node",auto_42
+D auto_43,"func",auto_44
+D auto_43,"last_param",auto_46
+D auto_43,"params",auto_50
+D auto_44,"var",auto_45
+D auto_45,"var",auto_21
 D auto_46,"name",auto_47
-D auto_46,"next_param",auto_31
 D auto_46,"value",auto_48
 D auto_48,"node",auto_49
 D auto_5,"next",auto_6
-D auto_5,"value",auto_18
-D auto_5,"var",auto_20
-D auto_50,"var",auto_51
+D auto_5,"value",auto_22
+D auto_5,"var",auto_26
+D auto_50,"name",auto_51
+D auto_50,"next_param",auto_46
+D auto_50,"value",auto_52
+D auto_52,"node",auto_53
+D auto_54,"name",auto_55
+D auto_54,"next_param",auto_39
+D auto_54,"value",auto_56
+D auto_56,"node",auto_57
+D auto_58,"var",auto_59
 D auto_6,"next",auto_7
-D auto_6,"var",auto_17
+D auto_6,"var",auto_21
 D auto_7,"next",auto_8
-D auto_7,"value",auto_14
-D auto_7,"var",auto_16
+D auto_7,"value",auto_16
+D auto_7,"var",auto_20
 D auto_8,"next",auto_9
-D auto_8,"var",auto_13
+D auto_8,"var",auto_15
 D auto_9,"value",auto_10
-D auto_9,"var",auto_12
+D auto_9,"var",auto_14

+ 7 - 0
interface/HUTN/test/graph_compilation_action_language/util.py

@@ -0,0 +1,7 @@
+import os
+
+def get_code_path(filename):
+    return os.path.abspath(os.path.dirname(__file__)) + os.sep + "code" + os.sep + filename
+
+def get_expected_path(filename):
+    return os.path.abspath(os.path.dirname(__file__)) + os.sep + "expected" + os.sep + filename.rsplit(".", 1)[0]

+ 19 - 0
interface/HUTN/test/modelling_language/code/my_petrinet.mvc

@@ -0,0 +1,19 @@
+import models/PetriNets as PetriNets
+
+PetriNets my_petrinet {
+    Place p1 {
+        tokens = 1
+    }
+    Place p2 {
+        tokens = 3
+    }
+    Transition t1 {}
+    P2T (p1, t1) {
+        weight = 1
+    }
+    T2P (t1, p2) {
+        weight = 2
+    }
+}
+
+export my_petrinet to models/my_petrinet

+ 33 - 0
interface/HUTN/test/modelling_language/code/my_petrinet_with_MM.mvc

@@ -0,0 +1,33 @@
+import models/SimpleClassDiagrams as SCD
+
+SCD PetriNets{
+    Class Natural {}
+    Class Place{
+        tokens : Natural
+    }
+    Class Transition{}
+    Association P2T (Place, Transition) {
+        weight : Natural
+    }
+    Association T2P (Transition, Place) {
+        weight : Natural
+    }
+}
+
+PetriNets my_petrinet {
+    Place p1 {
+        tokens = 1
+    }
+    Place p2 {
+        tokens = 3
+    }
+    Transition t1 {}
+    P2T (p1, t1) {
+        weight = 1
+    }
+    T2P (t1, p2) {
+        weight = 2
+    }
+}
+
+export my_petrinet to models/my_petrinet

+ 17 - 0
interface/HUTN/test/modelling_language/code/petrinets.mvc

@@ -0,0 +1,17 @@
+import models/SimpleClassDiagrams as SCD
+
+SCD PetriNets{
+    Class Natural {}
+    Class Place{
+        tokens : Natural
+    }
+    Class Transition{}
+    Association P2T (Place, Transition) {
+        weight : Natural
+    }
+    Association T2P (Transition, Place) {
+        weight : Natural
+    }
+}
+
+export PetriNets to models/PetriNets

+ 27 - 0
interface/HUTN/test/modelling_language/code/petrinets_constraints.mvc

@@ -0,0 +1,27 @@
+import models/SimpleClassDiagrams as SCD
+include "primitives.alh"
+
+SCD PetriNets{
+    Class Natural {
+        $
+            if (bool_not(is_physical_int(self))):
+                return "Natural has no integer value"
+            elif (integer_lt(self, 0)):
+                return "Natural does not have a positive or zero value"
+            else:
+                return "OK"
+         $
+    }
+    Class Place{
+        tokens : Natural
+    }
+    Class Transition{}
+    Association P2T (Place, Transition) {
+        weight : Natural
+    }
+    Association T2P (Transition, Place) {
+        weight : Natural
+    }
+}
+
+export PetriNets to models/PetriNets

+ 21 - 0
interface/HUTN/test/modelling_language/code/simpleclassdiagrams.mvc

@@ -0,0 +1,21 @@
+import /formalisms/SimpleClassDiagrams as SCD
+
+SCD SimpleClassDiagrams{
+    Class Any {}
+    Class Natural {}
+    Class String {}
+    Class Class{
+        lower_cardinality : Natural
+        upper_cardinality : Natural
+    }
+    Association Association (Class, Class){
+        name : String
+        source_lower_cardinality : Natural
+        source_upper_cardinality : Natural
+        target_lower_cardinality : Natural
+        target_upper_cardinality : Natural
+    }
+    Association Inheritance (Class, Class){}
+    Inheritance assoc_inh_class (Association, Class) {}
+    Inheritance class_inh_any (Class, Any) {}
+}

Разница между файлами не показана из-за своего большого размера
+ 1 - 0
interface/HUTN/test/modelling_language/expected/my_petrinet


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
interface/HUTN/test/modelling_language/expected/my_petrinet_with_MM


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
interface/HUTN/test/modelling_language/expected/petrinets


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
interface/HUTN/test/modelling_language/expected/petrinets_constraints


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
interface/HUTN/test/modelling_language/expected/simpleclassdiagrams


+ 33 - 0
interface/HUTN/test/modelling_language/test_compile.py

@@ -0,0 +1,33 @@
+import unittest
+import util
+
+from hutn_compiler.compiler import main
+import json
+
+def compile_file(obj, filename):
+    result = main(util.get_code_path(filename), "grammars/modelling.g", "M", [])
+    try:
+        expected = json.loads(open(util.get_expected_path(filename)).read())
+    except:
+        #f = open(util.get_expected_path(filename), 'w')
+        #f.write(json.dumps(result))
+        #f.close()
+        pass
+    assert result == expected
+
+class TestCompile(unittest.TestCase):
+    def test_PetriNets(self):
+        compile_file(self, "petrinets.mvc")
+
+    def test_PetriNetsInstance(self):
+        compile_file(self, "my_petrinet.mvc")
+
+    def test_SimpleClassDiagrams(self):
+        compile_file(self, "simpleclassdiagrams.mvc")
+
+    def test_PetriNetsBoth(self):
+        compile_file(self, "my_petrinet_with_MM.mvc")
+
+    def test_PetriNets_constraints(self):
+        compile_file(self, "petrinets_constraints.mvc")
+

+ 7 - 0
interface/HUTN/test/modelling_language/util.py

@@ -0,0 +1,7 @@
+import os
+
+def get_code_path(filename):
+    return os.path.abspath(os.path.dirname(__file__)) + os.sep + "code" + os.sep + filename
+
+def get_expected_path(filename):
+    return os.path.abspath(os.path.dirname(__file__)) + os.sep + "expected" + os.sep + filename.rsplit(".", 1)[0]

+ 1 - 1
interface/HUTN/test/util.py

@@ -4,4 +4,4 @@ def get_code_path(filename):
     return os.path.abspath(os.path.dirname(__file__)) + os.sep + "code" + os.sep + filename
 
 def get_expected_path(filename):
-    return os.path.abspath(os.path.dirname(__file__)) + os.sep + "expected" + os.sep + filename[:-3]
+    return os.path.abspath(os.path.dirname(__file__)) + os.sep + "expected" + os.sep + filename.rsplit(".", 1)[0]

+ 56 - 0
kernel/modelverse_kernel/compiled.py

@@ -418,3 +418,59 @@ def check_symbols(a, b, c, **remainder):
 
     result, = yield [("CNV", ["OK"])]
     raise PrimitiveFinished(result)
+
+def construct_const(**remainder):
+    v, = yield [("CNV", [{"value": "constant"}])]
+
+    # Get input: keep trying until we get something
+    try:
+        gen = __get_input(remainder)
+        inp = None
+        while 1:
+            inp = yield gen.send(inp)
+    except PrimitiveFinished as e:
+        inp = e.result
+
+    yield [("CD", [v, "node", inp])]
+
+    raise PrimitiveFinished(v)
+
+def instantiated_name(a, b, **remainder):
+    name_value, = yield [("RV", [b])]
+    if name_value == "":
+        b, = yield [("CNV", ["__" + str(a)])]
+    raise PrimitiveFinished(b)
+
+def retype(a, b, c, **remainder):
+    tm, =       yield [("RD", [a, "type_mapping"])]
+    m, =        yield [("RD", [a, "model"])]
+    mm, =       yield [("RD", [a, "metamodel"])]
+    mm_dict, =  yield [("RD", [mm, "model"])]
+    c_val, =    yield [("RV", [c])]
+    mm_ref, =   yield [("RD", [mm_dict, c_val])]
+    b_val, =    yield [("RV", [b])]
+    m_ref, =    yield [("RD", [m, b_val])]
+    prev_edge, = yield [("RDNE", [tm, m_ref])]
+    if prev_edge is not None:
+        yield [("DE", [prev_edge])]
+    t, =        yield [("CE", [tm, mm_ref])]
+    yield [("CE", [t, m_ref])]
+    raise PrimitiveFinished(None)
+
+def __get_input(parameters):
+    mvk = parameters["mvk"]
+    user_root = parameters["user_root"]
+    while 1:
+        try:
+            gen = mvk.input_init(user_root)
+            inp = None
+            while 1:
+                inp = yield gen.send(inp)
+        except StopIteration:
+            # Finished
+            if mvk.success:
+                # Got some input, so we can access it
+                raise PrimitiveFinished(mvk.input_value)
+            else:
+                # No input, so yield None but don't stop
+                yield None

+ 4 - 0
kernel/modelverse_kernel/main.py

@@ -113,6 +113,7 @@ class ModelverseKernel(object):
         parameters["root"] = self.root
         parameters["user_root"] = user_root
         parameters["username"] = username
+        parameters["mvk"] = self
 
         # prim is a generator itself!
         try:
@@ -420,6 +421,7 @@ class ModelverseKernel(object):
                                    ("CNV", ["finish"]),
                                   ]
             if variable is None:
+                print("READ " + str(var))
                 raise Exception("%s: not found as global: %s" % (self.debug_info, var_name))
 
             # Resolved a global, so this is a string
@@ -885,8 +887,10 @@ class ModelverseKernel(object):
                                ("DE", [returnvalue_link]),
                                ("DE", [phase_link]),
                               ]
+            self.input_value = value
         else:
             # No input yet, so just wait and don't advance IP or phase
+            self.input_value = None
             self.success = False
 
     def output_init(self, user_root):

+ 1 - 1
kernel/modelverse_kernel/primitives.py

@@ -70,7 +70,7 @@ def float_multiplication(a, b, **remainder):
 
 def float_division(a, b, **remainder):
     a_value, b_value =  yield [("RV", [a]), ("RV", [b])]
-    result, = yield [("CNV", [a_value / b_value])]
+    result, = yield [("CNV", [float(a_value) / float(b_value)])]
     raise PrimitiveFinished(result)
 
 def float_gt(a, b, **remainder):

+ 120 - 0
kernel/test/functions/utils.py

@@ -0,0 +1,120 @@
+import sys
+sys.path.append("../state")
+from modelverse_state.main import ModelverseState
+import json
+
+class MvSWrapper(object):
+    def __init__(self):
+        self.mvs = ModelverseState("../bootstrap/minimal.m")
+
+        self.mapping = {
+                   "RD": self.mvs.read_dict,
+                   "RR": self.mvs.read_root,
+                   "RO": self.mvs.read_outgoing,
+                   "RI": self.mvs.read_incoming,
+                   "RE": self.mvs.read_edge,
+                   "RDE": self.mvs.read_dict_edge,
+                   "RDK": self.mvs.read_dict_keys,
+                   "RDN": self.mvs.read_dict_node,
+                   "RDNE": self.mvs.read_dict_node_edge,
+                   "RRD": self.mvs.read_reverse_dict,
+                   "RV": self.mvs.read_value,
+                   "CN": self.mvs.create_node,
+                   "CNV": self.mvs.create_nodevalue,
+                   "CE": self.mvs.create_edge,
+                   "DE": self.mvs.delete_edge,
+                   "DN": self.mvs.delete_node,
+                   "CD": self.mvs.create_dict,
+                  }
+
+    def execute(self, command, params):
+        params = json.loads(json.dumps(params))
+        retval = self.mapping[command](*params)
+        retval = json.loads(json.dumps(retval))
+
+        return [retval[0]]
+
+def add_new_user(root, mvs, username):
+    hierarchy = mvs.execute("RD", [root, "__hierarchy"])[0]
+    initial = mvs.execute("RD", [hierarchy, "__IP"])[0]
+
+    user_root = mvs.execute("CN", [])[0]
+    _globals = mvs.execute("CN", [])[0]
+    frame = mvs.execute("CN", [])[0]
+    evalstack = mvs.execute("CN", [])[0]
+    symbols = mvs.execute("CN", [])[0]
+    _input = mvs.execute("CN", [])[0]
+    _output = mvs.execute("CN", [])[0]
+    returnvalue = mvs.execute("CN", [])[0]
+    phase = mvs.execute("CNV", ["init"])[0]
+
+    mvs.execute("CD", [root, username, user_root])
+    mvs.execute("CD", [user_root, "frame", frame])
+    mvs.execute("CD", [user_root, "globals", _globals])
+    mvs.execute("CD", [user_root, "input", _input])
+    mvs.execute("CD", [user_root, "last_input", _input])
+    mvs.execute("CD", [user_root, "output", _output])
+    mvs.execute("CD", [user_root, "last_output", _output])
+    mvs.execute("CD", [frame, "evalstack", evalstack])
+    mvs.execute("CD", [frame, "returnvalue", returnvalue])
+    mvs.execute("CD", [frame, "phase", phase])
+    mvs.execute("CD", [frame, "IP", initial])
+    mvs.execute("CD", [frame, "symbols", symbols])
+
+def execute_until_finished(mvk, mvs, operation="execute_rule", params=[]):
+    username = "user_1"
+    if operation == "initialize_new_user":
+        return add_new_user(mvk.root, mvs, username)
+    response = None
+    while 1:
+        mvs_commands = mvk.execute_yields(username, operation, params, response)
+        if mvs_commands is None:
+            break
+        response = []
+        for command, param in mvs_commands:
+            response.append(mvs.execute(command, param)[0])
+
+def get_inst(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    inst = mvs.execute("RD", [user_frame, "IP"])[0]
+    return mvs.execute("RV", [inst])[0]["value"]
+
+def get_phase(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    phase = mvs.execute("RD", [user_frame, "phase"])[0]
+    return mvs.execute("RV", [phase])[0]
+
+def get_returnvalue(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    returnvalue = mvs.execute("RD", [user_frame, "returnvalue"])[0]
+    return mvs.execute("RV", [returnvalue])[0]
+
+def get_inst_ref(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    return mvs.execute("RD", [user_frame, "IP"])[0]
+
+def get_returnvalue_ref(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    return mvs.execute("RD", [user_frame, "returnvalue"])[0]
+
+def get_phase_ref(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    phase = mvs.execute("RD", [user_frame, "phase"])[0]
+    return phase
+
+def read_primitive_interfaces(root, mvs):
+    hierarchy = mvs.execute("RD", [root, "__hierarchy"])[0]
+    primitives = mvs.execute("RD", [hierarchy, "primitives"])[0]
+    keys = mvs.execute("RDK", [primitives])[0]
+    d = {}
+    for k in keys:
+        value = mvs.execute("RDN", [primitives, k])[0]
+        name = mvs.execute("RV", [k])[0]
+        d[name] = value
+    return d

+ 120 - 0
kernel/test/instructions/utils.py

@@ -0,0 +1,120 @@
+import sys
+sys.path.append("../state")
+from modelverse_state.main import ModelverseState
+import json
+
+class MvSWrapper(object):
+    def __init__(self):
+        self.mvs = ModelverseState("../bootstrap/minimal.m")
+
+        self.mapping = {
+                   "RD": self.mvs.read_dict,
+                   "RR": self.mvs.read_root,
+                   "RO": self.mvs.read_outgoing,
+                   "RI": self.mvs.read_incoming,
+                   "RE": self.mvs.read_edge,
+                   "RDE": self.mvs.read_dict_edge,
+                   "RDK": self.mvs.read_dict_keys,
+                   "RDN": self.mvs.read_dict_node,
+                   "RDNE": self.mvs.read_dict_node_edge,
+                   "RRD": self.mvs.read_reverse_dict,
+                   "RV": self.mvs.read_value,
+                   "CN": self.mvs.create_node,
+                   "CNV": self.mvs.create_nodevalue,
+                   "CE": self.mvs.create_edge,
+                   "DE": self.mvs.delete_edge,
+                   "DN": self.mvs.delete_node,
+                   "CD": self.mvs.create_dict,
+                  }
+
+    def execute(self, command, params):
+        params = json.loads(json.dumps(params))
+        retval = self.mapping[command](*params)
+        retval = json.loads(json.dumps(retval))
+
+        return [retval[0]]
+
+def add_new_user(root, mvs, username):
+    hierarchy = mvs.execute("RD", [root, "__hierarchy"])[0]
+    initial = mvs.execute("RD", [hierarchy, "__IP"])[0]
+
+    user_root = mvs.execute("CN", [])[0]
+    _globals = mvs.execute("CN", [])[0]
+    frame = mvs.execute("CN", [])[0]
+    evalstack = mvs.execute("CN", [])[0]
+    symbols = mvs.execute("CN", [])[0]
+    _input = mvs.execute("CN", [])[0]
+    _output = mvs.execute("CN", [])[0]
+    returnvalue = mvs.execute("CN", [])[0]
+    phase = mvs.execute("CNV", ["init"])[0]
+
+    mvs.execute("CD", [root, username, user_root])
+    mvs.execute("CD", [user_root, "frame", frame])
+    mvs.execute("CD", [user_root, "globals", _globals])
+    mvs.execute("CD", [user_root, "input", _input])
+    mvs.execute("CD", [user_root, "last_input", _input])
+    mvs.execute("CD", [user_root, "output", _output])
+    mvs.execute("CD", [user_root, "last_output", _output])
+    mvs.execute("CD", [frame, "evalstack", evalstack])
+    mvs.execute("CD", [frame, "returnvalue", returnvalue])
+    mvs.execute("CD", [frame, "phase", phase])
+    mvs.execute("CD", [frame, "IP", initial])
+    mvs.execute("CD", [frame, "symbols", symbols])
+
+def execute_until_finished(mvk, mvs, operation="execute_rule", params=[]):
+    username = "user_1"
+    if operation == "initialize_new_user":
+        return add_new_user(mvk.root, mvs, username)
+    response = None
+    while 1:
+        mvs_commands = mvk.execute_yields(username, operation, params, response)
+        if mvs_commands is None:
+            break
+        response = []
+        for command, param in mvs_commands:
+            response.append(mvs.execute(command, param)[0])
+
+def get_inst(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    inst = mvs.execute("RD", [user_frame, "IP"])[0]
+    return mvs.execute("RV", [inst])[0]["value"]
+
+def get_phase(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    phase = mvs.execute("RD", [user_frame, "phase"])[0]
+    return mvs.execute("RV", [phase])[0]
+
+def get_returnvalue(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    returnvalue = mvs.execute("RD", [user_frame, "returnvalue"])[0]
+    return mvs.execute("RV", [returnvalue])[0]
+
+def get_inst_ref(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    return mvs.execute("RD", [user_frame, "IP"])[0]
+
+def get_returnvalue_ref(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    return mvs.execute("RD", [user_frame, "returnvalue"])[0]
+
+def get_phase_ref(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    phase = mvs.execute("RD", [user_frame, "phase"])[0]
+    return phase
+
+def read_primitive_interfaces(root, mvs):
+    hierarchy = mvs.execute("RD", [root, "__hierarchy"])[0]
+    primitives = mvs.execute("RD", [hierarchy, "primitives"])[0]
+    keys = mvs.execute("RDK", [primitives])[0]
+    d = {}
+    for k in keys:
+        value = mvs.execute("RDN", [primitives, k])[0]
+        name = mvs.execute("RV", [k])[0]
+        d[name] = value
+    return d

+ 120 - 0
kernel/test/primitives/utils.py

@@ -0,0 +1,120 @@
+import sys
+sys.path.append("../state")
+from modelverse_state.main import ModelverseState
+import json
+
+class MvSWrapper(object):
+    def __init__(self):
+        self.mvs = ModelverseState("../bootstrap/minimal.m")
+
+        self.mapping = {
+                   "RD": self.mvs.read_dict,
+                   "RR": self.mvs.read_root,
+                   "RO": self.mvs.read_outgoing,
+                   "RI": self.mvs.read_incoming,
+                   "RE": self.mvs.read_edge,
+                   "RDE": self.mvs.read_dict_edge,
+                   "RDK": self.mvs.read_dict_keys,
+                   "RDN": self.mvs.read_dict_node,
+                   "RDNE": self.mvs.read_dict_node_edge,
+                   "RRD": self.mvs.read_reverse_dict,
+                   "RV": self.mvs.read_value,
+                   "CN": self.mvs.create_node,
+                   "CNV": self.mvs.create_nodevalue,
+                   "CE": self.mvs.create_edge,
+                   "DE": self.mvs.delete_edge,
+                   "DN": self.mvs.delete_node,
+                   "CD": self.mvs.create_dict,
+                  }
+
+    def execute(self, command, params):
+        params = json.loads(json.dumps(params))
+        retval = self.mapping[command](*params)
+        retval = json.loads(json.dumps(retval))
+
+        return [retval[0]]
+
+def add_new_user(root, mvs, username):
+    hierarchy = mvs.execute("RD", [root, "__hierarchy"])[0]
+    initial = mvs.execute("RD", [hierarchy, "__IP"])[0]
+
+    user_root = mvs.execute("CN", [])[0]
+    _globals = mvs.execute("CN", [])[0]
+    frame = mvs.execute("CN", [])[0]
+    evalstack = mvs.execute("CN", [])[0]
+    symbols = mvs.execute("CN", [])[0]
+    _input = mvs.execute("CN", [])[0]
+    _output = mvs.execute("CN", [])[0]
+    returnvalue = mvs.execute("CN", [])[0]
+    phase = mvs.execute("CNV", ["init"])[0]
+
+    mvs.execute("CD", [root, username, user_root])
+    mvs.execute("CD", [user_root, "frame", frame])
+    mvs.execute("CD", [user_root, "globals", _globals])
+    mvs.execute("CD", [user_root, "input", _input])
+    mvs.execute("CD", [user_root, "last_input", _input])
+    mvs.execute("CD", [user_root, "output", _output])
+    mvs.execute("CD", [user_root, "last_output", _output])
+    mvs.execute("CD", [frame, "evalstack", evalstack])
+    mvs.execute("CD", [frame, "returnvalue", returnvalue])
+    mvs.execute("CD", [frame, "phase", phase])
+    mvs.execute("CD", [frame, "IP", initial])
+    mvs.execute("CD", [frame, "symbols", symbols])
+
+def execute_until_finished(mvk, mvs, operation="execute_rule", params=[]):
+    username = "user_1"
+    if operation == "initialize_new_user":
+        return add_new_user(mvk.root, mvs, username)
+    response = None
+    while 1:
+        mvs_commands = mvk.execute_yields(username, operation, params, response)
+        if mvs_commands is None:
+            break
+        response = []
+        for command, param in mvs_commands:
+            response.append(mvs.execute(command, param)[0])
+
+def get_inst(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    inst = mvs.execute("RD", [user_frame, "IP"])[0]
+    return mvs.execute("RV", [inst])[0]["value"]
+
+def get_phase(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    phase = mvs.execute("RD", [user_frame, "phase"])[0]
+    return mvs.execute("RV", [phase])[0]
+
+def get_returnvalue(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    returnvalue = mvs.execute("RD", [user_frame, "returnvalue"])[0]
+    return mvs.execute("RV", [returnvalue])[0]
+
+def get_inst_ref(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    return mvs.execute("RD", [user_frame, "IP"])[0]
+
+def get_returnvalue_ref(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    return mvs.execute("RD", [user_frame, "returnvalue"])[0]
+
+def get_phase_ref(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    phase = mvs.execute("RD", [user_frame, "phase"])[0]
+    return phase
+
+def read_primitive_interfaces(root, mvs):
+    hierarchy = mvs.execute("RD", [root, "__hierarchy"])[0]
+    primitives = mvs.execute("RD", [hierarchy, "primitives"])[0]
+    keys = mvs.execute("RDK", [primitives])[0]
+    d = {}
+    for k in keys:
+        value = mvs.execute("RDN", [primitives, k])[0]
+        name = mvs.execute("RV", [k])[0]
+        d[name] = value
+    return d

+ 120 - 0
kernel/test/rules/utils.py

@@ -0,0 +1,120 @@
+import sys
+sys.path.append("../state")
+from modelverse_state.main import ModelverseState
+import json
+
+class MvSWrapper(object):
+    def __init__(self):
+        self.mvs = ModelverseState("../bootstrap/minimal.m")
+
+        self.mapping = {
+                   "RD": self.mvs.read_dict,
+                   "RR": self.mvs.read_root,
+                   "RO": self.mvs.read_outgoing,
+                   "RI": self.mvs.read_incoming,
+                   "RE": self.mvs.read_edge,
+                   "RDE": self.mvs.read_dict_edge,
+                   "RDK": self.mvs.read_dict_keys,
+                   "RDN": self.mvs.read_dict_node,
+                   "RDNE": self.mvs.read_dict_node_edge,
+                   "RRD": self.mvs.read_reverse_dict,
+                   "RV": self.mvs.read_value,
+                   "CN": self.mvs.create_node,
+                   "CNV": self.mvs.create_nodevalue,
+                   "CE": self.mvs.create_edge,
+                   "DE": self.mvs.delete_edge,
+                   "DN": self.mvs.delete_node,
+                   "CD": self.mvs.create_dict,
+                  }
+
+    def execute(self, command, params):
+        params = json.loads(json.dumps(params))
+        retval = self.mapping[command](*params)
+        retval = json.loads(json.dumps(retval))
+
+        return [retval[0]]
+
+def add_new_user(root, mvs, username):
+    hierarchy = mvs.execute("RD", [root, "__hierarchy"])[0]
+    initial = mvs.execute("RD", [hierarchy, "__IP"])[0]
+
+    user_root = mvs.execute("CN", [])[0]
+    _globals = mvs.execute("CN", [])[0]
+    frame = mvs.execute("CN", [])[0]
+    evalstack = mvs.execute("CN", [])[0]
+    symbols = mvs.execute("CN", [])[0]
+    _input = mvs.execute("CN", [])[0]
+    _output = mvs.execute("CN", [])[0]
+    returnvalue = mvs.execute("CN", [])[0]
+    phase = mvs.execute("CNV", ["init"])[0]
+
+    mvs.execute("CD", [root, username, user_root])
+    mvs.execute("CD", [user_root, "frame", frame])
+    mvs.execute("CD", [user_root, "globals", _globals])
+    mvs.execute("CD", [user_root, "input", _input])
+    mvs.execute("CD", [user_root, "last_input", _input])
+    mvs.execute("CD", [user_root, "output", _output])
+    mvs.execute("CD", [user_root, "last_output", _output])
+    mvs.execute("CD", [frame, "evalstack", evalstack])
+    mvs.execute("CD", [frame, "returnvalue", returnvalue])
+    mvs.execute("CD", [frame, "phase", phase])
+    mvs.execute("CD", [frame, "IP", initial])
+    mvs.execute("CD", [frame, "symbols", symbols])
+
+def execute_until_finished(mvk, mvs, operation="execute_rule", params=[]):
+    username = "user_1"
+    if operation == "initialize_new_user":
+        return add_new_user(mvk.root, mvs, username)
+    response = None
+    while 1:
+        mvs_commands = mvk.execute_yields(username, operation, params, response)
+        if mvs_commands is None:
+            break
+        response = []
+        for command, param in mvs_commands:
+            response.append(mvs.execute(command, param)[0])
+
+def get_inst(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    inst = mvs.execute("RD", [user_frame, "IP"])[0]
+    return mvs.execute("RV", [inst])[0]["value"]
+
+def get_phase(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    phase = mvs.execute("RD", [user_frame, "phase"])[0]
+    return mvs.execute("RV", [phase])[0]
+
+def get_returnvalue(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    returnvalue = mvs.execute("RD", [user_frame, "returnvalue"])[0]
+    return mvs.execute("RV", [returnvalue])[0]
+
+def get_inst_ref(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    return mvs.execute("RD", [user_frame, "IP"])[0]
+
+def get_returnvalue_ref(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    return mvs.execute("RD", [user_frame, "returnvalue"])[0]
+
+def get_phase_ref(root, mvs):
+    user_root = mvs.execute("RD", [root, "user_1"])[0]
+    user_frame = mvs.execute("RD", [user_root, "frame"])[0]
+    phase = mvs.execute("RD", [user_frame, "phase"])[0]
+    return phase
+
+def read_primitive_interfaces(root, mvs):
+    hierarchy = mvs.execute("RD", [root, "__hierarchy"])[0]
+    primitives = mvs.execute("RD", [hierarchy, "primitives"])[0]
+    keys = mvs.execute("RDK", [primitives])[0]
+    d = {}
+    for k in keys:
+        value = mvs.execute("RDN", [primitives, k])[0]
+        name = mvs.execute("RV", [k])[0]
+        d[name] = value
+    return d

+ 2 - 2
scripts/compile.py

@@ -3,11 +3,11 @@ import os
 import urllib2
 import subprocess
 
-def do_compile(address, filename, username, modulename, mode, optionals=[]):
+def do_compile(address, filename, username, modulename, mode, optionals=[], grammar="grammars/actionlanguage.g"):
     filename = os.path.realpath(filename)
     try:
         urllib2.urlopen(urllib2.Request(address, 'op=set_input&username=user_manager&element_type=V&value="%s"' % username)).read()
-        subprocess.check_call([sys.executable, "hutn_compiler/compiler.py", filename, "grammars/actionlanguage.g", mode, username, modulename, filename, address] + optionals, cwd="interface/HUTN")
+        subprocess.check_call([sys.executable, "hutn_compiler/compiler.py", filename, grammar, mode, username, modulename, filename, address] + optionals, cwd="interface/HUTN")
     except urllib2.URLError:
         return 2
     except:

+ 54 - 0
scripts/execute_model.py

@@ -0,0 +1,54 @@
+import random
+import sys
+import multiprocessing
+
+from compile import do_compile
+from link_and_load import link_and_load
+
+models = []
+code = []
+
+address = sys.argv[1]
+username = sys.argv[2]
+
+for f in sys.argv[3:]:
+    if f.endswith(".mvc"):
+        models.append(f)
+    elif f.endswith(".alc"):
+        code.append(f)
+    else:
+        print("Unknown file format for file " + f)
+        print("Requires either .mvc or .alc")
+
+def do_compile_wrapper(filename, mode, grammar):
+    do_compile(address, filename, str(random.random()), filename, mode, ["--debug"], grammar=grammar)
+
+def initialize_SCD():
+    import urllib2
+    import urllib
+    import json
+    username = random.random()
+    urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % username, "username": "user_manager"}))).read()
+
+    data = []
+    data.append(["V", '4'])
+    data.append(["V", '"initialize_SCD"'])
+    data.append(["V", '"models/SimpleClassDiagrams"'])
+    data.append(["V", '"exit"'])
+    data.append(["V", '2'])
+
+    print("Initializing SCD")
+    urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "data": json.dumps(data), "username": username}))).read()
+    v = urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "username": username}))).read()
+    print("Initialized!")
+
+for f in models:
+    # Parse all models and upload them
+    initialize_SCD()
+
+    for m in models:
+        do_compile_wrapper(f, "MO", "grammars/modelling.g")
+
+    p = multiprocessing.Pool(multiprocessing.cpu_count() * 2)
+    p.map(lambda i: do_compile_wrapper(i, "PO", grammar="grammars/actionlanguage.g"), code)
+    link_and_load(address, username, code)

+ 1 - 0
scripts/fix_files.py

@@ -6,5 +6,6 @@ shutil.copy("kernel/test/utils.py", "kernel/test/primitives/utils.py")
 shutil.copy("kernel/test/utils.py", "kernel/test/rules/utils.py")
 
 shutil.copy("interface/HUTN/test/util.py", "interface/HUTN/test/grammar_action_language/util.py")
+shutil.copy("interface/HUTN/test/util.py", "interface/HUTN/test/modelling_language/util.py")
 shutil.copy("interface/HUTN/test/util.py", "interface/HUTN/test/graph_compilation_action_language/util.py")
 shutil.copy("interface/HUTN/test/util.py", "interface/HUTN/test/constructor_compilation_action_language/util.py")