Browse Source

Many additional changes, now linking to PythonPDEVS instead of the SCCD variant

Yentl Van Tendeloo 7 years ago
parent
commit
c9b3a3f166

+ 29 - 5
models/WSC/DEVS_simulate.alc

@@ -28,8 +28,8 @@ Boolean function main(model : Element):
 	String curr_submodel_parameters
 
 	model_rep = ""
-    model_rep = model_rep + "from DEVS import AtomicDEVS, CoupledDEVS\n"
-	model_rep = model_rep + "from infinity import INFINITY\n"
+    model_rep = model_rep + "from pypdevs.DEVS import AtomicDEVS, CoupledDEVS\n"
+	model_rep = model_rep + "from pypdevs.infinity import INFINITY\n"
 
     all_atomics = allInstances(model, "DEVS/AtomicDEVSBlock")
     while (read_nr_out(all_atomics) > 0):
@@ -56,7 +56,7 @@ Boolean function main(model : Element):
         model_rep = model_rep + "\tdef timeAdvance(self):\n" + cast_string(read_attribute(model, curr_atomic, "timeAdvance")) + "\n"
         model_rep = model_rep + "\tdef outputFnc(self):\n" + cast_string(read_attribute(model, curr_atomic, "outputFnc")) + "\n"
         model_rep = model_rep + "\tdef intTransition(self):\n" + cast_string(read_attribute(model, curr_atomic, "intTransition")) + "\n"
-        model_rep = model_rep + "\tdef extTransition(self, my_inputs):\n" + cast_string(read_attribute(model, curr_atomic, "extTransition")) + "\n"
+        model_rep = model_rep + "\tdef extTransition(self, inputs):\n" + cast_string(read_attribute(model, curr_atomic, "extTransition")) + "\n"
 
     all_coupleds = allInstances(model, "DEVS/CoupledDEVSBlock")
     while (read_nr_out(all_coupleds) > 0):
@@ -64,6 +64,7 @@ Boolean function main(model : Element):
         model_rep = model_rep + "class " + cast_string(read_attribute(model, curr_coupled, "name")) + "(CoupledDEVS):\n"
         model_rep = model_rep + "\tdef __init__(self, name, parameters):\n"
         model_rep = model_rep + "\t\tCoupledDEVS.__init__(self, name)\n"
+		model_rep = model_rep + "\t\tself.parameters = parameters\n"
         model_rep = model_rep + "\t\tself.my_ports = {"
         all_ports = allAssociationDestinations(model, curr_coupled, "DEVS/DEVSBlockToPort")
         while (read_nr_out(all_ports) > 0):
@@ -120,11 +121,34 @@ Boolean function main(model : Element):
 	String port
     String the_input
     String devs_model
-	port = comm_connect("pypdevs_simulator")
+	port = comm_connect("pypdevs_batch_simulator")
         
     comm_set(port, model_rep)
 
-	comm_set(port, "[\"simulate\"]")
+	String experiment
+	//experiment = ""
+	//experiment = experiment + "import random\n"
+	//experiment = experiment + "from pypdevs.simulator import Simulator\n"
+
+	//experiment = experiment + "def simulate(nresources, seed):\n"
+	//experiment = experiment + "\trandom.seed(seed)\n"
+	//experiment = experiment + "\tmodel = Root('root', [nresources])\n"
+	//experiment = experiment + "\tsim = Simulator(model)\n"
+	//experiment = experiment + "\tsim.setClassicDEVS()\n"
+	//experiment = experiment + "\tsim.simulate()\n"
+	//experiment = experiment + "\treturn model.finish.state\n"
+
+	//experiment = experiment + "def main():\n"
+	//experiment = experiment + "\tresults = ''\n"
+	//experiment = experiment + "\tfor i in range(1, 3):\n"
+	//experiment = experiment + "\t\tresults = results + str(i)\n"
+	//experiment = experiment + "\t\tfor v in range(1, 3):\n"
+	//experiment = experiment + "\t\t\tresults = results + ' ' + simulate(i, v)\n"
+	//experiment = experiment + "\t\tresults = results + '\\n'\n"
+	//experiment = experiment + "\tprint('Result: ' + results)\n"
+	//experiment = experiment + "\treturn results\n"
+	experiment = read_attribute(model, set_pop(allInstances(model, "Experiment/Experiment")), "code")
+	comm_set(port, experiment)
     
     while (True):
         if (comm_hasInput(port)):

+ 15 - 4
models/WSC/PM_to_DEVS.mvc

@@ -6,7 +6,11 @@ Composite schedule {
     {Contains} Success success {}
 
     {Contains} Atomic add_resource_handler {
-        LHS {}
+        LHS {
+            Pre_DEVS/CoupledDEVSBlock pre_resource_999 {
+                label = "root"
+            }
+        }
         RHS {
             Post_DEVS/DEVSInstance post_resource_1 {
                 label = "1"
@@ -20,7 +24,7 @@ Composite schedule {
                     $
                 value_parameters = $
                     String function value(model : Element, name : String, mapping : Element):
-                        return "[]"!
+                        return "[self.parameters[0]]"!
                     $
             }
             Post_DEVS/InputPort post_resource_2 {
@@ -43,6 +47,13 @@ Composite schedule {
             Post_DEVS/DEVSInstanceToPort (post_resource_1, post_resource_3) {
                 label = "5"
             }
+
+            Post_DEVS/CoupledDEVSBlock post_resource_999 {
+                label = "root"
+            }
+            Post_DEVS/SubModel (post_resource_999, post_resource_1) {
+                label = "submodel"
+            }
         }
     }
 
@@ -342,7 +353,7 @@ Composite schedule {
                     $
                 value_parameters = $
                     String function value(model : Element, name : String, mapping : Element):
-                        return "[]"!
+                        return "[" + cast_string(set_len(allIncomingAssociationInstances(model, name, "PM/Next"))) + "]"!
                     $
             }
             Post_Trace (post_sync_0, post_sync_1) {
@@ -406,7 +417,7 @@ Composite schedule {
                     $
                 value_parameters = $
                     String function value(model : Element, name : String, mapping : Element):
-                        return "[]"!
+                        return "[" + cast_string(read_attribute(model, mapping["0"], "distribution")) + "]"!
                     $
             }
             Post_Trace (post_xor_0, post_xor_1) {

+ 4 - 0
models/WSC/experiment.mvc

@@ -0,0 +1,4 @@
+SimpleAttribute String {}
+Class Experiment {
+    code : String
+}

+ 24 - 0
models/WSC/experiment_example.mvc

@@ -0,0 +1,24 @@
+Experiment {
+    code = """
+import random
+from pypdevs.simulator import Simulator
+
+def simulate(nresources, seed):
+    random.seed(seed)
+    model = Root('root', [nresources])
+    sim = Simulator(model)
+    sim.setClassicDEVS()
+    sim.simulate()
+    return model.submodels['finish'].state
+
+def main():
+    results = ''
+    for i in range(1, 3):
+        results = results + str(i)
+        for v in range(1, 3):
+            results = results + ' ' + simulate(i, v)
+        results = results + '\\n'
+    print('Result: ' + results)
+    return results
+    """
+}

+ 8 - 0
models/WSC/pm_PM_to_DEVS.mvc

@@ -39,6 +39,11 @@ Data devs_model {
     type = "formalisms/DEVS/DEVS_MM"
 }
 
+Data experiment_model {
+    name = "Experiment"
+    type = "formalisms/Experiment/Experiment_MM"
+}
+
 Data metrics_model {
     name = "Metrics"
     type = "formalisms/Metrics/Metrics_MM"
@@ -64,6 +69,9 @@ Produces (merge, devs_model) {
 Consumes (simulate, devs_model) {
     name = "DEVS"
 }
+Consumes (simulate, experiment_model) {
+    name = "Experiment"
+}
 Produces (simulate, metrics_model) {
     name = "metrics"
 }

+ 6 - 5
models/WSC/pm_example.mvc

@@ -3,14 +3,14 @@ Initial init {
 }
 Activity req {
     name = "define_requirements"
-    distribution = "lambda iteration: lambda: iteration"
+    distribution = "lambda iteration: iteration"
 }
 SimpleMerge merge {
     name = "merge_0"
 }
 Activity model {
     name = "model_system"
-    distribution = "lambda iteration: lambda: iteration"
+    distribution = "lambda iteration: iteration"
 }
 ParallelSplit split {
     name = "split_0"
@@ -18,21 +18,22 @@ ParallelSplit split {
 MultiInstance simulate {
     name = "simulate"
     nr_instances = 10
-    distribution = "lambda iteration: lambda: iteration"
+    distribution = "lambda iteration: iteration"
 }
 Activity check {
     name = "check"
-    distribution = "lambda iteration: lambda: iteration"
+    distribution = "lambda iteration: iteration"
 }
 Synchronization sync {
     name = "sync_0"
 }
 Activity evaluate {
     name = "evaluate"
-    distribution = "lambda iteration: lambda: iteration"
+    distribution = "lambda iteration: iteration"
 }
 ExclusiveChoice choice {
     name = "xor_0"
+    distribution = "lambda iteration: 1 - 1/iteration"
 }
 Finish finish {
     name = "finish"

+ 29 - 18
models/WSC/pm_library.mvc

@@ -13,7 +13,7 @@ AtomicDEVSBlock Initial {
     """
 
     outputFnc = """
-        return {self.control_out: {}}
+        return {self.my_ports['control_out']: {}}
     """
 
     intTransition = """
@@ -78,7 +78,7 @@ AtomicDEVSBlock ResourceHandler {
     """
 
     outputFnc = """
-        return {self.resource_out: {'id': self.state['queue'][0]}}
+        return {self.my_ports['resource_out']: {'id': self.state['queue'][0]}}
     """
 
     intTransition = """
@@ -89,7 +89,7 @@ AtomicDEVSBlock ResourceHandler {
     """
 
     extTransition = """
-        for inp in inputs[self.resource_in]:
+        for inp in inputs[self.my_ports['resource_in']]:
             if inp['type'] == 'request':
                 # Queue the request
                 self.state['queue'].append(inp['id'])
@@ -139,10 +139,10 @@ AtomicDEVSBlock Activity {
     outputFnc = """
         if self.state.mode == 'active':
             # Output the control token to the next model in line, and release the resources
-            return {self.control_out: {}, self.resource_out: [{'type': 'release'}]}
+            return {self.my_ports['control_out']: {}, self.my_ports['resource_out']: [{'type': 'release'}]}
         elif self.state.mode == 'request_resource':
             # Output a request for resources with a specified ID (used to find out whether this was our request)
-            return {self.resource_out: [{'type': 'request', 'id': '%s-%s' % (self.state.name, self.state.counter)}]}
+            return {self.my_ports['resource_out']: [{'type': 'request', 'id': '%s-%s' % (self.state.name, self.state.counter)}]}
         else:
             return {}
         """
@@ -164,13 +164,13 @@ AtomicDEVSBlock Activity {
 
     extTransition = """
         self.state.timer -= self.elapsed
-        if self.state.mode == 'inactive' and self.control_in in inputs:
+        if self.state.mode == 'inactive' and self.my_ports['control_in'] in inputs:
             # Got control token, so ask for the required resources
             self.state.mode = 'request_resource'
             self.state.timer = 0.0
             # NOTE this violates DEVS, though is easy to debug
             #print('Activate ' + str(self.state.name) + ' at time ' + str(self.time_last[0] + self.elapsed))
-        elif self.state.mode == 'wait_resource' and self.resource_in in inputs and inputs[self.resource_in]['id'] == '%s-%s' % (self.state.name, self.state.counter):
+        elif self.state.mode == 'wait_resource' and self.my_ports['resource_in'] in inputs and inputs[self.my_ports['resource_in']]['id'] == '%s-%s' % (self.state.name, self.state.counter):
             # Got required resources, so start execution
             self.state.mode = 'active'
             self.state.timer = self.state.random_sample()
@@ -189,6 +189,17 @@ OutputPort act_ro {
 DEVSBlockToPort (Activity, act_ri) {}
 DEVSBlockToPort (Activity, act_ro) {}
 
+InputPort act_ci {
+    name = "control_in"
+}
+
+OutputPort act_co {
+    name = "control_out"
+}
+
+DEVSBlockToPort (Activity, act_ci) {}
+DEVSBlockToPort (Activity, act_co) {}
+
 AtomicDEVSBlock ParallelSplit {
     name = "ParallelSplit"
 
@@ -204,7 +215,7 @@ AtomicDEVSBlock ParallelSplit {
         """
 
     outputFnc = """
-        return {self.control_out: {}}
+        return {self.my_ports['control_out']: {}}
         """
 
     intTransition = """
@@ -242,7 +253,7 @@ AtomicDEVSBlock Synchronization {
         """
 
     outputFnc = """
-        return {self.control_out: {}}
+        return {self.my_ports['control_out']: {}}
         """
 
     intTransition = """
@@ -295,9 +306,9 @@ AtomicDEVSBlock ExclusiveChoice {
 
     outputFnc = """
         if self.state.choice == 0:
-            return {self.control_out1: {}}
+            return {self.my_ports['control_out1']: {}}
         else:
-            return {self.control_out2: {}}
+            return {self.my_ports['control_out2']: {}}
         """
 
     intTransition = """
@@ -344,7 +355,7 @@ AtomicDEVSBlock SimpleMerge {
         """
 
     outputFnc = """
-        return {self.control_out: {}}
+        return {self.my_ports['control_out']: {}}
         """
 
     intTransition = """
@@ -388,7 +399,7 @@ AtomicDEVSBlock MultiInstance {
             def task_time(self):
                 return self.distribution(self.counter)
 
-        self.state, self.elapsed = MultiInstanceState(self.parameters[0], self.parameters[1], self.parameters[2])
+        self.state, self.elapsed = MultiInstanceState(self.parameters[0], self.parameters[1], self.parameters[2]), 0.0
         """
 
     timeAdvance = """
@@ -405,13 +416,13 @@ AtomicDEVSBlock MultiInstance {
     outputFnc = """
         if self.state.mode == 'request_resources':
             # Request all resources in one go
-            return {self.resource_out: [{'type': 'request', 'id': i} for i in self.state.requested]}
+            return {self.my_ports['resource_out']: [{'type': 'request', 'id': i} for i in self.state.requested]}
         elif self.state.mode == 'active':
             # Finished an instance, so release it
-            return {self.resource_out: [{'type': 'release'}]}
+            return {self.my_ports['resource_out']: [{'type': 'release'}]}
         elif self.state.mode == 'finish':
             # Finished execution of all, so pass on token
-            return {self.control_out: {}}
+            return {self.my_ports['control_out']: {}}
         else:
             return {}
         """
@@ -443,11 +454,11 @@ AtomicDEVSBlock MultiInstance {
         for t in self.state.running_tasks:
             t[0] -= self.elapsed
 
-        if self.state.mode == 'inactive' and self.control_in in inputs:
+        if self.state.mode == 'inactive' and self.my_ports['control_in'] in inputs:
             self.state.mode = 'request_resources'
             self.state.requested = ['%s-%s-%s' % (self.state.name, self.state.counter, i) for i in range(self.state.spawned)]
 
-        if self.state.mode in ['active', 'release_resource'] and self.resource_in in inputs:
+        if self.state.mode in ['active', 'release_resource'] and self.my_ports['resource_in'] in inputs:
             # Got a resource, so allocate it to an activity
             self.state.running_tasks.append([self.state.task_time(), self.state.requested.pop(0)])
             # NOTE this violates DEVS, though is easy to debug

+ 4 - 2
models/pm_translate.py

@@ -9,11 +9,13 @@ login("admin", "admin")
 model_add("formalisms/DEVS/DEVS_MM", "formalisms/SimpleClassDiagrams", open("models/WSC/DEVS.mvc", 'r').read())
 model_add("formalisms/Metrics/Metrics_MM", "formalisms/SimpleClassDiagrams", open("models/WSC/metrics.mvc", 'r').read())
 model_add("formalisms/PM/PM_Extended_MM", "formalisms/SimpleClassDiagrams", open("models/WSC/pm.mvc", 'r').read())
+model_add("formalisms/Experiment/Experiment_MM", "formalisms/SimpleClassDiagrams", open("models/WSC/experiment.mvc", 'r').read())
 
 model_add("models/PM/to_DEVS", "formalisms/ProcessModel", open("models/WSC/pm_PM_to_DEVS.mvc").read())
 
 model_add("models/DEVS/PM_library", "formalisms/DEVS/DEVS_MM", open("models/WSC/pm_library.mvc", 'r').read())
 model_add("models/PM/example_PM", "formalisms/PM/PM_Extended_MM", open("models/WSC/pm_example.mvc", 'r').read())
+model_add("models/Experiment/example_experiment", "formalisms/Experiment/Experiment_MM", open("models/WSC/experiment_example.mvc", 'r').read())
 
 def traceability_pm_devs(model):
     instantiate(model, "Association", ("PM/ProcessNode", "DEVS/DEVSInstance"), ID="Trace")
@@ -21,6 +23,6 @@ def traceability_pm_devs(model):
 transformation_add_MT({"PM": "formalisms/PM/PM_Extended_MM"}, {"DEVS": "formalisms/DEVS/DEVS_MM"}, "formalisms/PM/to_DEVS", open("models/WSC/PM_to_DEVS.mvc", 'r').read(), traceability_pm_devs)
 
 transformation_add_AL({"model1": "formalisms/DEVS/DEVS_MM", "model2": "formalisms/DEVS/DEVS_MM"}, {"result": "formalisms/DEVS/DEVS_MM"}, "formalisms/DEVS/merge", open("models/WSC/DEVS_merge.alc", 'r').read())
-transformation_add_AL({"DEVS": "formalisms/DEVS/DEVS_MM"}, {"metrics": "formalisms/Metrics/Metrics_MM"}, "formalisms/DEVS/simulate", open("models/WSC/DEVS_simulate.alc", 'r').read())
+transformation_add_AL({"DEVS": "formalisms/DEVS/DEVS_MM", "Experiment": "formalisms/Experiment/Experiment_MM"}, {"metrics": "formalisms/Metrics/Metrics_MM"}, "formalisms/DEVS/simulate", open("models/WSC/DEVS_simulate.alc", 'r').read())
 
-process_execute("models/PM/to_DEVS", {"PM": "models/PM/example_PM", "DEVS library": "models/DEVS/PM_library", "Metrics": "models/Metrics/metric"}, {})
+process_execute("models/PM/to_DEVS", {"PM": "models/PM/example_PM", "DEVS library": "models/DEVS/PM_library", "Metrics": "models/Metrics/metric", "Experiment": "models/Experiment/example_experiment"}, {})

+ 4 - 12
services/DEVS/main.py

@@ -6,26 +6,18 @@ from pprint import pprint
 from multiprocessing import Process, Pipe, freeze_support
 
 sys.path.append('services/DEVS/pypdevs/src')
-sys.path.append('services/DEVS/pypdevs/models')
+sys.path.append('services/DEVS/pypdevs/examples')
 
 from simulator import Controller
-from DEVS import AtomicDEVS, CoupledDEVS
-from infinity import INFINITY
+from ps_model import Root
 
 import threading, time
 
 def pypdevs_service(port):
-    code = service_get(port)
-    model_name = str(uuid.uuid4()).replace("-", "")
+    exec(service_get(port), globals(), {})
 
-    with open("services/DEVS/pypdevs/models/" + model_name + ".py", 'w') as f:
-        f.write(code)
+    controller = Controller(Root())
 
-    Root = getattr(__import__(model_name), "Root")
-    controller = Controller(Root('Root', []))
-    run_simulation(port, controller)
-
-def run_simulation(port, controller):
     def inputter():
         print("Waiting for input...")
         while 1:

+ 1 - 1
wrappers/modelverse_SCCD.py

@@ -1,7 +1,7 @@
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
-Date:   Tue May 15 13:44:39 2018
+Date:   Tue May 15 15:50:20 2018
 
 Model author: Yentl Van Tendeloo
 Model name:   MvK Server