/// <summary>
        /// Combines two graphs using the operator of this binary expression
        /// </summary>
        /// <param name="leftGraph"></param>
        /// <param name="rightGraph"></param>
        /// <returns></returns>
        private Functions.Graph combineGraph(Functions.Graph leftGraph, Functions.Graph rightGraph)
        {
            Functions.Graph retVal = null;

            switch (Operation)
            {
            case BinaryExpression.OPERATOR.ADD:
                retVal = leftGraph.AddGraph(rightGraph);
                break;

            case BinaryExpression.OPERATOR.SUB:
                retVal = leftGraph.SubstractGraph(rightGraph);
                break;

            case BinaryExpression.OPERATOR.MULT:
                retVal = leftGraph.MultGraph(rightGraph);
                break;

            case BinaryExpression.OPERATOR.DIV:
                retVal = leftGraph.DivGraph(rightGraph);
                break;
            }

            return(retVal);
        }
Exemple #2
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>
        /// <returns></returns>
        public override Functions.Graph createGraph(InterpretationContext context, Parameter parameter)
        {
            Functions.Graph retVal = base.createGraph(context, parameter);

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

            return(retVal);
        }
        /// <summary>
        /// Creates the result as a surface
        /// </summary>
        /// <param name="context"></param>
        /// <param name="leftFunction"></param>
        /// <param name="unboundLeft"></param>
        /// <param name="rightFunction"></param>
        /// <param name="unboundRight"></param>
        /// <returns></returns>
        private ICallable createGraphResult(InterpretationContext context, Functions.Function leftFunction, List <Parameter> unboundLeft, Functions.Function rightFunction, List <Parameter> unboundRight)
        {
            ICallable retVal = null;

            Functions.Graph leftGraph = createGraphForUnbound(context, Left, leftFunction, unboundLeft);
            if (leftGraph != null)
            {
                Functions.Graph rightGraph = createGraphForUnbound(context, Right, rightFunction, unboundRight);

                if (rightGraph != null)
                {
                    retVal = combineGraph(leftGraph, rightGraph).Function;
                }
                else
                {
                    AddError("Cannot create graph for " + Right);
                }
            }
            else
            {
                AddError("Cannot create graph for " + Left);
            }

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

            Functions.PredefinedFunctions.Cast cast = Called.Ref as Functions.PredefinedFunctions.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);
            }

            Function calledFunction = Called.Ref as Function;
            Dictionary <Parameter, Expression> parameterAssociation = null;

            if (calledFunction == null)
            {
                calledFunction       = Called.GetValue(context) 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));
            if (Xaxis != null)
            {
                retVal = calledFunction.createGraphForParameter(context, Xaxis);
            }
            else
            {
                retVal = Function.createGraphForValue(GetValue(context));
            }
            context.LocalScope.PopContext(token);

            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 override Functions.Graph createGraph(Interpreter.InterpretationContext context, Parameter parameter)
        {
            Functions.Graph retVal = base.createGraph(context, parameter);

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

            return(retVal);
        }
        /// <summary>
        /// Creates a graph for a single constant value
        /// </summary>
        /// <param name="retVal"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static Graph createGraph(double value, Parameter parameter = null)
        {
            Graph retVal = new Functions.Graph();

            Functions.Graph.Segment segment = new Functions.Graph.Segment(0, double.MaxValue, new Segment.Curve());
            segment.Expression.v0 = value;
            retVal.addSegment(segment);

            return(retVal);
        }
Exemple #7
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>
        /// <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);
        }
Exemple #8
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>
        /// <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);
        }
Exemple #9
0
        /// <summary>
        /// Provides the callable that is called by this expression
        /// </summary>
        /// <param name="namable"></param>
        /// <returns></returns>
        public override ICallable getCalled(InterpretationContext context)
        {
            ICallable retVal = null;

            Functions.Function function = InitialValue.Ref as Functions.Function;
            if (function == null)
            {
                function = InitialValue.getCalled(context) as Functions.Function;
            }

            if (function != null)
            {
                if (function.FormalParameters.Count == 1)
                {
                    int token = context.LocalScope.PushContext();
                    context.LocalScope.setGraphParameter((Parameter)function.FormalParameters[0]);
                    Functions.Graph graph = createGraph(context, (Parameter)function.FormalParameters[0]);
                    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]);
                    Functions.Surface surface = createSurface(context, (Parameter)function.FormalParameters[0], (Parameter)function.FormalParameters[1]);
                    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>
        /// 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);

            Graph leftGraph = Left.createGraph(context, parameter);

            if (leftGraph != null)
            {
                Graph rightGraph = Right.createGraph(context, parameter);

                if (rightGraph != null)
                {
                    retVal = combineGraph(leftGraph, rightGraph);
                }
            }

            return(retVal);
        }
Exemple #11
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>
        /// <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 double value from the IValue provided
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        private double getValue(Values.IValue val)
        {
            double retVal = 0;

            Constants.EnumValue enumValue = val as Constants.EnumValue;
            if (enumValue != null)
            {
                val = enumValue.Value;
            }

            Values.DoubleValue vd = val as Values.DoubleValue;
            if (vd != null)
            {
                retVal = vd.Val;
            }
            else
            {
                Values.IntValue vi = val as Values.IntValue;
                if (vi != null)
                {
                    retVal = (double)vi.Val;
                }
                else
                {
                    Functions.Function function = val as Functions.Function;
                    if (function != null)
                    {
                        Functions.Graph graph = function.Graph;
                        if (graph != null)
                        {
                            if (graph.Segments.Count == 1)
                            {
                                retVal = graph.Val(0);
                            }
                        }
                    }
                }
            }

            return(retVal);
        }
Exemple #13
0
        /// <summary>
        /// Provides the value associated to this Expression
        /// </summary>
        /// <param name="context">The context on which the value must be found</param>
        /// <returns></returns>
        public override Values.IValue GetValue(InterpretationContext context)
        {
            Values.IValue retVal = null;

            try
            {
                if (Parameters.Count == 1)
                {
                    int token = context.LocalScope.PushContext();
                    context.LocalScope.setGraphParameter(Parameters[0]);
                    Functions.Graph graph = createGraph(context, Parameters[0]);
                    context.LocalScope.PopContext(token);
                    if (graph != null)
                    {
                        retVal = graph.Function;
                    }
                }
                else if (Parameters.Count == 2)
                {
                    int token = context.LocalScope.PushContext();
                    context.LocalScope.setSurfaceParameters(Parameters[0], Parameters[1]);
                    Functions.Surface surface = createSurface(context, Parameters[0], Parameters[1]);
                    context.LocalScope.PopContext(token);
                    if (surface != null)
                    {
                        retVal = surface.Function;
                    }
                }
            }
            catch (Exception)
            {
                /// TODO Ugly hack, because functions & function types are merged.
                /// This provides an empty function as the type of this
                retVal = GetExpressionType() as Values.IValue;
            }

            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 virtual Functions.Graph createGraph(InterpretationContext context, Parameter parameter)
        {
            Functions.Graph retVal = null;

            return(retVal);
        }
Exemple #15
0
        /// <summary>
        /// Performs the arithmetic operation based on the type of the result
        /// </summary>
        /// <param name="context">The context used to perform this operation</param>
        /// <param name="left"></param>
        /// <param name="Operation"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        public virtual Values.IValue PerformArithmericOperation(Interpreter.InterpretationContext context, Values.IValue left, BinaryExpression.OPERATOR Operation, Values.IValue right)  // left +/-/*/div/exp right
        {
            Values.IValue retVal = null;

            Functions.Function leftFunction  = left as Functions.Function;
            Functions.Function rigthFunction = right as Functions.Function;

            if (rigthFunction == null)
            {
                if (leftFunction.Graph != null)
                {
                    Functions.Graph graph = Functions.Graph.createGraph(Functions.Function.getDoubleValue(right));
                    rigthFunction = graph.Function;
                }
                else
                {
                    Functions.Surface surface = Functions.Surface.createSurface(Functions.Function.getDoubleValue(right), leftFunction.Surface.XParameter, leftFunction.Surface.YParameter);
                    rigthFunction = surface.Function;
                }
            }

            if (leftFunction.Graph != null)
            {
                Functions.Graph tmp = null;
                switch (Operation)
                {
                case BinaryExpression.OPERATOR.ADD:
                    tmp = leftFunction.Graph.AddGraph(rigthFunction.Graph);
                    break;

                case BinaryExpression.OPERATOR.SUB:
                    tmp = leftFunction.Graph.SubstractGraph(rigthFunction.Graph);
                    break;

                case BinaryExpression.OPERATOR.MULT:
                    tmp = leftFunction.Graph.MultGraph(rigthFunction.Graph);
                    break;

                case BinaryExpression.OPERATOR.DIV:
                    tmp = leftFunction.Graph.DivGraph(rigthFunction.Graph);
                    break;
                }
                retVal = tmp.Function;
            }
            else
            {
                Functions.Surface rightSurface = rigthFunction.getSurface(leftFunction.Surface.XParameter, leftFunction.Surface.YParameter);
                Functions.Surface tmp          = null;
                switch (Operation)
                {
                case BinaryExpression.OPERATOR.ADD:
                    tmp = leftFunction.Surface.AddSurface(rightSurface);
                    break;

                case BinaryExpression.OPERATOR.SUB:
                    tmp = leftFunction.Surface.SubstractSurface(rightSurface);
                    break;

                case BinaryExpression.OPERATOR.MULT:
                    tmp = leftFunction.Surface.MultiplySurface(rightSurface);
                    break;

                case BinaryExpression.OPERATOR.DIV:
                    tmp = leftFunction.Surface.DivideSurface(rightSurface);
                    break;
                }
                retVal = tmp.Function;
            }

            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 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>
        /// Provides the value associated to this Expression
        /// </summary>
        /// <param name="context">The context on which the value must be found</param>
        /// <returns></returns>
        public override Values.IValue GetValue(InterpretationContext context)
        {
            Values.IValue   retVal   = null;
            ExplanationPart previous = SetupExplanation();

            Functions.Function function = getFunction(context);
            if (function != null)
            {
                long start = System.Environment.TickCount;

                Dictionary <Variables.Actual, Values.IValue> parameterValues = AssignParameterValues(context, function, true);
                List <Parameter> parameters = GetPlaceHolders(function, parameterValues);
                if (parameters == null)
                {
                    retVal = function.Evaluate(context, parameterValues);
                    if (retVal == null)
                    {
                        AddError("Call " + function.Name + " ( " + ParameterValues(parameterValues) + " ) returned nothing");
                    }
                }
                else if (parameters.Count == 1) // graph
                {
                    int token = context.LocalScope.PushContext();
                    context.LocalScope.setGraphParameter(parameters[0]);
                    Functions.Graph graph = function.createGraphForParameter(context, parameters[0]);
                    context.LocalScope.PopContext(token);
                    if (graph != null)
                    {
                        retVal = graph.Function;
                    }
                    else
                    {
                        AddError("Cannot create graph on Call " + function.Name + " ( " + ParameterValues(parameterValues) + " )");
                    }
                }
                else // surface
                {
                    Functions.Surface surface = function.createSurfaceForParameters(context, parameters[0], parameters[1]);
                    if (surface != null)
                    {
                        retVal = surface.Function;
                    }
                    else
                    {
                        AddError("Cannot create surface on Call " + function.Name + " ( " + ParameterValues(parameterValues) + " )");
                    }
                }

                long stop = System.Environment.TickCount;
                long span = (stop - start);
                function.ExecutionTimeInMilli += span;
                function.ExecutionCount       += 1;

                if (explain)
                {
                    CompleteExplanation(previous, function.Name + " ( " + ParameterValues(parameterValues) + " ) returned " + explainNamable(retVal) + "\n");
                }
            }
            else
            {
                AddError("Cannot find function " + ToString());
            }

            return(retVal);
        }