#include <iostream>
#include <string>
#include <map>
#include <memory>
#include <stdexcept>
class Context {
std::map<std::string, bool> variables;
public:
void assign(const std::string& var, bool value) {
variables[var] = value;
}
bool lookup(const std::string& var) const {
auto it = variables.find(var);
if (it != variables.end())
return it->second;
throw std::runtime_error("Undefined variable: " + var);
}
};
class BooleanExp {
public:
virtual ~BooleanExp() = default;
virtual bool evaluate(Context& ctx) = 0;
};
class VariableExp : public BooleanExp {
std::string name;
public:
explicit VariableExp(const std::string& name) : name(name) {}
bool evaluate(Context& ctx) override {
return ctx.lookup(name);
}
};
class AndExp : public BooleanExp {
std::shared_ptr<BooleanExp> left, right;
public:
AndExp(std::shared_ptr<BooleanExp> l, std::shared_ptr<BooleanExp> r)
: left(std::move(l)), right(std::move(r)) {}
bool evaluate(Context& ctx) override {
return left->evaluate(ctx) && right->evaluate(ctx);
}
};
class OrExp : public BooleanExp {
std::shared_ptr<BooleanExp> left, right;
public:
OrExp(std::shared_ptr<BooleanExp> l, std::shared_ptr<BooleanExp> r)
: left(std::move(l)), right(std::move(r)) {}
bool evaluate(Context& ctx) override {
return left->evaluate(ctx) || right->evaluate(ctx);
}
};
class NotExp : public BooleanExp {
std::shared_ptr<BooleanExp> operand;
public:
explicit NotExp(std::shared_ptr<BooleanExp> op)
: operand(std::move(op)) {}
bool evaluate(Context& ctx) override {
return !operand->evaluate(ctx);
}
};
int main() {
auto x = std::make_shared<VariableExp>("x");
auto y = std::make_shared<VariableExp>("y");
auto z = std::make_shared<VariableExp>("z");
auto notZ = std::make_shared<NotExp>(z);
auto xAndy = std::make_shared<AndExp>(x, y);
auto expr = std::make_shared<OrExp>(xAndy, notZ);
Context ctx;
ctx.assign("x", false);
ctx.assign("y", true);
ctx.assign("z", true);
std::cout << std::boolalpha;
std::cout << "Expression: (x AND y) OR (NOT z)\n\n";
bool result = expr->evaluate(ctx);
std::cout << "When x=false, y=true, z=true => " << result << "\n";
ctx.assign("x", true);
result = expr->evaluate(ctx);
std::cout << "When x=true, y=true, z=true => " << result << "\n";
ctx.assign("z", false);
result = expr->evaluate(ctx);
std::cout << "When x=true, y=true, z=false => " << result << "\n";
return 0;
}