/// <summary> /// Adds a new function to this graph /// </summary> /// <param name="function"></param> /// <param name="explain"></param> private void AddFunction(Function function, ExplanationPart explain) { if (function != null) { InterpretationContext context = new InterpretationContext(function); if (function.FormalParameters.Count == 1) { Parameter parameter = (Parameter)function.FormalParameters[0]; Graph graph = function.CreateGraph(context, parameter, explain); if (graph != null) { Functions.Add(function); Refresh(); } } else if (function.FormalParameters.Count == 2) { Surface surface = function.CreateSurface(context, explain); if (surface != null) { Functions.Add(function); Refresh(); } else { MessageBox.Show( Resources.GraphView_AddFunction_Cannot_add_this_function_to_the_display_view, Resources.GraphView_AddFunction_Cannot_display_function, MessageBoxButtons.OK, MessageBoxIcon.Error); } } } }
public override Function createFunction() { Function retVal = new Functions.Function(); _defaultValueSetter.SetDefaultValue(retVal); 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); 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> /// The menu items for this tree node /// </summary> /// <returns></returns> protected override List <MenuItem> GetMenuItems() { List <MenuItem> retVal = new List <MenuItem>(); MenuItem updateItem = new MenuItem("Update..."); updateItem.MenuItems.Add(new MenuItem("Update", AddUpdate)); updateItem.MenuItems.Add(new MenuItem("Remove", RemoveInUpdate)); retVal.Add(updateItem); retVal.Add(new MenuItem("Delete", DeleteHandler)); retVal.AddRange(base.GetMenuItems()); Function function = Item.Value as Function; if (function != null) { InterpretationContext context = new InterpretationContext(Item); if (function.FormalParameters.Count == 1) { Parameter parameter = (Parameter)function.FormalParameters[0]; Graph graph = function.CreateGraph(context, parameter, null); if (graph != null && graph.Segments.Count != 0) { retVal.Insert(6, new MenuItem("Display", DisplayHandler)); } } else if (function.FormalParameters.Count == 2) { Surface surface = function.CreateSurface(context, null); if (surface != null && surface.Segments.Count != 0) { retVal.Insert(6, new MenuItem("Display", DisplayHandler)); } } } else { retVal.Insert(5, new MenuItem("-")); retVal.Insert(6, new MenuItem("Display", DisplayHandler)); } if (Item.Type is StateMachine) { retVal.Insert(5, new MenuItem("-")); retVal.Insert(6, new MenuItem("View state diagram", ViewStateDiagramHandler)); } return(retVal); }
/// <summary> /// Provides the callable that is called by this expression /// </summary> /// <param name="context"></param> /// <param name="explain"></param> /// <returns></returns> public override ICallable GetCalled(InterpretationContext context, ExplanationPart explain) { ICallable retVal = null; Function function = InitialValue.Ref as Function; if (function == null) { function = InitialValue.GetCalled(context, explain) as Function; } if (function != null) { if (function.FormalParameters.Count == 1) { int token = context.LocalScope.PushContext(); context.LocalScope.SetGraphParameter((Parameter)function.FormalParameters[0]); Graph graph = CreateGraph(context, (Parameter)function.FormalParameters[0], explain); context.LocalScope.PopContext(token); if (graph != null) { retVal = graph.Function; } } else if (function.FormalParameters.Count == 2) { int token = context.LocalScope.PushContext(); context.LocalScope.SetSurfaceParameters((Parameter)function.FormalParameters[0], (Parameter)function.FormalParameters[1]); Surface surface = CreateSurface(context, (Parameter)function.FormalParameters[0], (Parameter)function.FormalParameters[1], explain); context.LocalScope.PopContext(token); if (surface != null) { retVal = surface.Function; } } else { AddError("Cannot evaluate REDUCE expression to a function", RuleChecksEnum.ExecutionFailed); } } else { AddError("Cannot evaluate REDUCE expression to a function", RuleChecksEnum.ExecutionFailed); } 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); }
/// <summary> /// Provides the type of this expression /// </summary> /// <returns></returns> public override Type GetExpressionType() { Function retVal = (Function)acceptor.getFactory().createFunction(); retVal.Name = ToString(); retVal.ReturnType = Expression.GetExpressionType(); foreach (Parameter parameter in Parameters) { Parameter param = (Parameter)acceptor.getFactory().createParameter(); param.Name = parameter.Name; param.Type = parameter.Type; retVal.appendParameters(param); } retVal.Enclosing = Root; return(retVal); }
/// <summary> /// Provides the double value from the IValue provided /// </summary> /// <param name="val"></param> /// <returns></returns> private double getValue(IValue val) { double retVal = 0; EnumValue enumValue = val as EnumValue; if (enumValue != null) { val = enumValue.Value; } DoubleValue vd = val as DoubleValue; if (vd != null) { retVal = vd.Val; } else { IntValue vi = val as IntValue; if (vi != null) { retVal = (double)vi.Val; } else { Function function = val as Function; if (function != null) { Graph graph = function.Graph; if (graph != null) { if (graph.Segments.Count == 1) { retVal = graph.Evaluate(0); } } } } } return(retVal); }
/// <summary> /// Displays the variable value /// </summary> /// <param name="sender"></param> /// <param name="args"></param> public void DisplayHandler(object sender, EventArgs args) { Function function = Item.Value as Function; if (function != null) { GraphView.GraphView view = new GraphView.GraphView(); GuiUtils.MdiWindow.AddChildWindow(view); view.Functions.Add(function); view.Refresh(); } else { StructureEditor.Window window = new StructureEditor.Window(); window.SetVariable(Item); if (GuiUtils.MdiWindow.DataDictionaryWindow != null) { GuiUtils.MdiWindow.AddChildWindow(window); window.Show(GuiUtils.MdiWindow.DataDictionaryWindow.Pane, DockAlignment.Right, 0.20); } } }
/// <summary> /// Gets the unbound parameters from either the surface or the graph of the function /// </summary> /// <param name="leftFunction"></param> /// <returns></returns> private List<Parameter> getUnboundParametersFromValue(Function leftFunction) { List<Parameter> retVal = new List<Parameter>(); if (leftFunction != null) { if (leftFunction.Surface != null) { retVal.Add(leftFunction.Surface.XParameter); retVal.Add(leftFunction.Surface.YParameter); } else if (leftFunction.Graph != null) { // TODO : Use the parameters from the graph when available retVal.Add((Parameter) leftFunction.FormalParameters[0]); } } return retVal; }
/// <summary> /// Gets the unbound parameters from the function definition and place holders /// </summary> /// <param name="context"></param> /// <param name="function"></param> /// <returns></returns> private List<Parameter> getUnboundParameter(InterpretationContext context, Function function) { List<Parameter> retVal = new List<Parameter>(); if (function != null) { foreach (Parameter formal in function.FormalParameters) { IVariable actual = context.FindOnStack(formal); if (actual != null) { PlaceHolder placeHolder = actual.Value as PlaceHolder; if (placeHolder != null) { retVal.Add(formal); } } } } 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> /// <param name="explain"></param> /// <returns></returns> private ICallable CreateSurfaceResult(InterpretationContext context, Function leftFunction, List<Parameter> unboundLeft, Function rightFunction, List<Parameter> unboundRight, ExplanationPart explain) { ICallable retVal = null; Surface leftSurface = CreateSurfaceForUnbound(context, Left, leftFunction, unboundLeft, explain); if (leftSurface != null) { Surface rightSurface = CreateSurfaceForUnbound(context, Right, rightFunction, unboundRight, explain); 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> /// Constructor /// </summary> /// <param name="panel"></param> /// <param name="model"></param> public FunctionModelControl(ModelDiagramPanel panel, Function model) : base(panel, model) { }
/// <summary> /// Creates the graph for the unbound parameters provided /// </summary> /// <param name="context"></param> /// <param name="expression"></param> /// <param name="function"></param> /// <param name="unbound"></param> /// <param name="explain"></param> /// <returns></returns> private Graph createGraphForUnbound(InterpretationContext context, Expression expression, Function function, List<Parameter> unbound, ExplanationPart explain) { Graph retVal; if (unbound.Count == 0) { if (function != null && function.FormalParameters.Count > 0) { retVal = function.CreateGraph(context, (Parameter) function.FormalParameters[0], explain); } else { retVal = Graph.createGraph(expression.GetValue(context, explain), null, explain); } } else { if (function == null) { retVal = expression.CreateGraph(context, unbound[0], explain); } else { retVal = function.CreateGraph(context, unbound[0], explain); } } return retVal; }
/// <summary> /// Converts a DataDictionary.Values.IValue into an EFSIPCInterface.Value /// </summary> /// <param name="value"></param> /// <returns></returns> public Value ConvertOut(IValue value) { // Handles the boolean case { BoolValue v = value as BoolValue; if (v != null) { return(new Values.BoolValue(v.Val)); } } // Handles the integer case { IntValue v = value as IntValue; if (v != null) { return(new Values.IntValue(v.Val)); } } // Handles the double case { DoubleValue v = value as DoubleValue; if (v != null) { return(new Values.DoubleValue(v.Val)); } } // Handles the string case { StringValue v = value as StringValue; if (v != null) { return(new Values.StringValue(v.Val)); } } // Handles the state case { State v = value as State; if (v != null) { return(new StateValue(v.FullName)); } } // Handles the enumeration value case { EnumValue v = value as EnumValue; if (v != null) { return(new Values.EnumValue(v.FullName)); } } // Handles the list case { ListValue v = value as ListValue; if (v != null) { List <Value> list = new List <Value>(); foreach (IValue item in v.Val) { list.Add(ConvertOut(item)); } return(new Values.ListValue(list)); } } // Handles the structure case { StructureValue v = value as StructureValue; if (v != null) { Dictionary <string, Value> record = new Dictionary <string, Value>(); foreach (KeyValuePair <string, INamable> pair in v.Val) { IVariable variable = pair.Value as IVariable; if (variable != null) { record.Add(variable.Name, ConvertOut(variable.Value)); } } return(new Values.StructureValue(record)); } } // Handles the function case { DataDictionary.Functions.Function v = value as DataDictionary.Functions.Function; if (v != null) { List <Segment> segments = new List <Segment>(); if (v.FormalParameters.Count == 1) { Graph graph = v.CreateGraph(new InterpretationContext(), (Parameter)v.FormalParameters[0], null); if (graph != null) { foreach (Graph.Segment segment in graph.Segments) { double length = segment.End - segment.Start; segments.Add(new Segment { A = segment.Expression.A, V0 = segment.Expression.V0, D0 = segment.Start, Length = length }); } } } return(new FunctionValue(segments)); } } // Handles the 'empty' value { EmptyValue emptyValue = value as EmptyValue; if (emptyValue != null) { return(null); } } throw new FaultException <EFSServiceFault>(new EFSServiceFault("Cannot convert value " + value)); }
/// <summary> /// Displays the graph /// </summary> /// <returns></returns> public void Display() { Util.DontNotify(() => { GraphVisualiser.Reset(); String name = null; // Computes the expected end to display double expectedEndX = 0; Dictionary <Function, Graph> graphs = new Dictionary <Function, Graph>(); foreach (Function function in Functions) { InterpretationContext context = new InterpretationContext(function); if (function.FormalParameters.Count == 1) { Parameter parameter = (Parameter)function.FormalParameters[0]; Graph graph = function.CreateGraph(context, parameter, null); if (graph != null) { expectedEndX = Math.Max(expectedEndX, graph.ExpectedEndX()); graphs.Add(function, graph); } } } double expectedEndY = 0; Dictionary <Function, Surface> surfaces = new Dictionary <Function, Surface>(); foreach (Function function in Functions) { InterpretationContext context = new InterpretationContext(function); if (function.FormalParameters.Count == 2) { Surface surface = function.CreateSurface(context, null); if (surface != null) { expectedEndX = Math.Max(expectedEndX, surface.ExpectedEndX()); expectedEndY = Math.Max(expectedEndY, surface.ExpectedEndY()); surfaces.Add(function, surface); } } } try { int maxX = Int32.Parse(Tb_MaxX.Text); expectedEndX = Math.Min(expectedEndX, maxX); } catch (Exception) { } // Creates the graphs foreach (KeyValuePair <Function, Graph> pair in graphs) { Function function = pair.Key; Graph graph = pair.Value; if (function != null && graph != null) { EfsProfileFunction efsProfileFunction = new EfsProfileFunction(graph); if (function.Name.Contains("Gradient")) { GraphVisualiser.AddGraph(new EfsGradientProfileGraph(GraphVisualiser, efsProfileFunction, function.FullName)); } else { GraphVisualiser.AddGraph(new EfsProfileFunctionGraph(GraphVisualiser, efsProfileFunction, function.FullName)); } if (name == null) { name = function.Name; } } } // Creates the surfaces foreach (KeyValuePair <Function, Surface> pair in surfaces) { Function function = pair.Key; Surface surface = pair.Value; if (surface != null) { EfsSurfaceFunction efsSurfaceFunction = new EfsSurfaceFunction(surface); GraphVisualiser.AddGraph(new EfsSurfaceFunctionGraph(GraphVisualiser, efsSurfaceFunction, function.FullName)); if (name == null) { name = function.Name; } } } Train train = new Train(GraphVisualiser); train.InitializeTrain(TrainPosition.GetDistance(), TrainPosition.GetSpeed(), TrainPosition.GetUnderReadingAmount(), TrainPosition.GetOverReadingAmount()); GraphVisualiser.AddGraph(train); GraphVisualiser.Annotations.Add(train.TrainLineAnnotation); GraphVisualiser.Annotations.Add(train.TrainAnnotation); if (name != null) { try { double val = double.Parse(Tb_MinX.Text); GraphVisualiser.SetMinX(val); } catch (Exception) { } try { double val = double.Parse(Tb_MaxX.Text); GraphVisualiser.SetMaxX(val); } catch (Exception) { } if (Cb_AutoYSize.Checked) { GraphVisualiser.SetMaxY(double.NaN); } else { double height; if (double.TryParse(Tb_MaxY.Text, out height)) { GraphVisualiser.SetMaxY(height); } else { GraphVisualiser.SetMaxY(double.NaN); } } GraphVisualiser.SetMinY2(double.NaN); GraphVisualiser.SetMaxY2(double.NaN); double top, bottom; if (double.TryParse(Tb_MinGrad.Text, out bottom)) { GraphVisualiser.SetMinY2(bottom); } if (double.TryParse(Tb_MaxGrad.Text, out top)) { GraphVisualiser.SetMaxY2(top); } GraphVisualiser.DrawGraphs(expectedEndX); } }); }
public override Function createFunction() { Function retVal = new Functions.Function(); _defaultValueSetter.SetDefaultValue(retVal); 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> /// <param name="explain"></param> /// <returns></returns> private ICallable CreateGraphResult(InterpretationContext context, Function leftFunction, List<Parameter> unboundLeft, Function rightFunction, List<Parameter> unboundRight, ExplanationPart explain) { ICallable retVal = null; Graph leftGraph = createGraphForUnbound(context, Left, leftFunction, unboundLeft, explain); if (leftGraph != null) { Graph rightGraph = createGraphForUnbound(context, Right, rightFunction, unboundRight, explain); if (rightGraph != null) { Graph combinedGraph = CombineGraph(leftGraph, rightGraph) as Graph; if (combinedGraph != null) { retVal = combinedGraph.Function; } } else { AddError("Cannot create graph for " + Right); } } else { AddError("Cannot create graph for " + Left); } 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 IValue PerformArithmericOperation(InterpretationContext context, IValue left, BinaryExpression.Operator operation, IValue right) // left +/-/*/div/exp right { IValue retVal = null; Function leftFunction = left as Function; Function rigthFunction = right as Function; if (leftFunction != null) { if (rigthFunction == null) { if (leftFunction.Graph != null) { Graph graph = Graph.createGraph(Function.GetDoubleValue(right)); rigthFunction = graph.Function; } else { Surface surface = Surface.createSurface(Function.GetDoubleValue(right), leftFunction.Surface.XParameter, leftFunction.Surface.YParameter); rigthFunction = surface.Function; } } if (leftFunction.Graph != null) { IGraph 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; } Graph tmpGraph = tmp as Graph; if (tmpGraph != null) { retVal = tmpGraph.Function; } } else { Surface rightSurface = rigthFunction.GetSurface(leftFunction.Surface.XParameter, leftFunction.Surface.YParameter); 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> /// Creates the graph for the unbount parameters provided /// </summary> /// <param name="context"></param> /// <param name="expression"></param> /// <param name="function"></param> /// <param name="unbound"></param> /// <param name="explain"></param> /// <returns></returns> private Surface CreateSurfaceForUnbound(InterpretationContext context, Expression expression, Function function, List<Parameter> unbound, ExplanationPart explain) { Surface retVal; if (unbound.Count == 0) { if (function != null) { Parameter xAxis = null; if (function.FormalParameters.Count > 0) { xAxis = (Parameter) function.FormalParameters[0]; } Parameter yAxis = null; if (function.FormalParameters.Count > 1) { yAxis = (Parameter) function.FormalParameters[1]; } retVal = function.CreateSurfaceForParameters(context, xAxis, yAxis, explain); } else { retVal = Surface.createSurface(expression.GetValue(context, explain), null, null); } } else if (unbound.Count == 1) { Graph graph = createGraphForUnbound(context, expression, function, unbound, explain); retVal = Surface.createSurface(graph.Function, unbound[0], null); } else { if (function == null) { retVal = expression.CreateSurface(context, unbound[0], unbound[1], explain); } else { retVal = function.CreateSurfaceForParameters(context, unbound[0], unbound[1], explain); } } return retVal; }