I have gone into detail in this issue thread https://github.com/sympy/sympy/issues/23709
but the gist is that I am trying to get the coefficients of an equation in the form:
parsed_input = 7*x 4*(10*x 6) >= 8*x 15
I am using the pattern:
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)
But when I do:
matching = parsed_input.match(expected_output)
I am mostly getting a=1 , p=40, q=24 and some other times I get a=4,p=10, q=6
How can I get a=4,p=10, q=6 everytime?
CodePudding user response:
Sometimes a custom parser can help:
def parse(lhs):
"""
>>> parse(lhs = 7*x Mul(8,x 1,evaluate=False) 3) #= a*x b*(c*x d) e
{'e': 3, 'a': 7, 'b': 8, 'c': 1, 'd': 1}
>>> parse(3*x 4)
{'e': 4, 'a': 3}
>>> parse(S(3))
{'e': 1}
"""
if lhs == x:
return {'a': 1}
if lhs.is_Number:
return {'e': lhs}
assert lhs.args
hit = {}
for arg in lhs.args:
if arg.is_Mul:
if not any(ai.args for ai in arg.args):
a,X = arg.as_coeff_Mul()
assert 'a' not in hit
hit['a'] = a
assert X == x
else:
b, A = arg.as_coeff_Mul()
assert A.is_Add
d, cx= A.as_coeff_Add()
c, X = cx.as_coeff_Mul()
assert X == x
assert not any(i in hit for i in 'bcd')
hit.update(dict(zip('bcd',(b,c,d))))
else:
assert not arg.args
assert 'e' not in hit
hit['e'] = arg
return hit