/// <summary> /// Provides the value of the function /// </summary> /// <param name="context"></param> /// <param name="actuals">the actual parameters values</param> /// <param name="explain"></param> /// <returns>The value for the function application</returns> public override IValue Evaluate(InterpretationContext context, Dictionary<Actual, IValue> actuals, ExplanationPart explain) { IValue retVal = null; int token = context.LocalScope.PushContext(); AssignParameters(context, actuals); ListValue value = context.FindOnStack(Collection) as ListValue; if (value != null) { Collection collectionType = value.Type as Collection; if (collectionType != null && collectionType.Type != null) { Type elementType = collectionType.Type; if (value.Val.Count >= collectionType.getMaxSize()) { AddError("Cannot allocate element in list : list full"); } else { retVal = elementType.DefaultValue; value.Val.Add(retVal); } } } context.LocalScope.PopContext(token); return retVal; }
/// <summary> /// Provides all the steps used to get the value of the expression /// </summary> /// <returns></returns> public ExplanationPart Explain() { ExplanationPart retVal = new ExplanationPart(Root); currentExplanation = retVal; try { explain = true; InterpretationContext context = new InterpretationContext(); Values.IValue value = GetValue(context); if (value != null) { retVal.Message = ToString() + " = " + explainNamable(value); } else { retVal.Message = "Cannot evaluate value for " + ToString(); } } finally { explain = false; } 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; Call calledFunction = Called as Call; if (calledFunction != null) { retVal = Called.GetValue(context, explain) as ICallable; } else { retVal = Called.GetCalled(context, explain); if (retVal == null) { Type type = Called.GetExpressionType(); if (type != null) { retVal = type.CastFunction; } if (retVal == null) { retVal = Called.GetValue(context, explain) as ICallable; } } } return(retVal); }
/// <summary> /// Sets the value associated to the explanation /// </summary> /// <param name="explain"></param> /// <param name="namable"></param> public static void SetNamable(ExplanationPart explain, INamable namable) { if (explain != null) { explain.RightPart = namable; } }
/// <summary> /// Adds an error message to the root element and explains it /// </summary> /// <param name="message"></param> /// <param name="explain"></param> public virtual void AddErrorAndExplain(string message, ExplanationPart explain) { if (RootLog != null) { RootLog.AddError(message); } }
/// <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, RuleChecksEnum.ExecutionFailed); } } } retVal.XParameter = xParam; retVal.YParameter = yParam; return(retVal); }
/// <summary> /// Constructor /// </summary> /// <param name="context"></param> /// <param name="statement"></param> /// <param name="variable"></param> /// <param name="explanation"></param> public InsertInListChange(InterpretationContext context, InsertStatement statement, IVariable variable, ExplanationPart explanation) : base(variable, null, null) { Context = context; Statement = statement; Explanation = explanation; }
/// <summary> /// Adds a sub explanation for the explain provided as parameter /// </summary> /// <param name="explain"></param> /// <param name="subExplain"></param> public static void AddSubExplanation(ExplanationPart explain, ExplanationPart subExplain) { if (explain != null) { explain.SubExplanations.Add(subExplain); } }
/// <summary> /// Provides the value associated to this Expression /// </summary> /// <param name="context">The context on which the value must be found</param> /// <param name="explain">The explanation to fill, if any</param> /// <returns></returns> protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain) { IValue retVal = null; if (Term != null) { retVal = Term.GetValue(context, explain); } else { if (Not.Equals(UnaryOp)) { BoolValue b = Expression.GetValue(context, explain) as BoolValue; if (b != null) { if (b.Val) { retVal = EfsSystem.Instance.BoolType.False; } else { retVal = EfsSystem.Instance.BoolType.True; } } else { AddError("Expression " + Expression + " does not evaluate to boolean", RuleChecksEnum.SemanticAnalysisError); } } else if (Minus.Equals(UnaryOp)) { IValue val = Expression.GetValue(context, explain); IntValue intValue = val as IntValue; if (intValue != null) { retVal = new IntValue(intValue.Type, -intValue.Val); } else { DoubleValue doubleValue = val as DoubleValue; if (doubleValue != null) { retVal = new DoubleValue(doubleValue.Type, -doubleValue.Val); } } if (retVal == null) { AddError("Cannot negate value for " + Expression, RuleChecksEnum.SemanticAnalysisError); } } else { retVal = Expression.GetValue(context, explain); } } return(retVal); }
/// <summary> /// Sets the explanation for this explain box /// </summary> /// <param name="explanation"></param> public void setExplanation(DataDictionary.Interpreter.ExplanationPart explanation) { explainTreeView.Nodes.Clear(); ExplainTreeNode node = new ExplainTreeNode(explanation); innerSetExplanation(explanation, node, 0); explainTreeView.Nodes.Add(node); }
/// <summary> /// Adds an error message to the root element and explains it /// </summary> /// <param name="message"></param> /// <param name="explain"></param> public override void AddErrorAndExplain(string message, ExplanationPart explain) { if (RootLog != null) { ExplanationPart.CreateSubExplanation(explain, message); RootLog.AddErrorAndExplain(message, explain); } }
/// <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 = function as Cast; if (cast != null) { // In case of cast, just take the surface of the enclosed expression Expression actual = ActualParameters[0]; retVal = actual.CreateSurface(context, xParam, yParam, explain); } else { if (function == null) { function = Called.GetCalled(context, explain) as Function; } if (function != null) { Parameter xAxis; Parameter yAxis; SelectXandYAxis(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"); } } } else { AddError("Cannot determine called function", RuleChecksEnum.SemanticAnalysisError); } } retVal.XParameter = xParam; retVal.YParameter = yParam; return(retVal); }
/// <summary> /// Creates the parameter value associationg according to actual parameters /// </summary> /// <param name="context">The interpretation context</param> /// <param name="callable">The callable</param> /// <param name="log">Indicates whether errors should be logged</param> /// <param name="explain"></param> /// <returns></returns> public Dictionary <Actual, IValue> AssignParameterValues(InterpretationContext context, ICallable callable, bool log, ExplanationPart explain) { // Compute the unnamed actual parameter values Dictionary <Actual, IValue> retVal = new Dictionary <Actual, IValue>(); if (callable.FormalParameters.Count == NamedActualParameters.Count + ActualParameters.Count) { int i = 0; foreach (Expression expression in ActualParameters) { Parameter parameter = (Parameter)callable.FormalParameters[i]; ExplanationPart subExplanation = ExplanationPart.CreateSubExplanation(explain, parameter); IValue val = expression.GetValue(context, subExplanation); if (val != null) { Actual actual = parameter.CreateActual(); val = val.RightSide(actual, false, false); retVal.Add(actual, val); } else { AddError("Cannot evaluate value for parameter " + i + " (" + expression + ") of function " + callable.Name, RuleChecksEnum.ExecutionFailed); throw new Exception("Evaluation of parameters failed: Cannot evaluate value for parameter " + i + " (" + expression + ") of function " + callable.Name); } ExplanationPart.SetNamable(subExplanation, val); i = i + 1; } foreach (KeyValuePair <Designator, Expression> pair in NamedActualParameters) { Parameter parameter = callable.GetFormalParameter(pair.Key.Image); ExplanationPart subExplanation = ExplanationPart.CreateSubExplanation(explain, parameter); IValue val = pair.Value.GetValue(context, subExplanation); if (val != null) { Actual actual = parameter.CreateActual(); val = val.RightSide(actual, false, false); actual.Value = val; retVal.Add(actual, val); } else { AddError("Cannot evaluate value for parameter " + pair.Key + " of function " + callable.Name, RuleChecksEnum.ExecutionFailed); throw new Exception("Evaluation of parameters failed: cannot evaluate value for parameter " + pair.Key + " of function " + callable.Name); } ExplanationPart.SetNamable(subExplanation, val); } } 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 = Called; if (retVal == null) { AddError("Cannot evaluate call to " + ToString(), RuleChecksEnum.ExecutionFailed); } return(retVal); }
/// <summary> /// Provides the element called by this term, if any /// </summary> /// <param name="context">The context on which the variable must be found</param> /// <param name="explain"></param> /// <returns></returns> public ICallable GetCalled(InterpretationContext context, ExplanationPart explain) { ICallable retVal = null; if (Designator != null) { retVal = Designator.GetCalled(context); } return(retVal); }
/// <summary> /// Creates a sub explanation for the explain provided as parameter /// </summary> /// <param name="explain"></param> /// <param name="root"></param> /// <param name="change"></param> /// <returns></returns> public static ExplanationPart CreateSubExplanation(ExplanationPart explain, ModelElement root, Change change) { ExplanationPart retVal = null; if (explain != null) { retVal = new ExplanationPart(root, change); explain.SubExplanations.Add(retVal); } return(retVal); }
/// <summary> /// Creates a sub explanation for the explain provided as parameter /// </summary> /// <param name="explain"></param> /// <param name="name"></param> /// <returns></returns> public static ExplanationPart CreateSubExplanation(ExplanationPart explain, string name) { ExplanationPart retVal = null; if (explain != null) { retVal = new ExplanationPart(explain.Element, name); explain.SubExplanations.Add(retVal); } return(retVal); }
/// <summary> /// Creates a sub explanation for the explain provided as parameter /// </summary> /// <param name="explain"></param> /// <param name="leftPart">What is evaluated</param> /// <param name="rightPart">The evaluated value</param> /// <returns></returns> public static ExplanationPart CreateSubExplanation(ExplanationPart explain, object leftPart, INamable rightPart = null) { ExplanationPart retVal = null; if (explain != null) { retVal = new ExplanationPart(explain.Element, leftPart, rightPart); explain.SubExplanations.Add(retVal); } return(retVal); }
/// <summary> /// Creates a sub explanation for the explain provided as parameter /// </summary> /// <param name="explain"></param> /// <param name="message"></param> /// <param name="leftPart"></param> /// <returns></returns> public static ExplanationPart CreateNamedSubExplanation(ExplanationPart explain, string message, object leftPart) { ExplanationPart retVal = null; if (explain != null) { retVal = new ExplanationPart(explain.Element, message); retVal.LeftPart = leftPart; explain.SubExplanations.Add(retVal); } return(retVal); }
/// <summary> /// Sets the explanation for this explain box /// </summary> /// <param name="explanation"></param> public void SetExplanation(ExplanationPart explanation) { Explanation = explanation; explainTreeView.Nodes.Clear(); if (explanation != null) { ExplainTreeNode node = new ExplainTreeNode(explanation); node.UpdateText(); InnerSetExplanation(explanation, node, 0); explainTreeView.Nodes.Add(node); } }
/// <summary> /// Setups the explanation /// </summary> /// <param name="previous">The previous explanation to store</param> /// <returns>The previous explanation (the one for which this is setup)</returns> protected ExplanationPart SetupExplanation() { ExplanationPart retVal = currentExplanation; if (explain) { ExplanationPart part = new ExplanationPart(Root); currentExplanation.SubExplanations.Add(part); currentExplanation = part; } 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 = 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); }
/// <summary> /// Provides the value associated to this Expression /// </summary> /// <param name="context">The context on which the value must be found</param> /// <param name="explain"></param> /// <returns></returns> public IValue GetValue(InterpretationContext context, ExplanationPart explain) { IValue retVal = null; if (Designator != null) { retVal = Designator.GetValue(context); } else if (LiteralValue != null) { retVal = LiteralValue.GetValue(context, explain); } return(retVal); }
/// <summary> /// Provides the value associated to this Expression /// </summary> /// <param name="context">The context on which the value must be found</param> /// <param name="explain">The explanation to fill, if any</param> /// <returns></returns> protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain) { ExplanationPart subPart = ExplanationPart.CreateSubExplanation(explain, BoundVariable); BoundVariable.Value = BindingExpression.GetValue(context, explain); ExplanationPart.SetNamable(subPart, BoundVariable.Value); int token = context.LocalScope.PushContext(); context.LocalScope.SetVariable(BoundVariable); IValue retVal = Expression.GetValue(context, explain); context.LocalScope.PopContext(token); return(retVal); }
/// <summary> /// Provides the value of the function /// </summary> /// <param name="context"></param> /// <param name="actuals">the actual parameters values</param> /// <param name="explain"></param> /// <returns>The value for the function application</returns> public override IValue Evaluate(InterpretationContext context, Dictionary<Actual, IValue> actuals, ExplanationPart explain) { IValue retVal = EFSSystem.BoolType.False; int token = context.LocalScope.PushContext(); AssignParameters(context, actuals); if (context.FindOnStack(Element).Value != EFSSystem.EmptyValue) { retVal = EFSSystem.BoolType.True; } context.LocalScope.PopContext(token); return retVal; }
/// <summary> /// Provides the value associated to this Expression /// </summary> /// <param name="context">The context on which the value must be found</param> /// <param name="explain">The explanation to fill, if any</param> /// <returns></returns> protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain) { StructureValue retVal = null; Structure structureType = Structure.GetExpressionType() as Structure; if (structureType != null) { retVal = new StructureValue(this, context, explain); } else { AddError("Cannot determine structure type for " + ToString(), RuleChecksEnum.ExecutionFailed); } return(retVal); }
/// <summary> /// Provides all the steps used to get the value of the expression /// </summary> /// <param name="context"></param> /// <returns></returns> public ExplanationPart Explain(InterpretationContext context = null) { ExplanationPart retVal = new ExplanationPart(Root, this); if (context == null) { context = new InterpretationContext(); } try { GetValue(context, retVal); } catch (Exception) { } return(retVal); }
/// <summary> /// Sets the node, and its subnode according to the content of the explanation /// </summary> /// <param name="part"></param> /// <param name="node"></param> /// <param param name="level">the level in which the explanation is inserted</param> private void innerSetExplanation(DataDictionary.Interpreter.ExplanationPart part, ExplainTreeNode node, int level) { foreach (DataDictionary.Interpreter.ExplanationPart subPart in part.SubExplanations) { ExplainTreeNode subNode = new ExplainTreeNode(subPart); innerSetExplanation(subPart, subNode, level + 1); node.Nodes.Add(subNode); } if (level <= 2) { node.Expand(); } else { node.Collapse(); } }
/// <summary> /// Provides the value associated to this Expression /// </summary> /// <param name="context">The context on which the value must be found</param> /// <param name="explain">The explanation to fill, if any</param> /// <returns></returns> protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain) { IValue retVal = null; ExplanationPart subExplanation = ExplanationPart.CreateSubExplanation(explain, this); try { if (Parameters.Count == 1) { int token = context.LocalScope.PushContext(); context.LocalScope.SetGraphParameter(Parameters[0]); Graph graph = CreateGraph(context, Parameters[0], subExplanation); 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]); Surface surface = CreateSurface(context, Parameters[0], Parameters[1], subExplanation); 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 IValue; } finally { ExplanationPart.SetNamable(subExplanation, retVal); } return(retVal); }
/// <summary> /// Provides the value of the function /// </summary> /// <param name="context"></param> /// <param name="actuals">the actual parameters values</param> /// <param name="explain"></param> /// <returns>The value for the function application</returns> public override IValue Evaluate(InterpretationContext context, Dictionary<Actual, IValue> actuals, ExplanationPart explain) { IValue retVal = null; int token = context.LocalScope.PushContext(); AssignParameters(context, actuals); DoubleValue value = context.findOnStack(Value).Value as DoubleValue; if (value != null) { int res = (int) Math.Round(value.Val); retVal = new IntValue(ReturnType, res); } context.LocalScope.PopContext(token); return retVal; }
/// <summary> /// Provides the value associated to this Expression /// </summary> /// <param name="context">The context on which the value must be found</param> /// <param name="explain"></param> /// <returns></returns> public virtual IValue GetExpressionValue(InterpretationContext context, ExplanationPart explain) { IValue retVal = null; try { Util.DontNotify(() => { retVal = GetValue(context, explain); }); } catch (Exception e) { ModelElement modelElement = context.Instance as ModelElement; if (modelElement != null) { modelElement.AddErrorAndExplain(e.Message, explain); } } 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; if (Term != null) { retVal = Term.GetCalled(context, explain); } else if (Expression != null) { retVal = Expression.GetCalled(context, explain); } // TODO : Investigate why this if (retVal == null) { retVal = GetValue(context, explain) as ICallable; } return(retVal); }
/// <summary> /// Provides the value associated to this Expression /// </summary> /// <param name="context">The context on which the value must be found</param> /// <param name="explain">The explanation to fill, if any</param> /// <returns></returns> protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain) { ListValue retVal = new ListValue(ExpressionType, new List <IValue>()); foreach (Expression expr in ListElements) { IValue val = expr.GetValue(context, explain); if (val != null) { if (val != EfsSystem.Instance.EmptyValue) { retVal.Val.Add(val); } } else { AddError("Cannot evaluate " + expr, RuleChecksEnum.ExecutionFailed); } } return(retVal); }
/// <summary> /// Provides the value associated to this Expression /// </summary> /// <param name="context">The context on which the value must be found</param> /// <param name="explain">The explanation to fill, if any</param> /// <returns></returns> protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain) { INamable retVal = Ref as IValue; if (retVal == null) { IVariable variable = Ref as IVariable; if (variable != null) { retVal = variable.Value; } } if (retVal == null) { InterpretationContext ctxt = new InterpretationContext(context); foreach (Expression expression in Arguments) { if (retVal != null) { ctxt.Instance = retVal; } retVal = expression.GetValue(ctxt, explain); if (retVal == EfsSystem.Instance.EmptyValue) { break; } } } if (retVal == null) { AddError(ToString() + " does not refer to a value", RuleChecksEnum.ExecutionFailed); } return(retVal as IValue); }
/// <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 (xParam == null || yParam == null) { AddError("Cannot have null parameters for Function expression " + ToString(), RuleChecksEnum.ExecutionFailed); } 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, explain); context.LocalScope.PopContext(token); } retVal.XParameter = xParam; retVal.YParameter = yParam; return(retVal); }
/// <summary> /// Provides the value of the function /// </summary> /// <param name="context"></param> /// <param name="actuals">the actual parameters values</param> /// <param name="explain"></param> /// <returns>The value for the function application</returns> public override IValue Evaluate(InterpretationContext context, Dictionary<Actual, IValue> actuals, ExplanationPart explain) { IValue retVal = null; int token = context.LocalScope.PushContext(); AssignParameters(context, actuals); BoolValue val = context.findOnStack(Value).Value as BoolValue; if (val != null) { if (val.Val) { retVal = EFSSystem.BoolType.False; } else { retVal = EFSSystem.BoolType.True; } } context.LocalScope.PopContext(token); return retVal; }
/// <summary> /// Provides the value of the function /// </summary> /// <param name="context"></param> /// <param name="actuals">the actual parameters values</param> /// <param name="explain"></param> /// <returns>The value for the function application</returns> public override IValue Evaluate(InterpretationContext context, Dictionary<Actual, IValue> actuals, ExplanationPart explain) { IValue retVal = null; int token = context.LocalScope.PushContext(); AssignParameters(context, actuals); ListValue value = context.FindOnStack(Collection) as ListValue; if (value != null) { Collection collectionType = value.Type as Collection; if (collectionType != null && collectionType.Type != null) { Type elementType = collectionType.Type; int i = 0; while (i < value.Val.Count && value.Val[i] != EFSSystem.EmptyValue) { i += 1; } if (i < value.Val.Count) { retVal = elementType.DefaultValue; value.Val[i] = retVal; } else { AddError("Cannot allocate element in list : list full"); } } } context.LocalScope.PopContext(token); return retVal; }
/// <summary> /// Adds a sub explanation for the explain provided as parameter /// </summary> /// <param name="explain"></param> /// <param name="subExplain"></param> public static void AddSubExplanation(ExplanationPart explain, ExplanationPart subExplain) { if (explain != null) { explain.SubExplanations.Add(subExplain); } }
/// <summary> /// Creates a sub explanation for the explain provided as parameter /// </summary> /// <param name="explain"></param> /// <param name="message"></param> /// <param name="leftPart"></param> /// <returns></returns> public static ExplanationPart CreateNamedSubExplanation(ExplanationPart explain, string message, object leftPart) { ExplanationPart retVal = null; if (explain != null) { retVal = new ExplanationPart(explain.Element, message); retVal.LeftPart = leftPart; explain.SubExplanations.Add(retVal); } 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; if (Term != null) { retVal = Term.GetCalled(context, explain); } else if (Expression != null) { retVal = Expression.GetCalled(context, explain); } // TODO : Investigate why this if (retVal == null) { retVal = GetValue(context, explain) as ICallable; } return retVal; }
/// <summary> /// Provides the value associated to this Expression /// </summary> /// <param name="context">The context on which the value must be found</param> /// <param name="explain">The explanation to fill, if any</param> /// <returns></returns> protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain) { IValue retVal = null; if (Term != null) { retVal = Term.GetValue(context, explain); } else { if (Not.Equals(UnaryOp)) { BoolValue b = Expression.GetValue(context, explain) as BoolValue; if (b != null) { if (b.Val) { retVal = EfsSystem.Instance.BoolType.False; } else { retVal = EfsSystem.Instance.BoolType.True; } } else { AddError("Expression " + Expression + " does not evaluate to boolean"); } } else if (Minus.Equals(UnaryOp)) { IValue val = Expression.GetValue(context, explain); IntValue intValue = val as IntValue; if (intValue != null) { retVal = new IntValue(intValue.Type, -intValue.Val); } else { DoubleValue doubleValue = val as DoubleValue; if (doubleValue != null) { retVal = new DoubleValue(doubleValue.Type, -doubleValue.Val); } } if (retVal == null) { AddError("Cannot negate value for " + Expression); } } else { retVal = Expression.GetValue(context, explain); } } return retVal; }
/// <summary> /// Provides the value associated to this Expression /// </summary> /// <param name="context">The context on which the value must be found</param> /// <param name="explain">The explanation to fill, if any</param> /// <returns></returns> protected internal override IValue GetValue(InterpretationContext context, ExplanationPart explain) { StructureValue retVal = null; Structure structureType = Structure.GetExpressionType() as Structure; if (structureType != null) { retVal = new StructureValue(this, context, explain); } else { AddError("Cannot determine structure type for " + 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 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> /// Provides the value of the prefix of the expression /// </summary> /// <param name="context">The context on which the value must be found</param> /// <param name="elementCount">The number of elements to consider</param> /// <param name="explain"></param> /// <returns></returns> public INamable GetPrefixValue(InterpretationContext context, int elementCount, ExplanationPart explain) { INamable retVal = null; InterpretationContext ctxt = new InterpretationContext(context); for (int i = 0; i < elementCount; i++) { if (retVal != null) { ctxt.Instance = retVal; } retVal = Arguments[i].GetValue(ctxt, explain); if (retVal == null) { retVal = Arguments[i].Ref; } if (retVal == EFSSystem.EmptyValue) { break; } } if (retVal == null) { AddError(ToString() + " prefix does not refer to a value"); } return retVal; }
/// <summary> /// Creates a sub explanation for the explain provided as parameter /// </summary> /// <param name="explain"></param> /// <param name="name"></param> /// <returns></returns> public static ExplanationPart CreateSubExplanation(ExplanationPart explain, string name) { ExplanationPart retVal = null; if (explain != null) { retVal = new ExplanationPart(explain.Element, name); explain.SubExplanations.Add(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); 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; }
/// <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 = Called; if (retVal == null) { AddError("Cannot evaluate call to " + 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); retVal = Graph.createGraph(GetValue(context, explain), parameter, explain); if (retVal == null) { throw new Exception("Cannot create graph for " + ToString()); } return retVal; }
/// <summary> /// Creates a list of changes to be applied on the system /// </summary> /// <param name="context">The context on which the changes should be computed</param> /// <param name="changes">The list of changes to be updated</param> /// <param name="explanation">The explanatino to fill, if any</param> /// <param name="apply">Indicates that the changes should be applied immediately</param> /// <param name="runner"></param> /// <returns>The list to fill with the changes</returns> public virtual void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation, bool apply, Runner runner) { if (!DeActivated) { long start = Environment.TickCount; try { if (Statement != null) { Statement.GetChanges(context, changes, explanation, apply, runner); } else { AddError("Invalid actions statement"); } } catch (Exception e) { AddException(e); } long stop = Environment.TickCount; long span = (stop - start); if (RuleCondition != null && RuleCondition.EnclosingRule != null) { // Rule execution execution time (as opposed to guard evaluation) RuleCondition.EnclosingRule.ExecutionTimeInMilli += span; RuleCondition.EnclosingRule.ExecutionCount += 1; } } }
/// <summary> /// Provides the value of the function /// </summary> /// <param name="context"></param> /// <param name="actuals"></param> /// <param name="explain"></param> /// <returns>The value for the function application</returns> public virtual IValue Evaluate(InterpretationContext context, Dictionary<Actual, IValue> actuals, ExplanationPart explain) { IValue retVal = null; bool useCache = EFSSystem.CacheFunctions; ExplainedValue explainedValue = null; // Only use the cached value when the EFSSystem indicates that caches should be used // This condition has been added to handle the fact that the user changes the status // of EFSSystem.CacheFunctions within a test session if (useCache) { if (_cachedResult == null) { _cachedResult = new CurryCache(this); } explainedValue = _cachedResult.GetValue(actuals); } if (explainedValue == null) { int token = context.LocalScope.PushContext(); AssignParameters(context, actuals); if (Cases.Count > 0) { bool preConditionSatisfied = false; // Statically defined function foreach (Case aCase in Cases) { // Evaluate the function ExplanationPart subExplanation = ExplanationPart.CreateSubExplanation(explain, aCase); preConditionSatisfied = aCase.EvaluatePreConditions(context, subExplanation); ExplanationPart.SetNamable(subExplanation, preConditionSatisfied ? EFSSystem.BoolType.True : EFSSystem.BoolType.False); if (preConditionSatisfied) { retVal = aCase.Expression.GetValue(context, subExplanation); break; } } if (!preConditionSatisfied) { ExplanationPart.CreateSubExplanation(explain, "Partial function called outside its domain"); AddError("Partial function called outside its domain"); } } else if (Surface != null && FormalParameters.Count == 2) { double x = 0.0; double y = 0.0; Parameter formal1 = (Parameter) FormalParameters[0]; Parameter formal2 = (Parameter) FormalParameters[1]; foreach (KeyValuePair<Actual, IValue> pair in actuals) { if (pair.Key.Parameter == formal1) { x = GetDoubleValue(pair.Value); } if (pair.Key.Parameter == formal2) { y = GetDoubleValue(pair.Value); } } retVal = new DoubleValue(EFSSystem.DoubleType, Surface.Val(x, y)); } else if (Graph != null && FormalParameters.Count < 2) { if (FormalParameters.Count == 0) { retVal = new DoubleValue(EFSSystem.DoubleType, Graph.Evaluate(0)); } else if (FormalParameters.Count == 1) { double x = 0.0; Parameter formal = (Parameter) FormalParameters[0]; foreach (KeyValuePair<Actual, IValue> pair in actuals) { if (pair.Key.Parameter == formal) { x = GetDoubleValue(pair.Value); } } retVal = new DoubleValue(EFSSystem.DoubleType, Graph.Evaluate(x)); } } context.LocalScope.PopContext(token); ExplanationPart.SetNamable(explain, retVal); if (useCache) { _cachedResult.SetValue(actuals, retVal, explain); } } else { retVal = explainedValue.Value; ExplanationPart subExplain = ExplanationPart.CreateSubExplanation(explain, "Cached result = "); ExplanationPart.SetNamable(subExplain, retVal); // Reuse the explanation of the return value computation // Topmost entry is the function call, useless, so don't provide it if (explainedValue.Explanation != null) { foreach (ExplanationPart part in explainedValue.Explanation.SubExplanations) { ExplanationPart.AddSubExplanation(subExplain, part); } } } return retVal; }
/// <summary> /// Creates a sub explanation for the explain provided as parameter /// </summary> /// <param name="explain"></param> /// <param name="leftPart"></param> /// <param name="rightPart"></param> /// <returns></returns> public static ExplanationPart CreateSubExplanation(ExplanationPart explain, object leftPart, INamable rightPart = null) { ExplanationPart retVal = null; if (explain != null) { retVal = new ExplanationPart(explain.Element, leftPart, rightPart); explain.SubExplanations.Add(retVal); } return retVal; }
/// <summary> /// Provides the value of the function /// </summary> /// <param name="context"></param> /// <param name="actuals">the actual parameters values</param> /// <param name="explain"></param> /// <returns>The value for the function application</returns> public override IValue Evaluate(InterpretationContext context, Dictionary<Actual, IValue> actuals, ExplanationPart explain) { IValue retVal = null; int token = context.LocalScope.PushContext(); AssignParameters(context, actuals); StructureValue startDate = context.findOnStack(StartDate).Value as StructureValue; if (startDate != null) { int year = GetIntValue(startDate, "Year"); int month = GetIntValue(startDate, "Month"); int day = GetIntValue(startDate, "Day"); int hour = GetIntValue(startDate, "Hour"); int minute = GetIntValue(startDate, "Minute"); int second = GetIntValue(startDate, "Second"); int tts = GetIntValue(startDate, "TTS"); DoubleValue addedTime = context.findOnStack(Increment).Value as DoubleValue; if (addedTime != null) { DateTime start = new DateTime(year, month, day, hour, minute, second, tts); DateTime currentTime = start.AddSeconds((double) addedTime.Val); retVal = GetEFSDate(currentTime, startDate.Type as Structure); } } context.LocalScope.PopContext(token); return retVal; }
/// <summary> /// Creates a sub explanation for the explain provided as parameter /// </summary> /// <param name="explain"></param> /// <param name="root"></param> /// <param name="change"></param> /// <returns></returns> public static ExplanationPart CreateSubExplanation(ExplanationPart explain, ModelElement root, Change change) { ExplanationPart retVal = null; if (explain != null) { retVal = new ExplanationPart(root, change); explain.SubExplanations.Add(retVal); } 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> /// <param name="explain"></param> /// <returns></returns> public virtual Graph CreateGraphForParameter(InterpretationContext context, Parameter parameter, ExplanationPart explain) { Graph retVal = Graph; if (retVal == null) { retVal = new Graph(); foreach (Case cas in Cases) { if (PreconditionSatisfied(context, cas, parameter, explain)) { Graph subGraph = cas.Expression.CreateGraph(context, parameter, explain); ReduceGraph(context, subGraph, cas, parameter, explain); retVal.Merge(subGraph); } } } return retVal; }
/// <summary> /// Sets the value associated to the explanation /// </summary> /// <param name="explain"></param> /// <param name="namable"></param> public static void SetNamable(ExplanationPart explain, INamable namable) { if (explain != null) { explain.RightPart = namable; } }
/// <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> /// Provides the value associated to this Expression /// </summary> /// <param name="context">The context on which the value must be found</param> /// <param name="explain">The explanation to fill, if any</param> /// <returns></returns> public override IValue GetValue(InterpretationContext context, ExplanationPart explain) { INamable retVal = Ref as IValue; if (retVal == null) { InterpretationContext ctxt = new InterpretationContext(context); for (int i = 0; i < Arguments.Count; i++) { if (retVal != null) { ctxt.Instance = retVal; } retVal = Arguments[i].GetValue(ctxt, explain); if (retVal == EFSSystem.EmptyValue) { break; } } } if (retVal == null) { AddError(ToString() + " does not refer to a value"); } return retVal as IValue; }
/// <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="explain"></param> /// <returns></returns> public virtual Surface CreateSurface(InterpretationContext context, ExplanationPart explain) { Surface retVal = Surface; if (retVal == null) { try { if (FormalParameters.Count == 2) { // Select which parameter is the X axis of the surface, and which is the Y Parameter xParameter = SelectXAxisParameter(context); Parameter yParameter = SelectYAxisParameter(xParameter); if (xParameter != null && yParameter != null) { int token = context.LocalScope.PushContext(); context.LocalScope.SetSurfaceParameters(xParameter, yParameter); retVal = CreateSurfaceForParameters(context, xParameter, yParameter, explain); context.LocalScope.PopContext(token); } } else { AddError("Wrong number of parameters for function " + FullName + " to create a surface"); } } catch (Exception e) { AddError("Cannot create surface of function, reason : " + e.Message); } } return retVal; }
/// <summary> /// Provides the value of the function /// </summary> /// <param name="context"></param> /// <param name="actuals">the actual parameters values</param> /// <param name="explain"></param> /// <returns>The value for the function application</returns> public override IValue Evaluate(InterpretationContext context, Dictionary<Actual, IValue> actuals, ExplanationPart explain) { IValue retVal = null; int token = context.LocalScope.PushContext(); AssignParameters(context, actuals); Collection collectionType = (Collection) EFSSystem.FindType( OverallNameSpaceFinder.INSTANCE.findByName(EFSSystem.Dictionaries[0], "Kernel.SpeedAndDistanceMonitoring.TargetSpeedMonitoring"), "Kernel.SpeedAndDistanceMonitoring.TargetSpeedMonitoring.SpeedRestrictions"); ListValue collection = new ListValue(collectionType, new List<IValue>()); Function function = context.findOnStack(Targets).Value as Function; if (function != null && !function.Name.Equals("EMPTY")) { Graph graph1 = createGraphForValue(context, function, explain); ComputeTargets(graph1.Function, collection); } context.LocalScope.PopContext(token); retVal = collection; 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; }