private static EquationStruct AtomicEquation(ref string equationIn, ref bool error) { EquationStruct node = null; EquationStruct child = null; string nextVar = GetNextVariableName(equationIn); string nextConst = GetNextConstant(equationIn); string op = ""; int precedence; int index; if (unaryOpsSym.Contains(Next(ref equationIn))) { op = Next(ref equationIn); Consume(ref equationIn, op.Length); precedence = unaryOps[unaryOpsSym.BinarySearch(op)].GetPrecedence(); child = ExpressionEquation(ref equationIn, precedence, ref error); if (!error) { node = MakeNode(op, child, null); } } else if (leftTerminators.Contains(Next(ref equationIn))) { index = leftTerminators.IndexOf(Next(ref equationIn)); Consume(ref equationIn, leftTerminators[index].Length); child = ExpressionEquation(ref equationIn, 0, ref error); if (!error) { Expect(ref equationIn, rightTerminators[index], ref error); if (!error) { node = MakeNode(leftTerminators[index] + rightTerminators[index], child, null); } } } else if (nextVar != "") { node = MakeLeaf(nextVar); if (!variableList.Contains(nextVar)) { variableList.Add(nextVar); } Consume(ref equationIn, nextVar.Length); } else if (nextConst != "") { node = MakeLeaf(nextConst); Consume(ref equationIn, nextConst.Length); } // Either an unbalanced operator or unexpected case was encountered -> return null else { frm_Main.UpdateLog("Error: Unrecognized sequence encountered during Atomic Equation parsing. Remaining equation = " + equationIn + System.Environment.NewLine); error = true; } return(node); }
private static string[] CalculateRange(string rawEquation, string variables) { int success = Consolidate.ConvertAndCheckInputs(rawEquation, variables, Solver.GetValidOperators(), Solver.GetValidTerminators(), Input.GetLineDelimiter(), Input.GetFieldDelimiter()); string[] results = null; if (success == 0) { EquationStruct eq = Consolidate.GetEquationStruct(); IntervalStruct[] intervals = Consolidate.GetIntervalStructList(); IntervalStruct range = Solver.FindRange(eq, intervals); if (range != null) { results = new string[] { Output.PrintInterval(range, false), Output.PrintEquationTree(eq) }; frm_Main.UpdateLog("Range calculated successfully." + System.Environment.NewLine); hasRun = true; } } else { successCode = success; } return(results); }
/* PARSING FUNCTIONS */ public static EquationStruct MakeEquationTree(string equationIn) { EquationStruct node = null; string parseString; // The error flag will be true if a parsing error is encountered bool error = false; try { System.Convert.ToDouble(equationIn); node = new EquationStruct(CONSTTOKEN, equationIn, null, null); frm_Main.UpdateLog("Warning: The user equation is a constant value and the range will only include this value." + System.Environment.NewLine); } catch (System.FormatException) { // Replacing implicit multiplications of constants by variables with an explicit operator if (binaryOpsSym.Contains("*")) { string temp = equationIn; Regex rgx = new Regex(implicitMultiplicationPattern); equationIn = rgx.Replace(equationIn, implicitMultiplicationReplacement); if (equationIn != temp) { frm_Main.UpdateLog("Warning: Encountered an implicit multiplication of a constant value and a variable. Expanding with explicit operator." + System.Environment.NewLine); } } // Parse the equation -> return null if an error occurs parseString = equationIn; node = ExpressionEquation(ref parseString, 0, ref error); if (!error) { Expect(ref parseString, ENDTOKEN, ref error); if (error) { frm_Main.UpdateLog("Error: Could not find the end of the equation." + System.Environment.NewLine); node = null; } } else { node = null; } } return(node); }
/* CALCULATION */ public static IntervalStruct FindRange(EquationStruct eqRoot, IntervalStruct[] intervals) { string[] varNames = GetVariableNamesFromIntervals(intervals); IntervalStruct range = null; if (eqRoot != null) { range = CalculateRange(eqRoot, intervals, varNames); } else { throw new System.ArgumentException("Error: No information was provided for the equation."); } return(range); }
private static EquationStruct MakeLeaf(string terminal) { EquationStruct leaf = null; try { double constant = System.Convert.ToDouble(terminal); leaf = new EquationStruct(CONSTTOKEN, terminal, null, null); } catch (System.FormatException) { leaf = new EquationStruct(VARTOKEN, terminal, null, null); } return(leaf); }
private static EquationStruct ExpressionEquation(ref string equationIn, int prec, ref bool error) { EquationStruct node = AtomicEquation(ref equationIn, ref error); EquationStruct child = null; string op = ""; int nextPrecedence = 0; if (!error) { while (binaryOpsSym.Contains(Next(ref equationIn)) && binaryOps[binaryOpsSym.IndexOf(Next(ref equationIn))].GetPrecedence() >= prec) { op = Consume(ref equationIn, binaryOps[binaryOpsSym.IndexOf(Next(ref equationIn))].GetOperator().Length); if (binaryOps[binaryOpsSym.IndexOf(op)].IsLeftAssociative()) { nextPrecedence = binaryOps[binaryOpsSym.IndexOf(op)].GetPrecedence() + 1; } else { nextPrecedence = binaryOps[binaryOpsSym.IndexOf(op)].GetPrecedence(); } child = ExpressionEquation(ref equationIn, nextPrecedence, ref error); if (!error) { node = MakeNode(op, node, child); } else { node = null; } } } else { node = null; } return(node); }
private static IntervalStruct CalculateRange(EquationStruct eqTree, IntervalStruct[] intervals, string[] intervalNames) { IntervalStruct range = null; IntervalStruct leftResult = null; IntervalStruct rightResult = null; double constant = 0; int varIndex = -1; // This is either a variable or a constant if (eqTree.GetLeftOperand() == null && eqTree.GetRightOperand() == null) { try { constant = System.Convert.ToDouble(eqTree.GetVariableName()); range = new IntervalStruct("", constant, constant, true, true); } catch (System.FormatException) { varIndex = System.Array.IndexOf(intervalNames, eqTree.GetVariableName()); if (varIndex > -1) { range = intervals[varIndex]; } else { frm_Main.UpdateLog("Error: Could not find an associated interval for variable " + eqTree.GetVariableName() + System.Environment.NewLine); } } } // This is an equation, so calculate the result else if (eqTree.GetOperator() == "+") { leftResult = CalculateRange(eqTree.GetLeftOperand(), intervals, intervalNames); rightResult = CalculateRange(eqTree.GetRightOperand(), intervals, intervalNames); if (leftResult != null && rightResult != null) { range = IntervalAddition(leftResult, rightResult); } } else if (eqTree.GetOperator() == "-") { leftResult = CalculateRange(eqTree.GetLeftOperand(), intervals, intervalNames); rightResult = CalculateRange(eqTree.GetRightOperand(), intervals, intervalNames); if (leftResult != null && rightResult != null) { range = IntervalSubtraction(leftResult, rightResult); } } else if (eqTree.GetOperator() == "*") { leftResult = CalculateRange(eqTree.GetLeftOperand(), intervals, intervalNames); rightResult = CalculateRange(eqTree.GetRightOperand(), intervals, intervalNames); if (leftResult != null && rightResult != null) { range = IntervalMultiplication(leftResult, rightResult); } } else if (eqTree.GetOperator() == "/") { leftResult = CalculateRange(eqTree.GetLeftOperand(), intervals, intervalNames); rightResult = CalculateRange(eqTree.GetRightOperand(), intervals, intervalNames); if (leftResult != null && rightResult != null) { range = IntervalDivision(leftResult, rightResult); } } else if (eqTree.GetOperator() == "^") { leftResult = CalculateRange(eqTree.GetLeftOperand(), intervals, intervalNames); rightResult = CalculateRange(eqTree.GetRightOperand(), intervals, intervalNames); if (leftResult != null && rightResult != null) { range = IntervalExponents(leftResult, rightResult); } } else if (eqTree.GetOperator() == "()") { range = CalculateRange(eqTree.GetLeftOperand(), intervals, intervalNames); } else { frm_Main.UpdateLog("Error: An unsupported operation was encountered while solving for the range of the equation (Unknown operator)." + System.Environment.NewLine); } return(range); }
/* * ConvertAndCheckInputs * ----------------------------------------------------------------------------------- * Returns an Integer code denoting the success of the parsing and conversion process. * Codes: * -3 -> Equation Parsing failed * -2 -> Variable Matching failed * -1 -> Equation Parser Initialization failed * 0 -> Success */ public static int ConvertAndCheckInputs(string eqString, string varList, OperatorStruct[] operators, string[][] terminators, string lineDelimiter, string fieldDelimiter) { string[] equationVars; List <int> eqVarIndex = new List <int>(); string[] intervalVars; List <int> ivVarIndex = new List <int>(); string[] intervalVars2; List <int> removeIndex = new List <int>(); int index; int success = 0; string message = ""; EquationConversion.ResetEquationConversion(); EquationConversion.ConfigureParser(operators, terminators); if (EquationConversion.IsReady()) { equationTreeRoot = EquationConversion.MakeEquationTree(eqString); if (equationTreeRoot != null) { if (varList != "") { intervalList = IntervalConversion.ConvertToIntervals(varList, lineDelimiter, fieldDelimiter); } intervalVars = GetVariableNamesFromIntervals(intervalList); equationVars = EquationConversion.GetVariableList(); // Find matching variable names from the interval structures and the equation for (int i = 0; i < equationVars.Length; i++) { index = Array.IndexOf(intervalVars, equationVars[i]); if (index > -1) { ivVarIndex.Add(index); eqVarIndex.Add(i); } } // Found fewer matching entries in the equation if (ivVarIndex.Count < intervalVars.Length) { message += "Warning: Extraneous variables found in interval list ("; // Sort list and reverse so that it is in descending order -> enables correct // behaviour for RemoveName(string[], int) ivVarIndex.Sort(); ivVarIndex.Reverse(); foreach (int v in ivVarIndex) { intervalVars = RemoveName(intervalVars, v); } foreach (string vName in intervalVars) { message += vName + ", "; } frm_Main.UpdateLog(message.Substring(0, message.Length - 2) + ")." + Environment.NewLine); // Find and remove extra intervals from the list intervalVars2 = GetVariableNamesFromIntervals(intervalList); for (int i = 0; i < intervalVars.Length; i++) { index = Array.IndexOf(intervalVars2, intervalVars[i]); if (index > -1) { removeIndex.Add(index); } } removeIndex.Sort(); removeIndex.Reverse(); foreach (int r in removeIndex) { intervalList = RemoveInterval(intervalList, r); } } // Found fewer matching entries in the variable list if (eqVarIndex.Count < equationVars.Length) { // This is a fail state success = -2; message = "Error: Cannot find intervals for variable name(s): "; foreach (int v in eqVarIndex) { equationVars = RemoveName(equationVars, v); } foreach (string vName in equationVars) { message += vName + ", "; } frm_Main.UpdateLog(message.Substring(0, message.Length - 2) + "." + Environment.NewLine); } } else { success = -3; } } else { frm_Main.UpdateLog("Error: Equation parser could not be configured."); success = -1; } return(success); }
/* NODE GENERATION FUNCTIONS */ private static EquationStruct MakeNode(string op, EquationStruct left, EquationStruct right) { return(new EquationStruct(op, "", left, right)); }