""" Generic SymPy-Independent Strategies """ def identity(x): yield x def exhaust(brule): """ Apply a branching rule repeatedly until it has no effect """ def exhaust_brl(expr): seen = {expr} for nexpr in brule(expr): if nexpr not in seen: seen.add(nexpr) yield from exhaust_brl(nexpr) if seen == {expr}: yield expr return exhaust_brl def onaction(brule, fn): def onaction_brl(expr): for result in brule(expr): if result != expr: fn(brule, expr, result) yield result return onaction_brl def debug(brule, file=None): """ Print the input and output expressions at each rule application """ if not file: from sys import stdout file = stdout def write(brl, expr, result): file.write("Rule: %s\n" % brl.__name__) file.write("In: %s\nOut: %s\n\n" % (expr, result)) return onaction(brule, write) def multiplex(*brules): """ Multiplex many branching rules into one """ def multiplex_brl(expr): seen = set() for brl in brules: for nexpr in brl(expr): if nexpr not in seen: seen.add(nexpr) yield nexpr return multiplex_brl def condition(cond, brule): """ Only apply branching rule if condition is true """ def conditioned_brl(expr): if cond(expr): yield from brule(expr) else: pass return conditioned_brl def sfilter(pred, brule): """ Yield only those results which satisfy the predicate """ def filtered_brl(expr): yield from filter(pred, brule(expr)) return filtered_brl def notempty(brule): def notempty_brl(expr): yielded = False for nexpr in brule(expr): yielded = True yield nexpr if not yielded: yield expr return notempty_brl def do_one(*brules): """ Execute one of the branching rules """ def do_one_brl(expr): yielded = False for brl in brules: for nexpr in brl(expr): yielded = True yield nexpr if yielded: return return do_one_brl def chain(*brules): """ Compose a sequence of brules so that they apply to the expr sequentially """ def chain_brl(expr): if not brules: yield expr return head, tail = brules[0], brules[1:] for nexpr in head(expr): yield from chain(*tail)(nexpr) return chain_brl def yieldify(rl): """ Turn a rule into a branching rule """ def brl(expr): yield rl(expr) return brl