Algorithm 在哪里可以找到将任意布尔表达式转换为合取或析取范式的方法?

Algorithm 在哪里可以找到将任意布尔表达式转换为合取或析取范式的方法?,algorithm,query-optimization,boolean-expression,Algorithm,Query Optimization,Boolean Expression,我已经编写了将表达式解析为抽象语法树的程序。现在,为了决定如何最好地计算查询,我对表达式使用了一系列启发式方法。不幸的是,有一些例子使得查询计划非常糟糕 我已经找到了一种可以证明的方法,可以更好地猜测应该如何计算查询,但是我需要首先将我的表达式放入CNF或DNF中,以便得到可以证明正确的答案。我知道这可能会导致时间和空间呈指数级增长,但对于我的用户运行的典型查询来说,这不是问题 现在,转换成CNF或DNF是我一直手工做的事情,目的是简化复杂的表达式。(好吧,也许不是一直都是这样,但我确实知道如何

我已经编写了将表达式解析为抽象语法树的程序。现在,为了决定如何最好地计算查询,我对表达式使用了一系列启发式方法。不幸的是,有一些例子使得查询计划非常糟糕

我已经找到了一种可以证明的方法,可以更好地猜测应该如何计算查询,但是我需要首先将我的表达式放入CNF或DNF中,以便得到可以证明正确的答案。我知道这可能会导致时间和空间呈指数级增长,但对于我的用户运行的典型查询来说,这不是问题

现在,转换成CNF或DNF是我一直手工做的事情,目的是简化复杂的表达式。(好吧,也许不是一直都是这样,但我确实知道如何使用demorgan定律、分配定律等)然而,我不确定如何开始将其转化为一种可作为算法实现的方法。我看过一些关于查询优化的论文,其中有几篇是从“首先我们把东西放进CNF”或“首先我们把东西放进DNF”开始的,他们似乎从来没有解释过他们实现这一点的方法


我应该从哪里开始?

对于无量词公式,朴素的香草算法是:

  • 对于CNF,转换为符合De Morgan法律的,然后分发或超过
  • 对于DNF,使用De Morgan laws将转换为,然后分发并覆盖或
我不清楚你的公式是否是量化的。但即使不是这样,维基百科的文章似乎也就到此结束了,它——在自动定理证明者的世界中大致相当——AlterEgo勾勒出了一个可用的算法(如果你想让这个转换更聪明一些,请指向参考文献)。如果您需要更多信息,请告诉我们您在哪里遇到了困难。

查看 例如:

def测试(自身): expr=parse(“a*(b+~c*d)”) 打印(expr) dnf_expr=规格化(boolean.OR,expr) 打印(列表(地图(str、dnf_expr))) cnf_expr=规格化(布尔型与,expr) 打印(列表(地图(str、cnf_expr))) 输出为:

a*(b+(~c*d))
['a*b', 'a*~c*d']
['a', 'b+~c', 'b+d']
更新:现在我更喜欢这样:

>>从sympy.logic.boolalg导入到\u dnf
>>>从sympy.abc进口A、B、C
>>>至(B及(A | C))
或(及(A,B)及(B,C))
>>>to|dnf((A&B)|(A&B)|(B&C)|(~B&C),正确)
或(A,C)

我看到了这个页面:。它显示了在伪代码中将布尔表达式转换为CNF的算法。帮助我开始这个话题。

这就足够让我开始了。谢谢:)当存在多个术语(例如多个嵌套的AND和OR级别以及多个变量)时,有没有关于“分布或覆盖AND”的方法的指针?@Jamie:你需要递归地为每一对生成一个乘法。这和挫败没有什么不同:)。在最坏的情况下,这需要指数时间。(转换为CNF或DNF是原始NP完全问题的核心,可满足性)该站点已被删除,这是一个存档: