Sympy 在简化时生成损坏的“分段”条件

我的代码

我在一个更大的程序中有效地减少了以下代码片段:


import sympy as sp

print('sympy version:', sp.__version__)


n = sp.symbols('n', integer=True)

expr = sp.Piecewise((0, sp.Ne(n, 3)), (-1/2, True))*sp.Piecewise((2, sp.Ne(n, 0)), (1, True))


print('raw expression:', expr)

print('simplified expression:', sp.simplify(expr))

对于简化的表达式,我期望相当于:


简化表达式:Piecewise((0, Eq(n, 0)), (-1.0, Eq(n, 3)), (0, True))


(这可能可以进一步简化为只有两个分支,但类似的东西。)


但是,我的实际输出是:


同情版本:1.3


原始表达式:分段((0, Ne(n, 3)), (-0.5, True))*分段((2, Ne(n, 0)), (1, True))


简化表达式:Piecewise((0, Ne(n, 3)), (-1.0, Ne(n, 0)), (-0.5, True))


我的问题

明显的问题是我没有得到我所期望的。但更重要的是,简化后的分段表达式存在明显的逻辑问题;更具体地说,在其中的条件。


第一个条件是Ne(n, 3),意思是“当 n 不等于 3 时将使用第一个值”。靠自己就好了。


但是,第二个条件是Ne(n, 0),根据第一个条件,这是完全无意义的。如果 n 为 0,则第一个条件为真,并且将使用第一个分支值,因此如果正在评估第二个条件,则从逻辑上保证 n 不为 0。


更糟糕的是,最后一个条件是True(即“否则”),如果不满足较早分支的条件,则这是默认条件。然而,逻辑上不可能到达这个分支,因为前两个条件划分了整数的整个空间(并被n定义为整数;但是,当n的数字类型未指定时,也会出现同样的问题)。


(我还想指出,在简化之前,原始 Piecewise 表达式中都不存在此问题。虽然它们确实Ne用于第一个分支条件,但第二个条件是 default True,这是完全有效的。)


我的问题

任何人都可以将其解释为预期行为吗?


如果没有,我计划将此作为错误提交给 SymPy。在发布之前,我确实在 SymPy 问题跟踪器中简要搜索了我的问题,但我没有看到任何与之匹配的内容。我只是想在这里仔细检查一下,我没有先忽略任何东西。


慕标5832272
浏览 195回答 1
1回答

至尊宝的传说

输出没有“损坏”或“无意义”。它在逻辑上是正确的,尽管没有以最简单的形式呈现。条件if n == 3 and n != 0可以简化为if n == 3。“可以简化”和“完全无意义”之间是有区别的。但是是的,请在 SymPy 跟踪器上报告它,因为简化不完整;更好的结果是Piecewise((0, Ne(n, 3)), (-1.0, True))。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python