Finished Evaluator System!
This commit is contained in:
parent
dacfa22a4b
commit
7ca9f7de84
|
@ -119,19 +119,21 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="app.cpp" />
|
||||
<ClCompile Include="maths\solver\term_rewriter\ds\ExprTree.cpp" />
|
||||
<ClCompile Include="maths\solver\Solver.cpp" />
|
||||
<ClCompile Include="maths\solver\term_rewriter\QMReducer.cpp" />
|
||||
<ClCompile Include="maths\solver\term_rewriter\QMReducerHelper.cpp" />
|
||||
<ClCompile Include="maths\solver\term_rewriter\QMRule.h" />
|
||||
<ClCompile Include="maths\solver\term_rewriter\ds\TermPool.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="maths\solver\term_rewriter\ds\ExprTree.h" />
|
||||
<ClInclude Include="maths\defines.h" />
|
||||
<ClInclude Include="maths\Equations.h" />
|
||||
<ClInclude Include="maths\solver\term_rewriter\QMReducer.h" />
|
||||
<ClInclude Include="maths\solver\term_rewriter\QMReducerHelper.h" />
|
||||
<ClInclude Include="maths\solver\term_rewriter\QMRuleSet.h" />
|
||||
<ClInclude Include="maths\terms\Brackets.h" />
|
||||
<ClInclude Include="maths\terms\Constant.h" />
|
||||
<ClInclude Include="maths\terms\Equal.h" />
|
||||
<ClInclude Include="maths\terms\Fraction.h" />
|
||||
<ClInclude Include="maths\terms\Operator.h" />
|
||||
<ClInclude Include="maths\terms\Paranthesis.h" />
|
||||
<ClInclude Include="maths\terms\Term.h" />
|
||||
|
@ -139,6 +141,8 @@
|
|||
<ClInclude Include="maths\terms\Variable.h" />
|
||||
<ClInclude Include="maths\tokenizer.h" />
|
||||
<ClInclude Include="maths\solver\Solver.h" />
|
||||
<ClInclude Include="maths\solver\term_rewriter\QMEvaluator.h" />
|
||||
<ClInclude Include="maths\solver\term_rewriter\ds\TermPool.h" />
|
||||
<ClInclude Include="vendor\lexertk.hpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
|
|
@ -24,7 +24,13 @@
|
|||
<ClCompile Include="maths\solver\term_rewriter\QMRule.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="maths\solver\term_rewriter\QMReducer.cpp">
|
||||
<ClCompile Include="maths\solver\term_rewriter\QMReducerHelper.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="maths\solver\term_rewriter\ds\TermPool.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="maths\solver\term_rewriter\ds\ExprTree.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
@ -71,10 +77,16 @@
|
|||
<ClInclude Include="maths\solver\term_rewriter\QMRuleSet.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="maths\solver\term_rewriter\QMReducer.h">
|
||||
<ClInclude Include="maths\solver\term_rewriter\QMReducerHelper.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="maths\terms\Fraction.h">
|
||||
<ClInclude Include="maths\solver\term_rewriter\QMEvaluator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="maths\solver\term_rewriter\ds\TermPool.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="maths\solver\term_rewriter\ds\ExprTree.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
|
|
@ -8,7 +8,10 @@
|
|||
#include "maths/solver/Solver.h"
|
||||
#include "maths/Equations.h"
|
||||
|
||||
#include "maths/solver/term_rewriter/QMReducer.h"
|
||||
#include "maths/solver/term_rewriter/QMReducerHelper.h"
|
||||
#include "maths/solver/term_rewriter/QMEvaluator.h"
|
||||
|
||||
#include "maths/solver/term_rewriter/ds/ExprTree.h"
|
||||
|
||||
//#define MAIN_APP
|
||||
#define APP_TEST
|
||||
|
@ -67,18 +70,13 @@ int main() {
|
|||
|
||||
#ifdef APP_TEST
|
||||
|
||||
|
||||
int main() {
|
||||
lexertk::generator lexer;
|
||||
lexer.process("4x/(2+2x)");
|
||||
lexer.process("2/2*4^2");
|
||||
|
||||
auto result = tokenize(lexer);
|
||||
|
||||
QMReducer reducer;
|
||||
reducer.setPool(result);
|
||||
auto frac = static_cast<Fraction*>(result[0]);
|
||||
|
||||
auto res = reducer.Div(frac->mNomin[0], frac->mDomin[0]);
|
||||
auto res = evaluate(result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <vector>
|
||||
#include <deque>
|
||||
#include <stack>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
|
|
@ -1 +1,35 @@
|
|||
#include "Solver.h"
|
||||
|
||||
void Solver::Parse(string equation)
|
||||
{
|
||||
}
|
||||
|
||||
Term * Solver::Solve()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Solver::CheckValidOps(Equation * equ)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Equation * Solver::RemoveWeightOfWings(Equation * equ)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Equation * Solver::OrderTerms(Equation * equ)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Equation * Solver::CheckDiversionCalcs(Equation * equ)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Equation * Solver::DoDiversionCalcs(Equation * equ)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
|
||||
#include "../../vendor/lexertk.hpp"
|
||||
|
||||
class Solver
|
||||
{
|
||||
class Solver {
|
||||
public:
|
||||
void Parse(string equation);
|
||||
Term* Solve();
|
||||
|
@ -25,20 +24,12 @@ public: // PRIVATE MEMBERS TODO: MARK PRIVATE IN FINAL BUILD
|
|||
public: // Program Side Calcs TODO: MARK PRIVATE IN FINAL BUILD
|
||||
bool CheckValidOps(Equation* equ);
|
||||
|
||||
Equation* RemNonEssentialOp(Equation* equ);
|
||||
bool CheckOpRemovalValidity(Operator* op);
|
||||
bool CheckOpT2RemovalNeed(Operator* op);
|
||||
Equation* BreakUselessBracks(Equation* equ);
|
||||
Equation* RemoveWeightOfWings(Equation* equ);
|
||||
Equation* OrderTerms(Equation* equ);
|
||||
|
||||
Equation* CheckDiversionCalcs(Equation* equ);
|
||||
Equation* DoDiversionCalcs(Equation* equ);
|
||||
|
||||
Term* MergeOpTerm(Operator* op, Term* t1, Term* t2);
|
||||
|
||||
public: // Math Side Calcs TODO: MARK PRIVATE IN FINAL BUIlD
|
||||
Equation* Evaluate(Equation* equ);
|
||||
};
|
||||
|
||||
#endif // !1
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
#ifndef QMEVALUATOR_H
|
||||
#define QMEVALUATOR_H
|
||||
#pragma once
|
||||
#include "../../Equations.h"
|
||||
#include "../../defines.h"
|
||||
#include "../../terms/Brackets.h"
|
||||
#include "../../terms/Constant.h"
|
||||
#include "../../terms/Equal.h"
|
||||
#include "../../terms/Operator.h"
|
||||
#include "../../terms/Term.h"
|
||||
#include "../../terms/Variable.h"
|
||||
#include "../../terms/Paranthesis.h"
|
||||
#include "../../tokenizer.h"
|
||||
|
||||
#include "../../../vendor/lexertk.hpp"
|
||||
|
||||
#include "QMRule.h"
|
||||
#include "QMRuleSet.h"
|
||||
#include "ds/ExprTree.h"
|
||||
#include "ds/TermPool.h"
|
||||
|
||||
TermPool mPool;
|
||||
static vector<Term*> solveNode(TreeNode * node) {
|
||||
if (node->_term->mType != TermTypes::Op) return { node->_term };
|
||||
|
||||
vector<Term*> res;
|
||||
auto op = node->_term;
|
||||
auto t1 = solveNode(node->_left);
|
||||
auto t2 = solveNode(node->_right);
|
||||
|
||||
Term* t1_final = nullptr;
|
||||
Term* t2_final = nullptr;
|
||||
|
||||
if (t1.size() > 1) {
|
||||
// convert it to bracket
|
||||
Bracket* brack = new Bracket();
|
||||
for (auto *term : t1) brack->mTerms.push_back(term);
|
||||
t1_final = brack;
|
||||
}
|
||||
else t1_final = t1[0];
|
||||
|
||||
if (t2.size() > 1) {
|
||||
// convert it to bracket
|
||||
Bracket* brack = new Bracket();
|
||||
for (auto *term : t2) brack->mTerms.push_back(term);
|
||||
t2_final = brack;
|
||||
}
|
||||
else t2_final = t2[0];
|
||||
|
||||
if (op->mOperator == '*')
|
||||
res = QMEvalHelper::Mul(t1_final, t2_final);
|
||||
if (op->mOperator == '/')
|
||||
res = QMEvalHelper::Div(t1_final, t2_final);
|
||||
if (op->mOperator == '+')
|
||||
res = QMEvalHelper::Add(t1_final, t2_final);
|
||||
if (op->mOperator == '-')
|
||||
res = QMEvalHelper::Sub(t1_final, t2_final);
|
||||
return res;
|
||||
}
|
||||
static void evaluate() {
|
||||
// Step 1:
|
||||
// Reduce Powers except for variables
|
||||
for (int i = 0; i < mPool.size(); i++)
|
||||
if (mPool[i]->mType == TermTypes::Const)
|
||||
*mPool[i] = *QMEvalHelper::ReducePower(mPool[i])[0];
|
||||
|
||||
// Step 2:
|
||||
// Remove begining sign, if any
|
||||
if (mPool[0]->mType == TermTypes::Op) {
|
||||
auto op = mPool.pop_back(); // remove op
|
||||
auto res = *mPool.begin();
|
||||
res->mValue = res->mValue * (op->mOperator == '+') ? 1 : -1; // multiply
|
||||
|
||||
mPool.pop_front(); // remove term going to be modified
|
||||
mPool.push_front(res);
|
||||
}
|
||||
|
||||
// Step 3:
|
||||
// Generate ExpressionTree
|
||||
ExprTree tree;
|
||||
tree.setPool(mPool.vec());
|
||||
tree.GenerateTree();
|
||||
|
||||
// Step 4: Evaluate!!!
|
||||
mPool.set(solveNode(tree.getHead()));
|
||||
}
|
||||
static vector<Term*> getPool() {
|
||||
vector<Term*> res;
|
||||
for (int i = 0; i < mPool.size(); i++)
|
||||
res.push_back(mPool[i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
static vector<Term*> evaluate(vector<Term*> term) {
|
||||
mPool.set(term);
|
||||
evaluate();
|
||||
return getPool();
|
||||
}
|
||||
|
||||
#endif // !QMEVALUATOR_H
|
|
@ -1,79 +0,0 @@
|
|||
#ifndef QMREDUCER_H
|
||||
#define QMREDUCER_H
|
||||
#pragma once
|
||||
|
||||
#include "../../Equations.h"
|
||||
#include "../../defines.h"
|
||||
#include "../../terms/Brackets.h"
|
||||
#include "../../terms/Constant.h"
|
||||
#include "../../terms/Equal.h"
|
||||
#include "../../terms/Operator.h"
|
||||
#include "../../terms/Term.h"
|
||||
#include "../../terms/Variable.h"
|
||||
#include "../../terms/Paranthesis.h"
|
||||
#include "../../terms/Fraction.h"
|
||||
#include "../../tokenizer.h"
|
||||
|
||||
#include "../../../vendor/lexertk.hpp"
|
||||
|
||||
#include "QMRule.h"
|
||||
#include "QMRuleSet.h"
|
||||
|
||||
// WARINING: Only one variable is allowed or errors will happen!
|
||||
|
||||
class QMReducer {
|
||||
public:
|
||||
void setRuleSet(QMRuleSet set) { mRuleSet = set; };
|
||||
void setPool(vector<Term*> terms) { mPool = terms; };
|
||||
|
||||
vector<Term*> Reduce();
|
||||
|
||||
private: // General Utilites
|
||||
bool IsSolvable(Term* t1, Operator* op, Term* t2);
|
||||
vector<Term*> BreakBracket(Bracket* brack, bool order = false, Identifier_t order_type = Identifier_t::_high_order_left);
|
||||
vector<Term*> OrderTerms(vector<Term*> terms, Identifier_t order);
|
||||
vector<Term*> getRangeOfTerms(vector<Term*> terms, int begin, int end);
|
||||
|
||||
Bracket* convertToBracket(Term* t1);
|
||||
Variable* convertToVariable(Term* t1);
|
||||
Constant* convertToConstant(Term* t1);
|
||||
|
||||
bool IsHigherSig(Term* t1, Term* t2);
|
||||
|
||||
bool IsEquTerms(Term* t1, Term* t2);
|
||||
bool IsEquTypes(Term* t1, Term* t2);
|
||||
bool IsEquPower(Term* t1, Term* t2);
|
||||
bool IsEquValue(Term* t1, Term* t2);
|
||||
bool IsEquVariable(Term* t1, Term* t2);
|
||||
bool IsBracket(Term* t1);
|
||||
|
||||
private: // Power Evaluation
|
||||
vector<Term*> ReducePower(Term* t1);
|
||||
|
||||
public: // Addition Evaluation // TODO: PRIVATE AFTER TESTING
|
||||
vector<Term*> Add(Term* t1, Term* t2, Identifier_t order = Identifier_t::_high_order_left);
|
||||
|
||||
public: // Subtraction Evaluation // TODO: PRIVATE AFTER TESTING
|
||||
vector<Term*> Sub(Term* t1, Term* t2, Identifier_t order = Identifier_t::_high_order_left);
|
||||
|
||||
public: // Multiplication Evaluation // TODO: PRIVATE AFTER TESTING
|
||||
vector<Term*> Mul(Term* t1, Term* t2, Identifier_t order = Identifier_t::_high_order_left);
|
||||
|
||||
public: // Division Evaluation // TODO: PRIVATE AFTER TESTING
|
||||
bool IsDivSolvable(Term* t1, Term* t2);
|
||||
bool IsDivSpecialCase(Term* t1, Term* t2);
|
||||
|
||||
vector<Term*> gcdofTerms(Term* t1, Term* t2);
|
||||
vector<Term*> FactorizeTermsToBrack(vector<Term*> terms, vector<Term*> terms2);
|
||||
vector<Term*> FactorizeTermsToBrack(vector<Term*> terms);
|
||||
|
||||
bool TermsMatch(vector<Term*> terms1, vector<Term*> terms2);
|
||||
|
||||
vector<Term*> Div(Term* t1, Term* t2, Identifier_t order = Identifier_t::_high_order_left);
|
||||
private:
|
||||
QMRuleSet mRuleSet;
|
||||
|
||||
vector<Term*> mPool;
|
||||
};
|
||||
|
||||
#endif // !QMREDUCER_H
|
|
@ -1,10 +1,19 @@
|
|||
#include "QMReducer.h"
|
||||
#include "QMReducerHelper.h"
|
||||
|
||||
vector<Term*> QMReducer::Reduce() {
|
||||
return vector<Term*>();
|
||||
vector<IdsWithTerms> QMEvalHelper::convertRangeToIds(vector<Term*> range) {
|
||||
vector<IdsWithTerms> result;
|
||||
|
||||
for (int i = 0; i < range.size(); i++) {
|
||||
IdsWithTerms resultant;
|
||||
resultant._id = getIdenByTerm(range[i]);
|
||||
resultant._term = range[i];
|
||||
result.push_back(resultant);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QMReducer::IsSolvable(Term * t1, Operator * op, Term * t2) {
|
||||
bool QMEvalHelper::IsSolvable(Term * t1, Operator * op, Term * t2) {
|
||||
// Constants check
|
||||
if (t1->mType == TermTypes::Const && t2->mType == TermTypes::Const) return true;
|
||||
if (t1->mType == TermTypes::Var && t2->mType == TermTypes::Var &&
|
||||
|
@ -32,7 +41,7 @@ bool QMReducer::IsSolvable(Term * t1, Operator * op, Term * t2) {
|
|||
|
||||
return false; // End situation
|
||||
}
|
||||
vector<Term*> QMReducer::BreakBracket(Bracket * brack, bool order, Identifier_t order_type) {
|
||||
vector<Term*> QMEvalHelper::BreakBracket(Bracket * brack, bool order, Identifier_t order_type) {
|
||||
vector<Term*> res;
|
||||
|
||||
if (brack->GetConstant() == nullptr) {
|
||||
|
@ -48,34 +57,38 @@ vector<Term*> QMReducer::BreakBracket(Bracket * brack, bool order, Identifier_t
|
|||
return res;
|
||||
}
|
||||
|
||||
vector<Term*> QMReducer::OrderTerms(vector<Term*> terms, Identifier_t order) {
|
||||
vector<Term*> QMEvalHelper::OrderTerms(vector<Term*> terms, Identifier_t order) {
|
||||
if (order == Identifier_t::_high_order_left)
|
||||
stable_sort(terms.begin(), terms.end(), [this](Term* t1, Term* t2) {return IsHigherSig(t1, t2); });
|
||||
else stable_sort(terms.begin(), terms.end(), [this](Term* t1, Term* t2) {return IsHigherSig(t2, t1); });;
|
||||
stable_sort(terms.begin(), terms.end(), [](Term* t1, Term* t2) {return IsHigherSig(t1, t2); });
|
||||
else stable_sort(terms.begin(), terms.end(), [](Term* t1, Term* t2) {return IsHigherSig(t2, t1); });;
|
||||
return terms;
|
||||
}
|
||||
|
||||
vector<Term*> QMReducer::getRangeOfTerms(vector<Term*> terms, int begin, int end) {
|
||||
vector<Term*> QMEvalHelper::getRangeOfTerms(vector<Term*> terms, int begin, int end) {
|
||||
vector<Term*> res;
|
||||
for (int i = begin; i < end; i++) res.push_back(terms[i]);
|
||||
for (int i = begin; i <= end; i++) res.push_back(terms[i]);
|
||||
return res;
|
||||
}
|
||||
vector<Identifier_t*> QMEvalHelper::getRangeOfIden(vector<Identifier_t*> terms, int begin, int end) {
|
||||
vector<Identifier_t*> res;
|
||||
for (int i = begin; i <= end; i++) res.push_back(terms[i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
Bracket * QMReducer::convertToBracket(Term * t1) {
|
||||
Bracket * QMEvalHelper::convertToBracket(Term * t1) {
|
||||
if (t1->mType != TermTypes::Brack) return false;
|
||||
return static_cast<Bracket*>(t1);
|
||||
}
|
||||
Variable * QMReducer::convertToVariable(Term * t1) {
|
||||
Variable * QMEvalHelper::convertToVariable(Term * t1) {
|
||||
if (t1->mType != TermTypes::Var) return false;
|
||||
return static_cast<Variable*>(t1);
|
||||
}
|
||||
Constant * QMReducer::convertToConstant(Term * t1) {
|
||||
Constant * QMEvalHelper::convertToConstant(Term * t1) {
|
||||
if (t1->mType != TermTypes::Const) return false;
|
||||
return static_cast<Constant*>(t1);
|
||||
}
|
||||
|
||||
bool QMReducer::IsHigherSig(Term * t1, Term * t2) { // x^2 > x : true
|
||||
bool QMEvalHelper::IsHigherSig(Term * t1, Term * t2) { // x^2 > x : true
|
||||
if (t1->mType == TermTypes::Brack)
|
||||
return true;
|
||||
else if (t1->mType == TermTypes::Op)
|
||||
|
@ -113,7 +126,7 @@ bool QMReducer::IsHigherSig(Term * t1, Term * t2) { // x^2 > x : true
|
|||
return false;
|
||||
}
|
||||
|
||||
bool QMReducer::IsEquTerms(Term * t1, Term * t2) {
|
||||
bool QMEvalHelper::IsEquTerms(Term * t1, Term * t2) {
|
||||
if (!IsEquTypes(t1, t2)) return false;
|
||||
if (!IsEquPower(t1, t2)) return false;
|
||||
if (!IsEquValue(t1, t2)) return false;
|
||||
|
@ -121,36 +134,35 @@ bool QMReducer::IsEquTerms(Term * t1, Term * t2) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool QMReducer::IsEquTypes(Term * t1, Term * t2) {
|
||||
bool QMEvalHelper::IsEquTypes(Term * t1, Term * t2) {
|
||||
return t1->mType == t2->mType;
|
||||
}
|
||||
bool QMReducer::IsEquPower(Term * t1, Term * t2) {
|
||||
bool QMEvalHelper::IsEquPower(Term * t1, Term * t2) {
|
||||
return t1->mPower == t2->mPower;
|
||||
}
|
||||
bool QMReducer::IsEquValue(Term * t1, Term * t2) {
|
||||
bool QMEvalHelper::IsEquValue(Term * t1, Term * t2) {
|
||||
return t1->mValue == t2->mValue;
|
||||
}
|
||||
bool QMReducer::IsEquVariable(Term * t1, Term * t2) {
|
||||
bool QMEvalHelper::IsEquVariable(Term * t1, Term * t2) {
|
||||
return t1->mVariable == t2->mVariable;
|
||||
}
|
||||
bool QMReducer::IsBracket(Term * t1) {
|
||||
bool QMEvalHelper::IsBracket(Term * t1) {
|
||||
return t1->mType == TermTypes::Brack;
|
||||
}
|
||||
|
||||
vector<Term*> QMReducer::ReducePower(Term * t1) {
|
||||
vector<Term*> QMEvalHelper::ReducePower(Term * t1) {
|
||||
if (IsBracket(t1)) return {}; // Brackets powers aren't allowed
|
||||
|
||||
if (t1->mType == TermTypes::Var) return { t1 };
|
||||
else
|
||||
t1->mValue = pow(t1->mValue, t1->mPower);
|
||||
t1->mValue = pow(t1->mValue, t1->mPower);
|
||||
t1->mPower = 1;
|
||||
|
||||
return { t1 };
|
||||
}
|
||||
|
||||
vector<Term*> QMReducer::Add(Term * t1, Term * t2, Identifier_t order) {
|
||||
vector<Term*> QMEvalHelper::Add(Term * t1, Term * t2, Identifier_t order) {
|
||||
vector<Term*> res;
|
||||
|
||||
|
||||
// check if one of the terms were brackets
|
||||
if (IsBracket(t1) || IsBracket(t2)) {
|
||||
// check which term is bracket
|
||||
|
@ -213,16 +225,14 @@ vector<Term*> QMReducer::Add(Term * t1, Term * t2, Identifier_t order) {
|
|||
else { // if it wasn't solvable
|
||||
// only 3 situations it is not solvable
|
||||
// these situations are treated the same
|
||||
// order them depending on arg 'order'
|
||||
res = { t1, t2 };
|
||||
res = OrderTerms(res, order);
|
||||
res = { t1, new Operator('+') , t2 };
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
vector<Term*> QMReducer::Sub(Term * t1, Term * t2, Identifier_t order) {
|
||||
vector<Term*> QMEvalHelper::Sub(Term * t1, Term * t2, Identifier_t order) {
|
||||
vector<Term*> res;
|
||||
|
||||
|
||||
|
@ -297,7 +307,7 @@ vector<Term*> QMReducer::Sub(Term * t1, Term * t2, Identifier_t order) {
|
|||
return res;
|
||||
}
|
||||
|
||||
vector<Term*> QMReducer::Mul(Term * t1, Term * t2, Identifier_t order) {
|
||||
vector<Term*> QMEvalHelper::Mul(Term * t1, Term * t2, Identifier_t order) {
|
||||
vector<Term*> res;
|
||||
|
||||
// check if one of the terms are brackets
|
||||
|
@ -342,8 +352,6 @@ vector<Term*> QMReducer::Mul(Term * t1, Term * t2, Identifier_t order) {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// niether are brackets
|
||||
else {
|
||||
|
@ -395,13 +403,13 @@ vector<Term*> QMReducer::Mul(Term * t1, Term * t2, Identifier_t order) {
|
|||
return res;
|
||||
}
|
||||
|
||||
bool QMReducer::IsDivSolvable(Term * t1, Term * t2) {
|
||||
bool QMEvalHelper::IsDivSolvable(Term * t1, Term * t2) {
|
||||
if (t1->mType == TermTypes::Var && t2->mType == TermTypes::Var) return true;
|
||||
if (t1->mType == TermTypes::Const && t2->mType == TermTypes::Const) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
bool QMReducer::IsDivSpecialCase(Term * t1, Term * t2) {
|
||||
bool QMEvalHelper::IsDivSpecialCase(Term * t1, Term * t2) {
|
||||
if (t1->mType == TermTypes::Brack &&
|
||||
t2->mType != TermTypes::Brack) return true;
|
||||
|
||||
|
@ -419,7 +427,7 @@ bool QMReducer::IsDivSpecialCase(Term * t1, Term * t2) {
|
|||
|
||||
return false;
|
||||
}
|
||||
vector<Term*> QMReducer::gcdofTerms(Term * t1, Term * t2) {
|
||||
vector<Term*> QMEvalHelper::gcdofTerms(Term * t1, Term * t2) {
|
||||
|
||||
if (t1->mType == TermTypes::Const && t2->mType == TermTypes::Const) {
|
||||
auto t1_const = convertToConstant(ReducePower(t1)[0]);
|
||||
|
@ -459,7 +467,7 @@ vector<Term*> QMReducer::gcdofTerms(Term * t1, Term * t2) {
|
|||
|
||||
return {};
|
||||
}
|
||||
vector<Term*> QMReducer::FactorizeTermsToBrack(vector<Term*> terms, vector<Term*> terms2) {
|
||||
vector<Term*> QMEvalHelper::FactorizeTermsToBrack(vector<Term*> terms, vector<Term*> terms2) {
|
||||
vector<Term*> allTerms;
|
||||
|
||||
for (int i = 0; i < terms.size(); i++)
|
||||
|
@ -493,7 +501,7 @@ vector<Term*> QMReducer::FactorizeTermsToBrack(vector<Term*> terms, vector<Term*
|
|||
|
||||
return { brack1, brack2 };
|
||||
}
|
||||
vector<Term*> QMReducer::FactorizeTermsToBrack(vector<Term*> allTerms) {
|
||||
vector<Term*> QMEvalHelper::FactorizeTermsToBrack(vector<Term*> allTerms) {
|
||||
Term* HCF_all = new Term();
|
||||
*HCF_all = *allTerms[0];
|
||||
for (int i = 0; i < allTerms.size(); i++)
|
||||
|
@ -510,7 +518,7 @@ vector<Term*> QMReducer::FactorizeTermsToBrack(vector<Term*> allTerms) {
|
|||
|
||||
return { brack };
|
||||
}
|
||||
bool QMReducer::TermsMatch(vector<Term*> terms1, vector<Term*> terms2) {
|
||||
bool QMEvalHelper::TermsMatch(vector<Term*> terms1, vector<Term*> terms2) {
|
||||
terms1 = OrderTerms(terms1, Identifier_t::_high_order_left);
|
||||
terms2 = OrderTerms(terms2, Identifier_t::_high_order_left);
|
||||
|
||||
|
@ -522,7 +530,7 @@ bool QMReducer::TermsMatch(vector<Term*> terms1, vector<Term*> terms2) {
|
|||
return true;
|
||||
}
|
||||
// WARNING: Make sure that t1 and t2 are in the simplest form.
|
||||
vector<Term*> QMReducer::Div(Term * t1, Term * t2, Identifier_t order) {
|
||||
vector<Term*> QMEvalHelper::Div(Term * t1, Term * t2, Identifier_t order) {
|
||||
|
||||
|
||||
// Check if division is solvable
|
||||
|
@ -585,11 +593,14 @@ vector<Term*> QMReducer::Div(Term * t1, Term * t2, Identifier_t order) {
|
|||
fraction_domin = convertToBracket(fraction[1]);
|
||||
fraction_domin->setConstant(nullptr); // Nullptr == 1
|
||||
|
||||
Fraction* frac = new Fraction();
|
||||
vector<Term*> res;
|
||||
for (int i = 0; i < fraction_nomin->mTerms.size(); i++)
|
||||
res.push_back(fraction_nomin->mTerms[i]);
|
||||
res.push_back(new Operator('/'));
|
||||
for (int i = 0; i < fraction_domin->mTerms.size(); i++)
|
||||
res.push_back(fraction_domin->mTerms[i]);
|
||||
|
||||
frac->mNomin = fraction_nomin->mTerms;
|
||||
frac->mDomin = fraction_domin->mTerms;
|
||||
return { frac };
|
||||
return res;
|
||||
}
|
||||
else if (t1->mType == TermTypes::Const && t2->mType == TermTypes::Var) {
|
||||
// const / var
|
||||
|
@ -639,10 +650,15 @@ vector<Term*> QMReducer::Div(Term * t1, Term * t2, Identifier_t order) {
|
|||
auto fraction = FactorizeTermsToBrack({ t1 }, t2_Brack->mTerms);
|
||||
|
||||
auto comfac = convertToBracket(fraction[0])->GetConstant();
|
||||
Fraction* frac = new Fraction();
|
||||
frac->mNomin = convertToBracket(fraction[0])->mTerms;
|
||||
frac->mDomin = convertToBracket(fraction[1])->mTerms;
|
||||
return { frac };
|
||||
|
||||
vector<Term*> res;
|
||||
for (auto *term : convertToBracket(fraction[0])->mTerms)
|
||||
res.push_back(term);
|
||||
res.push_back(new Operator('/'));
|
||||
for (auto *term : convertToBracket(fraction[1])->mTerms)
|
||||
res.push_back(term);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
#ifndef QMREDUCER_H
|
||||
#define QMREDUCER_H
|
||||
#pragma once
|
||||
// WARINING: Only one variable is allowed or errors will happen!
|
||||
|
||||
#include "../../Equations.h"
|
||||
#include "../../defines.h"
|
||||
#include "../../terms/Brackets.h"
|
||||
#include "../../terms/Constant.h"
|
||||
#include "../../terms/Equal.h"
|
||||
#include "../../terms/Operator.h"
|
||||
#include "../../terms/Term.h"
|
||||
#include "../../terms/Variable.h"
|
||||
#include "../../terms/Paranthesis.h"
|
||||
#include "../../tokenizer.h"
|
||||
|
||||
#include "../../../vendor/lexertk.hpp"
|
||||
|
||||
#include "QMRule.h"
|
||||
#include "QMRuleSet.h"
|
||||
|
||||
struct IdsWithTerms {
|
||||
Identifier_t _id;
|
||||
Term* _term;
|
||||
};
|
||||
class QMEvalHelper {
|
||||
public: // General Utilites
|
||||
static Identifier_t getIdenByTerm(Term* term) {
|
||||
if (term->mType == TermTypes::Const) return Identifier_t::_const;
|
||||
if (term->mType == TermTypes::Var) return Identifier_t::_var;
|
||||
if (term->mType == TermTypes::Brack) return Identifier_t::_brack;
|
||||
if (term->mType == TermTypes::Op) {
|
||||
if (term->mOperator == '+') return Identifier_t::_add;
|
||||
if (term->mOperator == '-') return Identifier_t::_sub;
|
||||
if (term->mOperator == '*') return Identifier_t::_mul;
|
||||
if (term->mOperator == '/') return Identifier_t::_div;
|
||||
}
|
||||
}
|
||||
static vector<IdsWithTerms> convertRangeToIds(vector<Term*> range);
|
||||
|
||||
static bool IsSolvable(Term* t1, Operator* op, Term* t2);
|
||||
static vector<Term*> BreakBracket(Bracket* brack, bool order = false, Identifier_t order_type = Identifier_t::_high_order_left);
|
||||
static vector<Term*> OrderTerms(vector<Term*> terms, Identifier_t order);
|
||||
static vector<Term*> getRangeOfTerms(vector<Term*> terms, int begin, int end);
|
||||
static vector<Identifier_t*> getRangeOfIden(vector<Identifier_t*> terms, int begin, int end);
|
||||
|
||||
static Bracket* convertToBracket(Term* t1);
|
||||
static Variable* convertToVariable(Term* t1);
|
||||
static Constant* convertToConstant(Term* t1);
|
||||
|
||||
static bool IsHigherSig(Term* t1, Term* t2);
|
||||
|
||||
static bool IsEquTerms(Term* t1, Term* t2);
|
||||
static bool IsEquTypes(Term* t1, Term* t2);
|
||||
static bool IsEquPower(Term* t1, Term* t2);
|
||||
static bool IsEquValue(Term* t1, Term* t2);
|
||||
static bool IsEquVariable(Term* t1, Term* t2);
|
||||
static bool IsBracket(Term* t1);
|
||||
|
||||
public: // Power Evaluation
|
||||
static vector<Term*> ReducePower(Term* t1);
|
||||
|
||||
public: // Addition Evaluation
|
||||
static vector<Term*> Add(Term* t1, Term* t2, Identifier_t order = Identifier_t::_high_order_left);
|
||||
|
||||
public: // Subtraction Evaluation
|
||||
static vector<Term*> Sub(Term* t1, Term* t2, Identifier_t order = Identifier_t::_high_order_left);
|
||||
|
||||
public: // Multiplication Evaluation
|
||||
static vector<Term*> Mul(Term* t1, Term* t2, Identifier_t order = Identifier_t::_high_order_left);
|
||||
|
||||
public: // Division Evaluation
|
||||
static bool IsDivSolvable(Term* t1, Term* t2);
|
||||
static bool IsDivSpecialCase(Term* t1, Term* t2);
|
||||
|
||||
static vector<Term*> gcdofTerms(Term* t1, Term* t2);
|
||||
static vector<Term*> FactorizeTermsToBrack(vector<Term*> terms, vector<Term*> terms2);
|
||||
static vector<Term*> FactorizeTermsToBrack(vector<Term*> terms);
|
||||
|
||||
static bool TermsMatch(vector<Term*> terms1, vector<Term*> terms2);
|
||||
|
||||
static vector<Term*> Div(Term* t1, Term* t2, Identifier_t order = Identifier_t::_high_order_left);
|
||||
};
|
||||
|
||||
#endif // !QMREDUCER_H
|
|
@ -17,6 +17,7 @@ enum Identifier_t {
|
|||
_const = 1,
|
||||
_var = 2,
|
||||
_brack,
|
||||
_frac,
|
||||
_eval,
|
||||
_add,
|
||||
_sub,
|
||||
|
@ -40,10 +41,11 @@ enum Identifier_t {
|
|||
|
||||
class QMRule {
|
||||
public:
|
||||
QMRule(vector<int> rule, vector<int> props, int prio)
|
||||
: mRules(rule), mProps(props), mPrior(prio) {}
|
||||
QMRule(vector<int> rule, vector<int> result, vector<int> props, int prio)
|
||||
: mRules(rule), mResult(result), mProps(props), mPrior(prio) {}
|
||||
|
||||
vector<int> GetRules() const { return mRules; }
|
||||
vector<int> GetResult() const { return mResult; }
|
||||
vector<int> GetProps() const { return mProps; }
|
||||
int GetPrior() { return mPrior; }
|
||||
|
||||
|
@ -62,6 +64,7 @@ public:
|
|||
}
|
||||
private:
|
||||
vector<int> mRules;
|
||||
vector<int> mResult;
|
||||
vector<int> mProps;
|
||||
int mPrior;
|
||||
};
|
||||
|
|
|
@ -31,6 +31,8 @@ public:
|
|||
stable_sort(mRuleSet.begin(), mRuleSet.end());
|
||||
}
|
||||
|
||||
int size() { return mRuleSet.size(); }
|
||||
|
||||
auto GetRuleSet() { return mRuleSet; }
|
||||
|
||||
inline QMRule& operator[](int index) {
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
#include "ExprTree.h"
|
||||
|
||||
void ExprTree::setPool(vector<Term*> pool) {
|
||||
mPool.set(pool);
|
||||
mHead = new TreeNode();
|
||||
}
|
||||
|
||||
void ExprTree::GenerateTree() {
|
||||
mHead = _genTree(mPool);
|
||||
}
|
||||
|
||||
void ExprTree::print() {
|
||||
_print("", mHead, false);
|
||||
}
|
||||
|
||||
TreeNode* ExprTree::_genTree(TermPool pool) {
|
||||
if (pool.size() == 0) return nullptr;
|
||||
if (pool.size() == 1) {
|
||||
TreeNode* node = new TreeNode();
|
||||
node->_term = pool[0];
|
||||
node->_left = nullptr;
|
||||
node->_right = nullptr;
|
||||
return node;
|
||||
}
|
||||
|
||||
// Number operations
|
||||
std::vector<pair<int, int>> operators;
|
||||
int counter = 0;
|
||||
|
||||
// DIV, MUL first
|
||||
for (int i = 0; i < pool.size(); i++) {
|
||||
if (pool[i]->mType == TermTypes::Op) {
|
||||
if (pool[i]->mOperator == '/') {
|
||||
pair<int, int> resultant;
|
||||
resultant.first = i;
|
||||
resultant.second = counter++;
|
||||
operators.push_back(resultant);
|
||||
}
|
||||
if (pool[i]->mOperator == '*') {
|
||||
pair <int, int> resultant;
|
||||
resultant.first = i;
|
||||
resultant.second = counter++;
|
||||
operators.push_back(resultant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ADD, SUB Second
|
||||
for (int i = 0; i < pool.size(); i++) {
|
||||
if (pool[i]->mType == TermTypes::Op) {
|
||||
if (pool[i]->mOperator == '+') {
|
||||
pair<int, int> resultant;
|
||||
resultant.first = i;
|
||||
resultant.second = counter++;
|
||||
operators.push_back(resultant);
|
||||
}
|
||||
else if (pool[i]->mOperator == '-') {
|
||||
pair<int, int> resultant;
|
||||
resultant.first = i;
|
||||
resultant.second = counter++;
|
||||
operators.push_back(resultant);
|
||||
}
|
||||
}
|
||||
}
|
||||
stable_sort(operators.begin(), operators.end(),
|
||||
[this](pair<int, int> arg1, pair<int, int> arg2) {
|
||||
return arg1.second < arg2.second;
|
||||
});
|
||||
|
||||
// Split upon op, recurse
|
||||
TermPool left, right;
|
||||
// dont get the op to left
|
||||
auto ptr1 = operators[operators.size() - 1].first;
|
||||
left.set(
|
||||
pool.getRange(0, ptr1-1)
|
||||
);
|
||||
// dont get the op to right
|
||||
right.set(
|
||||
pool.getRange(ptr1 + 1, pool.size()-1)
|
||||
);
|
||||
|
||||
// get the op here
|
||||
Term* op = pool[left.size()];
|
||||
TreeNode* node = new TreeNode();
|
||||
node->_term = op;
|
||||
node->_left = _genTree(left);
|
||||
node->_right = _genTree(right);
|
||||
return node;
|
||||
}
|
||||
|
||||
void ExprTree::_print(const std::string prefix, const TreeNode* node, bool isLeft) {
|
||||
if (node != nullptr) {
|
||||
cout << prefix;
|
||||
|
||||
cout << (isLeft ? "|--" : "^--");
|
||||
|
||||
// print the value of the node
|
||||
cout << node->_term->to_str() << endl;
|
||||
|
||||
_print(prefix + (isLeft ? "| " : " "), node->_left, true);
|
||||
_print(prefix + (isLeft ? "| " : " "), node->_right, false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef EXPR_TREE_H
|
||||
#define EXPR_TREE_H
|
||||
#pragma once
|
||||
#include "../../../Equations.h"
|
||||
#include "../../../defines.h"
|
||||
#include "../../../terms/Brackets.h"
|
||||
#include "../../../terms/Constant.h"
|
||||
#include "../../../terms/Equal.h"
|
||||
#include "../../../terms/Operator.h"
|
||||
#include "../../../terms/Term.h"
|
||||
#include "../../../terms/Variable.h"
|
||||
#include "../../../terms/Paranthesis.h"
|
||||
#include "../../../tokenizer.h"
|
||||
|
||||
#include "../../../../vendor/lexertk.hpp"
|
||||
#include "../QMReducerHelper.h"
|
||||
#include "TermPool.h"
|
||||
|
||||
struct TreeNode {
|
||||
Term* _term;
|
||||
TreeNode* _left = nullptr;
|
||||
TreeNode* _right = nullptr;
|
||||
};
|
||||
|
||||
class ExprTree {
|
||||
public:
|
||||
void setPool(vector<Term*> pool);
|
||||
void GenerateTree();
|
||||
|
||||
void print();
|
||||
|
||||
TreeNode* getHead() { return mHead; }
|
||||
|
||||
private:
|
||||
TreeNode* _genTree(TermPool pool);
|
||||
void _print(const std::string prefix, const TreeNode* node, bool isLeft);
|
||||
|
||||
TreeNode* mHead = nullptr;
|
||||
TermPool mPool;
|
||||
};
|
||||
|
||||
|
||||
#endif // !EXPR_TREE_H
|
|
@ -0,0 +1,74 @@
|
|||
#include "TermPool.h"
|
||||
|
||||
void TermPool::set(vector<Term*> terms) {
|
||||
this->clear();
|
||||
for (auto* term : terms)
|
||||
mList.push_back(term);
|
||||
}
|
||||
|
||||
void TermPool::insert(Term * term, int pos) {
|
||||
auto begining = std::begin(mList);
|
||||
while (pos--) begining++;
|
||||
mList.insert(begining, term);
|
||||
}
|
||||
|
||||
void TermPool::insertRange(vector<Term*> terms, int pos) {
|
||||
auto begining = std::begin(mList);
|
||||
while (pos--) begining++;
|
||||
for (auto *term : terms) mList.insert(begining++, term);
|
||||
}
|
||||
|
||||
void TermPool::deleteItem(int pos) {
|
||||
auto begining = std::begin(mList);
|
||||
while (pos--) begining++;
|
||||
mList.remove(*begining);
|
||||
}
|
||||
|
||||
void TermPool::deleteItemRange(int begin, int end) {
|
||||
for (int i = begin; i < end; i++)
|
||||
this->deleteItem(i);
|
||||
}
|
||||
|
||||
vector<Term*> TermPool::getRange(int begin, int end) {
|
||||
vector<Term*> res;
|
||||
for (int i = begin; i <= end; i++)
|
||||
res.push_back(this->operator[](i));
|
||||
return res;
|
||||
}
|
||||
|
||||
void TermPool::push_back(Term * term) {
|
||||
mList.push_back(term);
|
||||
}
|
||||
|
||||
void TermPool::push_front(Term * term) {
|
||||
mList.push_front(term);
|
||||
}
|
||||
|
||||
Term * TermPool::pop_back() {
|
||||
auto res = *mList.end();
|
||||
mList.pop_back();
|
||||
return res;
|
||||
}
|
||||
|
||||
Term * TermPool::pop_front() {
|
||||
auto res = *mList.begin();
|
||||
mList.pop_front();
|
||||
return res;
|
||||
}
|
||||
|
||||
void TermPool::clear() {
|
||||
mList.clear();
|
||||
}
|
||||
|
||||
Term * TermPool::operator[](int index) const {
|
||||
auto it = mList.begin();
|
||||
std::advance(it, index);
|
||||
// 'it' points to the element at index 'N'
|
||||
auto res = *it;
|
||||
return res;
|
||||
}
|
||||
|
||||
int TermPool::size() const {
|
||||
return mList.size();
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef TERMPOOL_H
|
||||
#define TERMPOOL_H
|
||||
#pragma once
|
||||
#include <list>
|
||||
#include "../../../Equations.h"
|
||||
#include "../../../defines.h"
|
||||
#include "../../../terms/Brackets.h"
|
||||
#include "../../../terms/Constant.h"
|
||||
#include "../../../terms/Equal.h"
|
||||
#include "../../../terms/Operator.h"
|
||||
#include "../../../terms/Term.h"
|
||||
#include "../../../terms/Variable.h"
|
||||
#include "../../../terms/Paranthesis.h"
|
||||
#include "../../../tokenizer.h"
|
||||
|
||||
#include "../../../../vendor/lexertk.hpp"
|
||||
|
||||
|
||||
class TermPool {
|
||||
public:
|
||||
void set(vector<Term*> terms);
|
||||
void insert(Term* term, int pos = -1);
|
||||
void insertRange(vector<Term*> terms, int pos = -1);
|
||||
void deleteItem(int pos);
|
||||
void deleteItemRange(int begin, int end);
|
||||
vector<Term*> getRange(int begin, int end);
|
||||
void push_back(Term* term);
|
||||
void push_front(Term* term);
|
||||
Term* pop_back();
|
||||
Term* pop_front();
|
||||
|
||||
auto begin() { return mList.begin(); }
|
||||
auto end() { return mList.end(); }
|
||||
|
||||
void clear();
|
||||
|
||||
Term* operator[](int index) const;
|
||||
auto getIterator(int index) {
|
||||
auto beginining = std::begin(mList);
|
||||
std::advance(beginining, index);
|
||||
return beginining;
|
||||
}
|
||||
|
||||
int size() const;
|
||||
void order() {
|
||||
mList.sort();
|
||||
}
|
||||
|
||||
vector<Term*> vec() {
|
||||
vector<Term*> res;
|
||||
for (auto *item : mList)
|
||||
res.push_back(item);
|
||||
return res;
|
||||
}
|
||||
private:
|
||||
list<Term*> mList;
|
||||
};
|
||||
|
||||
|
||||
#endif // !TERMPOOL_H
|
|
@ -10,13 +10,11 @@ using namespace std;
|
|||
|
||||
class Bracket : public Term {
|
||||
public:
|
||||
Bracket() {
|
||||
Term();
|
||||
Bracket() : Term() {
|
||||
mType = TermTypes::Brack;
|
||||
}
|
||||
|
||||
Bracket(vector<Term*> ts) {
|
||||
Term();
|
||||
Bracket(vector<Term*> ts) : Term() {
|
||||
mType = TermTypes::Brack;
|
||||
mTerms = ts;
|
||||
}
|
||||
|
@ -29,6 +27,17 @@ public:
|
|||
|
||||
Term* GetConstant() const { return mConstant; }
|
||||
|
||||
string to_str() override {
|
||||
string str;
|
||||
|
||||
if (mConstant != nullptr)
|
||||
str.append(mConstant->to_str());
|
||||
|
||||
for (int i = 0; i < mTerms.size(); i++)
|
||||
str.append(mTerms[i]->to_str());
|
||||
return str;
|
||||
}
|
||||
|
||||
private:
|
||||
Term *mConstant = nullptr; // Nullptr == 1
|
||||
};
|
||||
|
|
|
@ -7,11 +7,21 @@ using namespace std;
|
|||
|
||||
class Constant : public Term {
|
||||
public:
|
||||
Constant(NValue val = 0, NValue pwr = 1) {
|
||||
Term();
|
||||
Constant(NValue val = 0, NValue pwr = 1) : Term() {
|
||||
mValue = val;
|
||||
mPower = pwr;
|
||||
mType = TermTypes::Const;
|
||||
}
|
||||
|
||||
string to_str() override {
|
||||
stringstream str;
|
||||
str << setprecision(0) << mValue;
|
||||
if (mPower > 1) {
|
||||
str << "^";
|
||||
str << setprecision(0) << mPower;
|
||||
}
|
||||
return str.str();
|
||||
}
|
||||
|
||||
};
|
||||
#endif // !CONSTANT_H
|
||||
|
|
|
@ -8,9 +8,13 @@ using namespace std;
|
|||
|
||||
class Equal : public Term {
|
||||
public:
|
||||
Equal() {
|
||||
Equal() : Term() {
|
||||
mType = TermTypes::Equ;
|
||||
}
|
||||
|
||||
string to_str() override {
|
||||
return "=";
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !EQUAL_H
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
#ifndef FRACTION_H
|
||||
#define FRACTION_H
|
||||
#pragma once
|
||||
#include "../defines.h"
|
||||
#include "Term.h"
|
||||
using namespace std;
|
||||
|
||||
class Fraction: public Term {
|
||||
public:
|
||||
Fraction(vector<Term*> nomin = {}, vector<Term*> domin = {}) {
|
||||
Term();
|
||||
mNomin = nomin;
|
||||
mDomin = domin;
|
||||
mType = TermTypes::Frac;
|
||||
}
|
||||
|
||||
public: // TODO: try to change to private
|
||||
vector<Term*> mNomin;
|
||||
vector<Term*> mDomin;
|
||||
};
|
||||
#endif // !CONSTANT_H
|
|
@ -12,5 +12,12 @@ public:
|
|||
mOperator = oper;
|
||||
mType = TermTypes::Op;
|
||||
}
|
||||
|
||||
string to_str() override {
|
||||
stringstream str;
|
||||
str << mOperator;
|
||||
return str.str();
|
||||
}
|
||||
|
||||
};
|
||||
#endif // !OPERATOR_
|
||||
|
|
|
@ -6,13 +6,6 @@
|
|||
using namespace std;
|
||||
|
||||
class Term {
|
||||
public:
|
||||
virtual NValue GetValue() { return mValue; }
|
||||
virtual CValue GetVariable() { return mVariable; }
|
||||
virtual CValue GetOperator() { return mOperator; }
|
||||
virtual NValue GetPower() { return mPower; }
|
||||
|
||||
virtual int GetType() { return mType; };
|
||||
public:
|
||||
Term(NValue val = DEF_N, CValue var = DEF_C, CValue oper = DEF_C, NValue pwr = 1) {
|
||||
mValue = val;
|
||||
|
@ -21,6 +14,8 @@ public:
|
|||
mPower = pwr;
|
||||
}
|
||||
|
||||
virtual string to_str() { return "TERM_UNKNOWN"; };
|
||||
|
||||
NValue mValue = DEF_N;
|
||||
CValue mVariable = DEF_C;
|
||||
NValue mPower = 1;
|
||||
|
|
|
@ -8,11 +8,24 @@ using namespace std;
|
|||
|
||||
class Variable : public Term {
|
||||
public:
|
||||
Variable(NValue val = 1, CValue var = DEF_C, NValue pwr = 1) {
|
||||
Variable(NValue val = 1, CValue var = DEF_C, NValue pwr = 1) : Term() {
|
||||
mValue = val;
|
||||
mVariable = var;
|
||||
mPower = pwr;
|
||||
mType = TermTypes::Var;
|
||||
}
|
||||
|
||||
string to_str() override {
|
||||
stringstream str;
|
||||
if (mValue != 1)
|
||||
str << setprecision(0) << mValue;
|
||||
str << (char)mVariable;
|
||||
if (mPower > 1) {
|
||||
str << "^";
|
||||
str << setprecision(0) << mPower;
|
||||
}
|
||||
return str.str();
|
||||
}
|
||||
|
||||
};
|
||||
#endif // !VARIABLE_H
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include "terms/Term.h"
|
||||
#include "terms/Variable.h"
|
||||
#include "terms/Paranthesis.h"
|
||||
#include "terms/Fraction.h"
|
||||
|
||||
#include "../vendor/lexertk.hpp"
|
||||
|
||||
|
@ -164,42 +163,42 @@ static vector<Term*> combineBrackets(vector<Term*> terms) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static vector<Term*> combineOpWithTerms(vector<Term*> terms) {
|
||||
vector<Term*> result;
|
||||
|
||||
for (int i = 0; i < terms.size(); i++) {
|
||||
if (terms[i]->mType == TermTypes::Op) {
|
||||
// operator detected
|
||||
auto op = static_cast<Operator*>(terms[i]);
|
||||
if (op->mOperator == '/') {
|
||||
// division found
|
||||
|
||||
// check if it was the first
|
||||
if (i == 0) {
|
||||
// invalid
|
||||
cout << "Can't divide with a Nill nominator!" << endl;
|
||||
system("PAUSE");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
Fraction* frac = new Fraction();
|
||||
frac->mDomin.push_back(terms[i + 1]);
|
||||
frac->mNomin.push_back(terms[i - 1]);
|
||||
result.pop_back(); // pop the nominator, before push
|
||||
result.push_back(frac);
|
||||
|
||||
// consume the dominator
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
result.push_back(terms[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
//static vector<Term*> combineOpWithTerms(vector<Term*> terms) {
|
||||
// vector<Term*> result;
|
||||
//
|
||||
// for (int i = 0; i < terms.size(); i++) {
|
||||
// if (terms[i]->mType == TermTypes::Op) {
|
||||
// // operator detected
|
||||
// auto op = static_cast<Operator*>(terms[i]);
|
||||
// if (op->mOperator == '/') {
|
||||
// // division found
|
||||
//
|
||||
// // check if it was the first
|
||||
// if (i == 0) {
|
||||
// // invalid
|
||||
// cout << "Can't divide with a Nill nominator!" << endl;
|
||||
// system("PAUSE");
|
||||
// exit(0);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// Fraction* frac = new Fraction();
|
||||
// frac->mDomin.push_back(terms[i + 1]);
|
||||
// frac->mNomin.push_back(terms[i - 1]);
|
||||
// result.pop_back(); // pop the nominator, before push
|
||||
// result.push_back(frac);
|
||||
//
|
||||
// // consume the dominator
|
||||
// i += 1;
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// result.push_back(terms[i]);
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// return result;
|
||||
//}
|
||||
|
||||
static vector<Term*> tokenize(lexertk::generator lexed) {
|
||||
vector<Term*> result;
|
||||
|
@ -361,7 +360,7 @@ static vector<Term*> tokenize(lexertk::generator lexed) {
|
|||
|
||||
// post-fix fixes
|
||||
result = combineBrackets(result);
|
||||
result = combineOpWithTerms(result);
|
||||
//result = combineOpWithTerms(result);
|
||||
return result;
|
||||
}
|
||||
#endif // !TOKENIZER_H
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue