使用C / C ++实现de morgan的法律实现

时间:2013-12-26 08:59:40

标签: c++ c demorgans-law

  • 表达式1:(A和B或(不是C))

  • 表达式2:不是((不是A)或(不是B)和C)

我想将表达式2更改为expression1。所以表达式可以表示为如下图所示的树。这意味着“不”操作只能存在于叶节点中。

enter image description here

转换基于De Morgan's Law

以下是我的问题:

是否有C / C ++库实现此功能?我对C / C ++库知之甚少。我搜索了GMPhttp://mathworld.wolfram.com/但未找到解决方案。

谢谢!

1 个答案:

答案 0 :(得分:3)

当你以递归方式思考时,规则很简单:

  • not (X and Y) ==> (not X) or (not Y)
  • not (X or Y) ==> (not X) and (not Y)

所以在C ++中:

struct Node {
    virtual ~Node() {};
    virtual Node *copy() = 0;
    virtual Node *negation() = 0;

private:
    // Taboo
    Node(const Node&);
    Node& operator=(const Node&);
};

struct AndNode : Node {
    Node *left, *right;
    AndNode(Node *left, Node *right) : left(left), right(right) {}
    ~AndNode() { delete left; delete right; }
    Node *copy() { return new AndNode(left->copy(), right->copy()); }
    Node *negation();
};

struct OrNode : Node {
    Node *left, *right;
    OrNode(Node *left, Node *right) : left(left), right(right) {}
    ~OrNode() { delete left; delete right; }
    Node *copy() { return new OrNode(left->copy(), right->copy()); }
    Node *negation();
};

struct NotNode : Node {
    Node *x;
    NotNode(Node *x) : x(x) {}
    ~NotNode() { delete x; }
    Node *copy() { return new NotNode(x->copy()); }
    Node *negation();
};

struct VarNode : Node {
    std::string var;
    VarNode(const std::string& var) : var(var) {}
    Node *copy() { return new VarNode(var); }
};

negationand操作的or代码仅适用于De Morgan的法律,因此"推动"树下的否定

Node *AndNode::negation() {
    return new OrNode(left->negation(), right->negation());
}

Node *OrNode::negation() {
    return new AndNode(left->negation(), right->negation());
}

取而代之的是否定的简化

Node *NotNode::negation() {
    return x->copy();
}

只有叶子节点实际包含在否定操作中

Node *VarNode::negation() {
    return new NotNode(this->copy());
}

正如您所看到的,摩根定律只有两行,其他一切就是如何用C ++表示表达式树。拥有一个实现De Morgan变换的库是没有意义的,因为一旦你有了代表,它就是绝对无足轻重的。

使用包装器实现不同树表示的实现将是99%的样板和接口代码,以实现双线(完全无意义)。

只需使用您拥有的任何树形象直接实现它。