diff options
sem 15
1 files changed, 195 insertions, 0 deletions
| -rw-r--r-- | Sem. 15/ExpessionCalculator/ExpressionCalculator.h | 195 |
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 |
