예제 #1
0
        /// <summary>
        ///     Creates a list of changes to be applied on the system
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list of changes to be updated</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        /// <param name="runner"></param>
        /// <returns>The list to fill with the changes</returns>
        public virtual void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation,
                                       bool apply, Runner runner)
        {
            if (!DeActivated)
            {
                long start = Environment.TickCount;

                try
                {
                    if (Statement != null)
                    {
                        Statement.GetChanges(context, changes, explanation, apply, runner);
                    }
                    else
                    {
                        AddError("Invalid actions statement");
                    }
                }
                catch (Exception e)
                {
                    AddException(e);
                }

                long stop = Environment.TickCount;
                long span = (stop - start);

                if (RuleCondition != null && RuleCondition.EnclosingRule != null)
                {
                    // Rule execution execution time (as opposed to guard evaluation)
                    RuleCondition.EnclosingRule.ExecutionTimeInMilli += span;
                    RuleCondition.EnclosingRule.ExecutionCount       += 1;
                }
            }
        }
        /// <summary>
        ///     Provides the changes performed by this statement
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list to fill with the changes</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        /// <param name="runner"></param>
        public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation,
            bool apply, Runner runner)
        {
            IVariable var = VariableIdentification.GetVariable(context);
            if (var != null)
            {
                IValue value = Expression.GetExpressionValue(context, explanation);
                if (value != null)
                {
                    value = value.RightSide(var, true, true);
                }

                Range range = var.Type as Range;
                if (range != null && range.convert(value) == null)
                {
                    AddError("Value " + value + " is outside range");
                }
                else
                {
                    Change change = new Change(var, var.Value, value);
                    changes.Add(change, apply, runner);
                    ExplanationPart.CreateSubExplanation(explanation, Root, change);
                }
            }
            else
            {
                AddError("Cannot find variable " + VariableIdentification);
            }
        }
        /// <summary>
        ///     Provides the changes performed by this statement
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list to fill with the changes</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        /// <param name="runner"></param>
        public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation,
            bool apply, Runner runner)
        {
            int index = context.LocalScope.PushContext();
            context.LocalScope.setVariable(IteratorVariable);

            IVariable variable = ListExpression.GetVariable(context);
            if (variable != null)
            {
                // HacK : ensure that the value is a correct rigth side
                // and keep the result of the right side operation
                ListValue listValue = variable.Value.RightSide(variable, false, false) as ListValue;
                variable.Value = listValue;
                if (listValue != null)
                {
                    ListValue newListValue = new ListValue(listValue);

                    int i = 0;
                    foreach (IValue current in newListValue.Val)
                    {
                        IteratorVariable.Value = current;
                        if (conditionSatisfied(context, explanation))
                        {
                            break;
                        }
                        i += 1;
                    }

                    if (i < newListValue.Val.Count)
                    {
                        IValue value = Value.GetValue(context, explanation);
                        if (value != null)
                        {
                            newListValue.Val[i] = value;
                            Change change = new Change(variable, variable.Value, newListValue);
                            changes.Add(change, apply, runner);
                            ExplanationPart.CreateSubExplanation(explanation, Root, change);
                        }
                        else
                        {
                            Root.AddError("Cannot find value for " + Value.ToString());
                        }
                    }
                    else
                    {
                        Root.AddError("Cannot find value in " + ListExpression.ToString() + " which satisfies " +
                                      Condition.ToString());
                    }
                }
                else
                {
                    Root.AddError("Variable " + ListExpression.ToString() + " does not contain a list value");
                }
            }
            else
            {
                Root.AddError("Cannot find variable for " + ListExpression.ToString());
            }

            context.LocalScope.PopContext(index);
        }
예제 #4
0
 /// <summary>
 /// Provides the changes performed by this statement
 /// </summary>
 /// <param name="context">The context on which the changes should be computed</param>
 /// <param name="changes">The changes performed by this statement</param>
 /// <param name="explanation">The explanatino to fill, if any</param>
 /// <param name="apply">Indicates that the changes should be applied immediately</param>
 public abstract void GetChanges(Interpreter.InterpretationContext context, ChangeList changes, Interpreter.ExplanationPart explanation, bool apply);
        /// <summary>
        /// Computes the changes related to this event
        /// </summary>
        /// <param name="apply">Indicates that the changes should be applied directly</param>
        public override bool ComputeChanges(bool apply)
        {
            bool retVal = base.ComputeChanges(apply);

            if (retVal)
            {
                Explanation = new Interpreter.ExplanationPart(Action);
                Explanation.Message = "Action " + Action.Name;
                Interpreter.InterpretationContext context = new Interpreter.InterpretationContext(Instance);
                Changes = new ChangeList();
                Action.GetChanges(context, Changes, Explanation, apply);
                Changes.CheckChanges(Action);
                Message = Explanation.ToString();
            }

            return retVal;
        }
        /// <summary>
        ///     Provides the changes performed by this statement
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list to fill with the changes</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        /// <param name="runner"></param>
        public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation,
            bool apply, Runner runner)
        {
            // Explain what happens in this statement
            explanation = ExplanationPart.CreateSubExplanation(explanation, this);

            IVariable variable = ListExpression.GetVariable(context);
            if (variable != null)
            {
                // HacK : ensure that the value is a correct rigth side
                // and keep the result of the right side operation
                ListValue listValue = variable.Value.RightSide(variable, false, false) as ListValue;
                variable.Value = listValue;
                if (listValue != null)
                {
                    // Provide the state of the list before removing elements from it
                    ExplanationPart.CreateSubExplanation(explanation, "Input data = ", listValue);

                    ListValue newListValue = new ListValue(listValue.CollectionType, new List<IValue>());

                    int token = context.LocalScope.PushContext();
                    context.LocalScope.SetVariable(IteratorVariable);

                    int index = 0;
                    if (Position == PositionEnum.Last)
                    {
                        index = listValue.Val.Count - 1;
                    }

                    // Remove the element while required to do so
                    while (index >= 0 && index < listValue.Val.Count)
                    {
                        IValue value = listValue.Val[index];
                        index = NextIndex(index);

                        IteratorVariable.Value = value;
                        if (ConditionSatisfied(context, explanation))
                        {
                            if (Position != PositionEnum.All)
                            {
                                break;
                            }
                        }
                        else
                        {
                            InsertInResult(newListValue, value);
                        }
                    }

                    // Complete the list
                    while (index >= 0 && index < listValue.Val.Count)
                    {
                        IValue value = listValue.Val[index];

                        InsertInResult(newListValue, value);
                        index = NextIndex(index);
                    }

                    Change change = new Change(variable, variable.Value, newListValue);
                    changes.Add(change, apply, runner);
                    ExplanationPart.CreateSubExplanation(explanation, Root, change);

                    context.LocalScope.PopContext(token);
                }
            }
        }
예제 #7
0
        /// <summary>
        ///     Creates a list of changes to be applied on the system
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list of changes to be updated</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        /// <param name="runner"></param>
        /// <returns>The list to fill with the changes</returns>
        public virtual void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation,
            bool apply, Runner runner)
        {
            if (!DeActivated)
            {
                long start = Environment.TickCount;

                try
                {
                    if (Statement != null)
                    {
                        Statement.GetChanges(context, changes, explanation, apply, runner);
                    }
                    else
                    {
                        AddError("Invalid actions statement");
                    }
                }
                catch (Exception e)
                {
                    AddException(e);
                }

                long stop = Environment.TickCount;
                long span = (stop - start);

                if (RuleCondition != null && RuleCondition.EnclosingRule != null)
                {
                    // Rule execution execution time (as opposed to guard evaluation)
                    RuleCondition.EnclosingRule.ExecutionTimeInMilli += span;
                    RuleCondition.EnclosingRule.ExecutionCount += 1;
                }
            }
        }
        /// <summary>
        /// Provides the changes performed by this statement
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list to fill with the changes</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation, bool apply)
        {
            Variables.IVariable variable = ListExpression.GetVariable(context);
            if (variable != null)
            {
                // HacK : ensure that the value is a correct rigth side
                // and keep the result of the right side operation
                Values.ListValue listValue = variable.Value.RightSide(variable, false) as Values.ListValue;
                variable.Value = listValue;
                if (listValue != null)
                {
                    Values.ListValue newListValue = new Values.ListValue(listValue);

                    int i = 0;
                    foreach (Values.IValue current in newListValue.Val)
                    {
                        IteratorVariable.Value = current;
                        if (conditionSatisfied(context))
                        {
                            break;
                        }
                        i += 1;
                    }

                    if (i < newListValue.Val.Count)
                    {
                        Values.IValue value = Value.GetValue(context);
                        if (value != null)
                        {
                            newListValue.Val[i] = value;
                            Rules.Change change = new Rules.Change(variable, variable.Value, newListValue);
                            changes.Add(change, apply);
                            explanation.SubExplanations.Add(new ExplanationPart(Root, change));
                        }
                        else
                        {
                            Root.AddError("Cannot find value for " + Value.ToString());
                        }
                    }
                    else
                    {
                        Root.AddError("Cannot find value in " + ListExpression.ToString() + " which satisfies " + Condition.ToString());
                    }
                }
                else
                {
                    Root.AddError("Variable " + ListExpression.ToString() + " does not contain a list value");
                }
            }
            else
            {
                Root.AddError("Cannot find variable for " + ListExpression.ToString());
            }
        }
        /// <summary>
        /// Provides the changes performed by this statement
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list to fill with the changes</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation, bool apply)
        {
            if (Call != null)
            {
                InterpretationContext ctxt = getContext(context);
                Functions.Procedure procedure = Call.getProcedure(ctxt);
                if (procedure != null)
                {
                    ExplanationPart part = new ExplanationPart(Root);
                    part.Message = procedure.FullName;
                    explanation.SubExplanations.Add(part);

                    int token = ctxt.LocalScope.PushContext();
                    foreach (KeyValuePair<Variables.Actual, Values.IValue> pair in Call.AssignParameterValues(context, procedure, true))
                    {
                        ctxt.LocalScope.setVariable(pair.Key, pair.Value);
                    }

                    foreach (Rules.Rule rule in Rules)
                    {
                        ApplyRule(rule, changes, ctxt, part);
                    }

                    ctxt.LocalScope.PopContext(token);
                }
                else
                {
                    AddError("Cannot determine the called procedure for " + ToString());
                }
            }
            else
            {
                AddError("Expression " + ToString() + " is not a valid procedure call");
            }
        }
        /// <summary>
        /// Provides the changes performed by this statement
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list to fill with the changes</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation, bool apply)
        {
            Variables.IVariable variable = ListExpression.GetVariable(context);
            if (variable != null)
            {
                // HacK : ensure that the value is a correct rigth side
                // and keep the result of the right side operation
                Values.ListValue listValue = variable.Value.RightSide(variable, false) as Values.ListValue;
                variable.Value = listValue;
                if (listValue != null)
                {
                    Values.ListValue newListValue = new Values.ListValue(listValue.CollectionType, new List<Values.IValue>());

                    int token = context.LocalScope.PushContext();
                    context.LocalScope.setVariable(IteratorVariable);

                    int index = 0;
                    if (Position == PositionEnum.Last)
                    {
                        index = listValue.Val.Count - 1;
                    }

                    // Remove the element while required to do so
                    while (index >= 0 && index < listValue.Val.Count)
                    {
                        Values.IValue value = listValue.Val[index];
                        index = nextIndex(index);

                        if (value == EFSSystem.EmptyValue)
                        {
                            InsertInResult(newListValue, value);
                        }
                        else
                        {
                            IteratorVariable.Value = value;
                            if (conditionSatisfied(context))
                            {
                                if (Position != PositionEnum.All)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                InsertInResult(newListValue, value);
                            }
                        }
                    }

                    // Complete the list
                    while (index >= 0 && index < listValue.Val.Count)
                    {
                        Values.IValue value = listValue.Val[index];

                        InsertInResult(newListValue, value);
                        index = nextIndex(index);
                    }

                    // Fill the gap
                    while (newListValue.Val.Count < listValue.Val.Count)
                    {
                        newListValue.Val.Add(EFSSystem.EmptyValue);
                    }

                    Rules.Change change = new Rules.Change(variable, variable.Value, newListValue);
                    changes.Add(change, apply);
                    explanation.SubExplanations.Add(new ExplanationPart(Root, change));

                    context.LocalScope.PopContext(token);
                }
            }
        }
예제 #11
0
        /// <summary>
        ///     Provides the changes performed by this statement
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list to fill with the changes</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        /// <param name="runner"></param>
        public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation,
            bool apply, Runner runner)
        {
            IVariable variable = ListExpression.GetVariable(context);
            if (variable != null)
            {
                // HacK : ensure that the value is a correct rigth side
                // and keep the result of the right side operation
                ListValue listValue = variable.Value.RightSide(variable, false, false) as ListValue;
                variable.Value = listValue;
                if (listValue != null)
                {
                    IValue value = Value.GetValue(context, explanation);
                    if (value != null)
                    {
                        if (!listValue.Val.Contains(value))
                        {
                            ListValue newListValue = new ListValue(listValue);
                            int index = newListValue.Val.IndexOf(EFSSystem.EmptyValue);
                            if (index >= 0)
                            {
                                newListValue.Val[index] = value;
                            }
                            else
                            {
                                // List is full, try to remove an element before inserting the new element
                                if (ReplaceElement != null)
                                {
                                    IValue removeValue = ReplaceElement.GetValue(context, explanation);
                                    index = newListValue.Val.IndexOf(removeValue);
                                    if (index >= 0)
                                    {
                                        newListValue.Val[index] = value.RightSide(variable, true, true);
                                    }
                                    else
                                    {
                                        Root.AddError("Cannot remove replacing element " + removeValue.Name);
                                    }
                                }
                                else
                                {
                                    Root.AddError("Cannot add new element in list value : list is full");
                                }
                            }

                            Change change = new Change(variable, variable.Value, newListValue);
                            changes.Add(change, apply, runner);
                            ExplanationPart.CreateSubExplanation(explanation, Root, change);
                        }
                        else
                        {
                            AddError("Value " + value.LiteralName + " already present in list. It has not been added");
                        }
                    }
                    else
                    {
                        Root.AddError("Cannot find value for " + Value.ToString());
                    }
                }
                else
                {
                    Root.AddError("Variable " + ListExpression.ToString() + " does not contain a list value");
                }
            }
            else
            {
                Root.AddError("Cannot find variable for " + ListExpression.ToString());
            }
        }
 /// <summary>
 /// Provides the changes performed by this statement
 /// </summary>
 /// <param name="context">The context on which the changes should be computed</param>
 /// <param name="changes">The list to fill with the changes</param>
 /// <param name="explanation">The explanatino to fill, if any</param>
 /// <param name="apply">Indicates that the changes should be applied immediately</param>
 public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation, bool apply)
 {
     Variables.IVariable var = VariableIdentification.GetVariable(context);
     if (var != null)
     {
         string tmp = var.FullName;
         Values.IValue value = Expression.GetValue(context);
         if (value != null)
         {
             value = value.RightSide(var, true);
         }
         Rules.Change change = new Rules.Change(var, var.Value, value);
         changes.Add(change, apply);
         explanation.SubExplanations.Add(new ExplanationPart(Root, change));
     }
     else
     {
         AddError("Cannot find variable " + VariableIdentification.ToString());
     }
 }
        /// <summary>
        ///     Provides the changes performed by this statement
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list to fill with the changes</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        /// <param name="runner"></param>
        public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation,
            bool apply, Runner runner)
        {
            // Explain what happens in this statement
            explanation = ExplanationPart.CreateSubExplanation(explanation, this);

            // Evaluate the list on which the APPLY statement shall be evaluated
            ListValue listValue = null;

            if (SideEffectOnVariable)
            {
                // If the apply statement has side effect, copy the corresponding variable
                // to be able to roll back the changes (in case of execution step back for instance)
                IVariable variable = ListExpression.GetVariable(context);
                if (variable != null)
                {
                    if (variable.Value != EfsSystem.Instance.EmptyValue)
                    {
                        // HacK : ensure that the value is a correct rigth side
                        // and keep the result of the right side operation
                        listValue = variable.Value.RightSide(variable, false, false) as ListValue;
                        variable.Value = listValue;
                    }
                }
            }
            else
            {
                IValue value = ListExpression.GetValue(context, explanation);
                if (value != null)
                {
                    listValue = value as ListValue;
                }
            }

            if (listValue != null)
            {
                ExplanationPart.CreateSubExplanation(explanation, "Input data = ", listValue);
                int token = context.LocalScope.PushContext();
                context.LocalScope.SetVariable(IteratorVariable);
                bool elementFound = false;
                bool matchingElementFound = false;
                foreach (IValue value in listValue.Val)
                {
                    if (value != EfsSystem.Instance.EmptyValue)
                    {
                        // All elements should always be != from EmptyValue
                        elementFound = true;
                        IteratorVariable.Value = value;
                        if (ConditionSatisfied(context, explanation))
                        {
                            matchingElementFound = true;
                            AppliedStatement.GetChanges(context, changes, explanation, apply, runner);
                        }
                    }
                }

                if (!elementFound)
                {
                    ExplanationPart.CreateSubExplanation(explanation, "Empty collection");
                }
                else if (!matchingElementFound)
                {
                    ExplanationPart.CreateSubExplanation(explanation, "No matching element found");
                }

                context.LocalScope.PopContext(token);
            }
            else
            {
                ExplanationPart.CreateSubExplanation(explanation,
                    "List expression cannot be evaluated as a valid list value");
            }
        }
        /// <summary>
        /// Provides the changes performed by this statement
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list to fill with the changes</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation, bool apply)
        {
            Variables.IVariable variable = ListExpression.GetVariable(context);
            if (variable != null)
            {
                // HacK : ensure that the value is a correct rigth side
                // and keep the result of the right side operation
                Values.ListValue listValue = variable.Value.RightSide(variable, false) as Values.ListValue;
                variable.Value = listValue;
                if (listValue != null)
                {
                    Values.IValue value = Value.GetValue(context);
                    if (value != null)
                    {
                        Values.ListValue newListValue = new Values.ListValue(listValue);
                        int index = newListValue.Val.IndexOf(EFSSystem.EmptyValue);
                        if (index >= 0)
                        {
                            newListValue.Val[index] = value;
                        }
                        else
                        {
                            // List is full, try to remove an element before inserting the new element
                            if (ReplaceElement != null)
                            {
                                Values.IValue removeValue = ReplaceElement.GetValue(context);
                                index = newListValue.Val.IndexOf(removeValue);
                                if (index >= 0)
                                {
                                    newListValue.Val[index] = value;
                                }
                                else
                                {
                                    Root.AddError("Cannot remove replacing element " + removeValue.Name);
                                }
                            }
                            else
                            {
                                Root.AddError("Cannot add new element in list value : list is full");
                            }
                        }

                        Rules.Change change = new Rules.Change(variable, variable.Value, newListValue);
                        changes.Add(change, apply);
                        explanation.SubExplanations.Add(new ExplanationPart(Root, change));
                    }
                    else
                    {
                        Root.AddError("Cannot find value for " + Value.ToString());
                    }
                }
                else
                {
                    Root.AddError("Variable " + ListExpression.ToString() + " does not contain a list value");
                }
            }
            else
            {
                Root.AddError("Cannot find variable for " + ListExpression.ToString());
            }
        }
        /// <summary>
        ///     Provides the changes performed by this statement
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list to fill with the changes</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        /// <param name="runner"></param>
        public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation,
            bool apply, Runner runner)
        {
            if (Call != null)
            {
                InterpretationContext ctxt = getContext(context, explanation);
                Procedure procedure = Call.getProcedure(ctxt, explanation);
                if (procedure != null)
                {
                    ctxt.HasSideEffects = true;

                    // If the procedure has been defined in a structure,
                    // ensure that it is applied to an instance of that structure
                    Structure structure = procedure.Enclosing as Structure;
                    if (structure != null)
                    {
                        ITypedElement current = ctxt.Instance as ITypedElement;
                        while (current != null)
                        {
                            if (current.Type != structure)
                            {
                                IEnclosed enclosed = current as IEnclosed;
                                if (enclosed != null)
                                {
                                    current = enclosed.Enclosing as ITypedElement;
                                }
                                else
                                {
                                    current = null;
                                }
                            }
                            else
                            {
                                ctxt.Instance = current;
                                current = null;
                            }
                        }
                    }

                    ExplanationPart part = ExplanationPart.CreateSubExplanation(explanation, procedure);
                    if (ctxt.Instance is IVariable)
                    {
                        ExplanationPart.SetNamable(part, ctxt.Instance);
                        ExplanationPart instanceExplanation = ExplanationPart.CreateSubExplanation(part, "instance = ");
                        ExplanationPart.SetNamable(instanceExplanation, ctxt.Instance);
                    }

                    int token = ctxt.LocalScope.PushContext();
                    foreach (
                        KeyValuePair<Actual, IValue> pair in Call.AssignParameterValues(context, procedure, true, part))
                    {
                        ctxt.LocalScope.setVariable(pair.Key, pair.Value);
                    }

                    foreach (Rule rule in procedure.Rules)
                    {
                        ApplyRule(rule, changes, ctxt, part, runner);
                    }

                    ctxt.LocalScope.PopContext(token);
                }
                else
                {
                    AddError("Cannot determine the called procedure for " + ToString());
                }
            }
            else
            {
                AddError("Expression " + ToString() + " is not a valid procedure call");
            }
        }
        /// <summary>
        /// Applies a rule defined in a procedure
        /// </summary>
        /// <param name="rule"></param>
        /// <param name="changes"></param>
        /// <param name="ctxt"></param>
        private void ApplyRule(Rules.Rule rule, ChangeList changes, InterpretationContext ctxt, ExplanationPart explanation)
        {
            foreach (Rules.RuleCondition condition in rule.RuleConditions)
            {
                if (condition.EvaluatePreConditions(ctxt))
                {
                    foreach (Rules.Action action in condition.Actions)
                    {
                        action.GetChanges(ctxt, changes, explanation, true);
                    }

                    foreach (Rules.Rule subRule in condition.SubRules)
                    {
                        ApplyRule(subRule, changes, ctxt, explanation);
                    }
                    break;
                }
            }
        }
        /// <summary>
        ///     Applies a rule defined in a procedure
        /// </summary>
        /// <param name="rule"></param>
        /// <param name="changes"></param>
        /// <param name="ctxt"></param>
        /// <param name="explanation"></param>
        /// <param name="runner"></param>
        private void ApplyRule(Rule rule, ChangeList changes, InterpretationContext ctxt, ExplanationPart explanation,
            Runner runner)
        {
            foreach (RuleCondition condition in rule.RuleConditions)
            {
                ExplanationPart conditionExplanation = ExplanationPart.CreateSubExplanation(explanation, condition);

                if (condition.EvaluatePreConditions(ctxt, conditionExplanation, runner))
                {
                    ExplanationPart.SetNamable(conditionExplanation, EFSSystem.BoolType.True);
                    foreach (Action action in condition.Actions)
                    {
                        action.GetChanges(ctxt, changes, conditionExplanation, true, runner);
                    }

                    foreach (Rule subRule in condition.SubRules)
                    {
                        ApplyRule(subRule, changes, ctxt, conditionExplanation, runner);
                    }
                    break;
                }
                else
                {
                    ExplanationPart.SetNamable(conditionExplanation, EFSSystem.BoolType.False);
                }
            }
        }
 /// <summary>
 /// Provides the changes performed by this statement
 /// </summary>
 /// <param name="context">The context on which the changes should be computed</param>
 /// <param name="changes">The list to fill with the changes</param>
 /// <param name="explanation">The explanatino to fill, if any</param>
 /// <param name="apply">Indicates that the changes should be applied immediately</param>
 public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation, bool apply)
 {
     Variables.IVariable variable = ListExpression.GetVariable(context);
     if (variable != null)
     {
         // HacK : ensure that the value is a correct rigth side
         // and keep the result of the right side operation
         Values.ListValue listValue = variable.Value.RightSide(variable, false) as Values.ListValue;
         variable.Value = listValue;
         if (listValue != null)
         {
             int token = context.LocalScope.PushContext();
             context.LocalScope.setVariable(IteratorVariable);
             foreach (Values.IValue value in listValue.Val)
             {
                 if (value != EFSSystem.EmptyValue)
                 {
                     IteratorVariable.Value = value;
                     if (conditionSatisfied(context))
                     {
                         Call.GetChanges(context, changes, explanation, apply);
                     }
                 }
             }
             context.LocalScope.PopContext(token);
         }
         else
         {
             Root.AddError("List expression does not evaluate to a list value");
         }
     }
     else
     {
         Root.AddError("Cannot find variable for " + ListExpression.ToString());
     }
 }
        /// <summary>
        ///     Computes the changes related to this event
        /// </summary>
        /// <param name="apply">Indicates that the changes should be applied directly</param>
        /// <param name="runner"></param>
        public override bool ComputeChanges(bool apply, Runner runner)
        {
            bool retVal = base.ComputeChanges(apply, runner);

            if (retVal)
            {
                if (runner.Explain)
                {
                    Explanation = new ExplanationPart(Action, "Action ", Action);
                }

                InterpretationContext context = new InterpretationContext(Instance);
                Changes = new ChangeList();
                Action.GetChanges(context, Changes, Explanation, apply, runner);
                Changes.CheckChanges(Action);
            }

            return retVal;
        }
        /// <summary>
        ///     Provides the changes performed by this statement
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list to fill with the changes</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        /// <param name="runner"></param>
        public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation,
            bool apply, Runner runner)
        {
            // Explain what happens in this statement
            explanation = ExplanationPart.CreateSubExplanation(explanation, this);

            IVariable variable = ListExpression.GetVariable(context);
            if (variable != null)
            {
                if (variable.Value != EfsSystem.Instance.EmptyValue)
                {
                    // HacK : ensure that the value is a correct rigth side
                    // and keep the result of the right side operation
                    ListValue listValue = variable.Value.RightSide(variable, false, false) as ListValue;
                    variable.Value = listValue;

                    ExplanationPart.CreateSubExplanation(explanation, "Input data = ", listValue);
                    if (listValue != null)
                    {
                        int token = context.LocalScope.PushContext();
                        context.LocalScope.SetVariable(IteratorVariable);
                        bool elementFound = false;
                        bool matchingElementFound = false;
                        foreach (IValue value in listValue.Val)
                        {
                            if (value != EfsSystem.Instance.EmptyValue)
                            {
                                elementFound = true;
                                IteratorVariable.Value = value;
                                if (ConditionSatisfied(context, explanation))
                                {
                                    matchingElementFound = true;
                                    AppliedStatement.GetChanges(context, changes, explanation, apply, runner);
                                }
                            }
                        }

                        if (!elementFound)
                        {
                            ExplanationPart.CreateSubExplanation(explanation, "Empty collection");
                        }
                        else if (!matchingElementFound)
                        {
                            ExplanationPart.CreateSubExplanation(explanation, "No matching element found");
                        }

                        context.LocalScope.PopContext(token);
                    }
                    else
                    {
                        Root.AddError("List expression does not evaluate to a list value");
                    }
                }
            }
            else
            {
                Root.AddError("Cannot find variable for " + ListExpression);
            }
        }
        /// <summary>
        ///     Provides the changes performed by this statement
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list to fill with the changes</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        /// <param name="runner"></param>
        public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation,
            bool apply, Runner runner)
        {
            // Explain what happens in this statement
            explanation = ExplanationPart.CreateSubExplanation(explanation, this);

            IVariable variable = ListExpression.GetVariable(context);
            if (variable != null)
            {
                // HacK : ensure that the value is a correct rigth side
                // and keep the result of the right side operation
                ListValue listValue = variable.Value.RightSide(variable, false, false) as ListValue;
                variable.Value = listValue;
                if (listValue != null)
                {
                    ExplanationPart.CreateSubExplanation(explanation, "Input data = ", listValue);

                    IValue value = Value.GetExpressionValue(context, explanation);
                    if (value != null)
                    {
                        if (!listValue.Val.Contains(value))
                        {
                            ListValue newListValue = new ListValue(listValue);
                            int index = newListValue.Val.IndexOf(EfsSystem.Instance.EmptyValue);
                            if (index >= 0)
                            {
                                ExplanationPart.CreateSubExplanation(explanation, "Inserting", value);
                                newListValue.Val[index] = value;
                            }
                            else
                            {
                                // List is full, try to remove an element before inserting the new element
                                if (ReplaceElement != null)
                                {
                                    IValue removeValue = ReplaceElement.GetExpressionValue(context, explanation);
                                    ExplanationPart.CreateSubExplanation(explanation, "Replaced element", removeValue);
                                    index = newListValue.Val.IndexOf(removeValue);
                                    if (index >= 0)
                                    {
                                        ExplanationPart.CreateSubExplanation(explanation, "Replacing", value);
                                        newListValue.Val[index] = value.RightSide(variable, true, true);
                                    }
                                    else
                                    {
                                        Root.AddError("Cannot remove replacing element " + removeValue.Name);
                                    }
                                }
                                else
                                {
                                    Root.AddError("Cannot add new element in list value : list is full");
                                }
                            }

                            Change change = new Change(variable, variable.Value, newListValue);
                            changes.Add(change, apply, runner);
                            ExplanationPart.CreateSubExplanation(explanation, Root, change);
                        }
                        else
                        {
                            ExplanationPart.CreateSubExplanation(explanation, "NOT added : Already present in collection", value);
                        }
                    }
                    else
                    {
                        Root.AddError("Cannot find value for " + Value);
                    }
                }
                else
                {
                    Root.AddError("Variable " + ListExpression + " does not contain a list value");
                }
            }
            else
            {
                Root.AddError("Cannot find variable for " + ListExpression);
            }
        }
예제 #22
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;
            }
        }
예제 #23
0
 /// <summary>
 ///     Provides the changes performed by this statement
 /// </summary>
 /// <param name="context">The context on which the changes should be computed</param>
 /// <param name="changes">The changes performed by this statement</param>
 /// <param name="explanation">The explanatino to fill, if any</param>
 /// <param name="apply">Indicates that the changes should be applied immediately</param>
 /// <param name="runner"></param>
 public abstract void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation,
     bool apply, Runner runner);
        /// <summary>
        ///     Provides the changes performed by this statement
        /// </summary>
        /// <param name="context">The context on which the changes should be computed</param>
        /// <param name="changes">The list to fill with the changes</param>
        /// <param name="explanation">The explanatino to fill, if any</param>
        /// <param name="apply">Indicates that the changes should be applied immediately</param>
        /// <param name="runner"></param>
        public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation,
            bool apply, Runner runner)
        {
            IVariable variable = ListExpression.GetVariable(context);

            // ReSharper disable once ConditionIsAlwaysTrueOrFalse
            changes.Add(new InsertInListChange(context, this, variable, explanation), apply, runner);
        }