You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sympy匹配带括号表达式时如何稳定获取未展开项系数

SymPy Wild通配符匹配系数不稳定问题解决

问题描述

核心需求为提取指定形式不等式的系数,待匹配的目标不等式如下:

parsed_input = 7*x + 4*(10*x + 6) >= 8*x + 15

通过定义Wild通配符构建的匹配模式如下:

x = Wild("x",  properties=[lambda x: isinstance(x, Symbol)])
a = Wild("a",  properties=[lambda x: isinstance(x, Integer)])
p = Wild("p",  properties=[lambda x: isinstance(x, Integer)])
q = Wild("q",  properties=[lambda x: isinstance(x, Integer)])
b = Wild("b",  properties=[lambda x: isinstance(x, Integer)])
c = Wild("c",  properties=[lambda x: isinstance(x, Integer)])
r = Wild("r",  properties=[lambda x: isinstance(x, Integer)])
s = Wild("s",  properties=[lambda x: isinstance(x, Integer)])

expected_output = Ge(Mul(a, (p*x + q)) +b*x + c,  r*x + s)

执行匹配代码matching = parsed_input.match(expected_output)时,多数场景返回的匹配结果为a=1、p=40、q=24,仅偶发得到a=4、p=10、q=6的预期结果,需要稳定获取预期匹配值。

问题原因

SymPy的match方法默认会对表达式做自动展开化简匹配,4*(10*x+6)会被自动展开为40*x +24,此时匹配逻辑会把展开后的整项系数识别为a=1,无法保留原始表达式的括号结构匹配。

解决方法

要稳定保留原始括号结构的匹配结果,按以下规则配置即可:

  • 匹配前禁用表达式自动展开,使用UnevaluatedExpr包裹带括号的乘积项,保留原始语法树结构不被化简
  • 给系数通配符a增加额外属性校验,禁止匹配值为1,避免匹配到展开后整项系数为1的无效结果
  • 不要把固定符号x定义为Wild通配符,单独定义固定的Symbol类型变量x,避免通配符误匹配其他项

修改后的可运行代码如下:

from sympy import Ge, Mul, Symbol, Integer, Wild, UnevaluatedExpr

# 定义固定变量x,不要设为Wild
x = Symbol('x')
# 包裹乘积项阻止自动展开
parsed_input = 7*x + UnevaluatedExpr(4)*(10*x + 6) >= 8*x + 15

# 定义通配符,给a增加非1校验
a = Wild("a",  properties=[lambda x: isinstance(x, Integer) and x != 1])
p = Wild("p",  properties=[lambda x: isinstance(x, Integer)])
q = Wild("q",  properties=[lambda x: isinstance(x, Integer)])
b = Wild("b",  properties=[lambda x: isinstance(x, Integer)])
c = Wild("c",  properties=[lambda x: isinstance(x, Integer)])
r = Wild("r",  properties=[lambda x: isinstance(x, Integer)])
s = Wild("s",  properties=[lambda x: isinstance(x, Integer)])
x_wild = Wild("x_wild", properties=[lambda t: isinstance(t, Symbol)])

# 构建匹配模式
expected_pattern = Ge(Mul(a, (p*x_wild + q)) + b*x_wild + c, r*x_wild + s)
match_result = parsed_input.match(expected_pattern)

执行后将稳定返回预期匹配结果:{a:4, p:10, q:6, b:7, c:0, r:8, s:15, x_wild:x}。

如果待匹配表达式是通过解析字符串自动生成的,需要先遍历表达式的语法树,将所有外层为整数、内层为加法结构的乘积节点用UnevaluatedExpr包裹,避免解析阶段自动展开括号破坏原始结构。

内容的提问来源于stack exchange,提问作者Vikranth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 23:06:22