{"shas":[["39765b7a25183d2764f3edc1e962f1660fe8ca04","b274abc493535ae88cb3a0742f63e38c9241d67c@gmail.com","subs cleanup\n\n    All input to subs is reduced to a sequence of old, new tuples.\n    If the input is a dict or set (unordered containers) the replacements\n    are ordered. A special routine is used for dict; sets are sorted by\n    op count and in case of a tie, by the number of arguments.\n\n    This reduction to a single container allows all the individual\n    routines for different containers to be removed. In their place\n    is _subs which handles a single old->new substitution and caches\n    results. That routine also handles the case of self == old, allowing\n    that to be factored out of all _eval_subs routines.\n\n    An _eval_subs routine only needs to be written if an object nees more\n    than a rebuilding of subs attempts on its arguments. For example,\n    Integrals need to watch out for the integration variables and not\n    allow certain changes to them. Many objects (especially in secondquant)\n    were essentially duplicating the fallback behavior in _subs so they\n    were removed.\n\n    The recursion by _eval_subs into sub-arguments has been removed: when\n    _eval_subs has not made any changes and wants to try the replacement\n    of old -> new on sub-arguments, it should return None and this will be\n    handled by _subs. If no further processing of the expression is needed\n    then an expression should be returned.\n\n    Summary: call subs with raw old, new pairs: they will be sympified and\n             sorted if necessary.\n\n\t     _eval_subs need only deal with the case of self != old and\n\t     should not do any recursive calls. If the subs cannot\n\t     be performed on the given object and it should be tried on the\n\t     sub-arguments of the object, then None should be returned. If\n\t     further substitution of a subset of an expressions arguments\n\t     needs to be performed, _subs (not _eval_subs) should be called\n\t     on them; alternatively, if a subexpression (rather than a\n\t     subset of an expressions arguments) needs to be processed, then\n\t     _subs should be called on it, too.\n\n   There are further develops notes in the docstring.","Chris Smith"],["26d828866eba862becdcf2b1fdc60ee473778ca9","b274abc493535ae88cb3a0742f63e38c9241d67c@gmail.com","put debug code into subs\n\nHere is a test where the correct result is not obtained with count-op sorting\n\n>>> a,b,c,d,x = symbols('a:d,x', positive=True, bounded=True)\n>>> integrate(exp(-x**2 + I*c*x), x)\nsqrt(pi)*exp(-c**2/4)*erf(-I*c/2 + x)/2\n\nexpr\nexp(I*c*x - x**2)\n\ndict-sorted (old, new)\n[(exp(I*c*x), _x4), (exp(-x**2), _x3), (sqrt(pi)*exp(-c**2/4)*erf(-I*c/2 + x)/2,\n _x2), (exp(I*c*x - x**2), _x1), (x, _x0)]\nresult\n_x3*_x4\n\noplength-sorted (old, new)\n[(sqrt(pi)*exp(-c**2/4)*erf(-I*c/2 + x)/2, _x2), (exp(I*c*x - x**2), _x1), (exp(\n I*c*x), _x4), (exp(-x**2), _x3), (x, _x0)]\nresult\n_x1\n.\n.\n.\nevntually the unevaluated Integral is returned. So somewhere, a dict of substitutions is being sent and that routine wants them sorted according to 'in' logic.","Chris Smith"]],"ref":"refs/heads/subs_cleanup","size":2,"head":"26d828866eba862becdcf2b1fdc60ee473778ca9","push_id":40192981}