Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

I found another solution, which is better for me. It still requires me to use sympy, which is unfortunate because sympy symbols are incompatible with sage function declarations (TypeError: must construct a function with symbolic variables as arguments), but it's better than nothing.

There is a global thread-local parameters object sympy.core.parameters.global_parameters with a evaluate parameter that controls whether expressions should be evaluated or not. We can explicitly change the value of evaluate parameter:

sympy.core.parameters.global_parameters.evaluate = False

Or do the same, but using context manager class sympy.evaluate that pushes the evaluate parameter value for us:

with sympy.evaluate(False):
    print(x + x)

The evaluate global parameter is restored to the previous value once the code leaves the with statement.

This method is better than using UnevaluatedExpr because it doesn't mess with the order of expressions. For instance:

sympy.latex((5*x*y).subs(x, sympy.UnevaluatedExpr(8)))
'5 y 8'

The order of x (substituted with 8) and y has been changed.

with sympy.evaluate(False):
    print(sympy.latex((5*x*y).subs(x, 8)))

5 \cdot 8 y

The order has not been changed.

I could not find such global parameter in sage. hold argument is False by default (from sage source code):

if kwds.get('hold', False):

While in sympy the default value of hold's alternative evaluate argument is the global parameter evaluate:

eval = options.pop('evaluate', global_parameters.evaluate)

I wish I was wrong and there was actually any way to globally disable expressions evaluation in sagemath. I'm still looking for it :)