File size: 2,759 Bytes
114594c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
""" 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
|