summaryrefslogtreecommitdiff
path: root/simplifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'simplifier.cpp')
-rw-r--r--simplifier.cpp210
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);
+}