Website Summary Files Commits Branches @commit @diff @stats
path: root / Sem. 15 / ExpessionCalculator
diff options
context:
space:
mode:
Commitf1e6772e0b264388cf96500b75c6ae47272f2238 (patch)
Author
 angeld55 <angel_dimitriev@abv.bg>
2022-06-07 21:18:29 +0300
Committer
 angeld55 <angel_dimitriev@abv.bg>
2022-06-07 21:18:29 +0300
Filesba30e9f48d807ad1478ab985bc4e8781f2bf3341 /Sem. 15/ExpessionCalculator
Object-oriented_programming_FMI-f1e6772e0b264388cf96500b75c6ae47272f2238.tar
Object-oriented_programming_FMI-f1e6772e0b264388cf96500b75c6ae47272f2238.tar.gz
Object-oriented_programming_FMI-f1e6772e0b264388cf96500b75c6ae47272f2238.zip
Parent30601882aa51c1c6aa646c3bb6001f2c848adde7 (diff)
sem 15
2 files changed, 272 insertions, 0 deletions
-rw-r--r--Sem. 15/ExpessionCalculator/ExpressionCalculator.cpp77
-rw-r--r--Sem. 15/ExpessionCalculator/ExpressionCalculator.h195
diff --git a/Sem. 15/ExpessionCalculator/ExpressionCalculator.cpp b/Sem. 15/ExpessionCalculator/ExpressionCalculator.cpp
new file mode 100644
index 0000000..86c68c8
--- /dev/null
+++ b/Sem. 15/ExpessionCalculator/ExpressionCalculator.cpp
@@ -0,0 +1,77 @@
+#include "ExpressionCalculator.h"
+
+void ExpressionCalculator::copyFrom(const ExpressionCalculator& other)
+{
+ expr = other.expr->clone();
+}
+
+void ExpressionCalculator::free()
+{
+ delete expr;
+}
+
+bool isOperator(char ch)
+{
+ return ch == AND || ch == OR || ch == IFF || ch == IMPL || ch == XOR || ch == NEG;
+}
+
+ExpressionCalculator::BooleanExpr* parse(const MyString& str)
+{
+
+ if (str.getSize() == 1)
+ {
+ return new ExpressionCalculator::Variable(str[0]);
+ }
+
+ MyString strWithoutBrackets = str.subString(1, str.getSize() - 2); //We remove the brackets.
+
+
+ int countBrackets = 0;
+ for (size_t i = 0; i < strWithoutBrackets.getSize(); i++) //we start searching for the operation.
+ { // then we split to two expressions
+ if (strWithoutBrackets[i] == '(')
+ countBrackets++;
+ else if (strWithoutBrackets[i] == ')')
+ countBrackets--;
+ else if (isOperator(strWithoutBrackets[i]) && countBrackets == 0)
+ {
+ if (strWithoutBrackets[i] == NEG)
+ return new ExpressionCalculator::UnaryOperation('!', parse(strWithoutBrackets.subString(i + 1, strWithoutBrackets.getSize() - 1)));
+ else
+ return new ExpressionCalculator::BinaryOperation(parse(strWithoutBrackets.subString(0, i - 1)), strWithoutBrackets[i], parse(strWithoutBrackets.subString(i+1, strWithoutBrackets.getSize() - 1)));
+ }
+
+ }
+}
+
+ExpressionCalculator::ExpressionCalculator(const MyString& str)
+{
+ expr = parse(str);
+
+}
+ExpressionCalculator::ExpressionCalculator(const ExpressionCalculator& other)
+{
+ copyFrom(other);
+}
+ExpressionCalculator& ExpressionCalculator::operator=(const ExpressionCalculator& other)
+{
+ if (this != &other)
+ {
+ free();
+ copyFrom(other);
+ }
+ return *this;
+}
+ExpressionCalculator::~ExpressionCalculator()
+{
+ free();
+}
+
+bool ExpressionCalculator::isTautology() const
+{
+ return checkAll(expr, true);
+}
+bool ExpressionCalculator::isContradiction() const
+{
+ return checkAll(expr, false);
+} \ No newline at end of file
diff --git a/Sem. 15/ExpessionCalculator/ExpressionCalculator.h b/Sem. 15/ExpessionCalculator/ExpressionCalculator.h
new file mode 100644
index 0000000..eb21a99
--- /dev/null
+++ b/Sem. 15/ExpessionCalculator/ExpressionCalculator.h
@@ -0,0 +1,195 @@
+#include <iostream>
+#include <exception>
+#include "../MyString/MyString.h"
+
+const char AND = '^';
+const char OR = 'v';
+const char IMPL = '>'; //=>
+const char IFF = '='; // <=>
+const char XOR = '+';
+const char NEG = '!';
+
+class ExpressionCalculator
+{
+
+ class BooleanExpr
+ {
+ public:
+ bool vars[26] = { false };
+ size_t countVars = 0;
+
+
+ struct BooleanInterpretation
+ {
+ bool values[26] = { false };
+ BooleanInterpretation()
+ { }
+ void setValue(char ch, bool value)
+ {
+ if (ch < 'A' || ch > 'Z')
+ throw "error";
+
+ values[ch - 'A'] = value;
+ }
+ bool getValue(char ch) const
+ {
+ if (ch < 'A' || ch > 'Z')
+ throw "error";
+ return values[ch - 'A'];
+ }
+ };
+
+ virtual bool eval(const BooleanInterpretation& interpret) const = 0;
+
+ virtual BooleanExpr* clone() const = 0;
+ virtual ~BooleanExpr() = default;
+
+ };
+ class Variable : public BooleanExpr
+ {
+ char ch;
+ public:
+ Variable(char ch) : ch(ch)
+ {
+ vars[ch - 'A'] = true;
+ countVars = 1;
+ } ///only CAPITALS
+
+ bool eval(const BooleanInterpretation& interpret) const override
+ {
+ return interpret.getValue(ch);
+ }
+ BooleanExpr* clone() const override
+ {
+ return new Variable(*this);
+ }
+
+ };
+
+ class BinaryOperation : public BooleanExpr
+ {
+ BooleanExpr* left;
+ char op;
+ BooleanExpr* right;
+ public:
+ BinaryOperation(BooleanExpr* left, char op, BooleanExpr* right) : left(left), op(op), right(right)
+ {
+ for (int i = 0; i < 26; i++)
+ {
+ vars[i] = left->vars[i] || right->vars[i];
+ if (vars[i])
+ countVars++;
+
+ }
+ }
+
+ bool eval(const BooleanInterpretation& interpret) const override
+ {
+
+ switch (op)
+ {
+ case 'v': return left->eval(interpret) || right->eval(interpret);
+ case '^': return left->eval(interpret) && right->eval(interpret);
+ default: return false;
+ break;
+ }
+ }
+
+ BooleanExpr* clone() const override
+ {
+ return new BinaryOperation(left->clone(), op, right->clone());
+ }
+
+
+
+ ~BinaryOperation()
+ {
+ delete left;
+ delete right;
+ }
+ };
+
+ class UnaryOperation : public BooleanExpr
+ {
+ char ch; //!
+ BooleanExpr* expr;
+
+ public:
+ UnaryOperation(char ch, BooleanExpr* expr) : ch(ch), expr(expr)
+ {
+ for (int i = 0; i < 26; i++)
+ {
+ vars[i] = expr->vars[i];
+ if (vars[i])
+ countVars++;
+ }
+ }
+
+ BooleanExpr* clone() const override
+ {
+ return new UnaryOperation(ch, expr->clone());
+ }
+
+ bool eval(const BooleanInterpretation& interpret) const
+ {
+ if (ch == '!')
+ {
+ return !expr->eval(interpret);
+ }
+ else
+ {
+ //
+ return false;
+ }
+ }
+ ~UnaryOperation()
+ {
+ delete expr;
+ }
+ };
+
+ BooleanExpr::BooleanInterpretation convert(size_t number, bool vars[26]) const
+ {
+ BooleanExpr::BooleanInterpretation inter;
+
+ for (int i = 25; i >= 0; i--)
+ {
+ if (vars[i])
+ {
+ if (number % 2 == 1)
+ inter.setValue('A' + i, 1);
+ number /= 2;
+ }
+ }
+ return inter;
+ }
+
+ bool checkAll(BooleanExpr* expr, bool value) const
+ {
+ size_t varsCount = expr->countVars;
+ size_t intersCount = 1 << varsCount; ///!!!!! 2^varsCount
+
+ for (int i = 0; i < intersCount; i++)
+ {
+ if (expr->eval(convert(i, expr->vars)) != value)
+ return false;
+ }
+ return true;
+ }
+
+ BooleanExpr* expr;
+ void copyFrom(const ExpressionCalculator& other);
+ void free();
+
+public:
+ ExpressionCalculator(const MyString& str);
+ ExpressionCalculator(const ExpressionCalculator& other);
+ ExpressionCalculator& operator=(const ExpressionCalculator& other);
+ ~ExpressionCalculator();
+
+ bool isTautology() const;
+ bool isContradiction() const;
+
+ friend ExpressionCalculator::BooleanExpr* parse(const MyString& str);
+
+}; \ No newline at end of file