Finished Solver!

GUI To be Made!
This commit is contained in:
Ayham Mamoun 2019-03-17 17:06:34 +03:00
parent 7ca9f7de84
commit a7a28968c1
38 changed files with 689 additions and 105 deletions

View File

@ -83,7 +83,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<WarningLevel>TurnOffAllWarnings</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
@ -121,7 +121,7 @@
<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\QMReducerHelper.cpp" />
<ClCompile Include="maths\solver\term_rewriter\QMEvalHelper.cpp" />
<ClCompile Include="maths\solver\term_rewriter\QMRule.h" />
<ClCompile Include="maths\solver\term_rewriter\ds\TermPool.cpp" />
</ItemGroup>
@ -129,9 +129,10 @@
<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\QMReducerHelper.h" />
<ClInclude Include="maths\solver\term_rewriter\QMEvalHelper.h" />
<ClInclude Include="maths\solver\term_rewriter\QMRuleSet.h" />
<ClInclude Include="maths\terms\Brackets.h" />
<ClInclude Include="maths\terms\Bundle.h" />
<ClInclude Include="maths\terms\Constant.h" />
<ClInclude Include="maths\terms\Equal.h" />
<ClInclude Include="maths\terms\Operator.h" />

View File

@ -24,15 +24,15 @@
<ClCompile Include="maths\solver\term_rewriter\QMRule.h">
<Filter>Source Files</Filter>
</ClCompile>
<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>
<ClCompile Include="maths\solver\term_rewriter\QMEvalHelper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="maths\tokenizer.h">
@ -77,9 +77,6 @@
<ClInclude Include="maths\solver\term_rewriter\QMRuleSet.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="maths\solver\term_rewriter\QMReducerHelper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="maths\solver\term_rewriter\QMEvaluator.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -89,5 +86,11 @@
<ClInclude Include="maths\solver\term_rewriter\ds\ExprTree.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="maths\terms\Bundle.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="maths\solver\term_rewriter\QMEvalHelper.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -8,20 +8,19 @@
#include "maths/solver/Solver.h"
#include "maths/Equations.h"
#include "maths/solver/term_rewriter/QMReducerHelper.h"
#include "maths/solver/term_rewriter/QMEvalHelper.h"
#include "maths/solver/term_rewriter/QMEvaluator.h"
#include "maths/solver/term_rewriter/ds/ExprTree.h"
//#define MAIN_APP
#define APP_TEST
#define MAIN_APP
//#define APP_TEST
#ifdef MAIN_APP
using namespace std;
int main() {
while (true) {
@ -29,35 +28,19 @@ int main() {
string input;
cin >> input;
lexertk::generator generator;
cout << "Solution: " << endl;
if (!generator.process(input)) {
cout << "Failed to lex: " << input << endl;
system("PAUSE");
system("CLS");
return true;
}
Solver solver;
solver.Parse(input);
solver.Solve();
//lexertk::helper::commutative_inserter ci;
//ci.process(generator);
lexertk::helper::bracket_checker bc;
bc.process(generator);
if (!bc.result()) {
cout << "Failed Bracket Check!" << endl;
system("PAUSE");
system("CLS");
return 1;
}
#ifdef DEBUG_MODE
lexertk::helper::dump(generator);
#endif // DEBUG_MODE
Equation equation;
equation.Parse(generator);
for (auto *lwing : solver.mEquation->lwing)
cout << lwing->to_str();
cout << "=";
for (auto *rwing : solver.mEquation->rwing)
cout << rwing->to_str();
cout << endl;
system("PAUSE");
system("CLS");
@ -72,12 +55,23 @@ int main() {
int main() {
lexertk::generator lexer;
lexer.process("2/2*4^2");
lexer.process("12341-(2x+3)");
auto result = tokenize(lexer);
auto res = evaluate(result);
Solver solver;
solver.Parse("4+3=4x+6");
solver.Solve();
for (auto *lwing : solver.mEquation->lwing)
cout << lwing->to_str();
cout << "=";
for (auto *rwing : solver.mEquation->rwing)
cout << rwing->to_str();
cout << endl;
system("PAUSE");
return 0;
}

View File

@ -31,7 +31,7 @@ struct Equation {
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
(left) ? lwing_str.append(expression[i].value) : rwing_str.append(expression[i].value); // append to wings
}
// Tokenize wings

View File

@ -31,7 +31,7 @@ enum TermTypes {
Op,
Brack,
Equ,
Frac,
Bund,
};
// for string delimiter
@ -176,4 +176,12 @@ static int gcf(int x, int y) {
return gcd;
}
template<class T>
static bool IsInVector(vector<T> v, T elem) {
for (auto *item : v)
if (item == elem)
return true;
return false;
}
#endif // !

View File

@ -1,35 +1,533 @@
#include "Solver.h"
void Solver::Parse(string equation)
{
void Solver::Parse(string equation) {
mEquation = new Equation();
lexertk::generator lexer;
lexer.process(equation);
mEquation->Parse(lexer);
}
Term * Solver::Solve()
{
return nullptr;
Equation * Solver::Solve() {
// Put vars on one side and consts on another
mEquation = PutVarsInOneSide(mEquation);
mEquation = PutConstsInOneSide(mEquation);
// Evaluate lwing and rwing
mEquation->lwing = evaluate(mEquation->lwing);
mEquation->rwing = evaluate(mEquation->rwing);
// Check For Diversion Calculations
mEquation = ApplyDiversionCalcs(mEquation);
return mEquation;
}
bool Solver::CheckValidOps(Equation * equ)
{
return false;
vector<Term*> Solver::FlipTermSigns(vector<Term*> terms) {
vector<Term*> res;
terms = RemNonEssientalOps(terms);
for (int i = 0; i < terms.size(); i++) {
auto term = terms[i];
if (term->mType == TermTypes::Brack) {
auto brack = static_cast<Bracket*>(term);
if (brack->mConstant == nullptr) {
brack->mConstant = new Constant(-1, 1);
}
else
brack->mConstant->mValue = -brack->mConstant->mValue;
res.push_back(brack);
}
else {
term->mValue = -term->mValue;
res.push_back(term);
}
}
res = AddNonEssientalOps(terms);
return res;
}
Equation * Solver::RemoveWeightOfWings(Equation * equ)
{
return nullptr;
Equation * Solver::ApplyDiversionCalcs(Equation * equ) {
// Situations
// 2x = 50 -> x = 50/2, applies only if one var
auto lwing = RemNonEssientalOps(equ->lwing);
auto rwing = RemNonEssientalOps(equ->rwing);
if (lwing.size() == 1) {
// Check if x's coeffiecent is higher than 1 or lower
if (lwing[0]->mValue != 1 && lwing[0]->mPower == 1) {
// situation of "2x = 50 -> x = 50/2" is confirmed
auto domin = lwing[0]->mValue;
Bracket* brack = new Bracket();
for (int i = 0; i < rwing.size(); i++)
brack->mTerms.push_back(rwing[i]);
auto term = QMEvalHelper::Div(brack, new Constant(domin));
rwing.clear();
rwing = term;
lwing[0]->mValue = 1;
}
}
equ->lwing = lwing;
equ->rwing = rwing;
return equ;
}
Equation * Solver::OrderTerms(Equation * equ)
{
return nullptr;
bool Solver::CheckValidOps(Equation * equ) {
// Check Lwing
for (int i = 0; i < equ->lwing.size() - 1; i++) {
auto term = equ->lwing[i];
if (term->mType == TermTypes::Op) {
if (i == 0) {
if (term->mOperator == '/' || term->mOperator == '*') {
cout << "Can't have division or multiplication at the begining!" << endl;
system("PUASE");
exit(0);
}
continue;
}
auto before_Term = equ->lwing[i - 1];
auto after_Term = equ->lwing[i + 1];
if (before_Term->mType == TermTypes::Op ||
after_Term->mType == TermTypes::Op) {
cout << "Can't have trialing operators!" << endl;
system("PUASE");
exit(0);
}
}
}
// Check Rwing
for (int i = 0; i < equ->rwing.size() - 1; i++) {
auto term = equ->rwing[i];
if (term->mType == TermTypes::Op) {
if (i == 0) {
if (term->mOperator == '/' || term->mOperator == '*') {
cout << "Can't have division or multiplication at the begining!" << endl;
system("PUASE");
exit(0);
}
continue;
}
auto before_Term = equ->rwing[i - 1];
auto after_Term = equ->rwing[i + 1];
if (before_Term->mType == TermTypes::Op ||
after_Term->mType == TermTypes::Op) {
cout << "Can't have trialing operators!" << endl;
system("PUASE");
exit(0);
}
}
}
return true;
}
Equation * Solver::CheckDiversionCalcs(Equation * equ)
{
return nullptr;
Equation * Solver::PutVarsInOneSide(Equation * equ) {
Equation* res = new Equation();
vector<Term*> lwing = OrderTermsByValue(equ->lwing);
vector<Term*> rwing = OrderTermsByValue(equ->rwing);
lwing = RemNonEssientalOps(lwing);
rwing = RemNonEssientalOps(rwing);
vector<int> lwing_vars;
vector<int> rwing_vars;
// Find vars and place them in lwing_vars or rwing_vars
for (int i = 0; i < lwing.size(); i++) {
if (lwing[i]->mType == TermTypes::Bund) {
// check if it has a variable
Bundle* bundle = static_cast<Bundle*>(lwing[i]);
bool contains = false;
for (auto *term : bundle->mTerms)
if (term->mType == TermTypes::Var) { contains = true; continue; }
if (contains)
lwing_vars.push_back(i);
continue;
}
if (lwing[i]->mType == TermTypes::Var)
lwing_vars.push_back(i);
}
for (int i = 0; i < rwing.size(); i++) {
if (rwing[i]->mType == TermTypes::Bund) {
// check if it has a variable
Bundle* bundle = static_cast<Bundle*>(rwing[i]);
bool contains = false;
for (auto *term : bundle->mTerms)
if (term->mType == TermTypes::Var) { contains = true; continue; }
if (contains)
rwing_vars.push_back(i);
continue;
}
if (rwing[i]->mType == TermTypes::Var)
rwing_vars.push_back(i);
}
// place variables
for (auto lwing_term : lwing_vars)
res->lwing.push_back(lwing[lwing_term]);
for (auto rwing_term : rwing_vars) {
auto term = rwing[rwing_term];
term->mValue = -term->mValue;
res->lwing.push_back(term);
}
// place other terms
for (int i = 0; i < lwing.size(); i++) {
if (std::find(lwing_vars.begin(), lwing_vars.end(), i) != lwing_vars.end()) {
// variable encouterd
continue;
}
res->lwing.push_back(lwing[i]);
}
for (int i = 0; i < rwing.size(); i++) {
if (std::find(rwing_vars.begin(), rwing_vars.end(), i) != rwing_vars.end()) {
// variable encouterd
continue;
}
res->rwing.push_back(rwing[i]);
}
res->lwing = AddNonEssientalOps(res->lwing);
res->rwing = AddNonEssientalOps(res->rwing);
return res;
}
Equation * Solver::PutConstsInOneSide(Equation * equ) {
Equation* res = new Equation();
vector<Term*> lwing = OrderTermsByValue(equ->lwing);
vector<Term*> rwing = OrderTermsByValue(equ->rwing);
lwing = RemNonEssientalOps(lwing);
rwing = RemNonEssientalOps(rwing);
vector<int> lwing_const;
vector<int> rwing_const;
// Make lwing_const
for (int i = 0; i < lwing.size(); i++) {
if (lwing[i]->mType == TermTypes::Bund) {
// check if it has a constant
Bundle* bundle = static_cast<Bundle*>(lwing[i]);
bool contains = false;
for (auto *term : bundle->mTerms)
if (term->mType == TermTypes::Const) { contains = true; continue; }
if (contains)
lwing_const.push_back(i);
continue;
}
if (lwing[i]->mType == TermTypes::Const)
lwing_const.push_back(i);
}
// Make rwing_const
for (int i = 0; i < rwing.size(); i++) {
if (rwing[i]->mType == TermTypes::Bund) {
// check if it has a cosnstant
Bundle* bundle = static_cast<Bundle*>(rwing[i]);
bool contains = false;
for (auto *term : bundle->mTerms)
if (term->mType == TermTypes::Const) { contains = true; continue; }
if (contains)
rwing_const.push_back(i);
continue;
}
if (rwing[i]->mType == TermTypes::Const)
rwing_const.push_back(i);
}
// Place lwing constants in res->rwing
for (auto i : lwing_const) {
auto term = lwing[i];
term->mValue = -term->mValue;
res->rwing.push_back(term);
}
// Place rwing constants in res->rwing
for (auto i : rwing_const)
res->rwing.push_back(rwing[i]);
// Place other terms of lwing to res->lwing
for (int i = 0; i < lwing.size(); i++) {
if (std::find(lwing_const.begin(), lwing_const.end(), i) != lwing_const.end()) {
// constant encouterd
continue;
}
res->lwing.push_back(lwing[i]);
}
// Place other terms of rwing to res->rwing
for (int i = 0; i < rwing.size(); i++) {
if (std::find(rwing_const.begin(), rwing_const.end(), i) != rwing_const.end()) {
// constant encouterd
continue;
}
res->rwing.push_back(rwing[i]);
}
res->lwing = AddNonEssientalOps(res->lwing);
res->rwing = AddNonEssientalOps(res->rwing);
return res;
}
Equation * Solver::DoDiversionCalcs(Equation * equ)
{
return nullptr;
vector<Term*> Solver::RemNonEssientalOps(vector<Term*> terms) {
vector<Term*> res;
for (int i = 0; i < terms.size(); i++) {
auto term = terms[i];
if (term->mType == TermTypes::Op) {
if (term->mOperator == '+') {
auto after_term = terms[i + 1];
after_term->mValue = abs(after_term->mValue);
res.push_back(after_term);
i++;
continue;
}
if (term->mOperator == '-') {
auto after_term = terms[i+1];
after_term->mValue = after_term->mValue * -1;
res.push_back(after_term);
i++;
continue;
}
if (term->mOperator == '*') {
auto before_term = *res.end();
res.pop_back();
auto after_term = terms[i + 1];
Bundle* bundle = new Bundle();
bundle->mTerms.push_back(before_term);
bundle->mTerms.push_back(term);
bundle->mTerms.push_back(after_term);
res.push_back(bundle);
i++;
continue;
}
if (term->mOperator == '/') {
auto before_term = *(--res.end());
res.pop_back();
auto after_term = terms[i+1];
Bundle* bundle = new Bundle();
bundle->mTerms.push_back(before_term);
bundle->mTerms.push_back(term);
bundle->mTerms.push_back(after_term);
res.push_back(bundle);
i++;
continue;
}
}
res.push_back(term);
}
return res;
}
vector<Term*> Solver::AddNonEssientalOps(vector<Term*> terms) {
vector<Term*> res;
for (int i = 0; i < terms.size(); i++) {
auto term = terms[i];
if (i == 0) {
res.push_back(term);
continue;
}
if (term->mType == TermTypes::Bund) {
auto bundle = static_cast<Bundle*>(term);
for (auto *_term : bundle->mTerms)
res.push_back(_term);
continue;
}
if (term->mType == TermTypes::Brack) {
res.push_back(term);
continue;
}
// check if term was positive
if (term->mValue > 0) {
res.push_back(new Operator('+'));
res.push_back(term);
continue;
}
else if (term->mValue < 0) {
term->mValue = abs(term->mValue);
res.push_back(new Operator('-'));
res.push_back(term);
continue;
}
}
return res;
}
Bundle * Solver::BuildBundle(vector<Term*> terms) {
Bundle* bundle = new Bundle();
for (int i = 0; i < terms.size(); i++)
bundle->mTerms.push_back(terms[i]);
return bundle;
}
vector<Term*> Solver::BreakBundle(Bundle * bundle) {
vector<Term*> res;
for (auto *item : bundle->mTerms)
res.push_back(item);
return res;
}
vector<Term*> Solver::BundleTermsDuo(vector<Term*> terms) {
vector<Term*> res;
for (int i = 0; i < terms.size(); i++) {
auto term = terms[i];
if (term->mType == TermTypes::Op) {
if (term->mOperator == '/') {
if (i == 0) {
// invalid cant have division at begining
cout << "Can't have division at begining!" << endl;
system("PAUSE");
exit(0);
}
auto before_term = terms[i-1];
auto after_term = terms[i +1];
Bundle* bundle = new Bundle();
bundle->mTerms.push_back(before_term); // t1
bundle->mTerms.push_back(term); // op
bundle->mTerms.push_back(after_term); // t2
res.push_back(bundle);
i++;
continue;
}
else {
// if it was a multiplication
if (term->mOperator == '*') {
if (i == 0) {
// invalid cant have multiplication at begining
cout << "Can't have multiplication at begining!" << endl;
system("PAUSE");
exit(0);
}
auto before_term = terms[i-1];
auto after_term = terms[i + 1];
Bundle* bundle = new Bundle();
bundle->mTerms.push_back(before_term); // t1
bundle->mTerms.push_back(term); // op
bundle->mTerms.push_back(after_term); // t2
res.push_back(bundle);
i++;
continue;
}
// if it was not division and not multiplication
auto after_term = terms[i + 1];
Bundle* bundle = new Bundle();
bundle->mTerms.push_back(term); // operator
bundle->mTerms.push_back(after_term); // term
res.push_back(bundle);
i++;
continue;
}
}
res.push_back(term);
}
return res;
}
vector<Term*> Solver::BundleTermsTri(vector<Term*> terms) {
vector<Term*> res;
for (int i = 0; i < terms.size(); i++) {
auto term = terms[i];
if (term->mType == TermTypes::Op) {
if (term->mOperator == '/') {
if (i == 0) {
// invalid cant have division at begining
cout << "Can't have division at begining!" << endl;
system("PUASE");
exit(0);
}
auto before_term = terms[i - 1];
auto after_term = terms[i + 1];
Bundle* bundle = new Bundle();
bundle->mTerms.push_back(before_term); // t1
bundle->mTerms.push_back(term); // op
bundle->mTerms.push_back(after_term); // t2
res.push_back(bundle);
i++;
continue;
}
else {
// if it was a multiplication
if (term->mOperator == '*') {
if (i == 0) {
// invalid cant habe multiplication at begining
cout << "Can't have multiplication at beginign!" << endl;
system("PAUSE");
exit(0);
}
auto before_term = terms[i - 1];
auto after_term = terms[i + 1];
Bundle* bundle = new Bundle();
bundle->mTerms.push_back(before_term); // t1
bundle->mTerms.push_back(term); // op
bundle->mTerms.push_back(after_term); // t2
res.push_back(bundle);
i++;
continue;
}
// if it was not division and not multiplication
auto before_term = terms[i - 1];
auto after_term = terms[i + 1];
Bundle* bundle = new Bundle();
bundle->mTerms.push_back(before_term);
bundle->mTerms.push_back(term);
bundle->mTerms.push_back(after_term);
res.push_back(bundle);
i++;
continue;
}
}
res.push_back(term);
}
return res;
}
bool Solver::IsEqualBundle(Bundle * b1, Bundle * b2) {
auto b1_copy = OrderTermsByValue(b1->mTerms);
auto b2_copy = OrderTermsByValue(b2->mTerms);
if (b1_copy.size() != b2_copy.size()) return false;
for (int i = 0; i < b1_copy.size(); i++)
if (!QMEvalHelper::IsEquTerms(b1_copy[i], b2_copy[i]))
return false;
return true;
}
vector<Term*> Solver::OrderTermsByValue(vector<Term*> terms) {
vector<Term*> res;
res = RemNonEssientalOps(terms);
stable_sort(res.begin(), res.end(), QMEvalHelper::IsHigherSig);
res = AddNonEssientalOps(res);
return res;
}

View File

@ -11,25 +11,44 @@
#include "../terms/Variable.h"
#include "../terms/Paranthesis.h"
#include "../tokenizer.h"
#include "../terms/Bundle.h"
#include "../../vendor/lexertk.hpp"
#include "term_rewriter/QMEvalHelper.h"
#include "term_rewriter/QMEvaluator.h"
class Solver {
public:
void Parse(string equation);
Term* Solve();
Equation* Solve();
public: // PRIVATE MEMBERS TODO: MARK PRIVATE IN FINAL BUILD
Equation* equation = nullptr;
public: // Program Side Calcs TODO: MARK PRIVATE IN FINAL BUILD
Equation* mEquation = nullptr;
private: // Mathematics Side Class Todo: Mark Private in final build
vector<Term*> FlipTermSigns(vector<Term*> terms);
Equation* ApplyDiversionCalcs(Equation* equ);
private: // Program Side Calcs TODO: MARK PRIVATE IN FINAL BUILD
bool CheckValidOps(Equation* equ);
Equation* RemoveWeightOfWings(Equation* equ);
Equation* OrderTerms(Equation* equ);
Equation* PutVarsInOneSide(Equation* equ);
Equation* PutConstsInOneSide(Equation* equ);
Equation* CheckDiversionCalcs(Equation* equ);
Equation* DoDiversionCalcs(Equation* equ);
vector<Term*> RemNonEssientalOps(vector<Term*> terms);
vector<Term*> AddNonEssientalOps(vector<Term*> terms);
Bundle* BuildBundle(vector<Term*> term);
vector<Term*> BreakBundle(Bundle* bundle);
vector<Term*> BundleTermsDuo(vector<Term*> terms);
vector<Term*> BundleTermsTri(vector<Term*> terms);
bool IsEqualBundle(Bundle* b1, Bundle* b2);
vector<Term*> OrderTermsByValue(vector<Term*> terms);
};
#endif // !1
#endif

View File

@ -1,4 +1,4 @@
#include "QMReducerHelper.h"
#include "QMEvalHelper.h"
vector<IdsWithTerms> QMEvalHelper::convertRangeToIds(vector<Term*> range) {
vector<IdsWithTerms> result;
@ -44,13 +44,13 @@ bool QMEvalHelper::IsSolvable(Term * t1, Operator * op, Term * t2) {
vector<Term*> QMEvalHelper::BreakBracket(Bracket * brack, bool order, Identifier_t order_type) {
vector<Term*> res;
if (brack->GetConstant() == nullptr) {
if (brack->mConstant == nullptr) {
for (int i = 0; i < brack->mTerms.size(); i++)
res.push_back(brack->mTerms[i]);
}
for (int i = 0; i < brack->mTerms.size(); i++) {
auto returns = Mul(brack->GetConstant(), brack->mTerms[i]);
auto returns = Mul(brack->mConstant, brack->mTerms[i]);
for (int j = 0; j < returns.size(); j++)
res.push_back(returns[j]);
}
@ -91,12 +91,13 @@ Constant * QMEvalHelper::convertToConstant(Term * t1) {
bool QMEvalHelper::IsHigherSig(Term * t1, Term * t2) { // x^2 > x : true
if (t1->mType == TermTypes::Brack)
return true;
else if (t1->mType == TermTypes::Op)
if (t1->mType == TermTypes::Op)
return false;
else if (t2->mType == TermTypes::Op)
if (t2->mType == TermTypes::Op)
return true;
if (t1->mType == TermTypes::Var) {
// its a var check for other term
if (t2->mType == TermTypes::Bund) return false;
if (t2->mType == TermTypes::Brack) return false;
if (t2->mType == TermTypes::Var) {
@ -106,22 +107,29 @@ bool QMEvalHelper::IsHigherSig(Term * t1, Term * t2) { // x^2 > x : true
return t1->mValue >= t2->mValue;
}
// if t1 has higher or equal power
if (t1->mPower >= t2->mPower) return true;
if (t1->mPower >= t2->mPower)
return true;
else return false; // t2 is higher
}
return true;
}
else if (t1->mType == TermTypes::Const) {
if (t1->mType == TermTypes::Const) {
// its a const check for other term
if (t2->mType == TermTypes::Brack) return false;
if (t2->mType == TermTypes::Var) return false;
if (t2->mType == TermTypes::Const) {
// if same type
// check for power
return t1->mPower >= t2->mPower;
if (t1->mValue > t2->mValue) return true;
return false;
}
return true;
}
if (t1->mType == TermTypes::Bund)
return true;
if (t2->mType == TermTypes::Bund)
return false;
return false;
}
@ -485,7 +493,7 @@ vector<Term*> QMEvalHelper::FactorizeTermsToBrack(vector<Term*> terms, vector<Te
// make first bracket
Bracket* brack1 = new Bracket();
brack1->setConstant(HCF_all);
brack1->mConstant = HCF_all;
for (int i = 0; i < terms.size(); i++)
if (terms[i]->mType != TermTypes::Op)
brack1->mTerms.push_back(Div(terms[i], HCF_all)[0]);
@ -493,7 +501,7 @@ vector<Term*> QMEvalHelper::FactorizeTermsToBrack(vector<Term*> terms, vector<Te
// make second bracket
Bracket* brack2 = new Bracket();
brack2->setConstant(HCF_all);
brack2->mConstant = HCF_all;
for (int i = 0; i < terms2.size(); i++)
if (terms2[i]->mType != TermTypes::Op)
brack2->mTerms.push_back(Div(terms2[i], HCF_all)[0]);
@ -510,7 +518,7 @@ vector<Term*> QMEvalHelper::FactorizeTermsToBrack(vector<Term*> allTerms) {
// make bracket
Bracket* brack = new Bracket();
brack->setConstant(HCF_all);
brack->mConstant = HCF_all;
for (int i = 0; i < allTerms.size(); i++)
if (allTerms[i]->mType != TermTypes::Op)
brack->mTerms.push_back(Div(allTerms[i], HCF_all)[0]);
@ -582,16 +590,16 @@ vector<Term*> QMEvalHelper::Div(Term * t1, Term * t2, Identifier_t order) {
if (TermsMatch(fraction_nomin->mTerms, fraction_domin->mTerms))
// common bracket terms matched
// TIME FOR RECURSION!
return Div(fraction_nomin->GetConstant(), fraction_domin->GetConstant());
return Div(fraction_nomin->mConstant, fraction_domin->mConstant);
// check if taking out common factors make common bracket coeffiecient
auto fraction = FactorizeTermsToBrack(t1_brack->mTerms, t2_brack->mTerms);
// fraction[0] is nomin
// fraction[1] is domin
fraction_nomin = convertToBracket(fraction[0]);
fraction_nomin->setConstant(nullptr); // Nullptr == 1
fraction_nomin->mConstant = nullptr; // Nullptr == 1
fraction_domin = convertToBracket(fraction[1]);
fraction_domin->setConstant(nullptr); // Nullptr == 1
fraction_domin->mConstant = nullptr; // Nullptr == 1
vector<Term*> res;
for (int i = 0; i < fraction_nomin->mTerms.size(); i++)
@ -649,7 +657,7 @@ vector<Term*> QMEvalHelper::Div(Term * t1, Term * t2, Identifier_t order) {
auto fraction = FactorizeTermsToBrack({ t1 }, t2_Brack->mTerms);
auto comfac = convertToBracket(fraction[0])->GetConstant();
auto comfac = convertToBracket(fraction[0])->mConstant;
vector<Term*> res;
for (auto *term : convertToBracket(fraction[0])->mTerms)

View File

@ -1,5 +1,5 @@
#ifndef QMREDUCER_H
#define QMREDUCER_H
#ifndef QMEVAL_HELPER_H
#define QMEVAL_HELPER_H
#pragma once
// WARINING: Only one variable is allowed or errors will happen!

View File

@ -19,7 +19,7 @@
#include "ds/ExprTree.h"
#include "ds/TermPool.h"
TermPool mPool;
static TermPool mPool;
static vector<Term*> solveNode(TreeNode * node) {
if (node->_term->mType != TermTypes::Op) return { node->_term };

View File

@ -13,7 +13,7 @@
#include "../../../tokenizer.h"
#include "../../../../vendor/lexertk.hpp"
#include "../QMReducerHelper.h"
#include "../QMEvalHelper.h"
#include "TermPool.h"
struct TreeNode {

View File

@ -20,12 +20,8 @@ public:
}
vector<Term*> mTerms;
Term *mConstant = nullptr; // Nullptr == 1
void setConstant(Term* constant) {
mConstant = constant;
}
Term* GetConstant() const { return mConstant; }
string to_str() override {
string str;
@ -33,12 +29,13 @@ public:
if (mConstant != nullptr)
str.append(mConstant->to_str());
str.append("(");
for (int i = 0; i < mTerms.size(); i++)
str.append(mTerms[i]->to_str());
str.append(")");
return str;
}
private:
Term *mConstant = nullptr; // Nullptr == 1
};
#endif // !BRACKET_H

View File

@ -0,0 +1,25 @@
#ifndef BUNDLE_H
#pragma once
#include "../defines.h"
#include "Term.h"
using namespace std;
// An Abstract term for representing bundles of terms
// Ex: 2x/4x
class Bundle : public Term {
public:
Bundle() : Term() { mType = TermTypes::Bund; }
Bundle(vector<Term*> terms) : Term() { mType = TermTypes::Bund; mTerms = terms; }
string to_str() override {
string str;
for (int i = 0; i < mTerms.size(); i++)
str.append(mTerms[i]->to_str());
return str;
}
vector<Term*> mTerms;
};
#endif // !BUNDLE_H

View File

@ -14,7 +14,9 @@ public:
mPower = pwr;
}
virtual string to_str() { return "TERM_UNKNOWN"; };
virtual string to_str() {
return "TERM_UNKNOWN";
};
NValue mValue = DEF_N;
CValue mVariable = DEF_C;

View File

@ -114,7 +114,7 @@ static Bracket* tokenize_bracket(lexertk::generator gen, Token* token, string co
if (coefficient != "") {
lexertk::generator lex;
lex.process(coefficient);
result->setConstant(tokenize(lex)[0]);
result->mConstant = tokenize(lex)[0];
}
return result;
}
@ -136,9 +136,9 @@ static vector<Term*> combineBrackets(vector<Term*> terms) {
// if so combine the terms
Bracket* brack = new Bracket();
brack->mTerms = static_cast<Bracket*>(terms[i + 2])->mTerms;
auto constant = static_cast<Bracket*>(terms[i + 2])->GetConstant();
auto constant = static_cast<Bracket*>(terms[i + 2])->mConstant;
constant->mValue *= (term->mOperator == '+') ? +1 : -1;
brack->setConstant(constant);
brack->mConstant = constant;
result.push_back(brack);
i += 2;
continue;
@ -149,9 +149,17 @@ static vector<Term*> combineBrackets(vector<Term*> terms) {
// if so combine the terms
Bracket* brack = new Bracket();
brack->mTerms = static_cast<Bracket*>(terms[i + 1])->mTerms;
auto constant = static_cast<Bracket*>(terms[i + 1])->GetConstant();
constant->mValue *= (term->mOperator == '+') ? +1 : -1;
brack->setConstant(constant);
auto constant = static_cast<Bracket*>(terms[i + 1])->mConstant;
if (constant == nullptr) { // 1
Constant* Const = new Constant();
if (term->mOperator == '+')
Const->mValue = 1;
else Const->mValue = -1;
}
else {
constant->mValue *= (term->mOperator == '+') ? +1 : -1;
brack->mConstant = constant;
}
result.push_back(brack);
i += 1;
continue;

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,19 @@
 QMReducerHelper.cpp
r:\projects\quicmaf\quicmaf\maths\terms\term.h(10): warning C4309: 'default argument': truncation of constant value
r:\projects\quicmaf\quicmaf\maths\terms\term.h(22): warning C4305: 'initializing': truncation from 'int' to 'CValue'
r:\projects\quicmaf\quicmaf\maths\terms\term.h(22): warning C4309: 'initializing': truncation of constant value
r:\projects\quicmaf\quicmaf\maths\terms\term.h(24): warning C4305: 'initializing': truncation from 'int' to 'CValue'
r:\projects\quicmaf\quicmaf\maths\terms\term.h(24): warning C4309: 'initializing': truncation of constant value
r:\projects\quicmaf\quicmaf\maths\terms\variable.h(11): warning C4309: 'default argument': truncation of constant value
r:\projects\quicmaf\quicmaf\maths\tokenizer.h(99): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
r:\projects\quicmaf\quicmaf\maths\solver\term_rewriter\qmruleset.h(34): warning C4267: 'return': conversion from 'size_t' to 'int', possible loss of data
r:\projects\quicmaf\quicmaf\maths\solver\term_rewriter\qmreducerhelper.cpp(445): warning C4244: 'argument': conversion from 'NValue' to 'int', possible loss of data
r:\projects\quicmaf\quicmaf\maths\solver\term_rewriter\qmreducerhelper.cpp(453): warning C4244: 'argument': conversion from 'NValue' to 'int', possible loss of data
r:\projects\quicmaf\quicmaf\maths\solver\term_rewriter\qmreducerhelper.cpp(464): warning C4244: 'argument': conversion from 'NValue' to 'int', possible loss of data
r:\projects\quicmaf\quicmaf\maths\solver\term_rewriter\qmreducerhelper.cpp(472): warning C4244: 'argument': conversion from 'NValue' to 'int', possible loss of data
Generating code
2 of 790 functions ( 0.3%) were compiled, the rest were copied from previous compilation.
0 functions were new in current compilation
1 functions had inline decision re-evaluated but remain unchanged
Finished generating code
QuicMaf.vcxproj -> R:\Projects\QuicMaf\x64\Release\QuicMaf.exe

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,2 @@
#TargetFrameworkVersion=v4.0:PlatformToolSet=v141:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit:WindowsTargetPlatformVersion=10.0.17763.0
Release|x64|R:\Projects\QuicMaf\|

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
QuicMaf/x64/Release/app.obj Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
x64/Release/QuicMaf.exe Normal file

Binary file not shown.

BIN
x64/Release/QuicMaf.iobj Normal file

Binary file not shown.

BIN
x64/Release/QuicMaf.ipdb Normal file

Binary file not shown.

BIN
x64/Release/QuicMaf.pdb Normal file

Binary file not shown.