private static bool ReduceMultipliedAlphabeticFactors(ComponentListFactor leftFactor, ComponentListFactor rightFactor, out Expression expression) { // If any alphabetic factors are identical, convert to exponent if (leftFactor.Factor is AlphabeticFactor && rightFactor.Factor is AlphabeticFactor) { var leftAlpha = (AlphabeticFactor) leftFactor.Factor; var rightAlpha = (AlphabeticFactor) rightFactor.Factor; if (leftAlpha.Value.Equals(rightAlpha.Value)) { var shouldPower = leftFactor.IsInNumerator && rightFactor.IsInNumerator; if (shouldPower) { expression = new SingleComponentExpression(new FunctionComponent("^", new List<Expression> { Expressionizer.ToExpression(leftAlpha), NumberToExpression(new Integer(2)) })); return true; } expression = NumberToExpression(new Integer(1)); return true; } } expression = null; return false; }
private static bool ReduceFunctionsWithSameOperands(ComponentListFactor leftFactor, ComponentListFactor rightFactor, out Expression expression, Expression left, Expression right) { FunctionComponent leftFunction; FunctionComponent rightFunction; // If there are two functions with the same operands that should cancel out, cancel them out if (Common.IsFunction(left, out leftFunction) && Common.IsFunction(right, out rightFunction)) { if (leftFunction.Function.Name == rightFunction.Function.Name && leftFunction.Operands.Count == rightFunction.Operands.Count) { for (var i = 0; i < leftFunction.Operands.Count; i++) { var leftOperand = leftFunction.Operands[i]; var rightOperand = rightFunction.Operands[i]; if (!leftOperand.ToString().Equals(rightOperand.ToString())) { break; } if (leftFactor.IsInNumerator != rightFactor.IsInNumerator) { expression = Expressionizer.ToExpression(new NumericFactor(new Integer(1))); return true; } } } } expression = null; return false; }
private static bool CanReduce(ComponentListFactor leftFactor, ComponentListFactor rightFactor, out Expression expression) { if (ReduceMultipliedAlphabeticFactors(leftFactor, rightFactor, out expression)) { return true; } var left = Expressionizer.ToExpression(leftFactor.Factor); var right = Expressionizer.ToExpression(rightFactor.Factor); Number leftNumber; Number rightNumber; if ((Common.IsConstant(left, out leftNumber) && Common.IsFloat(right, out rightNumber)) || (Common.IsFloat(left, out leftNumber) && Common.IsConstant(right, out rightNumber)) || (Common.IsNumber(left, out leftNumber) && Common.IsNumber(right, out rightNumber))) { expression = Evaluate(leftNumber, rightNumber, leftFactor.IsInNumerator, rightFactor.IsInNumerator); return true; } ExpressionList leftList; ExpressionList rightList; if (Common.IsList(left, out leftList)) { expression = Evaluate(leftList, right, leftFactor.IsInNumerator == rightFactor.IsInNumerator); return true; } if (Common.IsList(right, out rightList)) { expression = Evaluate(rightList, left, leftFactor.IsInNumerator == rightFactor.IsInNumerator); return true; } IntegerFraction leftFraction; IntegerFraction rightFraction; if (Common.IsNumber(left, out leftNumber) && Common.IsIntegerFraction(right, out rightFraction)) { expression = Expressionizer.ToExpression(Evaluate(leftNumber, rightFraction, leftFactor.IsInNumerator, rightFactor.IsInNumerator)); return true; } if (Common.IsIntegerFraction(left, out leftFraction) && Common.IsNumber(right, out rightNumber)) { expression = Expressionizer.ToExpression(Evaluate(leftFraction, rightNumber, leftFactor.IsInNumerator, rightFactor.IsInNumerator)); return true; } if (Common.IsIntegerFraction(left, out leftFraction) && Common.IsIntegerFraction(right, out rightFraction)) { expression = Expressionizer.ToExpression(Evaluate(leftFraction, rightFraction, leftFactor.IsInNumerator, rightFactor.IsInNumerator)); return true; } if (ReduceFunctionsWithSameOperands(leftFactor, rightFactor, out expression, left, right)) { return true; } if (ReduceExponents(out expression, left, right)) { return true; } expression = null; return false; }