Ejemplo n.º 1
0
        /// <summary>
        /// Applies the selected actions and update the system state
        /// </summary>
        /// <param name="updates"></param>
        public void ApplyActivations(HashSet <Activation> activations)
        {
            foreach (Activation activation in activations)
            {
                if (activation.RuleCondition.Actions.Count > 0)
                {
                    // Register the fact that a rule has been triggered
                    Events.RuleFired ruleFired = new Events.RuleFired(activation.RuleCondition);
                    EventTimeLine.AddModelEvent(ruleFired);

                    // Registers all model updates due to this rule triggering
                    foreach (Rules.Action action in activation.RuleCondition.Actions)
                    {
                        if (action.Statement != null)
                        {
                            Events.VariableUpdate variableUpdate = new Events.VariableUpdate(action, activation.Instance);
                            EventTimeLine.AddModelEvent(variableUpdate);
                            ruleFired.AddVariableUpdate(variableUpdate);
                        }
                        else
                        {
                            action.AddError("Cannot parse action statement");
                        }
                    }
                }
            }

            CheckExpectationsState();
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Applies the selected actions and update the system state
        /// </summary>
        /// <param name="activations"></param>
        /// <param name="updates"></param>
        /// <param name="priority"></param>
        public void EvaluateActivations(HashSet<Activation> activations, acceptor.RulePriority priority,
            ref List<VariableUpdate> updates)
        {
            Dictionary<IVariable, Change> changes = new Dictionary<IVariable, Change>();
            Dictionary<Change, VariableUpdate> traceBack = new Dictionary<Change, VariableUpdate>();

            foreach (Activation activation in activations)
            {
                if (activation.RuleCondition.Actions.Count > 0)
                {
                    // Register the fact that a rule has been triggered
                    RuleFired ruleFired = new RuleFired(activation, priority);
                    EventTimeLine.AddModelEvent(ruleFired, this, true);
                    ExplanationPart changesExplanation = ExplanationPart.CreateSubExplanation(activation.Explanation,
                        "Changes");

                    // Registers all model updates due to this rule triggering
                    foreach (Action action in activation.RuleCondition.Actions)
                    {
                        if (action.Statement != null)
                        {
                            VariableUpdate variableUpdate = new VariableUpdate(action, activation.Instance, priority);
                            variableUpdate.ComputeChanges(false, this);
                            EventTimeLine.AddModelEvent(variableUpdate, this, false);
                            ruleFired.AddVariableUpdate(variableUpdate);
                            if (changesExplanation != null)
                            {
                                changesExplanation.SubExplanations.Add(variableUpdate.Explanation);
                            }
                            updates.Add(variableUpdate);

                            if (CheckForCompatibleChanges)
                            {
                                ChangeList actionChanges = variableUpdate.Changes;
                                if (variableUpdate.Action.Statement is ProcedureCallStatement)
                                {
                                    Dictionary<IVariable, Change> procedureChanges = new Dictionary<IVariable, Change>();

                                    foreach (Change change in variableUpdate.Changes.Changes)
                                    {
                                        procedureChanges[change.Variable] = change;
                                    }

                                    actionChanges = new ChangeList();
                                    foreach (Change change in procedureChanges.Values)
                                    {
                                        actionChanges.Add(change, false, this);
                                    }
                                }

                                foreach (Change change in actionChanges.Changes)
                                {
                                    IVariable variable = change.Variable;
                                    if (changes.ContainsKey(change.Variable))
                                    {
                                        Change otherChange = changes[change.Variable];
                                        Action otherAction = traceBack[otherChange].Action;
                                        if (!variable.Type.CompareForEquality(otherChange.NewValue, change.NewValue))
                                        {
                                            string action1 = ((INamable) action.Enclosing).FullName + " : " +
                                                             variableUpdate.Action.FullName;
                                            string action2 = ((INamable) otherAction.Enclosing).FullName + " : " +
                                                             traceBack[otherChange].Action.FullName;
                                            variableUpdate.Action.AddError(
                                                "Simultaneous change of the variable " + variable.FullName + " with different values. Conflit between\n" +
                                                action1 + "\n and \n" + action2);
                                        }
                                    }
                                    else
                                    {
                                        changes.Add(change.Variable, change);
                                        traceBack.Add(change, variableUpdate);
                                    }
                                }
                            }
                        }
                        else
                        {
                            action.AddError("Cannot parse action statement");
                        }
                    }
                }
            }

            // Handles the leave & enter state rules
            List<VariableUpdate> updatesToProcess = updates;
            updates = new List<VariableUpdate>();

            // Avoid considering twice the same transition
            List<Tuple<State, State>> transitions = new List<Tuple<State, State>>();

            while (updatesToProcess.Count > 0)
            {
                List<VariableUpdate> newUpdates = new List<VariableUpdate>();

                foreach (VariableUpdate update in updatesToProcess)
                {
                    updates.Add(update);

                    foreach (Change change in update.Changes.Changes)
                    {
                        if (change.Variable.Type is StateMachine)
                        {
                            State leavingState = (State) change.PreviousValue;
                            State enteringState = (State) change.NewValue;

                            bool transitionFound = false;
                            foreach (Tuple<State, State> transition in transitions)
                            {
                                if ((transition.Item1 == leavingState) && (transition.Item2 == enteringState))
                                {
                                    transitionFound = true;
                                    break;
                                }
                            }

                            if (! transitionFound)
                            {
                                Tuple<State, State> transition = new Tuple<State, State>(leavingState, enteringState);
                                transitions.Add(transition);

                                HandleLeaveState(priority, newUpdates, change.Variable, leavingState, enteringState);
                                HandleEnterState(priority, newUpdates, change.Variable, leavingState, enteringState);
                            }
                        }
                    }
                }

                updatesToProcess = newUpdates;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Applies the selected actions and update the system state
        /// </summary>
        /// <param name="updates"></param>
        public void ApplyActivations(HashSet<Activation> activations)
        {
            foreach (Activation activation in activations)
            {
                if (activation.RuleCondition.Actions.Count > 0)
                {
                    // Register the fact that a rule has been triggered
                    Events.RuleFired ruleFired = new Events.RuleFired(activation.RuleCondition);
                    EventTimeLine.AddModelEvent(ruleFired);

                    // Registers all model updates due to this rule triggering
                    foreach (Rules.Action action in activation.RuleCondition.Actions)
                    {
                        if (action.Statement != null)
                        {
                            Events.VariableUpdate variableUpdate = new Events.VariableUpdate(action, activation.Instance);
                            EventTimeLine.AddModelEvent(variableUpdate);
                            ruleFired.AddVariableUpdate(variableUpdate);
                        }
                        else
                        {
                            action.AddError("Cannot parse action statement");
                        }
                    }
                }
            }

            CheckExpectationsState();
        }