Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;表达式树遍历以将表达式就地更改为NNF_C++_Recursion - Fatal编程技术网

C++ C++;表达式树遍历以将表达式就地更改为NNF

C++ C++;表达式树遍历以将表达式就地更改为NNF,c++,recursion,C++,Recursion,我想把一个表达式转换成否定范式。为此,我有一个使用智能指针的二进制表达式树。问题是,尽管函数removeDoubleNot()在正确的时间被调用,但当双否定出现在二进制表达式中时,删除双否定不起作用。因此,例如:(A)∨-B)成为-A∧B而不是A∧B、 但它只在B上起作用。我假设错误在evaluate()中,但我还没有找到它。也许递归是错误的 // It is assumed that all Expressions are valid std::shared_ptr<Expression

我想把一个表达式转换成否定范式。为此,我有一个使用智能指针的二进制表达式树。问题是,尽管函数
removeDoubleNot()
在正确的时间被调用,但当双否定出现在二进制表达式中时,删除双否定不起作用。因此,例如:(A)∨-B)成为-A∧B而不是A∧B、 但它只在B上起作用。我假设错误在
evaluate()
中,但我还没有找到它。也许递归是错误的

// It is assumed that all Expressions are valid
std::shared_ptr<Expression> NNF::removeDoubleNot(std::shared_ptr<Not> expr) {
    // Left is a Not -> remove both Nots
    if (auto node = dynamic_cast<Not *>(expr->getLeft().get()))
        return node->getLeft();
    return expr;
}

std::shared_ptr<Expression> NNF::applyDeMorgan(std::shared_ptr<Not> expr) {
    // And
    if (auto node = dynamic_cast<And *>(expr->getLeft().get())) {
        auto newLeft = std::make_shared<Not>(node->getLeft());
        auto newRight = std::make_shared<Not>(node->getRight());
        return std::make_shared<Or>(newLeft, newRight);
    }
    // Or
    if (auto node = dynamic_cast<Or *>(expr->getLeft().get())) {
        auto newLeft = std::make_shared<Not>(node->getLeft());
        auto newRight = std::make_shared<Not>(node->getRight());
        return std::make_shared<And>(newLeft, newRight);
    }
    return expr;
}

std::shared_ptr<Expression> NNF::removeImplication(const std::shared_ptr<Implication> &expr) {
    auto newLeft = std::make_shared<Not>(expr->getLeft());
    auto newRight = expr->getRight();
    return std::make_shared<Or>(newLeft, newRight);
}

std::shared_ptr<Expression> NNF::moveNegationInwards(const std::shared_ptr<Not> &notExpr) {     
    expr = applyDeMorgan(node);
    if (auto node = std::dynamic_pointer_cast<Not>(expr))
        expr = removeDoubleNot(node);
    return expr;
}

std::shared_ptr<Expression> NNF::evaluate(std::shared_ptr<Expression> expr) {
    if (expr == nullptr)
        return nullptr;
    // Implication
    if(auto node = std::dynamic_pointer_cast<Implication>(expr)){
        auto ret = removeImplication(node);
        evaluate(ret->getLeft());
        evaluate(ret->getRight());
        return ret;
    }
    // Other binary than implication
    if(auto node = dynamic_cast<Binary*>(expr.get())){
        evaluate(node->getLeft());
        evaluate(node->getRight());
        return expr;
    }
    // Not
    if(auto node = std::dynamic_pointer_cast<Not>(expr)) {
        auto ret =  moveNegationInwards(node);
        evaluate(ret->getLeft());
        evaluate(ret->getRight());
        return ret;
    }
    return expr;
}

//假定所有表达式都有效
std::shared_ptr NNF::removeDoubleNot(std::shared_ptr expr){
//左为非->删除两个非
if(auto node=dynamic_cast(expr->getLeft().get()))
返回节点->getLeft();
返回表达式;
}
std::shared_ptr NNF::applyDeMorgan(std::shared_ptr expr){
//及
if(auto node=dynamic_cast(expr->getLeft().get())){
auto newLeft=std::make_shared(节点->getLeft());
auto newRight=std::make_shared(node->getRight());
return std::make_shared(newLeft,newRight);
}
//或
if(auto node=dynamic_cast(expr->getLeft().get())){
auto newLeft=std::make_shared(节点->getLeft());
auto newRight=std::make_shared(node->getRight());
return std::make_shared(newLeft,newRight);
}
返回表达式;
}
std::shared_ptr NNF::removemplication(const std::shared_ptr&expr){
auto newLeft=std::make_shared(expr->getLeft());
auto newRight=expr->getRight();
return std::make_shared(newLeft,newRight);
}
std::shared\u ptr NNF::movenegationwards(const std::shared\u ptr¬Expr){
expr=applyDeMorgan(节点);
if(自动节点=标准::动态指针转换(expr))
expr=removeDoubleNot(节点);
返回表达式;
}
std::shared\u ptr NNF::evaluate(std::shared\u ptr expr){
如果(expr==nullptr)
返回空ptr;
//暗示
if(自动节点=标准::动态指针转换(expr)){
auto-ret=重新建模(节点);
评估(ret->getLeft());
评估(ret->getRight());
返回ret;
}
//非蕴涵
if(auto node=dynamic_cast(expr.get())){
评估(node->getLeft());
评估(节点->获取权限());
返回表达式;
}
//不是
if(自动节点=标准::动态指针转换(expr)){
自动返回=向上移动(节点);
评估(ret->getLeft());
评估(ret->getRight());
返回ret;
}
返回表达式;
}

当您调用
evaluate(ret->getLeft())
时,您没有使用返回值,因此您永远不会更改当前的子表达式。 因此,您需要将其更改为:

ret->setLeft(evaluate(ret->getLeft()));
右翼也是如此


您可能想考虑在这样的错误中使用编译器警告。

看来,在<代码> Apple DeMeung<代码>中,您应该执行<代码> AutoNeLeLe= ReaveDouBeLeNoOT(STD::MaxAyStand(节点-> GETFELT()));代码>,以及类似的其他计算。@cigien所说的适用于您所否定的每个子表达式。