/// <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>
        ///     Creates the graph associated to this expression, when the given parameter ranges over the X axis
        /// </summary>
        /// <param name="context">The interpretation context</param>
        /// <param name="parameter">The parameters of *the enclosing function* for which the graph should be created</param>
        /// <param name="explain"></param>
        /// <returns></returns>
        public override Graph createGraph(InterpretationContext context, Parameter parameter, ExplanationPart explain)
        {
            Graph retVal = base.createGraph(context, parameter, explain);

            retVal = Graph.createGraph(GetValue(context, explain), parameter, explain);

            if (retVal == null)
            {
                throw new Exception("Cannot create graph for " + ToString());
            }

            return retVal;
        }
        /// <summary>
        ///     Creates the graph associated to this expression, when the given parameter ranges over the X axis
        /// </summary>
        /// <param name="context">The interpretation context</param>
        /// <param name="parameter">The parameters of *the enclosing function* for which the graph should be created</param>
        /// <param name="explain"></param>
        /// <returns></returns>
        public override Graph CreateGraph(InterpretationContext context, Parameter parameter, ExplanationPart explain)
        {
            Graph retVal = base.CreateGraph(context, parameter, explain);

            if (Term != null)
            {
                retVal = Graph.createGraph(GetValue(context, explain), parameter, explain);
            }
            else if (Expression != null)
            {
                if (UnaryOp == null)
                {
                    retVal = Expression.CreateGraph(context, parameter, explain);
                }
                else if (UnaryOp == Minus)
                {
                    retVal = Expression.CreateGraph(context, parameter, explain);
                    retVal.Negate();
                }
                else
                {
                    throw new Exception("Cannot create graph where NOT operator is defined");
                }
            }

            return retVal;
        }
 /// <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 virtual Surface CreateSurface(InterpretationContext context, Parameter xParam, Parameter yParam,
     ExplanationPart explain)
 {
     return null;
 }
        /// <summary>
        /// Creates the graph associated to this expression, when the given parameter ranges over the X axis
        /// </summary>
        /// <param name="context">The interpretation context</param>
        /// <param name="parameter">The parameters of *the enclosing function* for which the graph should be created</param>
        /// <returns></returns>
        public override Functions.Graph createGraph(InterpretationContext context, Parameter parameter)
        {
            Functions.Graph retVal = base.createGraph(context, parameter);

            Functions.Graph graph = InitialValue.createGraph(context, parameter);
            if (graph != null)
            {
                Values.ListValue value = ListExpression.GetValue(context) as Values.ListValue;
                if (value != null)
                {
                    int token = PrepareIteration(context);
                    AccumulatorVariable.Value = graph.Function;

                    foreach (Values.IValue v in value.Val)
                    {
                        if (v != EFSSystem.EmptyValue)
                        {
                            IteratorVariable.Value = v;
                            if (conditionSatisfied(context))
                            {
                                AccumulatorVariable.Value = IteratorExpression.GetValue(context);
                            }
                        }
                        NextIteration();
                    }
                    Functions.Function function = AccumulatorVariable.Value as Functions.Function;
                    if (function != null)
                    {
                        retVal = function.Graph;
                    }
                    else
                    {
                        retVal = Functions.Function.createGraphForValue(AccumulatorVariable.Value);
                    }
                    EndIteration(context, token);
                }
            }
            else
            {
                throw new Exception("Cannot create graph for initial value " + InitialValue.ToString());
            }

            return retVal;
        }
        /// <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>
        /// <returns>The surface which corresponds to this expression</returns>
        public override Functions.Surface createSurface(Interpreter.InterpretationContext context, Parameter xParam, Parameter yParam)
        {
            Functions.Surface retVal = base.createSurface(context, xParam, yParam);

            retVal = Functions.Surface.createSurface(GetValue(context), xParam, yParam);

            if (retVal == null)
            {
                throw new Exception("Cannot create surface for " + ToString());
            }
            retVal.XParameter = xParam;
            retVal.YParameter = yParam;

            return retVal;
        }
        /// <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>
        /// <returns>The surface which corresponds to this expression</returns>
        public override Functions.Surface createSurface(Interpreter.InterpretationContext context, Parameter xParam, Parameter yParam)
        {
            Functions.Surface retVal = base.createSurface(context, xParam, yParam);

            if (xParam == null || yParam == null)
            {
                AddError("Cannot have null parameters for Function expression " + ToString());
            }
            else
            {
                int token = context.LocalScope.PushContext();
                Parameter xAxis = Parameters[0];
                Parameter yAxis = Parameters[1];
                context.LocalScope.setSurfaceParameters(xAxis, yAxis);
                retVal = Expression.createSurface(context, xAxis, yAxis);
                context.LocalScope.PopContext(token);
            }
            retVal.XParameter = xParam;
            retVal.YParameter = yParam;

            return retVal;
        }
        /// <summary>
        /// Provides the graph of this function if it has been statically defined
        /// </summary>
        /// <param name="context">the context used to create the graph</param>
        /// <returns></returns>
        public virtual Graph createGraph(Interpreter.InterpretationContext context, Parameter parameter)
        {
            Graph retVal = Graph;

            if (retVal == null)
            {
                try
                {
                    Interpreter.InterpretationContext ctxt = new Interpreter.InterpretationContext(context);
                    if (Cases.Count > 0)
                    {
                        // For now, just create graphs for functions using 0 or 1 parameter.
                        if (FormalParameters.Count == 0)
                        {
                            Values.IValue value = Evaluate(ctxt, new Dictionary<Variables.Actual, Values.IValue>());
                            retVal = Graph.createGraph(value, parameter);
                        }
                        else if (FormalParameters.Count == 1)
                        {
                            Parameter param = (Parameter)FormalParameters[0];
                            int token = ctxt.LocalScope.PushContext();
                            Values.IValue actualValue = null;
                            if (parameter != null)
                            {
                                Variables.IVariable actual = ctxt.findOnStack(parameter);
                                if (actual != null)
                                {
                                    actualValue = actual.Value;
                                }
                                else
                                {
                                    actualValue = new Values.PlaceHolder(parameter.Type, 1);
                                }

                                ctxt.LocalScope.setParameter(param, actualValue);
                            }
                            retVal = createGraphForParameter(ctxt, param);

                            if (getCacheable() && actualValue is Values.PlaceHolder)
                            {
                                Graph = retVal;
                            }

                            ctxt.LocalScope.PopContext(token);
                        }
                        else
                        {
                            Values.IValue value = Evaluate(ctxt, new Dictionary<Variables.Actual, Values.IValue>());
                            retVal = Graph.createGraph(value, parameter);
                        }
                    }
                }
                catch (Exception e)
                {
                    AddError("Cannot create graph of function, reason : " + e.Message);
                }
            }

            return retVal;
        }
        /// <summary>
        /// Creates the graph for a given parameter, the other parameters are considered fixed by the interpretation context
        /// </summary>
        /// <param name="context">The interpretation context</param>
        /// <param name="parameter">The parameter for the X axis</param>
        /// <returns></returns>
        public virtual Graph createGraphForParameter(Interpreter.InterpretationContext context, Parameter parameter)
        {
            Graph retVal = Graph;

            if (retVal == null)
            {
                retVal = new Graph();

                foreach (Case cas in Cases)
                {
                    if (PreconditionSatisfied(context, cas, parameter))
                    {
                        Graph subGraph = cas.Expression.createGraph(context, parameter);
                        ReduceGraph(context, subGraph, cas, parameter);
                        retVal.Merge(subGraph);
                    }
                }
            }

            return retVal;
        }
        /// <summary>
        /// Reduces the X axis of the surface according to the preconditions of this case
        /// </summary>
        /// <param name="context">The context used to reduce the surface</param>
        /// <param name="cas">The case used to reduce the surface</param>
        /// <param name="surface">The surface to reduce</param>
        /// <param name="parameter">The parameter for which the reduction has been performed</param>
        /// <returns>The reduced surface</returns>
        private Surface ReduceSurface(Interpreter.InterpretationContext context, Case cas, Surface surface, out Parameter parameter)
        {
            Surface retVal;

            // Evaluate the axis
            parameter = null;
            foreach (Rules.PreCondition preCondition in cas.PreConditions)
            {
                List<Graph.Segment> boundaries = EvaluateBoundaries(context, preCondition, surface.XParameter);
                if (boundaries.Count != 0 && !fullRange(boundaries))
                {
                    if (parameter != surface.YParameter)
                    {
                        parameter = surface.XParameter;
                    }
                    else
                    {
                        throw new Exception("Cannot reduce a graph on both X axis and Y axis on the same time (1)");
                    }
                }
                else
                {
                    boundaries = EvaluateBoundaries(context, preCondition, surface.YParameter);
                    if (boundaries.Count != 0 && !fullRange(boundaries))
                    {
                        if (parameter != surface.XParameter)
                        {
                            parameter = surface.YParameter;
                        }
                        else
                        {
                            throw new Exception("Cannot reduce a graph on both X axis and Y axis on the same time (2)");
                        }
                    }
                }
            }

            if (parameter == surface.XParameter)
            {
                // Reduce the surface on the X axis
                retVal = new Surface(surface.XParameter, surface.YParameter);
                foreach (Surface.Segment segment in surface.Segments)
                {
                    retVal.AddSegment(new Surface.Segment(segment));
                }

                // Reduces the segments according to this preconditions
                foreach (Rules.PreCondition preCondition in cas.PreConditions)
                {
                    List<Graph.Segment> boundaries = EvaluateBoundaries(context, preCondition, surface.XParameter);
                    retVal.Reduce(boundaries);
                }
            }
            else if (parameter == surface.YParameter)
            {
                // Reduce the surface, for all segments of the X axis, on the Y axis
                retVal = new Surface(surface.XParameter, surface.YParameter);
                foreach (Surface.Segment segment in surface.Segments)
                {
                    // Reduces the segments according to this preconditions
                    foreach (Rules.PreCondition preCondition in cas.PreConditions)
                    {
                        List<Graph.Segment> boundaries = EvaluateBoundaries(context, preCondition, surface.YParameter);
                        segment.Graph.Reduce(boundaries);
                    }
                    if (!segment.Empty())
                    {
                        retVal.AddSegment(segment);
                    }
                }
            }
            else
            {
                retVal = surface;
            }

            return retVal;
        }
        /// <summary>
        /// Selects the Y axis of the surface, according to the X parameter
        /// </summary>
        /// <returns>the Y axis if the surface</returns>
        private Parameter SelectYAxisParameter(Parameter Xparameter)
        {
            Parameter retVal = (Parameter)FormalParameters[0];

            if (retVal == Xparameter)
            {
                retVal = (Parameter)FormalParameters[1];
            }

            return retVal;
        }
 /// <summary>
 /// Reduces the graph to the only part releated to the preconditions
 /// </summary>
 /// <param name="context">The context used to evaluate the precondition and segment value</param>
 /// <param name="graph">The graph to reduce</param>
 /// <param name="cas">The case which is used to reduce the graph</param>
 /// <param name="parameter"></param>
 /// <returns></returns>
 private void ReduceGraph(Interpreter.InterpretationContext context, Graph graph, Case cas, Parameter parameter)
 {
     foreach (Rules.PreCondition preCondition in cas.PreConditions)
     {
         List<Graph.Segment> boundaries = EvaluateBoundaries(context, preCondition, parameter);
         graph.Reduce(boundaries);
     }
 }
        /// <summary>
        /// Indicates whether all preconditions are satisfied for a given case, ignoring expressions like x (y) <= xxx or x (y) >= xxx
        /// </summary>
        /// <param name="context">The interpretation context</param>
        /// <param name="cas">The case to evaluate</param>
        /// <param name="x">First parameter</param>
        /// <param name="y">Second parameter</param>
        /// <returns></returns>
        private bool PreconditionSatisfied(Interpreter.InterpretationContext context, Case cas, Parameter x, Parameter y)
        {
            bool retVal = true;

            foreach (Rules.PreCondition preCondition in cas.PreConditions)
            {
                if (!ExpressionBasedOnParameter(x, preCondition.ExpressionTree) && !ExpressionBasedOnParameter(y, preCondition.ExpressionTree))
                {
                    Values.BoolValue boolValue = preCondition.ExpressionTree.GetValue(context) as Values.BoolValue;
                    if (boolValue == null)
                    {
                        throw new Exception("Cannot evaluate precondition " + preCondition.Name);
                    }
                    else if (!boolValue.Val)
                    {
                        retVal = false;
                        break;
                    }
                }
            }

            return retVal;
        }
        /// <summary>
        /// Indicates that the expression is a function call using the parameter as argument value
        /// </summary>
        /// <param name="expression">The expression to evaluate</param>
        /// <param name="parameter">The parameter</param>
        /// <returns></returns>
        private bool FunctionCallOnParameter(Interpreter.Expression expression, Parameter parameter)
        {
            bool retVal = false;

            Interpreter.Call call = expression as Interpreter.Call;
            if (call != null)
            {
                foreach (Interpreter.Expression expr in call.AllParameters)
                {
                    foreach (Types.ITypedElement element in expr.GetRightSides())
                    {
                        if (element == parameter)
                        {
                            retVal = true;
                            break;
                        }
                    }
                }
            }

            return retVal;
        }
Example #15
0
        /// <summary>
        ///     Selects the X and Y axis of the surface to be created according to the function for which the surface need be
        ///     created and the parameters on which the surface is created
        /// </summary>
        /// <param name="context">The interpretation context</param>
        /// <param name="xParam">The X parameter for which the surface need be created</param>
        /// <param name="yParam">The Y parameter for which the surface need be created</param>
        /// <param name="function">The function creating the surface</param>
        /// <param name="Xaxis">The resulting X axis</param>
        /// <param name="Yaxis">The resulting Y axis</param>
        /// <returns>true if the axis could be selected</returns>
        private void SelectXandYAxis(InterpretationContext context, Parameter xParam, Parameter yParam,
            Function function, out Parameter Xaxis, out Parameter Yaxis)
        {
            Xaxis = null;
            Yaxis = null;

            Dictionary<Parameter, Expression> association = getParameterAssociation(function);
            if (association != null)
            {
                foreach (KeyValuePair<Parameter, Expression> pair in association)
                {
                    if (pair.Value.Ref == xParam)
                    {
                        if (Xaxis == null)
                        {
                            Xaxis = pair.Key;
                        }
                        else
                        {
                            Root.AddError("Cannot evaluate surface for function call " + ToString() +
                                          " which has more than 1 X axis parameter");
                            Xaxis = null;
                            break;
                        }
                    }

                    if (pair.Value.Ref == yParam)
                    {
                        if (Yaxis == null)
                        {
                            Yaxis = pair.Key;
                        }
                        else
                        {
                            Root.AddError("Cannot evaluate surface for function call " + ToString() +
                                          " which has more than 1 Y axis parameter");
                            Yaxis = null;
                            break;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Provides the surface of this function if it has been statically defined
        /// </summary>
        /// <param name="context">the context used to create the graph</param>
        /// <param name="Xparameter">The parameter used for the X axis</param>
        /// <param name="Yparameter">The parameter used for the Y axis</param>
        /// <returns></returns>
        public virtual Surface createSurfaceForParameters(Interpreter.InterpretationContext context, Parameter Xparameter, Parameter Yparameter)
        {
            Surface retVal = Surface;

            if (retVal == null)
            {
                if (Xparameter != null)
                {
                    if (Yparameter != null)
                    {
                        if (Cases.Count > 0)
                        {
                            retVal = new Surface(Xparameter, Yparameter);

                            foreach (Case cas in Cases)
                            {
                                if (PreconditionSatisfied(context, cas, Xparameter, Yparameter))
                                {
                                    Surface surface = cas.Expression.createSurface(context, Xparameter, Yparameter);
                                    if (surface != null)
                                    {
                                        Parameter parameter = null;
                                        surface = ReduceSurface(context, cas, surface, out parameter);

                                        if (parameter == null || parameter == surface.XParameter)
                                        {
                                            retVal.MergeX(surface);
                                        }
                                        else
                                        {
                                            retVal = Surface.MergeY(retVal, surface);
                                        }
                                    }
                                    else
                                    {
                                        AddError("Cannot create surface for expression " + cas.ExpressionText);
                                        retVal = null;
                                        break;
                                    }
                                }
                            }
                        }
                        else if (Graph != null)
                        {
                            // The function is defined by a graph
                            // Extend it to a surface
                            // TODO: Check the right parameter
                            retVal = Graph.ToSurfaceX();
                            retVal.XParameter = Xparameter;
                            retVal.YParameter = Yparameter;
                        }
                        else
                        {
                            AddError("cannot create surface for function " + Name + " with given parameters");
                        }
                    }
                    else
                    {
                        // Function with 1 parameter that ranges over the Xaxis
                        retVal = new Surface(Xparameter, Yparameter);
                        Functions.Graph graph = createGraphForParameter(context, Xparameter);
                        foreach (Graph.Segment segment in graph.Segments)
                        {
                            Graph newGraph = Graph.createGraph(segment.Expression.v0);
                            Surface.Segment newSegment = new Surface.Segment(segment.Start, segment.End, newGraph);
                            retVal.AddSegment(newSegment);
                        }
                    }
                }
                else if (Yparameter != null)
                {
                    // TODO : Remove check code
                    if ((Yparameter.Enclosing != this))
                    {
                        System.Diagnostics.Debugger.Break();
                    }

                    // Function with 1 parameter that ranges over the Yaxis
                    retVal = new Surface(Xparameter, Yparameter);
                    Graph graph = createGraphForParameter(context, Yparameter);
                    Surface.Segment segment = new Functions.Surface.Segment(0, double.MaxValue, graph);
                    retVal.AddSegment(segment);
                }
                else
                {
                    AddError("Invalid parameters for surface creation");
                }
            }

            retVal.XParameter = Xparameter;
            retVal.YParameter = Yparameter;

            return retVal;
        }
        /// <summary>
        /// Creates the graph associated to this expression, when the given parameter ranges over the X axis
        /// </summary>
        /// <param name="context">The interpretation context</param>
        /// <param name="parameter">The parameters of *the enclosing function* for which the graph should be created</param>
        /// <returns></returns>
        public override Functions.Graph createGraph(InterpretationContext context, Parameter parameter)
        {
            Functions.Graph retVal = base.createGraph(context, parameter);

            retVal = Functions.Graph.createGraph(GetValue(context), parameter);

            if (retVal == null)
            {
                throw new Exception("Cannot create graph for " + ToString());
            }

            return retVal;
        }
        /// <summary>
        /// Provides the surface which corresponds to the parameters provided
        /// </summary>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <returns></returns>
        public Surface getSurface(Parameter X, Parameter Y)
        {
            Surface retVal = null;

            if (Surface != null)
            {
                // TODO : Ensure parameters are OK
                retVal = Surface;
            }
            else if (Graph != null)
            {
                // TODO : Check parameters name for conversion to X surface (or not done here) Y surface
                Parameter parameter = (Parameter)FormalParameters[0];
                retVal = this.Graph.ToSurfaceX();
            }

            if (getCacheable())
            {
                Surface = retVal;
            }

            return retVal;
        }
        /// <summary>
        /// Creates the graph associated to this expression, when the given parameter ranges over the X axis
        /// </summary>
        /// <param name="context">The interpretation context</param>
        /// <param name="parameter">The parameters of *the enclosing function* for which the graph should be created</param>
        /// <returns></returns>
        public override Functions.Graph createGraph(InterpretationContext context, Parameter parameter)
        {
            Functions.Graph retVal = base.createGraph(context, parameter);

            if (parameter == Parameters[0] || parameter == Parameters[1])
            {
                retVal = Expression.createGraph(context, parameter);
            }
            else
            {
                throw new Exception("Cannot create graph for parameter " + parameter.Name);
            }

            return retVal;
        }
        /// <summary>
        /// Evaluates the boundaries associated to a specific preCondition
        /// </summary>
        /// <param name="context">The context used to evaluate the precondition and segment value</param>
        /// <param name="preCondition">The precondition to evaluate the range</param>
        /// <param name="parameter"></param>
        /// <returns></returns>
        private List<Graph.Segment> EvaluateBoundaries(Interpreter.InterpretationContext context, Rules.PreCondition preCondition, Parameter parameter)
        {
            List<Graph.Segment> retVal = new List<Graph.Segment>();

            if (parameter != null)
            {
                Interpreter.BinaryExpression expression = preCondition.ExpressionTree as Interpreter.BinaryExpression;
                if (ExpressionBasedOnParameter(parameter, expression))
                {
                    Values.IValue val;
                    if (expression.Right.Ref == parameter)
                    {
                        // Expression like xxx <= Parameter
                        val = expression.Left.GetValue(context);
                        switch (expression.Operation)
                        {
                            case Interpreter.BinaryExpression.OPERATOR.LESS:
                            case Interpreter.BinaryExpression.OPERATOR.LESS_OR_EQUAL:
                                retVal.Add(new Graph.Segment(getDoubleValue(val), double.MaxValue, new Graph.Segment.Curve()));
                                break;

                            case Interpreter.BinaryExpression.OPERATOR.GREATER:
                            case Interpreter.BinaryExpression.OPERATOR.GREATER_OR_EQUAL:
                                retVal.Add(new Graph.Segment(0, getDoubleValue(val), new Graph.Segment.Curve()));
                                break;

                            default:
                                throw new Exception("Invalid comparison operator while evaluating Graph of function");
                        }
                    }
                    else
                    {
                        if (expression.Left.Ref == parameter)
                        {
                            // Expression like Parameter <= xxx
                            val = expression.Right.GetValue(context);
                            switch (expression.Operation)
                            {
                                case Interpreter.BinaryExpression.OPERATOR.LESS:
                                case Interpreter.BinaryExpression.OPERATOR.LESS_OR_EQUAL:
                                    retVal.Add(new Graph.Segment(0, getDoubleValue(val), new Graph.Segment.Curve()));
                                    break;

                                case Interpreter.BinaryExpression.OPERATOR.GREATER:
                                case Interpreter.BinaryExpression.OPERATOR.GREATER_OR_EQUAL:
                                    retVal.Add(new Graph.Segment(getDoubleValue(val), double.MaxValue, new Graph.Segment.Curve()));
                                    break;

                                default:
                                    throw new Exception("Invalid comparison operator while evaluating Graph of function");
                            }
                        }
                        else
                        {
                            if (FunctionCallOnParameter(expression.Right, parameter))
                            {
                                Graph graph = expression.Right.createGraph(context, parameter);
                                if (graph != null)
                                {
                                    // Expression like xxx <= f(Parameter)
                                    val = expression.Left.GetValue(context);
                                    retVal = graph.GetSegments(Interpreter.BinaryExpression.Inverse(expression.Operation), getDoubleValue(val));
                                }
                                else
                                {
                                    AddError("Cannot create graph for " + expression.Right);
                                }
                            }
                            else
                            {
                                Graph graph = expression.Left.createGraph(context, parameter);
                                if (graph != null)
                                {
                                    // Expression like f(Parameter) <= xxx
                                    val = expression.Right.GetValue(context);
                                    retVal = graph.GetSegments(expression.Operation, getDoubleValue(val));
                                }
                                else
                                {
                                    throw new Exception("Cannot evaluate bounds of segment");
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (!ExpressionBasedOnPlaceHolder(context, expression))
                    {
                        Values.BoolValue value = preCondition.ExpressionTree.GetValue(context) as Values.BoolValue;
                        if (value != null && value.Val)
                        {
                            retVal.Add(new Graph.Segment(0, double.MaxValue, new Graph.Segment.Curve()));
                        }
                    }
                }
            }
            else
            {
                AddError("Parameter is null");
            }

            return retVal;
        }
 /// <summary>
 ///     Creates the graph associated to this expression, when the given parameter ranges over the X axis
 /// </summary>
 /// <param name="context">The interpretation context</param>
 /// <param name="parameter">The parameters of *the enclosing function* for which the graph should be created</param>
 /// <param name="explain"></param>
 /// <returns></returns>
 public virtual Graph CreateGraph(InterpretationContext context, Parameter parameter, ExplanationPart explain)
 {
     return null;
 }
        /// <summary>
        /// Indicates if the expression if of the form parameter <= xxx or xxx <= parameter
        /// </summary>
        /// <param name="parameter">The parameter of the template</param>
        /// <param name="expression">The expression to analyze</param>
        /// <returns></returns>
        private bool ExpressionBasedOnParameter(Parameter parameter, Interpreter.Expression expression)
        {
            bool retVal = false;

            Interpreter.BinaryExpression binaryExpression = expression as Interpreter.BinaryExpression;
            if (binaryExpression != null)
            {
                retVal = binaryExpression.Right.Ref == parameter
                      || binaryExpression.Left.Ref == parameter
                      || FunctionCallOnParameter(binaryExpression.Right, parameter)
                      || FunctionCallOnParameter(binaryExpression.Left, parameter);
            }

            return retVal;
        }
        /// <summary>
        ///     Creates the graph associated to this expression, when the given parameter ranges over the X axis
        /// </summary>
        /// <param name="context">The interpretation context</param>
        /// <param name="parameter">The parameters of *the enclosing function* for which the graph should be created</param>
        /// <param name="explain"></param>
        /// <returns></returns>
        public override Graph CreateGraph(InterpretationContext context, Parameter parameter, ExplanationPart explain)
        {
            Graph retVal = Graph.createGraph(GetValue(context, explain), parameter, explain);

            return retVal;
        }
Example #24
0
        /// <summary>
        ///     Creates the graph associated to this expression, when the given parameter ranges over the X axis
        /// </summary>
        /// <param name="context">The interpretation context</param>
        /// <param name="parameter">The parameters of *the enclosing function* for which the graph should be created</param>
        /// <param name="explain"></param>
        /// <returns></returns>
        public override Graph createGraph(InterpretationContext context, Parameter parameter, ExplanationPart explain)
        {
            Graph retVal = base.createGraph(context, parameter, explain);

            Cast cast = Called.Ref as Cast;
            if (cast != null)
            {
                // In case of cast, just take the graph of the enclosed expression
                Parameter param = (Parameter) cast.FormalParameters[0];
                retVal = cast.createGraphForParameter(context, param, explain);
            }

            Function calledFunction = Called.Ref as Function;
            Dictionary<Parameter, Expression> parameterAssociation = null;
            if (calledFunction == null)
            {
                calledFunction = Called.GetValue(context, explain) as Function;
                parameterAssociation = createParameterAssociation(calledFunction);
            }
            else
            {
                parameterAssociation = ParameterAssociation;
            }

            Parameter Xaxis = null;
            foreach (KeyValuePair<Parameter, Expression> pair in parameterAssociation)
            {
                if (pair.Value.Ref == parameter)
                {
                    if (Xaxis == null)
                    {
                        Xaxis = pair.Key;
                    }
                    else
                    {
                        Root.AddError("Cannot evaluate graph for function call " + ToString() +
                                      " which has more than 1 parameter used as X axis");
                        Xaxis = null;
                        break;
                    }
                }
            }

            int token = context.LocalScope.PushContext();
            calledFunction.AssignParameters(context, AssignParameterValues(context, calledFunction, false, explain));
            if (Xaxis != null)
            {
                retVal = calledFunction.createGraphForParameter(context, Xaxis, explain);
            }
            else
            {
                retVal = Function.createGraphForValue(GetValue(context, explain));
            }
            context.LocalScope.PopContext(token);

            return retVal;
        }
        /// <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>
        /// <returns>The surface which corresponds to this expression</returns>
        public override Functions.Surface createSurface(Interpreter.InterpretationContext context, Parameter xParam, Parameter yParam)
        {
            Functions.Surface retVal = base.createSurface(context, xParam, yParam);

            Functions.Surface surface = InitialValue.createSurface(context, xParam, yParam);
            if (surface != null)
            {
                Values.ListValue value = ListExpression.GetValue(context) as Values.ListValue;
                if (value != null)
                {
                    int token = PrepareIteration(context);
                    AccumulatorVariable.Value = surface.Function;

                    foreach (Values.IValue v in value.Val)
                    {
                        if (v != EFSSystem.EmptyValue)
                        {
                            IteratorVariable.Value = v;
                            if (conditionSatisfied(context))
                            {
                                AccumulatorVariable.Value = IteratorExpression.GetValue(context);
                            }
                        }
                        NextIteration();
                    }
                    Functions.Function function = AccumulatorVariable.Value as Functions.Function;
                    if (function != null)
                    {
                        retVal = function.Surface;
                    }
                    else
                    {
                        throw new Exception("Expression does not reduces to a function");
                    }
                    EndIteration(context, token);
                }
            }
            else
            {
                throw new Exception("Cannot create surface for initial value " + InitialValue.ToString());
            }
            retVal.XParameter = xParam;
            retVal.YParameter = yParam;

            return retVal;
        }
Example #26
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);

            Function function = getFunction(context, explain);
            Cast cast = Called.Ref as Cast;
            if (cast != null)
            {
                // In case of cast, just take the surface of the enclosed expression
                Expression actual = (Expression) ActualParameters[0];
                retVal = actual.createSurface(context, xParam, yParam, explain);
            }
            else
            {
                Parameter Xaxis = null;
                Parameter Yaxis = null;

                if (function == null)
                {
                    function = Called.getCalled(context, explain) as Function;
                }

                SelectXandYAxis(context, xParam, yParam, function, out Xaxis, out Yaxis);
                if (Xaxis != null || Yaxis != null)
                {
                    int token = context.LocalScope.PushContext();
                    function.AssignParameters(context, AssignParameterValues(context, function, true, explain));
                    retVal = function.createSurfaceForParameters(context, Xaxis, Yaxis, explain);
                    context.LocalScope.PopContext(token);
                }
                else
                {
                    IValue value = GetValue(context, explain);
                    if (value != null)
                    {
                        retVal = Surface.createSurface(value, xParam, yParam);
                    }
                    else
                    {
                        throw new Exception("Cannot create surface for expression");
                    }
                }
            }
            retVal.XParameter = xParam;
            retVal.YParameter = yParam;

            return retVal;
        }
        /// <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);

            retVal = Surface.createSurface(GetValue(context, explain), xParam, yParam);

            if (retVal == null)
            {
                throw new Exception("Cannot create surface for " + ToString());
            }
            retVal.XParameter = xParam;
            retVal.YParameter = yParam;

            return retVal;
        }
Example #28
0
        private void CheckActualAgainstFormal(Dictionary<string, Expression> actuals, Expression expression,
            Parameter parameter)
        {
            actuals[parameter.Name] = expression;

            expression.checkExpression();
            Type argumentType = expression.GetExpressionType();
            if (argumentType == null)
            {
                AddError("Cannot evaluate argument type for argument " + expression.ToString());
            }
            else
            {
                if (parameter.Type == null)
                {
                    AddError("Cannot evaluate formal parameter type for " + parameter.Name);
                }
                else
                {
                    if (!parameter.Type.Match(argumentType))
                    {
                        AddError("Invalid argument " + expression.ToString() + " type, expected " +
                                 parameter.Type.FullName + ", actual " + argumentType.FullName);
                    }
                }
            }
        }
        /// <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);

            if (Term != null)
            {
                retVal = Surface.createSurface(xParam, yParam, GetValue(context, explain), explain);
            }
            else if (Expression != null)
            {
                if (UnaryOp == null)
                {
                    retVal = Expression.CreateSurface(context, xParam, yParam, explain);
                }
                else
                {
                    if (UnaryOp == Minus)
                    {
                        retVal = Expression.CreateSurface(context, xParam, yParam, explain);
                        retVal.Negate();
                    }
                    else
                    {
                        AddError("Cannot create surface with unary op " + UnaryOp);
                    }
                }
            }
            retVal.XParameter = xParam;
            retVal.YParameter = yParam;

            return retVal;
        }
        /// <summary>
        ///     Creates the graph associated to this expression, when the given parameter ranges over the X axis
        /// </summary>
        /// <param name="context">The interpretation context</param>
        /// <param name="parameter">The parameters of *the enclosing function* for which the graph should be created</param>
        /// <param name="explain"></param>
        /// <returns></returns>
        public override Graph CreateGraph(InterpretationContext context, Parameter parameter, ExplanationPart explain)
        {
            Graph retVal = base.CreateGraph(context, parameter, explain);

            Graph graph = InitialValue.CreateGraph(context, parameter, explain);
            if (graph != null)
            {
                ListValue value = ListExpression.GetValue(context, explain) as ListValue;
                if (value != null)
                {
                    int token = PrepareIteration(context);
                    AccumulatorVariable.Value = graph.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.Graph;
                    }
                    else
                    {
                        retVal = Function.CreateGraphForValue(AccumulatorVariable.Value);
                    }
                    EndIteration(context, explain, token);
                }
            }
            else
            {
                throw new Exception("Cannot create graph for initial value " + InitialValue);
            }

            return retVal;
        }