The top-level var
has this "binding injection behaviour" to avoid having to write the print name of the symbolic variable "x"
and the python symbol you bind it to separately, since generally you'd want them to agree. The non-toplevel SR.var
does not have that behaviour, so SR.var("x,y,z")
returns the right symbols, but doesn't bind them. You have to assign them, giving you the option of naming them differently, like
symbol_x, symbol_y = SR.var("x,y")
(with the top-level var this would result in symbol_x
as well as x
being bound to the same symbol x
). Explicit assignment can sometimes be useful to avoid name clashes.
You can invoke darker magic to get the result of the top-level var. For instance, once you've done var('symbols')
you can use
_(x,y,z)=symbols
which works because of sage's preparser:
sage: preparse("_(x,y,z)=symbols")
'__tmp__=var("x,y,z"); _ = symbolic_expression(symbols).function(x,y,z)'
so it calls var for you.
Alternatively, with the following definition:
class symbols:
def __init__(self, names):
self._symbols = map(SR.symbol, names)
def _first_ngens(self,n):
return self._symbols[:n]
you'd be able to leverage another preparser feature to write
_.<x,y,z>=symbols()
because it preparses as:
sage: preparse("_.<x,y,z>=symbols()")
"_ = symbols(names=('x', 'y', 'z',)); (x, y, z,) = _._first_ngens(3)"