瀏覽代碼

Start execution of condition on transition

Yentl Van Tendeloo 8 年之前
父節點
當前提交
b1885389bf
共有 5 個文件被更改,包括 112 次插入218 次删除
  1. 3 6
      bootstrap/modelling.alc
  2. 54 7
      integration/code/minimal_SCCD.mvc
  3. 1 1
      kernel/modelverse_jit/jit.py
  4. 20 190
      models/SCCD.mvc
  5. 34 14
      models/SCCD_execute.alc

+ 3 - 6
bootstrap/modelling.alc

@@ -592,7 +592,6 @@ Element function construct_model_raw(metamodel : Element):
 			log("Modelling error: did not understand command " + command)
 
 Element function get_func_AL_model(al_model : Element):
-	Element result
 	Element initial_function
 
 	// Find the initial function
@@ -600,11 +599,9 @@ Element function get_func_AL_model(al_model : Element):
 
 	if (read_nr_out(initial_function) == 0):
 		log("Could not find function to execute in this model!")
-		return create_node()!
+		return read_root()!
 	elif (read_nr_out(initial_function) > 1):
 		log("Too many functions to execute in this model!")
-		return create_node()!
+		return read_root()!
 	else:
-		initial_function = al_model["model"][set_pop(allAssociationDestinations(al_model, set_pop(initial_function), "initial_funcdef"))]
-
-	return initial_function!
+		return al_model["model"][set_pop(allAssociationDestinations(al_model, set_pop(initial_function), "initial_funcdef"))]!

+ 54 - 7
integration/code/minimal_SCCD.mvc

@@ -1,3 +1,5 @@
+include "primitives.alh"
+
 Diagram my_SCCD {
     name = "SimpleSCCD"
     author = "Yentl"
@@ -11,21 +13,66 @@ Class main {
 CompositeState main_statechart {
     name = "root"
     isInitial = True
-
-    {composite_children} BasicState root_a {
-        name = "a"
+    {composite_children} BasicState init {
+        name = "initial"
         isInitial = True
     }
 
-    {composite_children} BasicState root_b {
-        name = "b"
+    {composite_children} ParallelState main_parallel {
+        name = "parallel"
         isInitial = False
+
+        {parallel_children} CompositeState parallel_x {
+            {composite_children} BasicState x_a {
+                name = "xa"
+                isInitial = True
+            }
+            {composite_children} BasicState x_b {
+                name = "xb"
+                isInitial = False
+            }
+            {composite_children} BasicState x_c {
+                name = "xc"
+                isInitial = False
+            }
+        }
+
+        {parallel_children} CompositeState parallel_y {
+            {composite_children} BasicState y_a {
+                name = "ya"
+                isInitial = True
+            }
+            {composite_children} BasicState y_b {
+                name = "yb"
+                isInitial = False
+            }
+        }
     }
+}
+
+
+transition (x_a, x_b) {
+    name = "X"
+    event = "X"
+}
+
+transition (x_b, x_c) {
+    name = "Z"
+    cond = $
+            Boolean function cond(attributes : Element):
+                log("in condition")
+                return (1 > 0)!
+        $
+}
 
+transition (y_a, y_b) {
+    name = "Y"
+    event = "Y"
 }
 
-transition (root_a, root_b) {
-    name = "A2B"
+transition (init, main_parallel) {
+    name = "init"
+    event = "init"
 }
 
 diagram_classes (my_SCCD, main) {}

+ 1 - 1
kernel/modelverse_jit/jit.py

@@ -570,7 +570,7 @@ class ModelverseJit(object):
     def jit_compile(self, task_root, body_id, suggested_name=None):
         """Tries to jit the function defined by the given entry point id and parameter list."""
         if body_id is None:
-            raise ValueError('body_id cannot be None: ' + suggested_name)
+            raise ValueError('body_id cannot be None: ' + str(suggested_name))
         elif body_id in self.jitted_entry_points:
             raise primitive_functions.PrimitiveFinished(
                 self.jit_globals[self.jitted_entry_points[body_id]])

+ 20 - 190
models/SCCD.mvc

@@ -2,86 +2,25 @@ include "primitives.alh"
 include "object_operations.alh"
 include "modelling.alh"
 
-SimpleAttribute Neutral {}
-SimpleAttribute Boolean {
-    constraint = $
-    String function constraint(model: Element, id: String):
-        if (bool_not(is_physical_boolean(model["model"][id]))):
-            return "Boolean has no boolean value at " + id!
-        else:
-            return "OK"!
-    $
-}
-SimpleAttribute String {
-    constraint = $
-    String function constraint(model: Element, id: String):
-        if (bool_not(is_physical_string(model["model"][id]))):
-            return "String has no string value at " + id!
-        else:
-            return "OK"!
-    $
-}
-SimpleAttribute Natural {
-    constraint =$
-    String function constraint(model: Element, id: String):
-        if (bool_not(is_physical_int(model["model"][id]))):
-            return "Natural has no integer value at " + id!
-        elif (integer_lt(model["model"][id], 0)):
-            return "Natural does not have a positive or zero value at " + id!
-        else:
-            return "OK"!
-     $
-}
-SimpleAttribute PositiveFloat {
-    constraint =$
-    String function constraint(model: Element, id: String):
-        if (bool_not(is_physical_float(model["model"][id]))):
-            return "PositiveFloat has no float value at " + id!
-        elif (integer_lt(model["model"][id], 0)):
-            return "PositiveFloat does not have a positive or zero value at " + id!
-        else:
-            return "OK"!
-     $
-}
-SimpleAttribute EventScope {
-    constraint =$
-    String function constraint(model: Element, id: String):
-        String self
-        self = model["model"][id]
-        if (bool_not(is_physical_string(self))):
-            return "EventScope has no string value at " + id!
-        elif (bool_or(bool_or(bool_or(self != "broad", self != "cd"), bool_or(self != "narrow", self != "output")), self != 'local')):
-            return "EventScope can be either 'local', 'broad', 'cd', 'narrow' or 'output' and it does not have a proper value at " + id!
-        else:
-            return "OK"!
-    $
-}
+SimpleAttribute Action {}
+SimpleAttribute Boolean {}
+SimpleAttribute String {}
+SimpleAttribute Natural {}
 
 Class Diagram{
     name : String
-    author ?: String
-    description ?: String
-    top ?: String
-    class_reference_items ?: String
+    author : String
+    description : String
     lower_cardinality = 1
     upper_cardinality = 1
 }
-Class Inport{
-    name: String
-}
-Class Outport{
-    name: String
-}
-Association diagram_inports(Diagram, Inport){}
-Association diagram_outports(Diagram, Outport){}
 
 Class Class{
     name : String
-    constructor_body ?: String
-    destructor ?: String
-    default ?: Boolean
-    external ?: Boolean
-    class_behaviour_items ?: String
+    constructor_body? : Action
+    destructor? : Action
+    default : Boolean
+    external : Boolean
 }
 Association diagram_classes(Diagram, Class){
     target_lower_cardinality = 1
@@ -89,97 +28,43 @@ Association diagram_classes(Diagram, Class){
 
 Class Attribute{
     name : String
-    type ?: String
 }
 Association class_attributes(Class, Attribute){}
 
 Class Method{
     name : String
-    body : String
-    return_type ?: String
-}
-
-Class FormalParameter{
-    name: String
-    type ?: String
-    default ?: String
-}
-Association method_parameters(Method, FormalParameter){}
-Association class_methods(Class, Method){}
-Association class_constructor_parameters(Class, FormalParameter){}
-
-Class CanvasPosition{
-    x1: Natural
-    y1: Natural
-    x2 ?: Natural
-    y2 ?: Natural
-}
-Association class_ref_position(Class, CanvasPosition){
-    target_upper_cardinality = 1
-}
-Association class_beh_position(Class, CanvasPosition){
-    target_upper_cardinality = 1
+    body : Action
 }
 
 Association association(Class, Class){
     name : String
-    min ?: Natural
-    max ?: Natural
     source_upper_cardinality = 1
 }
-Association association_positions(association, CanvasPosition){
-    order: Natural
-}
 
 Association inheritance(Class, Class){
     priority ?: Natural
     source_upper_cardinality = 1
 }
 
-Class SuperClassConstructorParameter{
-    value : Neutral
-}
-Association inheritance_parent_constructor_parameters(inheritance, SuperClassConstructorParameter){
-    order : Natural
-}
-Association inheritance_positions(inheritance, CanvasPosition){
-    order: Natural
-}
-
 Class State{
     name : String
-    state_reference_path ?: String
-}
-Association state_position(State, CanvasPosition){
-    target_upper_cardinality = 1
 }
 
 Class BasicState : State{
     isInitial : Boolean
-    onEntryScript ?: String
-    onExitScript ?: String
+    onEntryScript? : Action
+    onExitScript? : Action
 }
 
 Association behaviour(Class, BasicState){
     target_lower_cardinality = 1
     target_upper_cardinality = 1
 }
-Association behaviour_positions(behaviour, CanvasPosition){
-    order: Natural
-}
-
-Class ActualParameter{
-    exp: String
-}
 
 Class Raise{
-    event: String
-    scope ?: EventScope
-    port ?: String
-    target ?: String
-}
-Association raise_parameters(Raise, ActualParameter){
-    order : Natural
+    event : String
+    scope? : String
+    target? : String
 }
 Association state_onentry_raises(BasicState, Raise){
     order : Natural
@@ -204,67 +89,12 @@ Class HistoryState : State{
 
 Association transition(State, State){
     name: String
-    cond ?: String
-    script ?: String
-    after ?: PositiveFloat
-    event ?: String
-    port ?: String
+    cond? : Action
+    script? : Action
+    after? : Action
+    event? : String
     source_upper_cardinality = 1
 }
-Association transition_parameters(transition, FormalParameter){
-    order : Natural
-}
 Association transition_raises(transition, Raise){
     order : Natural
 }
-Association transition_positions(transition, CanvasPosition){
-    order: Natural
-}
-
-GlobalConstraint {
-        global_constraint = $
-            String function constraint(model : Element):
-                Element composite_states
-                Element parallel_states
-                Element children
-                String state
-                String child
-                String name
-                Boolean CompInitialFound
-                Element encountered_names
-
-                composite_states = allInstances(model, "CompositeState")
-                parallel_states = allInstances(model, "ParallelState")
-
-                while (list_len(composite_states) >0):
-                    CompInitialFound = False
-                    encountered_names = create_node()
-                    state = set_pop(composite_states)
-                    children = allAssociationDestinations(model, state, "composite_children")
-                    while (list_len(children)>0):
-                        child = set_pop(children)
-                        name = read_attribute(model, child, 'name')
-                        if (set_in(encountered_names, name)):
-                            return "Unique state identifier names on the same level/parent violated"!
-                        else:
-                            set_add(encountered_names, name)
-                        if bool_and(read_type(model, child) != 'HistoryState' , read_attribute(model, child, 'isInitial')):
-                            CompInitialFound = True
-                    if CompInitialFound == False:
-                        return "Composite state does not have an initial child state"!
-
-                while (list_len(parallel_states) >0):
-                    encountered_names = create_node()
-                    state = set_pop(parallel_states)
-                    children = allAssociationDestinations(model, state, "parallel_children")
-                    while (list_len(children)>0):
-                        child = set_pop(children)
-                        name = read_attribute(model, child, 'name')
-                        if (set_in(encountered_names, name)):
-                            return "Unique state identifier names on the same level/parent violated"!
-                        else:
-                            set_add(encountered_names, name)
-
-                return "OK"!
-        $
-}

+ 34 - 14
models/SCCD_execute.alc

@@ -58,7 +58,6 @@ Element function expand_composite_state(model : Element, composite_state : Strin
 
 	// Fetch the initial state
 	initial = set_pop(filter(model, allAssociationDestinations(model, composite_state, "SCCD/composite_children"), "isInitial", True))
-	log("Got initial state: " + initial)
 
 	// Expand the initial state, depending on what it is
 	return expand_state(model, initial)!
@@ -92,6 +91,15 @@ Void function start_class(model : Element, data : Element, class : String):
 	initial_state = set_pop(allAssociationDestinations(model, class, "SCCD/behaviour"))
 	dict_add(class_handle, "states", expand_state(model, initial_state))
 
+	// Add all attributes
+	Element attributes
+	attributes = create_node()
+	Element attrs
+	attrs = allAssociationDestinations(model, class, "SCCD/class_attributes")
+	while (read_nr_out(attrs) > 0):
+		dict_add(attributes, read_attribute(model, set_pop(attrs), "name"), create_node())
+	dict_add(class_handle, "attributes", attributes)
+
 	set_add(data["classes"], class_handle)
 
 	return!
@@ -103,6 +111,7 @@ Element function get_enabled_transitions(model : Element, state : String, interr
 	Element to_filter
 	String attr
 	String transition
+	Element cond
 
 	result = create_node()
 	to_filter = allOutgoingAssociationInstances(model, state, "SCCD/transition")
@@ -110,11 +119,25 @@ Element function get_enabled_transitions(model : Element, state : String, interr
 	while (read_nr_out(to_filter) > 0):
 		transition = set_pop(to_filter)
 		attr = read_attribute(model, transition, "event")
-		if (element_eq(attr, read_root())):
-			// No event defined, so is fine
-			set_add(result, transition)
-		elif (value_eq(attr, interrupt)):
-			// Event defined, and that is the one of the event we got in
+		if (bool_or(element_eq(attr, read_root()), value_eq(attr, interrupt))):
+			// Event is OK
+			cond = read_attribute(model, transition, "cond")
+			log("Resolved condition")
+			if (element_neq(cond, read_root())):
+				log("Result = " + cast_e2s(cond))
+				cond = get_func_AL_model(cond)
+				log("Resolved = " + cast_e2s(cond))
+				// Execute condition
+				if (bool_not(cond(create_node()))):
+					log("Evaluated to True")
+					// Condition false, so skip
+					continue!
+				else:
+					log("Evaluated to False")
+			else:
+				log("NO condition")
+			// Condition is OK
+
 			set_add(result, transition)
 
 	return result!
@@ -128,8 +151,9 @@ Float function step_class(model : Element, data : Element, class : Element, inte
 	String state
 	Element transitions
 	String transition
+	Float t_min
+	Float t_current
 
-	log(string_join("Stepping ", class["ID"]))
 	states = set_copy(class["states"])
 	new_states = create_node()
 
@@ -138,14 +162,10 @@ Float function step_class(model : Element, data : Element, class : Element, inte
 
 		// Fetch transitions in this state specifically (NO parent)
 		transitions = get_enabled_transitions(model, state, interrupt)
-		log("Got enabled transitions: " + cast_v2s(read_nr_out(transitions)))
 		if (read_nr_out(transitions) != 0):
 			// Found an enabled transition, so store that one
 			transition = random_choice(transitions)
-			log("Executing enabled transition: " + cast_v2s(read_attribute(model, transition, "name")))
-
-			set_add(new_states, readAssociationDestination(model, transition))
-			log("Found new state: " + cast_v2s(read_attribute(model, readAssociationDestination(model, transition), "name")))
+			set_merge(new_states, expand_state(model, readAssociationDestination(model, transition)))
 		else:
 			// Try going to the parent
 			// TODO
@@ -188,7 +208,6 @@ Boolean function main(model : Element):
 	// Find initial
 	String default_class
 	default_class = set_pop(filter(model, allInstances(model, "SCCD/Class"), "default", True))
-	log("Found default class: " + default_class)
 
 	// Start up the default class
 	start_class(model, data, default_class)
@@ -211,4 +230,5 @@ Boolean function main(model : Element):
 
 		timeout = step(model, data, interrupt)
 
-	return True!
+	// We should never get here!
+	return False!