diff --git a/QuicMaf/QuicMaf.vcxproj b/QuicMaf/QuicMaf.vcxproj
index 42de025..86a8195 100644
--- a/QuicMaf/QuicMaf.vcxproj
+++ b/QuicMaf/QuicMaf.vcxproj
@@ -119,9 +119,15 @@
+
+
+
+
+
+
@@ -131,6 +137,7 @@
+
diff --git a/QuicMaf/QuicMaf.vcxproj.filters b/QuicMaf/QuicMaf.vcxproj.filters
index 6514295..bc41458 100644
--- a/QuicMaf/QuicMaf.vcxproj.filters
+++ b/QuicMaf/QuicMaf.vcxproj.filters
@@ -18,6 +18,15 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
@@ -53,5 +62,17 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
\ No newline at end of file
diff --git a/QuicMaf/QuicMaf.vcxproj.user b/QuicMaf/QuicMaf.vcxproj.user
index 0b0f24d..66eed93 100644
--- a/QuicMaf/QuicMaf.vcxproj.user
+++ b/QuicMaf/QuicMaf.vcxproj.user
@@ -3,4 +3,7 @@
true
+
+ WindowsLocalDebugger
+
\ No newline at end of file
diff --git a/QuicMaf/app.cpp b/QuicMaf/app.cpp
index 6f9bbc1..67af4c3 100644
--- a/QuicMaf/app.cpp
+++ b/QuicMaf/app.cpp
@@ -5,10 +5,11 @@
#include "vendor/lexertk.hpp"
-#include "maths/tokenizer.h"
+#include "maths/solver/Solver.h"
+#include "maths/Equations.h"
-#define MAIN_APP
-//#define APP_TEST
+//#define MAIN_APP
+#define APP_TEST
#ifdef MAIN_APP
@@ -44,13 +45,14 @@ int main() {
system("CLS");
return 1;
}
-
+
#ifdef DEBUG_MODE
lexertk::helper::dump(generator);
#endif // DEBUG_MODE
+ Equation equation;
+ equation.Parse(generator);
- auto result = tokenize(generator);
system("PAUSE");
system("CLS");
@@ -64,5 +66,14 @@ int main() {
#ifdef APP_TEST
+int main() {
+ lexertk::generator lexer;
+ lexer.process("_const+_const,_eval:no_diff_Var");
+
+ //auto result = tokenize(lexer);
+
+
+ return 0;
+}
#endif
\ No newline at end of file
diff --git a/QuicMaf/maths/Equations.h b/QuicMaf/maths/Equations.h
new file mode 100644
index 0000000..78229f3
--- /dev/null
+++ b/QuicMaf/maths/Equations.h
@@ -0,0 +1,48 @@
+#ifndef EQUATIONS_H
+#define EQUATIONS_H
+#pragma once
+#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"
+
+struct Equation {
+ vector lwing;
+ vector rwing;
+
+ // TODO: Optimize this mess
+ void Parse(lexertk::generator expression) {
+ string lwing_str;
+ string rwing_str;
+
+ bool left = true;
+ for (int i = 0; i < expression.size(); i++) {
+ if (expression[i].value[0] == '\0') continue;
+
+ if (expression[i].value[0] == '=') {
+ left = !left;
+ continue; // dont add equal sign
+ }
+ else left = left;
+ (left) ? lwing_str.push_back(expression[i].value[0]) : rwing_str.push_back(expression[i].value[0]); // append to wings
+ }
+
+ // Tokenize wings
+ lexertk::generator lwing_lexer;
+ lwing_lexer.process(lwing_str);
+ lwing = tokenize(lwing_lexer);
+
+ lexertk::generator rwing_lexer;
+ rwing_lexer.process(rwing_str);
+ rwing = tokenize(rwing_lexer);
+ }
+};
+
+#endif // !EQUATIONS_H
\ No newline at end of file
diff --git a/QuicMaf/maths/defines.h b/QuicMaf/maths/defines.h
index 75e34d9..44596e1 100644
--- a/QuicMaf/maths/defines.h
+++ b/QuicMaf/maths/defines.h
@@ -7,8 +7,12 @@
#include
#include
+#include
#include
+#include
+#include
+
using namespace std;
#define DEF_C -999
@@ -25,7 +29,6 @@ enum TermTypes {
Equ,
};
-
// for string delimiter
static vector split(string s, string delimiter) {
size_t pos_start = 0, pos_end, delim_len = delimiter.length();
@@ -51,7 +54,7 @@ static void removeSubstrs(string& s, string& p) {
s.erase(i, n);
}
-int getPrecedence(char c) {
+static int getPrecedence(char c) {
//if (!isArithmitic(c)) return -1; // invalid
if (c == '*') return 1;
@@ -64,7 +67,7 @@ int getPrecedence(char c) {
// return true if c1 is higher precedence
// return false if c2 is higher precedence
-bool compPrecedence(char c1, char c2) {
+static bool compPrecedence(char c1, char c2) {
return getPrecedence(c1) > getPrecedence(c2);
}
@@ -149,4 +152,23 @@ static int getTermType(string str) {
else return Var;
}
+// 1 is pos
+// -1 is neg
+// 0 is 0
+static int sign(NValue x) {
+ return (x > 0) ? 1 : ((x < 0) ? -1 : 0);
+}
+
+
+// Function to calculate highest common divisor
+static int gcf(int x, int y) {
+ int gcd;
+
+ for (int i = 1; i <= x && i <= y; i++)
+ if (x % i == 0 && y % i == 0)
+ gcd = i;
+
+ return gcd;
+}
+
#endif // !
diff --git a/QuicMaf/maths/solver/Solver.cpp b/QuicMaf/maths/solver/Solver.cpp
new file mode 100644
index 0000000..ef27f99
--- /dev/null
+++ b/QuicMaf/maths/solver/Solver.cpp
@@ -0,0 +1 @@
+#include "Solver.h"
diff --git a/QuicMaf/maths/solver/Solver.h b/QuicMaf/maths/solver/Solver.h
new file mode 100644
index 0000000..aac7e5d
--- /dev/null
+++ b/QuicMaf/maths/solver/Solver.h
@@ -0,0 +1,44 @@
+#ifndef SOLVER_H
+#define SOLVER_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"
+
+class Solver
+{
+public:
+ void Parse(string equation);
+ Term* Solve();
+
+public: // PRIVATE MEMBERS TODO: MARK PRIVATE IN FINAL BUILD
+ Equation* equation = nullptr;
+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
diff --git a/QuicMaf/maths/solver/term_rewriter/QMReducer.h b/QuicMaf/maths/solver/term_rewriter/QMReducer.h
new file mode 100644
index 0000000..6f70f09
--- /dev/null
+++ b/QuicMaf/maths/solver/term_rewriter/QMReducer.h
@@ -0,0 +1 @@
+#pragma once
diff --git a/QuicMaf/maths/solver/term_rewriter/QMRule.cpp b/QuicMaf/maths/solver/term_rewriter/QMRule.cpp
new file mode 100644
index 0000000..fc05a48
--- /dev/null
+++ b/QuicMaf/maths/solver/term_rewriter/QMRule.cpp
@@ -0,0 +1,6 @@
+#include "QMRule.h"
+
+vector QMRule::Reduce()
+{
+ return vector();
+}
diff --git a/QuicMaf/maths/solver/term_rewriter/QMRule.h b/QuicMaf/maths/solver/term_rewriter/QMRule.h
new file mode 100644
index 0000000..b3481d7
--- /dev/null
+++ b/QuicMaf/maths/solver/term_rewriter/QMRule.h
@@ -0,0 +1,73 @@
+#ifndef QMRULE_H
+#define QMRULE_H
+#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"
+
+enum Identifier_t {
+ _const = 1,
+ _var = 2,
+ _brack,
+ _eval,
+ _add,
+ _sub,
+ _mul,
+ _div,
+ _equ,
+ _const_aval,
+ _var_aval,
+ _pow_diff,
+ _no_pow_diff,
+ _var_diff,
+ _no_var_diff,
+ _high_order_left,
+ _high_order_right,
+ _priority1,
+ _priority2,
+ _priority3,
+ _priority4,
+ _priority5,
+};
+
+class QMRule {
+public:
+ QMRule(vector rule, vector props, int prio)
+ : mRules(rule), mProps(props), mPrior(prio) {}
+
+ vector GetRules() const { return mRules; }
+ vector GetProps() const { return mProps; }
+ int GetPrior() { return mPrior; }
+
+ bool operator==(const QMRule& left) const {
+ if (left.mPrior != mPrior) return false;
+ if (left.mProps != mProps) return false;
+ if (left.mRules != mRules) return false;
+ return true;
+ }
+
+ bool operator>(const QMRule& left) const {
+ return (left.mPrior > mPrior);
+ }
+ bool operator<(const QMRule& left) const {
+ return (left.mPrior < mPrior);
+ }
+
+ vector Reduce(vector terms); // applies self rule on terms vector, only once
+private:
+ vector Evaluate(); // evaluation method
+
+
+ vector mRules;
+ vector mProps;
+ int mPrior;
+};
+#endif // QMRULE_H
diff --git a/QuicMaf/maths/solver/term_rewriter/QMRuleSet.h b/QuicMaf/maths/solver/term_rewriter/QMRuleSet.h
new file mode 100644
index 0000000..6c08446
--- /dev/null
+++ b/QuicMaf/maths/solver/term_rewriter/QMRuleSet.h
@@ -0,0 +1,35 @@
+#ifndef QMRULESET_H
+#define QMRULESET_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"
+
+class QMRuleSet {
+public:
+ void push_back(QMRule rule);
+ void push_front(QMRule rule);
+
+ void pop_back(QMRule rule);
+ void pop_front(QMRule rule);
+
+ void order();
+
+ auto GetRuleSet() { return mRuleSet; }
+
+private:
+ deque mRuleSet;
+};
+
+#endif // !QMRULESET_H
diff --git a/QuicMaf/maths/terms/Brackets.h b/QuicMaf/maths/terms/Brackets.h
index 5f020ef..7a5e5b9 100644
--- a/QuicMaf/maths/terms/Brackets.h
+++ b/QuicMaf/maths/terms/Brackets.h
@@ -13,7 +13,12 @@ public:
Bracket() {
Term();
mType = TermTypes::Brack;
- mConstant = new Constant(1);
+ }
+
+ Bracket(vector ts) {
+ Term();
+ mType = TermTypes::Brack;
+ mTerms = ts;
}
vector mTerms;
@@ -21,6 +26,8 @@ public:
void setConstant(Term* constant) {
mConstant = constant;
}
+
+ Term* GetConstant() const { return mConstant; }
private:
Term *mConstant;
diff --git a/QuicMaf/maths/terms/Term.h b/QuicMaf/maths/terms/Term.h
index 4f56d4e..4cc4dea 100644
--- a/QuicMaf/maths/terms/Term.h
+++ b/QuicMaf/maths/terms/Term.h
@@ -23,8 +23,9 @@ public:
NValue mValue = DEF_N;
CValue mVariable = DEF_C;
- CValue mOperator = DEF_C;
NValue mPower = 1;
+ CValue mOperator = DEF_C;
+ bool mSquareRoot = false;
int mType = -1;
};
#endif // !TERM_H
diff --git a/QuicMaf/maths/terms/Variable.h b/QuicMaf/maths/terms/Variable.h
index a534085..df93e51 100644
--- a/QuicMaf/maths/terms/Variable.h
+++ b/QuicMaf/maths/terms/Variable.h
@@ -8,12 +8,11 @@ using namespace std;
class Variable : public Term {
public:
- Variable(NValue val = 0, CValue var = DEF_C, NValue pwr = 1) {
+ Variable(NValue val = 1, CValue var = DEF_C, NValue pwr = 1) {
mValue = val;
mVariable = var;
mPower = pwr;
mType = TermTypes::Var;
}
-
};
#endif // !VARIABLE_H
diff --git a/QuicMaf/maths/terms/term_parser.h b/QuicMaf/maths/terms/term_parser.h
index 1d7cd0d..d81a5ae 100644
--- a/QuicMaf/maths/terms/term_parser.h
+++ b/QuicMaf/maths/terms/term_parser.h
@@ -1,3 +1,13 @@
+/*
+ ****************************************************
+
+ This Code Is Depreciated
+ Remade and tuned in:
+ tokenizer.h
+
+ ****************************************************
+*/
+
#ifndef TERM_PARSER_H
#define TERM_PARSER_H
#pragma once
diff --git a/QuicMaf/maths/tokenizer.h b/QuicMaf/maths/tokenizer.h
index b263dce..d6d464e 100644
--- a/QuicMaf/maths/tokenizer.h
+++ b/QuicMaf/maths/tokenizer.h
@@ -1,3 +1,20 @@
+/*
+ ***************************************************************************
+
+ The goal of this class is to tokenize a string of equation and splits
+ it to mathematical term, with brackets begin a complete terms alone.
+ Ex:
+ 2(5 + 9) - 56=90
+ If the above input was given to the main function in this class it must give an output of:
+ vector:
+ - 2(5 + 9)
+ - -
+ - 56
+ - =
+ - 90
+
+ ***************************************************************************
+*/
#ifndef TOKENIZER_H
#define TOKENIZER_H
#pragma once
@@ -75,11 +92,11 @@ static Bracket* tokenize_bracket(lexertk::generator gen, Token* token, string co
index++;
} while (!(!state && counter == 0));
- bracks = retriveSubLexer(gen, Token(token->begin, index-1));
+ bracks = retriveSubLexer(gen, Token(token->begin, index - 1));
token->end = index - 1; // to make sure we move the token pointer to the end of bracks
// DELETE THIS BRACKET PARANTHESIS
- bracks = retriveSubLexer(bracks, Token(1, bracks.size()-2));
+ bracks = retriveSubLexer(bracks, Token(1, bracks.size() - 2));
// Tokenize its term
// first make sure it is not empty
@@ -102,6 +119,50 @@ static Bracket* tokenize_bracket(lexertk::generator gen, Token* token, string co
return result;
}
+static vector combineBrackets(vector terms) {
+ vector result;
+
+ for (int i = 0; i < terms.size(); i++) {
+ auto term = terms[i];
+
+ if (term->mType == TermTypes::Op &&
+ (term->mOperator == '-' || term->mOperator == '+')) {
+ // if after it was a number
+ if (terms[i + 1]->mType == TermTypes::Const || terms[i + 1]->mType == TermTypes::Var) {
+ // check for safety
+ if (!(terms.size() <= i + 2))
+ // if after it was a bracket too
+ if (terms[i + 2]->mType == TermTypes::Brack) {
+ // if so combine the terms
+ Bracket* brack = new Bracket();
+ brack->mTerms = static_cast(terms[i + 2])->mTerms;
+ auto constant = static_cast(terms[i + 2])->GetConstant();
+ constant->mValue *= (term->mOperator == '+') ? +1 : -1;
+ brack->setConstant(constant);
+ result.push_back(brack);
+ i += 2;
+ continue;
+ }
+ }
+ else {
+ if (terms[i + 1]->mType == TermTypes::Brack) {
+ // if so combine the terms
+ Bracket* brack = new Bracket();
+ brack->mTerms = static_cast(terms[i + 1])->mTerms;
+ auto constant = static_cast(terms[i + 1])->GetConstant();
+ constant->mValue *= (term->mOperator == '+') ? +1 : -1;
+ brack->setConstant(constant);
+ result.push_back(brack);
+ i += 1;
+ continue;
+ }
+ }
+ }
+ result.push_back(term);
+ }
+ return result;
+}
+
static vector tokenize(lexertk::generator lexed) {
vector result;
@@ -130,18 +191,38 @@ static vector tokenize(lexertk::generator lexed) {
/////// ENDING OF TREE
}
- Variable* Var = nullptr;
- Var = new Variable(atof(&lex.value[0]), after_lex.value[0], atof(&lexed[i + 3].value[0]));
- result.push_back(Var);
- tok.end = i + 3;
- /////// ENDING OF TREE
+ // check for bracket
+ if (lexed[i + 4].value == "(") {
+ // bracket detected
+ tok.begin += 4; // consume coefficient
+ result.push_back(tokenize_bracket(lexed, &tok, lex.value + after_lex.value + lexed[i + 2].value + lexed[i + 3].value));
+ /////// ENDING OF TREE
+ }
+ else {
+ // simple power variable
+ Variable* Var = nullptr;
+ Var = new Variable(atof(&lex.value[0]), after_lex.value[0], atof(&lexed[i + 3].value[0]));
+ result.push_back(Var);
+ tok.end = i + 3;
+ /////// ENDING OF TREE
+ }
}
else {
- // The variable is simple!
- Variable* Var = nullptr;
- Var = new Variable(atof(&lex.value[0]), after_lex.value[0]);
- result.push_back(Var);
- tok.end = i + 1;
+
+ if (lexed[i + 2].value == "(") {
+ // bracket detected
+ tok.begin += 2;
+ result.push_back(tokenize_bracket(lexed, &tok, lex.value + after_lex.value));
+ /////// ENDING OF TREE
+ }
+ else {
+ // The variable is simple!
+ Variable* Var = nullptr;
+ Var = new Variable(atof(&lex.value[0]), after_lex.value[0]);
+ result.push_back(Var);
+ tok.end = i + 1;
+ /////// ENDING OF TREE
+ }
}
}
else if (isBrackets(after_lex.value[0]) && isBracketsOpening(after_lex.value[0])) {
@@ -163,11 +244,18 @@ static vector tokenize(lexertk::generator lexed) {
/////// ENDING OF TREE
}
- Constant* Const = nullptr;
- Const = new Constant(atof(&lex.value[0]), atof(&lexed[i + 2].value[0]));
- result.push_back(Const);
- tok.end = i + 2;
- /////// ENDING OF TREE
+ // check for brackets
+ if (lexed[i + 3].value == "(") {
+ tok.begin += 3;
+ result.push_back(tokenize_bracket(lexed, &tok, lex.value + after_lex.value + lexed[i + 2].value));
+ }
+ else {
+ Constant* Const = nullptr;
+ Const = new Constant(atof(&lex.value[0]), atof(&lexed[i + 2].value[0]));
+ result.push_back(Const);
+ tok.end = i + 2;
+ /////// ENDING OF TREE
+ }
}
else {
// The number is simple!
@@ -219,6 +307,7 @@ static vector tokenize(lexertk::generator lexed) {
op = new Operator(lex.value[0]);
result.push_back(op);
tok.end = i;
+
}
else if (isEqualChar(lex.value[0])) {
// equal sign
@@ -232,6 +321,8 @@ static vector tokenize(lexertk::generator lexed) {
i = tok.end; // no need to increment, automatically done in loop statment
}
+ result = combineBrackets(result);
+
return result;
}
#endif // !TOKENIZER_H
diff --git a/bin/Debug-x64/QuicMaf.exe b/bin/Debug-x64/QuicMaf.exe
index 5a07a84..ad45554 100644
Binary files a/bin/Debug-x64/QuicMaf.exe and b/bin/Debug-x64/QuicMaf.exe differ
diff --git a/bin/Debug-x64/QuicMaf.ilk b/bin/Debug-x64/QuicMaf.ilk
index 8832296..566f227 100644
Binary files a/bin/Debug-x64/QuicMaf.ilk and b/bin/Debug-x64/QuicMaf.ilk differ
diff --git a/bin/Debug-x64/QuicMaf.pdb b/bin/Debug-x64/QuicMaf.pdb
index a90f8be..b07b581 100644
Binary files a/bin/Debug-x64/QuicMaf.pdb and b/bin/Debug-x64/QuicMaf.pdb differ
diff --git a/notes2.txt b/notes2.txt
new file mode 100644
index 0000000..fc0cbab
--- /dev/null
+++ b/notes2.txt
@@ -0,0 +1,17 @@
+Term1 Term2
+--------------
+Var Var
+Var Bracket
+Var Const
+Var Op
+Const Const
+Const Var
+Const Bracket
+Const Op
+Bracket Bracket
+Bracket Var
+Bracket Const
+Bracket Op
+Op Var
+Op Const
+Op Bracket
\ No newline at end of file
diff --git a/notes3.txt b/notes3.txt
new file mode 100644
index 0000000..91b331f
--- /dev/null
+++ b/notes3.txt
@@ -0,0 +1,43 @@
+- Break brackets:
+ - Mutliply each child term with coefficeint, ignore operators.
+- Solve:
+ - Rules:
+ // These ruls are not complete in the application we should take in mind
+ // that 'const * var' might come as 'var * const' and still evaluate to the same thing
+ // Also it must always evaluate using the 'TermHelper' class.
+ - const * const, eval
+ - const * var, eval
+ - const * bracket, eval
+ - const / const, eval
+ - const / var, eval
+ - const / bracket, eval
+ - const + const, eval
+ - const + var, eval
+ - const + bracket, eval
+ - const - const, eval
+ - const - var, eval
+ - const - bracket, eval
+ - Apply Rules, until no difference.
+
+- Move variables to the right:
+ - Specific Rules:
+ // These rules are not complete in the application we should take in mind
+ // that 'const * var' might come as 'var * const' THIS IS FOR ALL RULES!
+ // Also it should evaluate to something like this, although not always:
+ - const * const, const * const
+ - const * var, const * var
+ - const * bracket, const * bracket
+ - const / const, const / const
+ - const / var, const / var
+ - const / bracket, const / bracket
+ - const + const, cosnt + const
+ - const + var, const + var
+ - const + bracket, const + bracket
+ - const - const, const - const
+ - const - var, const - var
+ - const - bracket, const - bracket
+ - Keep appling rules until there is no change.
+
+BreakBrackets()
+Move_Variables_To_The_Right()
+Solve()