diff options
Diffstat (limited to 'simplifier.cpp')
-rw-r--r-- | simplifier.cpp | 210 |
1 files changed, 199 insertions, 11 deletions
diff --git a/simplifier.cpp b/simplifier.cpp index 8fb926c..d258515 100644 --- a/simplifier.cpp +++ b/simplifier.cpp @@ -6,13 +6,13 @@ #include "include/expressions.hpp" #include <cstddef> -void Simplifier::simplifyChildren(Expression *root, Expression *left, Expression *right) { - left = root->getLeft()->simplify(root->getLeft(), this); - right = root->getRight()->simplify(root->getRight(), this); +void Simplifier::simplifyChildren(Expression *root, Expression **left, Expression **right) const { + *left = root->getLeft()->simplify(this); + *right = root->getRight()->simplify(this); } // Reglas de simplificación. -Expression *Simplifier::ruleEval(Expression *expr) { +Expression *Simplifier::ruleEval(Expression *expr) const { Literal *left = dynamic_cast <Literal *>(expr->getLeft()); Literal *right = dynamic_cast <Literal *>(expr->getRight()); @@ -22,7 +22,7 @@ Expression *Simplifier::ruleEval(Expression *expr) { return NULL; } -Expression *Simplifier::ruleMultiplyByOne(MultiplicationExpression *expr) { +Expression *Simplifier::ruleMultiplyByOne(MultiplicationExpression *expr) const { Literal *left = dynamic_cast <Literal *>(expr->getLeft()); Literal *right = dynamic_cast <Literal *>(expr->getRight()); @@ -35,7 +35,7 @@ Expression *Simplifier::ruleMultiplyByOne(MultiplicationExpression *expr) { return NULL; } -Expression *Simplifier::ruleDivideByOne(DivisionExpression *expr) { +Expression *Simplifier::ruleDivideByOne(DivisionExpression *expr) const { Literal *right = dynamic_cast <Literal *>(expr->getRight()); if (right != NULL && right->getValue() == 1) @@ -44,7 +44,7 @@ Expression *Simplifier::ruleDivideByOne(DivisionExpression *expr) { return NULL; } -Expression *Simplifier::ruleMultiplyByZero(MultiplicationExpression *expr) { +Expression *Simplifier::ruleMultiplyByZero(MultiplicationExpression *expr) const { Literal *left = dynamic_cast <Literal *>(expr->getLeft()); Literal *right = dynamic_cast <Literal *>(expr->getRight()); @@ -54,7 +54,7 @@ Expression *Simplifier::ruleMultiplyByZero(MultiplicationExpression *expr) { return NULL; } -Expression *Simplifier::ruleZeroDivision(DivisionExpression *expr) { +Expression *Simplifier::ruleZeroDivision(DivisionExpression *expr) const { Literal *left = dynamic_cast <Literal *>(expr->getLeft()); if(left != NULL && left->getValue() == 0) @@ -63,7 +63,7 @@ Expression *Simplifier::ruleZeroDivision(DivisionExpression *expr) { return NULL; } -Expression *Simplifier::ruleOnePower(PowerExpression *expr) { +Expression *Simplifier::ruleOnePower(PowerExpression *expr) const { Literal *right = dynamic_cast <Literal *>(expr->getRight()); if(right != NULL && right->getValue() == 1) @@ -72,7 +72,7 @@ Expression *Simplifier::ruleOnePower(PowerExpression *expr) { return NULL; } -Expression *Simplifier::ruleZeroPower(PowerExpression *expr) { +Expression *Simplifier::ruleZeroPower(PowerExpression *expr) const { Literal *right = dynamic_cast <Literal *>(expr->getRight()); if(right != NULL && right->getValue() == 0) @@ -81,7 +81,7 @@ Expression *Simplifier::ruleZeroPower(PowerExpression *expr) { return NULL; } -Expression *Simplifier::addZero(AddExpression *expr) { +Expression *Simplifier::addSubstractZero(Expression *expr) const { Literal *left = dynamic_cast <Literal *>(expr->getLeft()); Literal *right = dynamic_cast <Literal *>(expr->getRight()); @@ -93,3 +93,191 @@ Expression *Simplifier::addZero(AddExpression *expr) { return NULL; } + +// Para variables y constantes sólo devolveremos una copia. +Expression *Simplifier::visit(Variable *expr) const { + return expr->copy(); +} + +Expression *Simplifier::visit(Literal *expr) const { + return expr->copy(); +} + +// Para las funciones sólo simplificaremos su argumento. +Expression *Simplifier::visit(Function *expr) const { + Expression *simplified = expr->getArg()->simplify(this); + + return new Function(simplified, expr->getFunctionName()); +} + +// Igual en negaciones. +Expression *Simplifier::visit(NegationExpression *expr) const { + Expression *simplified = expr->getRight()->simplify(this); + + return new NegationExpression(simplified); +} + +Expression *Simplifier::visit(AddExpression *expr) const { + Expression *left = NULL, *right = NULL, *simplified; + AddExpression *root; + + simplifyChildren(expr, &left, &right); + root = new AddExpression(left, right); + /* Primera regla: vemos si se puede evaluar. + (Los dos nodos hijos son números). */ + simplified = ruleEval(root); + + if(simplified != NULL) { + delete root; + + return simplified; + } + + /* Segunda regla: vemos si uno de los nodos + hijo es 0.*/ + simplified = addSubstractZero(root); + + if(simplified != NULL) { + delete root; + + return simplified; + } + + /* No se pudo simplificar más: regresamos un nodo suma + con los nodos hijo simplificados.*/ + return root; +} + +Expression *Simplifier::visit(SubExpression *expr) const { + Expression *left = NULL, *right = NULL, *simplified; + SubExpression *root; + + simplifyChildren(expr, &left, &right); + root = new SubExpression(left, right); + + simplified = ruleEval(root); + + if(simplified != NULL) { + delete root; + + return simplified; + } + + simplified = addSubstractZero(root); + + if(simplified != NULL) { + delete root; + + return simplified; + } + + return root; +} + +Expression *Simplifier::visit(MultiplicationExpression *expr) const { + Expression *left = NULL, *right = NULL, *simplified; + MultiplicationExpression *root; + + simplifyChildren(expr, &left, &right); + root = new MultiplicationExpression(left, right); + + simplified = ruleEval(root); + + if(simplified != NULL) { + delete root; + + return simplified; + } + + simplified = ruleMultiplyByOne(root); + + if(simplified != NULL) { + delete root; + + return simplified; + } + + simplified = ruleMultiplyByZero(root); + + if(simplified != NULL) { + delete root; + + return simplified; + } + + return root; +} + +Expression *Simplifier::visit(DivisionExpression *expr) const { + Expression *left = NULL, *right = NULL, *simplified; + DivisionExpression *root; + + simplifyChildren(expr, &left, &right); + root = new DivisionExpression(left, right); + + simplified = ruleEval(root); + + if(simplified != NULL) { + delete root; + + return simplified; + } + + simplified = ruleDivideByOne(root); + + if(simplified != NULL) { + delete root; + + return simplified; + } + + simplified = ruleZeroDivision(root); + + if(simplified != NULL) { + delete root; + + return simplified; + } + + return root; +} + +Expression *Simplifier::visit(PowerExpression *expr) const { + Expression *left = NULL, *right = NULL, *simplified; + PowerExpression *root; + + simplifyChildren(expr, &left, &right); + root = new PowerExpression(left, right); + + simplified = ruleEval(root); + + if(simplified != NULL) { + delete root; + + return simplified; + } + + simplified = ruleOnePower(expr); + + if(simplified != NULL) { + delete root; + + return simplified; + } + + simplified = ruleZeroPower(root); + + if(simplified != NULL) { + delete root; + + return simplified; + } + + return root; +} + +Expression *simplify(Expression *to_simplify) { + Simplifier s; + + return to_simplify->simplify(&s); +} |