符号+逻辑模块:assert(is_cnf(to_cnf(expr,simple = True)))失败

问题描述 投票:0回答:1

我正在尝试使用sympy来帮助我解析一些与逻辑相关的文本文件(在进行额外的字符串处理之后:例如,生成像x0, x1...这样的numbered x-vars,)并且我不理解以下行为:

in_ = '( ( x1 & x2 & x3 & x4 & x5 & x6 & x7 & x8 & x9 )  |  ( x1 & x2 & x3 & x4 & x5 & x6 & x7 & x10 & x9 )  |  ( x1 & x11 & x3 & x12 & x5 & x13 & x14 & x15 & x9 ) ) '

from sympy.parsing.sympy_parser import parse_expr
from sympy.logic.boolalg import to_cnf, is_cnf

parsed = parse_expr(in_, evaluate=False)
cnf_candidate = to_cnf(parsed, simplify=True)  # broken with simp=True; works with simp=False
cnf_status = is_cnf(cnf_candidate)

print(parsed)
print(cnf_candidate)
print(cnf_status)

assert cnf_status 

> (x1 & x10 & x2 & x3 & x4 & x5 & x6 & x7 & x9) | (x1 & x11 & x12 & x13 & x14 & x15 & x3 & x5 & x9) 
(x1 & x2 & x3 & x4 & x5 & x6 & x7 & x8 & x9)

> (x1 & x10 & x2 & x3 & x4 & x5 & x6 & x7 & x9) | (x1 & x11 & x12 & x13 & x14 & x15 & x3 & x5 & x9) | 
(x1 & x2 & x3 & x4 & x5 & x6 & x7 & x8 & x9)

> False
> AssertionError

这看起来真糟糕!

  • [to_cnf不会真正产生cnf,也不会警告我(使用simplify=True)。

没有简化:

  • 它起作用,并且输出显示预期的指数爆炸

这看起来有点像“我将永远无法将其最小化,所以我不会尝试”没有任何反馈

我想念什么吗?我的用法是否正确(我假设sympys解析能够与我的编号变量一起使用)。

((现在让我们忽略更多理论上的方面->指数爆炸;简化的可行性)

python sympy boolean-logic
1个回答
0
投票

带有to_cnfsimplify=True功能在不通过simplify_logic标志设置的情况下调用force=True。由于该表达式具有8个以上的变量,因此不会尝试转换为cnf,并且例程不会检查简化结果是否为cnf形式。一个简单的补丁是

diff --git a/sympy/logic/boolalg.py b/sympy/logic/boolalg.py
index dd734ce..d544ea7 100644
--- a/sympy/logic/boolalg.py
+++ b/sympy/logic/boolalg.py
@@ -1714,7 +1714,9 @@ def to_cnf(expr, simplify=False):
         return expr

     if simplify:
-        return simplify_logic(expr, 'cnf', True)
+        new = simplify_logic(expr, 'cnf', True)
+        if is_cnf(new):
+            return new

     # Don't convert unless we have to
     if is_cnf(expr):

然后(如果要尝试简化结果,则必须用simplify_logic调用force=True

© www.soinside.com 2019 - 2024. All rights reserved.