/// <summary>
        ///     Provides the value associated to this Expression
        /// </summary>
        /// <param name="context">The context on which the value must be found</param>
        /// <param name="explain">The explanation to fill, if any</param>
        /// <returns></returns>
        protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain)
        {
            IValue retVal = EfsSystem.Instance.BoolType.True;

            ListValue value = ListExpression.GetValue(context, explain) as ListValue;

            if (value != null)
            {
                int token = PrepareIteration(context);
                if (Condition != null)
                {
                    foreach (IValue v in value.Val)
                    {
                        if (v != EfsSystem.Instance.EmptyValue)
                        {
                            // All elements should always be != from EmptyValue
                            ElementFound           = true;
                            IteratorVariable.Value = v;
                            if (!ConditionSatisfied(context, explain))
                            {
                                MatchingElementFound = true;
                                retVal = EfsSystem.Instance.BoolType.False;
                                break;
                            }
                        }
                        NextIteration();
                    }
                }
                EndIteration(context, explain, token);
            }

            return(retVal);
        }
示例#2
0
            public override void GetChanges(InterpretationContext context, ChangeList changes,
                                            ExplanationPart explanation, bool apply, Runner runner)
            {
                Change change = new Change(Variable, Variable.Value, Value);

                changes.Add(change, apply, runner);
            }
示例#3
0
        /// <summary>
        ///     Provides the value of the function
        /// </summary>
        /// <param name="context"></param>
        /// <param name="actuals">the actual parameters values</param>
        /// <param name="explain"></param>
        /// <returns>The value for the function application</returns>
        public override IValue Evaluate(InterpretationContext context, Dictionary <Actual, IValue> actuals,
                                        ExplanationPart explain)
        {
            IValue retVal = null;

            int token = context.LocalScope.PushContext();

            AssignParameters(context, actuals);

            Collection collectionType =
                (Collection)
                EFSSystem.FindType(
                    OverallNameSpaceFinder.INSTANCE.findByName(EFSSystem.Dictionaries[0],
                                                               "Default"),
                    "TargetsCol");
            ListValue collection = new ListValue(collectionType, new List <IValue>());

            Function function = context.FindOnStack(Targets).Value as Function;

            if (function != null && !function.Name.Equals("EMPTY"))
            {
                Graph graph1 = createGraphForValue(context, function, explain);
                ComputeTargets(graph1.Function, collection);
            }

            context.LocalScope.PopContext(token);

            retVal = collection;
            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)
        {
            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;
                Collection collection = var.Type as Collection;
                if (range != null && range.convert(value) == null)
                {
                    AddError("Value " + value + " is outside range", RuleChecksEnum.ExecutionFailed);
                }
                else if (collection != null && collection.convert(value) == null)
                {
                    AddError("Value " + value + " cannot be assigned to variable", RuleChecksEnum.ExecutionFailed);
                }
                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, RuleChecksEnum.ExecutionFailed);
            }
        }
示例#5
0
        /// <summary>
        ///     Add actions when leaving a state
        /// </summary>
        /// <param name="priority"></param>
        /// <param name="updates"></param>
        /// <param name="variable"></param>
        /// <param name="leaveState"></param>
        /// <param name="enterState"></param>
        private void HandleLeaveState(acceptor.RulePriority?priority, List <VariableUpdate> updates, IVariable variable,
                                      State leaveState, State enterState)
        {
            if (!_processedStates.Contains(leaveState))
            {
                _processedStates.Add(leaveState);

                if (!leaveState.getStateMachine().Contains(leaveState, enterState))
                {
                    if (leaveState.getLeaveAction() != null)
                    {
                        Rules.Rule            rule           = (Rules.Rule)leaveState.getLeaveAction();
                        ExplanationPart       explanation    = new ExplanationPart(rule, "Rule evaluation");
                        HashSet <Activation>  newActivations = new HashSet <Activation>();
                        List <VariableUpdate> newUpdates     = new List <VariableUpdate>();
                        // the priority is not specified for the rule evaluation since
                        // the rules of the leave states have to be executed regardless the priority
                        rule.Evaluate(this, null, variable, newActivations, explanation);
                        EvaluateActivations(newActivations, priority, newUpdates);
                        updates.AddRange(newUpdates);
                    }

                    if (leaveState.EnclosingState != null)
                    {
                        HandleLeaveState(priority, updates, variable, leaveState.EnclosingState, enterState);
                    }
                }

                _processedStates.Remove(leaveState);
            }
        }
        /// <summary>
        ///     Provides the value associated to this Expression
        /// </summary>
        /// <param name="context">The context on which the value must be found</param>
        /// <param name="explain">The explanation to fill, if any</param>
        /// <returns></returns>
        protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain)
        {
            ListValue retVal = null;

            ListValue value = ListExpression.GetValue(context, explain) as ListValue;

            if (value != null)
            {
                int token = PrepareIteration(context);
                retVal = new ListValue((Collection)GetExpressionType(), new List <IValue>());
                foreach (IValue v in value.Val)
                {
                    if (v != EfsSystem.Instance.EmptyValue)
                    {
                        // All elements should always be != from EmptyValue
                        ElementFound           = true;
                        IteratorVariable.Value = v;

                        if (ConditionSatisfied(context, explain))
                        {
                            MatchingElementFound = true;
                            retVal.Val.Add(v);
                        }
                    }
                    NextIteration();
                }
                EndIteration(context, explain, token);
            }

            return(retVal);
        }
        /// <summary>
        ///     Provides the value of the function
        /// </summary>
        /// <param name="context"></param>
        /// <param name="actuals">the actual parameters values</param>
        /// <param name="explain"></param>
        /// <returns>The value for the function application</returns>
        public override IValue Evaluate(InterpretationContext context, Dictionary <Actual, IValue> actuals,
                                        ExplanationPart explain)
        {
            IValue retVal = null;

            int token = context.LocalScope.PushContext();

            AssignParameters(context, actuals);

            DoubleValue value    = context.FindOnStack(Value).Value as DoubleValue;
            DoubleValue multiple = context.FindOnStack(Multiple).Value as DoubleValue;

            if (value != null && multiple != null)
            {
                double res = Math.Floor(value.Val);
                while (res > 0 && res % multiple.Val != 0)
                {
                    res--;
                }
                retVal = new DoubleValue(ReturnType, res);
            }

            context.LocalScope.PopContext(token);

            return(retVal);
        }
示例#8
0
        /// <summary>
        ///     Provides the value of the function
        /// </summary>
        /// <param name="context"></param>
        /// <param name="actuals">the actual parameters values</param>
        /// <param name="explain"></param>
        /// <returns>The value for the function application</returns>
        public override IValue Evaluate(InterpretationContext context, Dictionary <Actual, IValue> actuals,
                                        ExplanationPart explain)
        {
            IValue retVal;

            int token = context.LocalScope.PushContext();

            AssignParameters(context, actuals);

            Function function = (Function)acceptor.getFactory().createFunction();

            function.Name      = "AddIncrement ( Function => " + getName(Function) + ", Value => " + getName(Increment) + ")";
            function.Enclosing = EFSSystem;
            Parameter parameter = (Parameter)acceptor.getFactory().createParameter();

            parameter.Name = "X";
            parameter.Type = EFSSystem.DoubleType;
            function.appendParameters(parameter);
            function.ReturnType = EFSSystem.DoubleType;
            function.Graph      = CreateGraph(context, parameter, explain);

            retVal = function;
            context.LocalScope.PopContext(token);

            return(retVal);
        }
示例#9
0
        /// <summary>
        ///     Provides the value of the function
        /// </summary>
        /// <param name="context"></param>
        /// <param name="actuals">the actual parameters values</param>
        /// <param name="explain"></param>
        /// <returns>The value for the function application</returns>
        public override IValue Evaluate(InterpretationContext context, Dictionary <Actual, IValue> actuals,
                                        ExplanationPart explain)
        {
            IValue retVal = null;

            int token = context.LocalScope.PushContext();

            AssignParameters(context, actuals);
            BoolValue val = context.FindOnStack(Value).Value as BoolValue;

            if (val != null)
            {
                if (val.Val)
                {
                    retVal = EFSSystem.BoolType.False;
                }
                else
                {
                    retVal = EFSSystem.BoolType.True;
                }
            }
            context.LocalScope.PopContext(token);

            return(retVal);
        }
示例#10
0
 /// <summary>
 ///     Adds a new function to this graph
 /// </summary>
 /// <param name="function"></param>
 /// <param name="explain"></param>
 private void AddFunction(Function function, ExplanationPart explain)
 {
     if (function != null)
     {
         InterpretationContext context = new InterpretationContext(function);
         if (function.FormalParameters.Count == 1)
         {
             Parameter parameter = (Parameter)function.FormalParameters[0];
             Graph     graph     = function.CreateGraph(context, parameter, explain);
             if (graph != null)
             {
                 Functions.Add(function);
                 Refresh();
             }
         }
         else if (function.FormalParameters.Count == 2)
         {
             Surface surface = function.CreateSurface(context, explain);
             if (surface != null)
             {
                 Functions.Add(function);
                 Refresh();
             }
             else
             {
                 MessageBox.Show(
                     Resources.GraphView_AddFunction_Cannot_add_this_function_to_the_display_view,
                     Resources.GraphView_AddFunction_Cannot_display_function,
                     MessageBoxButtons.OK,
                     MessageBoxIcon.Error);
             }
         }
     }
 }
示例#11
0
        /// <summary>
        ///     Provides the surface of this function if it has been statically defined
        /// </summary>
        /// <param name="context">the context used to create the surface</param>
        /// <param name="explain"></param>
        /// <returns></returns>
        public override Surface CreateSurface(InterpretationContext context, ExplanationPart explain)
        {
            Surface retVal = null;

            Surface defaultSurface = createSurfaceForValue(context, context.FindOnStack(DefaultFunction).Value, explain);

            if (defaultSurface != null)
            {
                Surface overrideSurface = createSurfaceForValue(context, context.FindOnStack(OverrideFunction).Value,
                                                                explain);
                if (overrideSurface != null)
                {
                    retVal = defaultSurface.Override(overrideSurface);
                }
                else
                {
                    OverrideFunction.AddError("Cannot create graph for OVERRIDE argument");
                }
            }
            else
            {
                DefaultFunction.AddError("Cannot create graph for DEFAULT argument");
            }

            return(retVal);
        }
示例#12
0
        /// <summary>
        ///     Provides the value of the function
        /// </summary>
        /// <param name="context"></param>
        /// <param name="actuals">the actual parameters values</param>
        /// <param name="explain"></param>
        /// <returns>The value for the function application</returns>
        public override IValue Evaluate(InterpretationContext context, Dictionary <Actual, IValue> actuals,
                                        ExplanationPart explain)
        {
            IValue retVal = null;

            int token = context.LocalScope.PushContext();

            AssignParameters(context, actuals);

            StructureValue startDate = context.FindOnStack(StartDate).Value as StructureValue;

            if (startDate != null)
            {
                int year   = GetIntValue(startDate, "Year");
                int month  = GetIntValue(startDate, "Month");
                int day    = GetIntValue(startDate, "Day");
                int hour   = GetIntValue(startDate, "Hour");
                int minute = GetIntValue(startDate, "Minute");
                int second = GetIntValue(startDate, "Second");
                int tts    = GetIntValue(startDate, "TTS");

                DoubleValue addedTime = context.FindOnStack(Increment).Value as DoubleValue;
                if (addedTime != null)
                {
                    DateTime start       = new DateTime(year, month, day, hour, minute, second, tts);
                    DateTime currentTime = start.AddSeconds(addedTime.Val);

                    retVal = GetEfsDate(currentTime, startDate.Type as Structure);
                }
            }

            context.LocalScope.PopContext(token);

            return(retVal);
        }
示例#13
0
        /// <summary>
        ///     Provides the value of the function
        /// </summary>
        /// <param name="context"></param>
        /// <param name="actuals">the actual parameters values</param>
        /// <param name="explain"></param>
        /// <returns>The value for the function application</returns>
        public override IValue Evaluate(InterpretationContext context, Dictionary <Actual, IValue> actuals,
                                        ExplanationPart explain)
        {
            IValue retVal;

            int token = context.LocalScope.PushContext();

            AssignParameters(context, actuals);

            Function function = (Function)acceptor.getFactory().createFunction();

            function.Name      = "MINSURFACE (" + getName(First) + ", " + getName(Second) + ")";
            function.Enclosing = EFSSystem;
            function.Surface   = CreateSurface(context, explain);

            Parameter parameterX = (Parameter)acceptor.getFactory().createParameter();

            parameterX.Name = "X";
            parameterX.Type = EFSSystem.DoubleType;
            function.appendParameters(parameterX);

            Parameter parameterY = (Parameter)acceptor.getFactory().createParameter();

            parameterY.Name = "Y";
            parameterY.Type = EFSSystem.DoubleType;
            function.appendParameters(parameterY);

            function.ReturnType = EFSSystem.DoubleType;

            retVal = function;
            context.LocalScope.PopContext(token);

            return(retVal);
        }
示例#14
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>
        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>
 /// Constructor
 /// </summary>
 /// <param name="context"></param>
 /// <param name="statement"></param>
 /// <param name="variable"></param>
 /// <param name="explanation"></param>
 public InsertInListChange(InterpretationContext context, InsertStatement statement, IVariable variable, ExplanationPart explanation)
     : base(variable, null, null)
 {
     Context     = context;
     Statement   = statement;
     Explanation = explanation;
 }
示例#16
0
        /// <summary>
        ///     Provides the surface of this function if it has been statically defined
        /// </summary>
        /// <param name="context">the context used to create the surface</param>
        /// <param name="explain"></param>
        /// <returns></returns>
        public override Surface CreateSurface(InterpretationContext context, ExplanationPart explain)
        {
            Surface retVal = null;

            IValue  firstValue   = context.FindOnStack(First).Value;
            IValue  secondValue  = context.FindOnStack(Second).Value;
            Surface firstSurface = createSurfaceForValue(context, firstValue, explain);

            if (firstSurface != null)
            {
                Surface secondSurface = createSurfaceForValue(context, secondValue, explain);
                if (secondSurface != null)
                {
                    retVal = firstSurface.Min(secondSurface);
                }
                else
                {
                    Second.AddError("Cannot create surface for " + Second);
                }
            }
            else
            {
                First.AddError("Cannot create surface for " + First);
            }

            return(retVal);
        }
示例#17
0
        /// <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.Instance.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.Instance.BoolType.False);
                }
            }
        }
示例#18
0
        /// <summary>
        ///     Provides the value of the function
        /// </summary>
        /// <param name="context"></param>
        /// <param name="actuals">the actual parameters values</param>
        /// <param name="explain"></param>
        /// <returns>The value for the function application</returns>
        public override IValue Evaluate(InterpretationContext context, Dictionary <Actual, IValue> actuals,
                                        ExplanationPart explain)
        {
            IValue retVal = null;

            int token = context.LocalScope.PushContext();

            AssignParameters(context, actuals);

            ListValue value = context.FindOnStack(Collection) as ListValue;

            if (value != null)
            {
                Collection collectionType = value.Type as Collection;
                if (collectionType != null && collectionType.Type != null)
                {
                    Type elementType = collectionType.Type;

                    if (value.Val.Count >= collectionType.getMaxSize())
                    {
                        AddError("Cannot allocate element in list : list full");
                    }
                    else
                    {
                        retVal = elementType.DefaultValue;
                        value.Val.Add(retVal);
                    }
                }
            }
            context.LocalScope.PopContext(token);

            return(retVal);
        }
示例#19
0
        /// <summary>
        /// Provides the value of the function
        /// </summary>
        /// <param name="context"></param>
        /// <param name="actuals">the actual parameters values</param>
        /// <param name="explain"></param>
        /// <returns>The value for the function application</returns>
        public override IValue Evaluate(InterpretationContext context, Dictionary <Actual, IValue> actuals,
                                        ExplanationPart explain)
        {
            ListValue retVal = null;

            int token = context.LocalScope.PushContext();

            AssignParameters(context, actuals);

            StringValue value = context.FindOnStack(Value).Value as StringValue;

            if (value != null)
            {
                retVal = new ListValue(EfsSystem.Instance.StringCollection, new List <IValue>());

                foreach (char c in value.Val)
                {
                    StringValue character = new StringValue(EfsSystem.Instance.StringType, c.ToString(CultureInfo.InvariantCulture));
                    retVal.Val.Add(character);
                }
            }

            context.LocalScope.PopContext(token);

            return(retVal);
        }
示例#20
0
        /// <summary>
        ///     Evaluates the rule and its sub rules
        /// </summary>
        /// <param name="runner"></param>
        /// <param name="priority">the priority level : a rule can be activated only if its priority level == priority</param>
        /// <param name="instance">The instance on which the rule must be evaluated</param>
        /// <param name="activations">the rule conditions to be activated</param>
        /// <param name="explanation">The explanation part to be filled</param>
        /// <returns>the number of actions that were activated during this evaluation</returns>
        public bool Evaluate(Runner runner, acceptor.RulePriority?priority, IModelElement instance,
                             HashSet <Activation> activations, ExplanationPart explanation)
        {
            bool retVal = false;

            if (UpdatedBy.Count == 0 && !IsRemoved && (priority == null || ActivationPriorities.Contains((acceptor.RulePriority)priority)))
            {
                long start = Environment.TickCount;

                foreach (RuleCondition ruleCondition in RuleConditions)
                {
                    retVal = ruleCondition.Evaluate(runner, priority, instance, activations, explanation);
                    if (retVal)
                    {
                        break;
                    }
                }

                // Guard evaluation execution time
                long stop = Environment.TickCount;
                long span = (stop - start);
                ExecutionTimeInMilli += span;
            }

            return(retVal);
        }
示例#21
0
        /// <summary>
        ///     Provides the value associated to this Expression
        /// </summary>
        /// <param name="context">The context on which the value must be found</param>
        /// <param name="explain">The explanation to fill, if any</param>
        /// <returns></returns>
        protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain)
        {
            int       count = 0;
            ListValue value = ListExpression.GetValue(context, explain) as ListValue;

            if (value != null)
            {
                int token = PrepareIteration(context);
                foreach (IValue v in value.Val)
                {
                    if (v != EfsSystem.Instance.EmptyValue)
                    {
                        // All elements should always be != from EmptyValue
                        ElementFound           = true;
                        IteratorVariable.Value = v;
                        if (ConditionSatisfied(context, explain))
                        {
                            MatchingElementFound = true;
                            count += 1;
                        }
                    }
                    NextIteration();
                }
                EndIteration(context, explain, token);
            }

            return(new IntValue(EfsSystem.Instance.IntegerType, count));
        }
示例#22
0
        /// <summary>
        ///     Expression of the case
        /// </summary>
        /// <param name="context"></param>
        /// <param name="explain"></param>
        public bool EvaluatePreConditions(InterpretationContext context, ExplanationPart explain)
        {
            bool retVal = true;

            foreach (PreCondition preCondition in PreConditions)
            {
                Expression expression = preCondition.Expression;
                BoolValue  value      = expression.GetValue(context, explain) as BoolValue;

                if (value != null)
                {
                    retVal = retVal && value.Val;
                }
                else
                {
                    retVal = false;
                }

                if (!retVal)
                {
                    break;
                }
            }
            return(retVal);
        }
示例#23
0
        /// <summary>
        ///     Provides the value of the function
        /// </summary>
        /// <param name="context"></param>
        /// <param name="actuals">the actual parameters values</param>
        /// <param name="explain"></param>
        /// <returns>The value for the function application</returns>
        public override IValue Evaluate(InterpretationContext context, Dictionary <Actual, IValue> actuals,
                                        ExplanationPart explain)
        {
            IValue retVal = null;

            AssignParameters(context, actuals);
            Graph graph = createGraphForValue(context, context.FindOnStack(FunctionA).Value, explain);

            if (graph != null)
            {
                foreach (Graph.Segment segment in graph.Segments)
                {
                    if (segment.Expression.A == 0.0)
                    {
                        double speed = segment.Expression.V0;

                        Function function = context.FindOnStack(FunctionB).Value as Function;
                        if (function.FormalParameters.Count > 0)
                        {
                            Parameter functionParameter = (Parameter)function.FormalParameters[0];
                            Actual    actual            = functionParameter.CreateActual();
                            actual.Value = new DoubleValue(EFSSystem.DoubleType, speed);
                            Dictionary <Actual, IValue> values = new Dictionary <Actual, IValue>();
                            values[actual] = new DoubleValue(EFSSystem.DoubleType, speed);
                            IValue solution    = function.Evaluate(context, values, explain);
                            double doubleValue = GetDoubleValue(solution);

                            if (doubleValue >= segment.Start && doubleValue <= segment.End)
                            {
                                retVal = new DoubleValue(EFSSystem.DoubleType, doubleValue);
                                break;
                            }
                        }
                        else
                        {
                            FunctionB.AddError("The FunctionB doesn't have any parameter");
                            break;
                        }
                    }
                    else
                    {
                        FunctionA.AddError("The FunctionA is not a step function");
                        break;
                    }
                }
            }
            else
            {
                FunctionA.AddError("Cannot create graph for " + FunctionA);
            }

            if (retVal == null)
            {
                FunctionA.AddError("Cannot compute the intersection of " + FunctionA + " and " + FunctionB);
                FunctionB.AddError("Cannot compute the intersection of " + FunctionA + " and " + FunctionB);
            }

            return(retVal);
        }
示例#24
0
        private void openStructureEditorToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bool            dialogShown = false;
            ExplanationPart part        = Instance as ExplanationPart;

            if (part != null)
            {
                IValue value = part.RightPart as IValue;
                if (value != null)
                {
                    StructureEditor.Window window = new StructureEditor.Window();
                    window.SetModel(value);
                    window.ShowDialog();
                    dialogShown = true;
                }

                Action action = part.Element as Action;
                if (!dialogShown && action != null)
                {
                    VisitStatement(action.Statement);
                    dialogShown = true;
                }

                Expectation expectation = part.Element as Expectation;
                if (!dialogShown && expectation != null)
                {
                    VisitExpression(expectation.Expression);
                    dialogShown = true;
                }
            }

            if (!dialogShown)
            {
                const bool   doSemanticalAnalysis = true;
                const bool   silent = true;
                ModelElement root   = Instance as ModelElement;
                if (root == null)
                {
                    root = EfsSystem.Instance.Dictionaries[0];
                }

                string     text       = EditionTextBox.Text;
                Expression expression = new Parser().Expression(root, text, AllMatches.INSTANCE,
                                                                doSemanticalAnalysis, null, silent);
                if (expression != null)
                {
                    expression          = VisitExpression(expression);
                    EditionTextBox.Text = expression.ToString();
                }

                Statement statement = new Parser().Statement(root, text, silent);
                if (statement != null)
                {
                    statement           = VisitStatement(statement);
                    EditionTextBox.Text = statement.ToString();
                }
            }
        }
示例#25
0
        /// <summary>
        ///     Provides the value of the function
        /// </summary>
        /// <param name="context"></param>
        /// <param name="actuals">the actual parameters values</param>
        /// <param name="explain"></param>
        /// <returns>The value for the function application</returns>
        public override IValue Evaluate(InterpretationContext context, Dictionary <Actual, IValue> actuals,
                                        ExplanationPart explain)
        {
            IValue retVal = EFSSystem.BoolType.False;

            int token = context.LocalScope.PushContext();

            AssignParameters(context, actuals);

            ListValue collection = context.FindOnStack(Collection).Value as ListValue;

            if (collection != null)
            {
                IValue expectedFirst = context.FindOnStack(ExpectedFirst).Value;
                if (expectedFirst != null)
                {
                    int firstIndex = collection.Val.IndexOf(expectedFirst);
                    if (firstIndex >= 0)
                    {
                        IValue expectedSecond = context.FindOnStack(ExpectedSecond).Value;
                        if (expectedSecond != null)
                        {
                            int secondIndex = collection.Val.IndexOf(expectedSecond);

                            if (secondIndex >= 0)
                            {
                                if (firstIndex < secondIndex)
                                {
                                    retVal = EFSSystem.BoolType.True;
                                }
                            }
                            else
                            {
                                Collection.AddError("Cannot find " + expectedSecond.FullName + " in " +
                                                    collection.ToString() + " to evaluate " + Name);
                            }
                        }
                        else
                        {
                            Collection.AddError("Cannot evaluate second element to evaluate " + Name);
                        }
                    }
                    else
                    {
                        Collection.AddError("Cannot find " + expectedFirst.FullName + " in " + collection.ToString() +
                                            " to evaluate " + Name);
                    }
                }
                else
                {
                    Collection.AddError("Cannot evaluate first element to evaluate " + Name);
                }
            }
            context.LocalScope.PopContext(token);

            return(retVal);
        }
示例#26
0
        /// <summary>
        ///     Handles a double click event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TimeLineControl_DoubleClick(object sender, EventArgs e)
        {
            ModelEvent evt = GetEventUnderMouse();

            VariableUpdate variableUpdate = evt as VariableUpdate;

            if (variableUpdate != null)
            {
                ExplanationPart explain        = variableUpdate.Explanation;
                ExplainBox      explainTextBox = new ExplainBox();
                explainTextBox.SetExplanation(explain);
                GuiUtils.MdiWindow.AddChildWindow(explainTextBox);
            }

            RuleFired rulefired = evt as RuleFired;

            if (rulefired != null)
            {
                ExplanationPart explain        = rulefired.Explanation;
                ExplainBox      explainTextBox = new ExplainBox();
                explainTextBox.SetExplanation(explain);
                GuiUtils.MdiWindow.AddChildWindow(explainTextBox);
            }

            Expect expect = evt as Expect;

            if (expect != null)
            {
                Expectation expectation = expect.Expectation;

                if (expectation != null)
                {
                    ExplanationPart explanation = expect.Explanation;
                    if (explanation == null)
                    {
                        explanation = expectation.Explain;
                    }

                    ExplainBox explainTextBox = new ExplainBox();
                    explainTextBox.SetExplanation(explanation);
                    GuiUtils.MdiWindow.AddChildWindow(explainTextBox);
                }
            }

            ModelInterpretationFailure modelInterpretationFailure = evt as ModelInterpretationFailure;

            if (modelInterpretationFailure != null)
            {
                ExplainBox explainTextBox = new ExplainBox();
                explainTextBox.SetExplanation(modelInterpretationFailure.Explanation);
                GuiUtils.MdiWindow.AddChildWindow(explainTextBox);
            }
        }
示例#27
0
        /// <summary>
        ///     Provides the value of the function.
        ///     The function returns true if the string passes the check.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="actuals">the actual parameters values</param>
        /// <param name="explain"></param>
        /// <returns>The value for the function application</returns>
        public override IValue Evaluate(InterpretationContext context, Dictionary <Actual, IValue> actuals,
                                        ExplanationPart explain)
        {
            IValue retVal = EFSSystem.BoolType.False;

            int token = context.LocalScope.PushContext();

            AssignParameters(context, actuals);

            StringValue number = context.FindOnStack(Number).Value as StringValue;

            if (number != null && number.Val != "")
            {
                string       textValue = number.Val;
                NumberStyles style     = NumberStyles.Number;
                if (textValue.StartsWith("0x", StringComparison.CurrentCultureIgnoreCase))
                {
                    textValue = textValue.Substring(2);
                    style     = NumberStyles.HexNumber;
                }
                if (textValue.EndsWith(" h", StringComparison.CurrentCultureIgnoreCase))
                {
                    textValue = textValue.Substring(0, textValue.Length - 2);
                    style     = NumberStyles.HexNumber;
                }
                while (textValue[textValue.Length - 1] == 'F')
                {
                    textValue = textValue.Substring(0, textValue.Length - 1);
                    style     = NumberStyles.HexNumber;
                }

                if (style == NumberStyles.HexNumber)
                {
                    ulong val;
                    if (ulong.TryParse(textValue, style, CultureInfo.InvariantCulture, out val))
                    {
                        retVal = EFSSystem.BoolType.True;
                    }
                }
                else
                {
                    Decimal val;
                    if (Decimal.TryParse(textValue, style, CultureInfo.InvariantCulture, out val))
                    {
                        retVal = EFSSystem.BoolType.True;
                    }
                }
            }
            context.LocalScope.PopContext(token);

            return(retVal);
        }
        /// <summary>
        ///     Ends the iteration
        /// </summary>
        /// <param name="context"></param>
        /// <param name="explain"></param>
        /// <param name="token"></param>
        protected virtual void EndIteration(InterpretationContext context, ExplanationPart explain, int token)
        {
            if (!ElementFound)
            {
                ExplanationPart.CreateSubExplanation(explain, "Empty collection");
            }
            else if (!MatchingElementFound)
            {
                ExplanationPart.CreateSubExplanation(explain, "No matching element found");
            }

            context.LocalScope.PopContext(token);
        }
示例#29
0
        /// <summary>
        ///     Sets the explanation for this explain box
        /// </summary>
        /// <param name="explanation"></param>
        public void SetExplanation(ExplanationPart explanation)
        {
            Explanation = explanation;

            explainTreeView.Nodes.Clear();
            if (explanation != null)
            {
                ExplainTreeNode node = new ExplainTreeNode(explanation);
                node.UpdateText();
                InnerSetExplanation(explanation, node, 0);
                explainTreeView.Nodes.Add(node);
            }
        }
示例#30
0
        /// <summary>
        ///     Provides the surface of this function if it has been statically defined
        /// </summary>
        /// <param name="context">the context used to create the surface</param>
        /// <param name="xParam">The X axis of this surface</param>
        /// <param name="yParam">The Y axis of this surface</param>
        /// <param name="explain"></param>
        /// <returns>The surface which corresponds to this expression</returns>
        public override Surface CreateSurface(InterpretationContext context, Parameter xParam, Parameter yParam,
                                              ExplanationPart explain)
        {
            Surface retVal = base.CreateSurface(context, xParam, yParam, explain);

            Surface surface = InitialValue.CreateSurface(context, xParam, yParam, explain);

            if (surface != null)
            {
                ListValue value = ListExpression.GetValue(context, explain) as ListValue;
                if (value != null)
                {
                    int token = PrepareIteration(context);
                    AccumulatorVariable.Value = surface.Function;

                    foreach (IValue v in value.Val)
                    {
                        if (v != EfsSystem.Instance.EmptyValue)
                        {
                            // All elements should always be != from EmptyValue
                            ElementFound           = true;
                            IteratorVariable.Value = v;
                            if (ConditionSatisfied(context, explain))
                            {
                                MatchingElementFound      = true;
                                AccumulatorVariable.Value = IteratorExpression.GetValue(context, explain);
                            }
                        }
                        NextIteration();
                    }
                    Function function = AccumulatorVariable.Value as Function;
                    if (function != null)
                    {
                        retVal = function.Surface;
                    }
                    else
                    {
                        throw new Exception("Expression does not reduces to a function");
                    }
                    EndIteration(context, explain, token);
                }
            }
            else
            {
                throw new Exception("Cannot create surface for initial value " + InitialValue);
            }
            retVal.XParameter = xParam;
            retVal.YParameter = yParam;

            return(retVal);
        }
        /// <summary>
        ///     Indicates whether the condition is satisfied with the value provided
        ///     Hyp : the value of the iterator variable has been assigned before
        /// </summary>
        /// <param name="context"></param>
        /// <param name="explain"></param>
        /// <returns></returns>
        public bool ConditionSatisfied(InterpretationContext context, ExplanationPart explain)
        {
            bool retVal = true;

            if (Condition != null)
            {
                BoolValue b = Condition.GetExpressionValue(context, explain) as BoolValue;
                ExplanationPart.CreateSubExplanation(explain, Condition, b);

                if (b == null)
                {
                    retVal = false;
                }
                else
                {
                    retVal = b.Val;
                }
            }

            return retVal;
        }
        /// <summary>
        ///     Provides the value associated to this Expression
        /// </summary>
        /// <param name="context">The context on which the value must be found</param>
        /// <param name="explain">The explanation to fill, if any</param>
        /// <returns></returns>
        protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain)
        {
            IValue retVal = EfsSystem.Instance.EmptyValue;

            ListValue value = ListExpression.GetValue(context, explain) as ListValue;
            if (value != null)
            {
                int token = PrepareIteration(context);
                for (int i = value.Val.Count - 1; i >= 0; i--)
                {
                    IValue v = value.Val[i];

                    if (v != EfsSystem.Instance.EmptyValue)
                    {
                        // All elements should always be != from EmptyValue
                        ElementFound = true;
                        IteratorVariable.Value = v;
                        if (ConditionSatisfied(context, explain))
                        {
                            MatchingElementFound = true;
                            retVal = IteratorVariable.Value;
                            break;
                        }
                    }
                    NextIteration();
                }
                EndIteration(context, explain, token);
            }

            return retVal;
        }
        /// <summary>
        ///     Provides the value associated to this Expression
        /// </summary>
        /// <param name="context">The context on which the value must be found</param>
        /// <param name="explain">The explanation to fill, if any</param>
        /// <returns></returns>
        protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain)
        {
            IValue retVal = null;

            ListValue value = ListExpression.GetValue(context, explain) as ListValue;
            if (value != null)
            {
                int token = PrepareIteration(context);
                context.LocalScope.SetVariable(AccumulatorVariable);

                Type resultType = GetExpressionType();
                if (resultType != null)
                {
                    AccumulatorVariable.Value = resultType.getValue("0");
                    foreach (IValue v in value.Val)
                    {
                        if (v != EfsSystem.Instance.EmptyValue)
                        {
                            // All elements should always be != from EmptyValue
                            ElementFound = true;
                            IteratorVariable.Value = v;
                            if (ConditionSatisfied(context, explain))
                            {
                                MatchingElementFound = true;
                                AccumulatorVariable.Value = Accumulator.GetValue(context, explain);
                            }
                        }
                        NextIteration();
                    }
                }
                EndIteration(context, explain, token);

                retVal = AccumulatorVariable.Value;
            }

            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);

            // 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 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 value associated to this Expression
        /// </summary>
        /// <param name="context">The context on which the value must be found</param>
        /// <param name="explain">The explanation to fill, if any</param>
        /// <returns></returns>
        protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain)
        {
            IValue retVal = EfsSystem.Instance.EmptyValue;

            ListValue value = ListExpression.GetValue(context, explain) as ListValue;
            if (value != null)
            {
                int token = PrepareIteration(context);
                foreach (IValue v in value.Val)
                {
                    if (v != EfsSystem.Instance.EmptyValue)
                    {
                        ElementFound = true;
                        IteratorVariable.Value = v;
                        if (ConditionSatisfied(context, explain))
                        {
                            MatchingElementFound = true;
                            retVal = v;
                            break;
                        }
                    }
                    NextIteration();
                }

                EndIteration(context, explain, token);
            }

            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>
        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);
                }
            }
        }
 /// <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>
        /// 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>
        /// 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 value associated to this Expression
        /// </summary>
        /// <param name="context">The context on which the value must be found</param>
        /// <param name="explain">The explanation to fill, if any</param>
        /// <returns></returns>
        public override IValue GetValue(InterpretationContext context, ExplanationPart explain)
        {
            int count = 0;
            ListValue value = ListExpression.GetValue(context, explain) as ListValue;
            if (value != null)
            {
                int token = PrepareIteration(context);
                foreach (IValue v in value.Val)
                {
                    if (v != EFSSystem.EmptyValue)
                    {
                        ElementFound = true;
                        IteratorVariable.Value = v;
                        if (conditionSatisfied(context, explain))
                        {
                            MatchingElementFound = true;
                            count += 1;
                        }
                    }
                    NextIteration();
                }
                EndIteration(context, explain, token);
            }

            return new IntValue(EFSSystem.IntegerType, count);
            ;
        }
示例#42
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 value associated to this Expression
        /// </summary>
        /// <param name="context">The context on which the value must be found</param>
        /// <param name="explain">The explanation to fill, if any</param>
        /// <returns></returns>
        public override IValue GetValue(InterpretationContext context, ExplanationPart explain)
        {
            IValue retVal = null;

            ListValue value = ListExpression.GetValue(context, explain) as ListValue;
            if (value != null)
            {
                int token = PrepareIteration(context);
                retVal = EFSSystem.BoolType.False;
                foreach (IValue v in value.Val)
                {
                    if (v != EFSSystem.EmptyValue)
                    {
                        ElementFound = true;
                        IteratorVariable.Value = v;
                        if (Condition != null)
                        {
                            BoolValue b = Condition.GetValue(context, explain) as BoolValue;
                            if (b != null && b.Val)
                            {
                                MatchingElementFound = true;
                                retVal = EFSSystem.BoolType.True;
                                break;
                            }
                        }
                        else
                        {
                            retVal = EFSSystem.BoolType.True;
                            break;
                        }
                    }
                    NextIteration();
                }
                EndIteration(context, explain, token);
            }

            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>
        ///     Indicates whether the condition is satisfied with the value provided
        ///     Hyp : the value of the iterator variable has been assigned before
        /// </summary>
        /// <param name="context"></param>
        /// <param name="explain"></param>
        /// <returns></returns>
        public bool conditionSatisfied(InterpretationContext context, ExplanationPart explain)
        {
            bool retVal = true;

            if (Condition != null)
            {
                BoolValue b = Condition.GetValue(context, explain) as BoolValue;
                if (b == null)
                {
                    retVal = false;
                }
                else
                {
                    retVal = b.Val;
                }
            }

            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)
        {
            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);
        }
        /// <summary>
        ///     Provides the value associated to this Expression
        /// </summary>
        /// <param name="context">The context on which the value must be found</param>
        /// <param name="explain">The explanation to fill, if any</param>
        /// <returns></returns>
        protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain)
        {
            ListValue retVal = null;

            ListValue value = ListExpression.GetValue(context, explain) as ListValue;
            if (value != null)
            {
                int token = PrepareIteration(context);
                retVal = new ListValue((Collection) GetExpressionType(), new List<IValue>());
                List<IValue> range = new List<IValue>(value.Val);
                foreach (IValue v in range)
                {
                    if (v != EfsSystem.Instance.EmptyValue)
                    {
                        // All elements should always be != from EmptyValue
                        ElementFound = true;
                        IteratorVariable.Value = v;

                        if (ConditionSatisfied(context, explain))
                        {
                            MatchingElementFound = true;
                            retVal.Val.Add(IteratorExpression.GetValue(context, explain));
                        }
                    }
                    NextIteration();
                }
                EndIteration(context, explain, token);
            }

            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)
        {
            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>
        ///     Ends the iteration
        /// </summary>
        /// <param name="context"></param>
        /// <param name="explain"></param>
        /// <param name="token"></param>
        protected virtual void EndIteration(InterpretationContext context, ExplanationPart explain, int token)
        {
            if (!ElementFound)
            {
                ExplanationPart.CreateSubExplanation(explain, "Empty collection");
            }
            else if (!MatchingElementFound)
            {
                ExplanationPart.CreateSubExplanation(explain, "No matching element found");
            }

            context.LocalScope.PopContext(token);
        }
        /// <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>
        /// 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>
        ///     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>
        /// <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);
            }
        }
        /// <summary>
        ///     Provides the context on which function evaluation should be performed
        /// </summary>
        /// <param name="context"></param>
        /// <param name="explain"></param>
        /// <returns></returns>
        private InterpretationContext getContext(InterpretationContext context, ExplanationPart explain)
        {
            InterpretationContext retVal = context;

            DerefExpression deref = Call.Called as DerefExpression;
            if (deref != null)
            {
                IValue value = deref.GetPrefixValue(context, deref.Arguments.Count - 1, explain) as IValue;
                if (value != null)
                {
                    retVal = new InterpretationContext(context, value);
                }
            }

            return retVal;
        }
        /// <summary>
        ///     Provides the callable that is called by this expression
        /// </summary>
        /// <param name="context"></param>
        /// <param name="explain"></param>
        /// <returns></returns>
        public override ICallable GetCalled(InterpretationContext context, ExplanationPart explain)
        {
            ICallable retVal = null;

            Function function = InitialValue.Ref as Function;
            if (function == null)
            {
                function = InitialValue.GetCalled(context, explain) as Function;
            }

            if (function != null)
            {
                if (function.FormalParameters.Count == 1)
                {
                    int token = context.LocalScope.PushContext();
                    context.LocalScope.SetGraphParameter((Parameter) function.FormalParameters[0]);
                    Graph graph = CreateGraph(context, (Parameter) function.FormalParameters[0], explain);
                    context.LocalScope.PopContext(token);
                    if (graph != null)
                    {
                        retVal = graph.Function;
                    }
                }
                else if (function.FormalParameters.Count == 2)
                {
                    int token = context.LocalScope.PushContext();
                    context.LocalScope.SetSurfaceParameters((Parameter) function.FormalParameters[0],
                        (Parameter) function.FormalParameters[1]);
                    Surface surface = CreateSurface(context, (Parameter) function.FormalParameters[0],
                        (Parameter) function.FormalParameters[1], explain);
                    context.LocalScope.PopContext(token);
                    if (surface != null)
                    {
                        retVal = surface.Function;
                    }
                }
                else
                {
                    AddError("Cannot evaluate REDUCE expression to a function");
                }
            }
            else
            {
                AddError("Cannot evaluate REDUCE expression to a function");
            }

            return retVal;
        }
        /// <summary>
        ///     Provides the value associated to this Expression
        /// </summary>
        /// <param name="context">The context on which the value must be found</param>
        /// <param name="explain">The explanation to fill, if any</param>
        /// <returns></returns>
        protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain)
        {
            int count = 0;
            ListValue value = ListExpression.GetValue(context, explain) as ListValue;
            if (value != null)
            {
                int token = PrepareIteration(context);
                foreach (IValue v in value.Val)
                {
                    if (v != EfsSystem.Instance.EmptyValue)
                    {
                        // All elements should always be != from EmptyValue
                        ElementFound = true;
                        IteratorVariable.Value = v;
                        if (ConditionSatisfied(context, explain))
                        {
                            MatchingElementFound = true;
                            count += 1;
                        }
                    }
                    NextIteration();
                }
                EndIteration(context, explain, token);
            }

            return new IntValue(EfsSystem.Instance.IntegerType, count);
        }
        /// <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);
                }
            }
        }
        /// <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 value associated to this Expression
        /// </summary>
        /// <param name="context">The context on which the value must be found</param>
        /// <param name="explain">The explanation to fill, if any</param>
        /// <returns></returns>
        protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain)
        {
            IValue retVal = EfsSystem.Instance.BoolType.False;

            ListValue value = ListExpression.GetValue(context, explain) as ListValue;
            if (value != null)
            {
                int token = PrepareIteration(context);
                retVal = EfsSystem.Instance.BoolType.False;
                foreach (IValue v in value.Val)
                {
                    if (v != EfsSystem.Instance.EmptyValue)
                    {
                        // All elements should always be != from EmptyValue
                        ElementFound = true;
                        IteratorVariable.Value = v;
                        if (Condition != null)
                        {
                            BoolValue b = Condition.GetValue(context, explain) as BoolValue;
                            if (b != null && b.Val)
                            {
                                MatchingElementFound = true;
                                retVal = EfsSystem.Instance.BoolType.True;
                                break;
                            }
                        }
                        else
                        {
                            retVal = EfsSystem.Instance.BoolType.True;
                            break;
                        }
                    }
                    NextIteration();
                }
                EndIteration(context, explain, token);
            }

            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)
        {
            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());
            }
        }