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

发布于 2024-12-13 10:14:10 字数 500 浏览 0 评论 0原文

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

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

现在,为了简化复杂的表达式,我一直手动转换为 CNF 或 DNF。 (好吧,也许不是一直,但我确实知道如何使用例如德摩根定律、分配定律等来实现这一点。)但是,我不确定如何开始将其转化为一种方法可以作为算法实现。我看过有关查询优化的论文,其中有几篇以“首先我们将内容放入 CNF”或“首先我们将内容放入 DNF”开头,但他们似乎从未解释过实现这一目标的方法。

我应该从哪里开始?

I've written a little app that parses expressions into abstract syntax trees. Right now, I use a bunch of heuristics against the expression in order to decide how to best evaluate the query. Unfortunately, there are examples which make the query plan extremely bad.

I've found a way to provably make better guesses as to how queries should be evaluated, but I need to put my expression into CNF or DNF first in order to get provably correct answers. I know this could result in potentially exponential time and space, but for typical queries my users run this is not a problem.

Now, converting to CNF or DNF is something I do by hand all the time in order to simplify complicated expressions. (Well, maybe not all the time, but I do know how that's done using e.g. demorgan's laws, distributive laws, etc.) However, I'm not sure how to begin translating that into a method that is implementable as an algorithm. I've looked at papers on query optimization, and several start with "well first we put things into CNF" or "first we put things into DNF", and they never seem to explain their method for accomplishing that.

Where should I start?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

路还长,别太狂 2024-12-20 10:14:10

看看 https://github.com/bastikr/boolean.py
示例:

def test(self):
    expr = parse("a*(b+~c*d)")
    print(expr)

    dnf_expr = normalize(boolean.OR, expr)
    print(list(map(str, dnf_expr)))

    cnf_expr = normalize(boolean.AND, expr)
    print(list(map(str, cnf_expr)))

输出为:

a*(b+(~c*d))
['a*b', 'a*~c*d']
['a', 'b+~c', 'b+d']

更新:现在我更喜欢这个 sympy 逻辑包

>>> from sympy.logic.boolalg import to_dnf
>>> from sympy.abc import A, B, C
>>> to_dnf(B & (A | C))
Or(And(A, B), And(B, C))
>>> to_dnf((A & B) | (A & ~B) | (B & C) | (~B & C), True)
Or(A, C)

Look at https://github.com/bastikr/boolean.py
Example:

def test(self):
    expr = parse("a*(b+~c*d)")
    print(expr)

    dnf_expr = normalize(boolean.OR, expr)
    print(list(map(str, dnf_expr)))

    cnf_expr = normalize(boolean.AND, expr)
    print(list(map(str, cnf_expr)))

Output is:

a*(b+(~c*d))
['a*b', 'a*~c*d']
['a', 'b+~c', 'b+d']

UPDATE: Now I prefer this sympy logic package:

>>> from sympy.logic.boolalg import to_dnf
>>> from sympy.abc import A, B, C
>>> to_dnf(B & (A | C))
Or(And(A, B), And(B, C))
>>> to_dnf((A & B) | (A & ~B) | (B & C) | (~B & C), True)
Or(A, C)
年华零落成诗 2024-12-20 10:14:10

对于无量词公式,朴素的普通算法是:

我不清楚你的公式是否被量化。但即使它们不是,维基百科关于合取范式<的文章似乎已经结束/a>,及其 - 在自动定理证明世界中大致等效 - 子句范式 改变自我概述了一个可用的算法(如果你想进行这种转换,请指出参考文献更聪明一点)。如果您需要更多,请告诉我们更多有关您遇到困难的地方。

The naive vanilla algorithm, for quantifier-free formulae, is :

It's unclear to me if your formulae are quantified. But even if they aren't, it seems the end of the wikipedia articles on conjunctive normal form, and its - roughly equivalent in the automated theorm prover world - clausal normal form alter ego outline a usable algorithm (and point to references if you want to make this transformation a bit more clever). If you need more than that, please do tell us more about where you encounter a difficulty.

空城旧梦 2024-12-20 10:14:10

我遇到过这个页面:如何将公式转换为 CNF。它以伪代码形式展示了将布尔表达式转换为 CNF 的算法。帮助我开始了解这个主题。

I've came across this page: How to Convert a Formula to CNF. It shows the algorithm to convert a Boolean expression to CNF in pseudo code. Helped me to get started into this topic.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文