自动简化冗余算术关系
Automatically simplify redundant arithmetic relations
我正在寻找一种自动确定 (a < 12) & (a < 3) & (c >= 4)
与 (a < 3) & (c >= 4)
相同的方法。我在 Python 中查看了 Matlab 的符号工具箱和 SymPy,但它们显然只能简化纯布尔逻辑(例如,simplify(a & b | b & a) -> ans=(a & b)
)
有没有办法像上面描述的那样使用这些符号数学工具?
编辑
如对@user12750353 的回答的评论中所述,我还想简化与布尔 OR 连接的关系系统,例如 ((a < 12) & (a < 3) & (c >= 4)) | (a < 1)
.
您可以在 sympy inequality solvers 中查看一些选项。
我可以 reduce_inequalities
解决你的问题
from sympy.abc import a, c
import sympy.solvers.inequalities as neq
t = neq.reduce_inequalities([a < 12, a < 3, c >= 4])
结果
(4 <= c) & (-oo < a) & (a < 3) & (c < oo)
它也适用于一些更复杂的例子
只要每个不等式有一个变量。
SymPy 集可用于进行单变量简化,例如((x < 3) & (x < 5)).as_set() -> Interval.open(-oo, 3)
并且集合可以转换回关系。以下将复杂表达式转换为 cnf 形式,根据自由符号分隔参数并简化单变量参数,同时保持多变量参数不变。
def f(eq):
from collections import defaultdict
from sympy import to_cnf, ordered
cnf = to_cnf(eq)
args = defaultdict(list)
for a in cnf.args:
args[tuple(ordered(a.free_symbols))].append(a)
_args = []
for k in args:
if len(k) == 1:
_args.append(cnf.func(*args[k]).as_set().as_relational(k[0]))
else:
_args.append(cnf.func(*args[k]))
return cnf.func(*_args)
例如:
>>> from sympy.abc import a, c
>>> f((a < 1) | ((c >= 4) & (a < 3) & (a < 12)))
(a < 3) & ((c >= 4) | (a < 1))
我正在寻找一种自动确定 (a < 12) & (a < 3) & (c >= 4)
与 (a < 3) & (c >= 4)
相同的方法。我在 Python 中查看了 Matlab 的符号工具箱和 SymPy,但它们显然只能简化纯布尔逻辑(例如,simplify(a & b | b & a) -> ans=(a & b)
)
有没有办法像上面描述的那样使用这些符号数学工具?
编辑
如对@user12750353 的回答的评论中所述,我还想简化与布尔 OR 连接的关系系统,例如 ((a < 12) & (a < 3) & (c >= 4)) | (a < 1)
.
您可以在 sympy inequality solvers 中查看一些选项。
我可以 reduce_inequalities
解决你的问题
from sympy.abc import a, c
import sympy.solvers.inequalities as neq
t = neq.reduce_inequalities([a < 12, a < 3, c >= 4])
结果
(4 <= c) & (-oo < a) & (a < 3) & (c < oo)
它也适用于一些更复杂的例子
只要每个不等式有一个变量。
SymPy 集可用于进行单变量简化,例如((x < 3) & (x < 5)).as_set() -> Interval.open(-oo, 3)
并且集合可以转换回关系。以下将复杂表达式转换为 cnf 形式,根据自由符号分隔参数并简化单变量参数,同时保持多变量参数不变。
def f(eq):
from collections import defaultdict
from sympy import to_cnf, ordered
cnf = to_cnf(eq)
args = defaultdict(list)
for a in cnf.args:
args[tuple(ordered(a.free_symbols))].append(a)
_args = []
for k in args:
if len(k) == 1:
_args.append(cnf.func(*args[k]).as_set().as_relational(k[0]))
else:
_args.append(cnf.func(*args[k]))
return cnf.func(*_args)
例如:
>>> from sympy.abc import a, c
>>> f((a < 1) | ((c >= 4) & (a < 3) & (a < 12)))
(a < 3) & ((c >= 4) | (a < 1))