/// <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 (Term != null) { retVal = Functions.Surface.createSurface(xParam, yParam, GetValue(context)); } else if (Expression != null) { if (UnaryOp == null) { retVal = Expression.createSurface(context, xParam, yParam); } else { if (UnaryOp == MINUS) { retVal = Expression.createSurface(context, xParam, yParam); retVal.Negate(); } else { AddError("Cannot create surface with unary op " + UnaryOp); } } } retVal.XParameter = xParam; retVal.YParameter = yParam; return(retVal); }
/// <summary> /// Combines two surfaces using the operator of this binary expression /// </summary> /// <param name="leftSurface"></param> /// <param name="rightSurface"></param> /// <returns></returns> private Functions.Surface combineSurface(Functions.Surface leftSurface, Functions.Surface rightSurface) { Functions.Surface retVal = null; switch (Operation) { case BinaryExpression.OPERATOR.ADD: retVal = leftSurface.AddSurface(rightSurface); break; case BinaryExpression.OPERATOR.SUB: retVal = leftSurface.SubstractSurface(rightSurface); break; case BinaryExpression.OPERATOR.MULT: retVal = leftSurface.MultiplySurface(rightSurface); break; case BinaryExpression.OPERATOR.DIV: retVal = leftSurface.DivideSurface(rightSurface); break; } 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); Functions.Function function = getFunction(context); Functions.PredefinedFunctions.Cast cast = Called.Ref as Functions.PredefinedFunctions.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); } else { Parameter Xaxis = null; Parameter Yaxis = null; if (function == null) { function = Called.getCalled(context) 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)); retVal = function.createSurfaceForParameters(context, Xaxis, Yaxis); context.LocalScope.PopContext(token); } else { Values.IValue value = GetValue(context); if (value != null) { retVal = Functions.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> /// <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); }
/// <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 surface associated to the value provided /// </summary> /// <param name="value"></param> /// <returns></returns> protected Surface createSurfaceForValue(Interpreter.InterpretationContext context, Values.IValue value) { Surface retVal = null; Function function = value as Function; if (function != null) { retVal = function.createSurface(context); } else { Values.DoubleValue val = value as Values.DoubleValue; Graph graph = new Graph(); graph.addSegment(new Graph.Segment(0, double.MaxValue, new Graph.Segment.Curve(0, val.Val, 0))); retVal = new Functions.Surface(null, null); retVal.AddSegment(new Surface.Segment(0, double.MaxValue, graph)); } 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 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 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 createSurfaceResult(InterpretationContext context, Functions.Function leftFunction, List <Parameter> unboundLeft, Functions.Function rightFunction, List <Parameter> unboundRight) { ICallable retVal = null; Functions.Surface leftSurface = createSurfaceForUnbound(context, Left, leftFunction, unboundLeft); if (leftSurface != null) { Functions.Surface rightSurface = createSurfaceForUnbound(context, Right, rightFunction, unboundRight); if (rightSurface != null) { retVal = combineSurface(leftSurface, rightSurface).Function; } else { AddError("Cannot create surface for " + Right); } } else { AddError("Cannot create surface for " + Left); } 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 virtual Functions.Surface createSurface(Interpreter.InterpretationContext context, Parameter xParam, Parameter yParam) { Functions.Surface retVal = null; return(retVal); }
/// <summary> /// Creates the surface associated to the value provided /// </summary> /// <param name="value"></param> /// <returns></returns> protected Surface createSurfaceForValue(Interpreter.InterpretationContext context, Values.IValue value) { Surface retVal = null; Function function = value as Function; if (function != null) { retVal = function.createSurface(context); } else { Values.DoubleValue val = value as Values.DoubleValue; Graph graph = new Graph(); graph.addSegment(new Graph.Segment(0, double.MaxValue, new Graph.Segment.Curve(0, val.Val, 0))); retVal = new Functions.Surface(null, null); retVal.AddSegment(new Surface.Segment(0, double.MaxValue, graph)); } 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); }
/// <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); }