summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--expression_base.cpp6
-rw-r--r--include/expressions.hpp23
-rw-r--r--include/simplifier.hpp6
-rw-r--r--simplifier.cpp95
4 files changed, 120 insertions, 10 deletions
diff --git a/expression_base.cpp b/expression_base.cpp
index 3829715..2aff278 100644
--- a/expression_base.cpp
+++ b/expression_base.cpp
@@ -4,6 +4,7 @@
#include <string>
#include "include/expressions.hpp"
+#include "include/simplifier.hpp"
#include "include/lexer.hpp"
using std::string;
@@ -15,6 +16,11 @@ Expression *Expression::getLeft() {
return left;
}
+template <class E>
+Expression *Expression::simplify(E *expr ,const Simplifier *s) {
+ return s->visit(expr);
+}
+
Expression *Expression::getRight() {
return right;
}
diff --git a/include/expressions.hpp b/include/expressions.hpp
index a293408..604801d 100644
--- a/include/expressions.hpp
+++ b/include/expressions.hpp
@@ -24,6 +24,7 @@ enum trig_functions {
};
class Differentiator; // Forward declaration
+class Simplifier;
class Expression {
public:
@@ -31,9 +32,11 @@ public:
virtual ~Expression() = default;
std::string getRepr();
virtual Expression *diff(const Differentiator *d) = 0;
+ template <class E>
+ Expression *simplify(E *expr, const Simplifier *s);
Expression *getLeft();
Expression *getRight();
- virtual float eval(int arg) = 0;
+ virtual float eval(int arg=0) = 0;
virtual Expression *copy() = 0; // Regresa una copia de la expresión actual.
protected:
Expression *left;
@@ -51,7 +54,7 @@ public:
explicit Literal(int value);
~Literal();
int getValue();
- float eval(int arg) override;
+ float eval(int arg=0) override;
Expression *diff(const Differentiator *d) override;
Expression *copy() override;
protected:
@@ -66,7 +69,7 @@ public:
Function(Expression *arg, trig_functions name);
~Function();
Expression *getArg();
- float eval(int arg) override;
+ float eval(int arg=0) override;
Expression *diff(const Differentiator *d) override;
trig_functions getFunctionName() const;
Expression *copy() override;
@@ -81,7 +84,7 @@ private:
public:
explicit Variable(char name);
~Variable();
- float eval(int arg) override;
+ float eval(int arg=0) override;
Expression *diff(const Differentiator *d) override;
Expression *copy() override;
protected:
@@ -92,7 +95,7 @@ class AddExpression : public Expression {
public:
AddExpression(Expression *left, Expression *right);
~AddExpression();
- float eval(int arg) override;
+ float eval(int arg=0) override;
Expression *diff(const Differentiator *d) override;
Expression *copy() override;
};
@@ -101,7 +104,7 @@ class SubExpression : public Expression {
public:
SubExpression(Expression *left, Expression *right);
~SubExpression();
- float eval(int arg) override;
+ float eval(int arg=0) override;
Expression *copy() override;
Expression *diff(const Differentiator *d) override;
};
@@ -110,7 +113,7 @@ class NegationExpression : public Expression {
public:
explicit NegationExpression(Expression *right);
~NegationExpression();
- float eval(int arg) override;
+ float eval(int arg=0) override;
Expression *copy() override;
Expression *diff(const Differentiator *d) override;
protected:
@@ -121,7 +124,7 @@ class DivisionExpression : public Expression {
public:
DivisionExpression(Expression *left, Expression *right);
~DivisionExpression();
- float eval(int arg) override;
+ float eval(int arg=0) override;
Expression *copy() override;
Expression *diff(const Differentiator *d) override;
};
@@ -130,7 +133,7 @@ class MultiplicationExpression : public Expression {
public:
MultiplicationExpression(Expression *left, Expression *right);
~MultiplicationExpression();
- float eval(int arg) override;
+ float eval(int arg=0) override;
Expression *copy() override;
Expression *diff(const Differentiator *d) override;
};
@@ -139,7 +142,7 @@ class PowerExpression : public Expression {
public:
PowerExpression(Expression *left, Expression *right);
~PowerExpression();
- float eval(int arg) override;
+ float eval(int arg=0) override;
Expression *copy() override;
Expression *diff(const Differentiator *d) override;
};
diff --git a/include/simplifier.hpp b/include/simplifier.hpp
index 948c569..dcc3225 100644
--- a/include/simplifier.hpp
+++ b/include/simplifier.hpp
@@ -1,3 +1,7 @@
+/* PIA - Lenguajes Modernos de Programación
+ * FACULTAD DE CIENCIAS FÍSICO MATEMÁTICAS
+ * Luis Sebastián Martínez Vega - LCC */
+
#ifndef SIMPLIFIER_H
#define SIMPLIFIER_H
#include "expressions.hpp"
@@ -5,12 +9,14 @@
class Simplifier {
private:
void simplifyChildren(Expression *root, Expression *left, Expression *right);
+ Expression *ruleEval(Expression *expr);
Expression *ruleMultiplyByOne(MultiplicationExpression *expr);
Expression *ruleDivideByOne(DivisionExpression *expr);
Expression *ruleMultiplyByZero(MultiplicationExpression *expr);
Expression *ruleZeroDivision(DivisionExpression *expr);
Expression *ruleOnePower(PowerExpression *expr);
Expression *ruleZeroPower(PowerExpression *expr);
+ Expression *addZero(AddExpression *expr);
public:
Expression *visit(Variable *expr);
Expression *visit(Literal *expr);
diff --git a/simplifier.cpp b/simplifier.cpp
new file mode 100644
index 0000000..8fb926c
--- /dev/null
+++ b/simplifier.cpp
@@ -0,0 +1,95 @@
+/* PIA - Lenguajes Modernos de Programación
+ * FACULTAD DE CIENCIAS FÍSICO MATEMÁTICAS
+ * Luis Sebastián Martínez Vega - LCC */
+
+#include "include/simplifier.hpp"
+#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);
+}
+
+// Reglas de simplificación.
+Expression *Simplifier::ruleEval(Expression *expr) {
+ Literal *left = dynamic_cast <Literal *>(expr->getLeft());
+ Literal *right = dynamic_cast <Literal *>(expr->getRight());
+
+ if(left != NULL && right != NULL)
+ return new Literal(expr->eval());
+
+ return NULL;
+}
+
+Expression *Simplifier::ruleMultiplyByOne(MultiplicationExpression *expr) {
+ Literal *left = dynamic_cast <Literal *>(expr->getLeft());
+ Literal *right = dynamic_cast <Literal *>(expr->getRight());
+
+ if(left != NULL && left->getValue() == 1)
+ return expr->getRight()->copy();
+
+ if(right != NULL && right->getValue() == 1)
+ return expr->getLeft()->copy();
+
+ return NULL;
+}
+
+Expression *Simplifier::ruleDivideByOne(DivisionExpression *expr) {
+ Literal *right = dynamic_cast <Literal *>(expr->getRight());
+
+ if (right != NULL && right->getValue() == 1)
+ return expr->getLeft()->copy();
+
+ return NULL;
+}
+
+Expression *Simplifier::ruleMultiplyByZero(MultiplicationExpression *expr) {
+ Literal *left = dynamic_cast <Literal *>(expr->getLeft());
+ Literal *right = dynamic_cast <Literal *>(expr->getRight());
+
+ if((left != NULL && left->getValue() == 0) || (right != NULL && right->getValue() == 0))
+ return new Literal(0);
+
+ return NULL;
+}
+
+Expression *Simplifier::ruleZeroDivision(DivisionExpression *expr) {
+ Literal *left = dynamic_cast <Literal *>(expr->getLeft());
+
+ if(left != NULL && left->getValue() == 0)
+ return new Literal(0);
+
+ return NULL;
+}
+
+Expression *Simplifier::ruleOnePower(PowerExpression *expr) {
+ Literal *right = dynamic_cast <Literal *>(expr->getRight());
+
+ if(right != NULL && right->getValue() == 1)
+ return expr->getLeft()->copy();
+
+ return NULL;
+}
+
+Expression *Simplifier::ruleZeroPower(PowerExpression *expr) {
+ Literal *right = dynamic_cast <Literal *>(expr->getRight());
+
+ if(right != NULL && right->getValue() == 0)
+ return new Literal(1);
+
+ return NULL;
+}
+
+Expression *Simplifier::addZero(AddExpression *expr) {
+ Literal *left = dynamic_cast <Literal *>(expr->getLeft());
+ Literal *right = dynamic_cast <Literal *>(expr->getRight());
+
+ if(left != NULL && left->getValue() == 0)
+ return expr->getRight()->copy();
+
+ if(right != NULL && right->getValue() == 0)
+ return expr->getLeft()->copy();
+
+ return NULL;
+}