I was confused with the sympy.sympify's option evaluate
I've test the following code and it works perfectly
import sympy as sp
def test(s1 = "x1 - x2*x3"):
e1 = sp.sympify(s1)
syms = sorted(e1.free_symbols, key=lambda s: s.name)
p1 = sp.Poly(e1, *syms, expand=False)
if I add the evaluate option to sp.sympify, then error occurs
bug code
import sympy as sp
def test(s1 = "x1 - x2*x3"):
e1 = sp.sympify(s1, evaluate=False)
syms = sorted(e1.free_symbols, key=lambda s: s.name)
p1 = sp.Poly(e1, *syms, expand=False)
main error message
sympy.polys.polyerrors.PolynomialError: x2*x3 contains an element of the set of generators.
I want to know why evaluate=False option caused an error in sp.Poly.
You have set evaluate=False which causes the expression to be not canonicalised:
In [15]: e1 = parse_expr("x1 - x2*x3")
In [16]: srepr(e1)
Out[16]: "Add(Symbol('x1'), Mul(Integer(-1), Symbol('x2'), Symbol('x3')))"
In [17]: e2 = parse_expr("x1 - x2*x3", evaluate=False)
In [18]: srepr(e2)
Out[18]: "Add(Symbol('x1'), Mul(Integer(-1), Mul(Symbol('x2'), Symbol('x3'))))"
Notice the unflattened Mul inside a Mul.
You have also set expand to False in the Poly constructor which prevents it from canonicalising the unflattened Mul:
In [22]: Poly(e2, list(e2.free_symbols))
Out[22]: Poly(-x2*x3 + x1, x2, x1, x3, domain='ZZ')
In [23]: Poly(e2, list(e2.free_symbols), expand=False)
...
PolynomialError: x2*x3 contains an element of the set of generators.
To create the Poly something needs to canonicalise the expression so you cannot have both evaluate=False and expand=False (I have no idea why you would want to combine these options).