【问题标题】:Converting an expression to conjunctive normal form with a twist将表达式转换为带有扭曲的合取范式
【发布时间】:2010-10-26 23:36:55
【问题描述】:

我有一个库,我必须与之交互,它基本上充当数据源。检索数据时,我可以将特殊的“过滤器表达式”传递给该库,然后将其转换为 SQL WHERE 部分。这些表达非常有限。它们必须是合取范式。喜欢:

(A or B or C) and (D or E or F) and ...

这当然不适合编程。所以我想制作一个小包装器,它可以解析任意表达式并将它们转换为这种正常形式。喜欢:

(A and (B or C) and D) or E

会被翻译成这样的:

(A or E) and (B or C or E) and (D or E)

我可以使用Irony 库将表达式解析为树。现在我需要对其进行规范化,但我不知道如何...哦,还有,这里是转折点:

  • 最终表达式可能不包含 NOT 运算符。但是,我可以通过将运算符替换为逆运算符来反转各个项。所以,这没关系:

    (not A or not B) AND (not C or not D)

    但这不是:

    not (A or B) and not (C or D)

  • 我想让表达式尽可能简单,因为它会被翻译成几乎相同的 SQL WHERE 语句,因此复杂的语句很可能会降低执行速度。

【问题讨论】:

    标签: expression conjunctive-normal-form


    【解决方案1】:

    我会在树上使用两次迭代,虽然它可能是一次。

    第一次迭代:通过遍历树并使用德摩根定律 (wikipedia link) 去除您的 NOT 节点,并在适用的情况下删除双重否定。

    第二次迭代(NOT 现在只在叶节点之前) 穿过你的树:

    Case "AND NODE":
        fine, inspect the children
    Case "OR NODE":
        if there is a child which is neither a Leaf nor a NOT node
            apply the distributive law.
            start from parent of current node again
        else
            fine, inspect children
    

    之后你应该完成了。

    【讨论】:

    • 呵呵,我自己也快到了。 :)
    猜你喜欢
    • 2014-07-14
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    • 2011-07-07
    相关资源
    最近更新 更多