def _smart_subs(expr, sub_dict):
 expr = _crawl(expr, _tan_repl_func)
 def _recurser(expr, sub_dict):
  (num, den) = _fraction_decomp(expr)
  if (den != 1):
   denom_subbed = _recurser(den, sub_dict)
   if (denom_subbed.evalf() == 0):
    expr = simplify(expr)
   else:
    num_subbed = _recurser(num, sub_dict)
    return (num_subbed / denom_subbed)
  val = _sub_func(expr, sub_dict)
  if (val is not None):
   return val
  new_args = (_recurser(arg, sub_dict) for arg in expr.args)
  return expr.func(*new_args)
 return _recurser(expr, sub_dict)

def _smart_subs ( expr , sub_dict ) : expr = _crawl ( expr , _tan_repl_func ) def _recurser ( expr , sub_dict ) : ( num , den ) = _fraction_decomp ( expr ) if ( den != 1 ) : denom_subbed = _recurser ( den , sub_dict ) if ( denom_subbed . evalf ( ) == 0 ) : expr = simplify ( expr ) else : num_subbed = _recurser ( num , sub_dict ) return ( num_subbed / denom_subbed ) val = _sub_func ( expr , sub_dict ) if ( val is not None ) : return val new_args = ( _recurser ( arg , sub_dict ) for arg in expr . args ) return expr . func ( * new_args ) return _recurser ( expr , sub_dict )
performs subs .