/// <summary> /// Creates the surface associated to the value provided /// </summary> /// <param name="context"></param> /// <param name="value"></param> /// <param name="explain"></param> /// <returns></returns> protected Surface createSurfaceForValue(InterpretationContext context, IValue value, ExplanationPart explain) { Surface retVal = null; Function function = value as Function; if (function != null) { retVal = function.CreateSurface(context, explain); } else { DoubleValue val = value as DoubleValue; Graph graph = new Graph(); graph.AddSegment(new Graph.Segment(0, double.MaxValue, new Graph.Segment.Curve(0, val.Val, 0))); retVal = new 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 graph</param> /// <param name="xParameter">The parameter used for the X axis</param> /// <param name="yParameter">The parameter used for the Y axis</param> /// <param name="explain"></param> /// <returns></returns> public virtual Surface CreateSurfaceForParameters(InterpretationContext context, Parameter xParameter, Parameter yParameter, ExplanationPart explain) { 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, explain)) { Surface surface = cas.Expression.CreateSurface(context, xParameter, yParameter, explain); if (surface != null) { Parameter parameter = null; surface = ReduceSurface(context, cas, surface, out parameter, explain); 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); Graph graph = CreateGraphForParameter(context, xParameter, explain); 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) { // Function with 1 parameter that ranges over the Yaxis retVal = new Surface(xParameter, yParameter); Graph graph = CreateGraphForParameter(context, yParameter, explain); Surface.Segment segment = new Surface.Segment(0, double.MaxValue, graph); retVal.AddSegment(segment); } else { AddError("Invalid parameters for surface creation"); } } if (retVal != null) { retVal.XParameter = xParameter; retVal.YParameter = yParameter; } 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> /// <param name="explain"></param> /// <returns>The reduced surface</returns> private Surface ReduceSurface(InterpretationContext context, Case cas, Surface surface, out Parameter parameter, ExplanationPart explain) { Surface retVal; // Evaluate the axis parameter = null; foreach (PreCondition preCondition in cas.PreConditions) { List<ISegment> boundaries = EvaluateBoundaries(context, preCondition, surface.XParameter, explain); 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, explain); 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 (ISurfaceSegment segment in surface.Segments) { retVal.AddSegment(new Surface.Segment(segment)); } // Reduces the segments according to this preconditions foreach (PreCondition preCondition in cas.PreConditions) { List<ISegment> boundaries = EvaluateBoundaries(context, preCondition, surface.XParameter, explain); 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 (PreCondition preCondition in cas.PreConditions) { List<ISegment> boundaries = EvaluateBoundaries(context, preCondition, surface.YParameter, explain); segment.Graph.Reduce(boundaries); } if (!segment.Empty()) { retVal.AddSegment(segment); } } } else { retVal = surface; } return retVal; }
/// <summary> /// Creates the surface associated to the value provided /// </summary> /// <param name="context"></param> /// <param name="value"></param> /// <param name="explain"></param> /// <returns></returns> protected Surface createSurfaceForValue(InterpretationContext context, IValue value, ExplanationPart explain) { Surface retVal = null; Function function = value as Function; if (function != null) { retVal = function.createSurface(context, explain); } else { DoubleValue val = value as DoubleValue; Graph graph = new Graph(); graph.AddSegment(new Graph.Segment(0, double.MaxValue, new Graph.Segment.Curve(0, val.Val, 0))); retVal = new 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 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; }