瀏覽代碼

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)
 			log("Modelling error: did not understand command " + command)
 
 
 Element function get_func_AL_model(al_model : Element):
 Element function get_func_AL_model(al_model : Element):
-	Element result
 	Element initial_function
 	Element initial_function
 
 
 	// Find the 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):
 	if (read_nr_out(initial_function) == 0):
 		log("Could not find function to execute in this model!")
 		log("Could not find function to execute in this model!")
-		return create_node()!
+		return read_root()!
 	elif (read_nr_out(initial_function) > 1):
 	elif (read_nr_out(initial_function) > 1):
 		log("Too many functions to execute in this model!")
 		log("Too many functions to execute in this model!")
-		return create_node()!
+		return read_root()!
 	else:
 	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 {
 Diagram my_SCCD {
     name = "SimpleSCCD"
     name = "SimpleSCCD"
     author = "Yentl"
     author = "Yentl"
@@ -11,21 +13,66 @@ Class main {
 CompositeState main_statechart {
 CompositeState main_statechart {
     name = "root"
     name = "root"
     isInitial = True
     isInitial = True
-
-    {composite_children} BasicState root_a {
-        name = "a"
+    {composite_children} BasicState init {
+        name = "initial"
         isInitial = True
         isInitial = True
     }
     }
 
 
-    {composite_children} BasicState root_b {
-        name = "b"
+    {composite_children} ParallelState main_parallel {
+        name = "parallel"
         isInitial = False
         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) {}
 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):
     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."""
         """Tries to jit the function defined by the given entry point id and parameter list."""
         if body_id is None:
         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:
         elif body_id in self.jitted_entry_points:
             raise primitive_functions.PrimitiveFinished(
             raise primitive_functions.PrimitiveFinished(
                 self.jit_globals[self.jitted_entry_points[body_id]])
                 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 "object_operations.alh"
 include "modelling.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{
 Class Diagram{
     name : String
     name : String
-    author ?: String
-    description ?: String
-    top ?: String
-    class_reference_items ?: String
+    author : String
+    description : String
     lower_cardinality = 1
     lower_cardinality = 1
     upper_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{
 Class Class{
     name : String
     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){
 Association diagram_classes(Diagram, Class){
     target_lower_cardinality = 1
     target_lower_cardinality = 1
@@ -89,97 +28,43 @@ Association diagram_classes(Diagram, Class){
 
 
 Class Attribute{
 Class Attribute{
     name : String
     name : String
-    type ?: String
 }
 }
 Association class_attributes(Class, Attribute){}
 Association class_attributes(Class, Attribute){}
 
 
 Class Method{
 Class Method{
     name : String
     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){
 Association association(Class, Class){
     name : String
     name : String
-    min ?: Natural
-    max ?: Natural
     source_upper_cardinality = 1
     source_upper_cardinality = 1
 }
 }
-Association association_positions(association, CanvasPosition){
-    order: Natural
-}
 
 
 Association inheritance(Class, Class){
 Association inheritance(Class, Class){
     priority ?: Natural
     priority ?: Natural
     source_upper_cardinality = 1
     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{
 Class State{
     name : String
     name : String
-    state_reference_path ?: String
-}
-Association state_position(State, CanvasPosition){
-    target_upper_cardinality = 1
 }
 }
 
 
 Class BasicState : State{
 Class BasicState : State{
     isInitial : Boolean
     isInitial : Boolean
-    onEntryScript ?: String
-    onExitScript ?: String
+    onEntryScript? : Action
+    onExitScript? : Action
 }
 }
 
 
 Association behaviour(Class, BasicState){
 Association behaviour(Class, BasicState){
     target_lower_cardinality = 1
     target_lower_cardinality = 1
     target_upper_cardinality = 1
     target_upper_cardinality = 1
 }
 }
-Association behaviour_positions(behaviour, CanvasPosition){
-    order: Natural
-}
-
-Class ActualParameter{
-    exp: String
-}
 
 
 Class Raise{
 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){
 Association state_onentry_raises(BasicState, Raise){
     order : Natural
     order : Natural
@@ -204,67 +89,12 @@ Class HistoryState : State{
 
 
 Association transition(State, State){
 Association transition(State, State){
     name: String
     name: String
-    cond ?: String
-    script ?: String
-    after ?: PositiveFloat
-    event ?: String
-    port ?: String
+    cond? : Action
+    script? : Action
+    after? : Action
+    event? : String
     source_upper_cardinality = 1
     source_upper_cardinality = 1
 }
 }
-Association transition_parameters(transition, FormalParameter){
-    order : Natural
-}
 Association transition_raises(transition, Raise){
 Association transition_raises(transition, Raise){
     order : Natural
     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
 	// Fetch the initial state
 	initial = set_pop(filter(model, allAssociationDestinations(model, composite_state, "SCCD/composite_children"), "isInitial", True))
 	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
 	// Expand the initial state, depending on what it is
 	return expand_state(model, initial)!
 	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"))
 	initial_state = set_pop(allAssociationDestinations(model, class, "SCCD/behaviour"))
 	dict_add(class_handle, "states", expand_state(model, initial_state))
 	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)
 	set_add(data["classes"], class_handle)
 
 
 	return!
 	return!
@@ -103,6 +111,7 @@ Element function get_enabled_transitions(model : Element, state : String, interr
 	Element to_filter
 	Element to_filter
 	String attr
 	String attr
 	String transition
 	String transition
+	Element cond
 
 
 	result = create_node()
 	result = create_node()
 	to_filter = allOutgoingAssociationInstances(model, state, "SCCD/transition")
 	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):
 	while (read_nr_out(to_filter) > 0):
 		transition = set_pop(to_filter)
 		transition = set_pop(to_filter)
 		attr = read_attribute(model, transition, "event")
 		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)
 			set_add(result, transition)
 
 
 	return result!
 	return result!
@@ -128,8 +151,9 @@ Float function step_class(model : Element, data : Element, class : Element, inte
 	String state
 	String state
 	Element transitions
 	Element transitions
 	String transition
 	String transition
+	Float t_min
+	Float t_current
 
 
-	log(string_join("Stepping ", class["ID"]))
 	states = set_copy(class["states"])
 	states = set_copy(class["states"])
 	new_states = create_node()
 	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)
 		// Fetch transitions in this state specifically (NO parent)
 		transitions = get_enabled_transitions(model, state, interrupt)
 		transitions = get_enabled_transitions(model, state, interrupt)
-		log("Got enabled transitions: " + cast_v2s(read_nr_out(transitions)))
 		if (read_nr_out(transitions) != 0):
 		if (read_nr_out(transitions) != 0):
 			// Found an enabled transition, so store that one
 			// Found an enabled transition, so store that one
 			transition = random_choice(transitions)
 			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:
 		else:
 			// Try going to the parent
 			// Try going to the parent
 			// TODO
 			// TODO
@@ -188,7 +208,6 @@ Boolean function main(model : Element):
 	// Find initial
 	// Find initial
 	String default_class
 	String default_class
 	default_class = set_pop(filter(model, allInstances(model, "SCCD/Class"), "default", True))
 	default_class = set_pop(filter(model, allInstances(model, "SCCD/Class"), "default", True))
-	log("Found default class: " + default_class)
 
 
 	// Start up the default class
 	// Start up the default class
 	start_class(model, data, default_class)
 	start_class(model, data, default_class)
@@ -211,4 +230,5 @@ Boolean function main(model : Element):
 
 
 		timeout = step(model, data, interrupt)
 		timeout = step(model, data, interrupt)
 
 
-	return True!
+	// We should never get here!
+	return False!