Przeglądaj źródła

Added all constraints and fixed the problem of the constraint not being found

Yentl Van Tendeloo 9 lat temu
rodzic
commit
4f2de3b94c

+ 8 - 3
bootstrap/conformance_scd.alc

@@ -113,9 +113,9 @@ String function conformance_scd(model : Element):
 		keys = dict_keys(model["model"])
 		while (0 < list_len(keys)):
 			model_name = set_pop(keys)
-			log("Check " + model_name)
 			element = model["model"][model_name]
 			type_name = reverseKeyLookup(metamodel["model"], dict_read_node(typing, element))
+			log((("Check " + model_name) + " : ") + type_name)
 
 			if (bool_not(dict_in_node(typing, element))):
 				return "Model has no type specified: " + model_name
@@ -123,8 +123,9 @@ String function conformance_scd(model : Element):
 			if (bool_not(set_in_node(metamodel["model"], dict_read_node(typing, element)))):
 				return "Type of element not in specified metamodel: " + model_name
 
-			if (bool_not(is_nominal_instance(model, model_name, type_name))):
-				return "Element is not an instance of its specified type: " + model_name
+			// This is true by definition of is_nominal_instance
+			//if (bool_not(is_nominal_instance(model, model_name, type_name))):
+			//	return "Element is not an instance of its specified type: " + model_name
 
 			if (is_edge(element)):
 				src_model = reverseKeyLookup(model["model"], read_edge_src(element))
@@ -146,6 +147,7 @@ String function conformance_scd(model : Element):
 			// First the incoming, so we are at B in the above figure
 			if (bool_not(dict_in(spo_cache, type_name))):
 				dict_add(spo_cache, type_name, selectPossibleOutgoing(metamodel, type_name, dict_keys(cardinalities)))
+
 			check_list = spo_cache[type_name]
 			while (0 < list_len(check_list)):
 				check_type = set_pop(check_list)
@@ -171,6 +173,7 @@ String function conformance_scd(model : Element):
 			// Identical, but for outgoing, and thus for A in the figure
 			if (bool_not(dict_in(spi_cache, type_name))):
 				dict_add(spi_cache, type_name, selectPossibleIncoming(metamodel, type_name, dict_keys(cardinalities)))
+
 			check_list = spi_cache[type_name]
 			while (0 < list_len(check_list)):
 				check_type = set_pop(check_list)
@@ -195,8 +198,10 @@ String function conformance_scd(model : Element):
 
 			Element constraint_function
 			constraint_function = read_attribute(metamodel, reverseKeyLookup(metamodel["model"], dict_read_node(typing, element)), "constraint")
+			log((("Constraint for " + model_name) + ": ") + cast_e2s(constraint_function))
 			if (element_neq(constraint_function, read_root())):
 				String result
+				log("Execute constraint")
 				result = constraint_function(model, model_name)
 				if (result != "OK"):
 					return result

+ 16 - 18
bootstrap/metamodels.alc

@@ -323,30 +323,28 @@ Element function initialize_SCD(location : String):
 	instantiate_attribute(scd, "call_params", "target_upper_cardinality", 1)
 	instantiate_attribute(scd, "call_last_param", "target_upper_cardinality", 1)
 
-	// Add constraints to all primitive classes
-	//add_constraint(scd, "if", constraint_if)
-	//add_constraint(scd, "while", constraint_while)
-	//add_constraint(scd, "break", constraint_break)
-	//add_constraint(scd, "continue", constraint_continue)
-	//add_constraint(scd, "assign", constraint_assign)
-	//add_constraint(scd, "return", constraint_return)
-	//add_constraint(scd, "output", constraint_output)
-	//add_constraint(scd, "input", constraint_input)
-	//add_constraint(scd, "declare", constraint_declare)
-	//add_constraint(scd, "global", constraint_global)
-	//add_constraint(scd, "access", constraint_access)
-	//add_constraint(scd, "constant", constraint_constant)
-	//add_constraint(scd, "resolve", constraint_resolve)
-	//add_constraint(scd, "call", constraint_call)
-
 	// Now still allow for constraints on classes
 	instantiate_link(scd, "Association", "constraint", "Class", "funcdef")
 	instantiate_attribute(scd, "constraint", "name", "constraint")
 
+	// Add constraints to all primitive classes
+	add_constraint(scd, "if", constraint_if)
+	add_constraint(scd, "while", constraint_while)
+	add_constraint(scd, "break", constraint_break)
+	add_constraint(scd, "continue", constraint_continue)
+	add_constraint(scd, "assign", constraint_assign)
+	add_constraint(scd, "return", constraint_return)
+	add_constraint(scd, "output", constraint_output)
+	add_constraint(scd, "input", constraint_input)
+	add_constraint(scd, "declare", constraint_declare)
+	add_constraint(scd, "global", constraint_global)
+	add_constraint(scd, "access", constraint_access)
+	add_constraint(scd, "constant", constraint_constant)
+	add_constraint(scd, "resolve", constraint_resolve)
+	add_constraint(scd, "call", constraint_call)
+
 	// And add some, to enforce correct physical types
-	log("Add Natural constraint")
 	add_constraint(scd, "Natural", constraint_natural)
-	log("Add String constraint")
 	add_constraint(scd, "String", constraint_string)
 
 	// Finally done, so export!

+ 11 - 0
integration/test_pn_interface.py

@@ -381,3 +381,14 @@ class TestPetrinetInterface(unittest.TestCase):
             attr_add + prompt + \
             ["OK"] + prompt,
             mode))
+
+    def test_po_pn_interface_verify_PN_OK(self):
+        self.pn_interface_verify_PN_OK("PO")
+
+    def test_co_pn_interface_verify_PN_OK(self):
+        self.pn_interface_verify_PN_OK("CO")
+
+    def pn_interface_verify_PN_OK(self, mode):
+        self.assertTrue(run_file(all_files,
+            ["load", "PetriNets", "verify"],
+            init + load + loaded + ["OK"], mode))

+ 50 - 16
scripts/prompt.py

@@ -3,6 +3,38 @@ import urllib2
 import threading
 import subprocess
 import os
+import sys
+
+sys.path.append("../interface/HUTN")
+sys.path.append("interface/HUTN")
+from hutn_compiler.compiler import main as hutn_compile
+
+memory = {}
+
+def send_data(commands, address, username):
+    def flush_data(data):
+        if data:
+            urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "data": json.dumps(data), "username": username}))).read()
+        return []
+
+    var_list = {}
+    data = []
+    for p in v:
+        if isinstance(p, int):
+            if p not in var_list:
+                data = flush_data(data)
+                val = urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "username": username}))).read()
+                val = val.split("=", 2)[1].split("&", 1)[0]
+                var_list[p] = val
+                continue
+            else:
+                val = var_list[p]
+                t = "R"
+        else:
+            val = p
+            t = "V"
+        data.append([t, val])
+    flush_data(data)
 
 def local_print(string):
     if os.name == "posix":
@@ -21,10 +53,7 @@ local_print("Please specify Modelverse location (default: 127.0.0.1:8001)")
 
 location = raw_input()
 if location == "":
-    address = "127.0.0.1"
-    port = 8001
-else:
-    address, port = location.strip().split(":")
+    address = "http://127.0.0.1:8001/"
 
 local_print("Username (default: test)")
 username = raw_input()
@@ -34,14 +63,16 @@ else:
     username = username.strip()
 
 # If user shouldn't exist yet, we create it
-urllib2.urlopen(urllib2.Request("http://%s:%s/" % (address, port), urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % username, "username": "user_manager"}))).read()
+urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % username, "username": "user_manager"}))).read()
 
 local_print("Switching context to Modelverse: all data is piped.")
+local_print("Use command $ to switch to HUTN parsing mode.")
+local_print("Use \\ before the value to use a primitive value different from a string, which is already JSON serialized.")
 local_print("To quit: execute command 'quit'")
 
 def print_output():
     while 1:
-        output = urllib2.urlopen(urllib2.Request("http://%s:%s/" % (address, port), urllib.urlencode({"op": "get_output", "username": username}))).read()
+        output = urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "username": username}))).read()
         l, r = output.split("&", 1)
         if "value" in l:
             output = l
@@ -59,15 +90,18 @@ while 1:
     if command == "quit":
         local_print("Received quit: breaking connection to Modelverse immediately!")
         break
-    try:
-        # Could be a number
-        _ = float(command)
-        command = str(command)
-        local_print("Interpreting value as a number")
-    except:
-        if len(command) > 0 and command[0] == "\\":
-            command = '{"value": "%s"}' % command[1:]
+
+    if command.startswith("$"):
+        # Invoke the HUTN parser
+        with open("__constraint.al", 'w') as f:
+            f.write("Element function constraint(model : Element, element_name : String):\n")
+        commands = hutn_compile(tmp_file, grammar_file, "CS")
+        send_data(commands, address)
+    else:
+        # Just send a normal request
+        if command.startswith("\\"):
+            command = command
         else:
             command = '"%s"' % command
-        local_print("Got command string: " + str(command))
-    urllib2.urlopen(urllib2.Request("http://%s:%s/" % (address, port), urllib.urlencode({"op": "set_input", "element_type": "V", "value": command, "username": username}))).read()
+
+        urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "element_type": "V", "value": command, "username": username}))).read()