chore: 添加虚拟环境到仓库
- 添加 backend_service/venv 虚拟环境 - 包含所有Python依赖包 - 注意:虚拟环境约393MB,包含12655个文件
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
from . import traverse
|
||||
from .core import (
|
||||
condition, debug, multiplex, exhaust, notempty,
|
||||
chain, onaction, sfilter, yieldify, do_one, identity)
|
||||
from .tools import canon
|
||||
|
||||
__all__ = [
|
||||
'traverse',
|
||||
|
||||
'condition', 'debug', 'multiplex', 'exhaust', 'notempty', 'chain',
|
||||
'onaction', 'sfilter', 'yieldify', 'do_one', 'identity',
|
||||
|
||||
'canon',
|
||||
]
|
||||
@@ -0,0 +1,116 @@
|
||||
""" 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
|
||||
@@ -0,0 +1,117 @@
|
||||
from sympy.strategies.branch.core import (
|
||||
exhaust, debug, multiplex, condition, notempty, chain, onaction, sfilter,
|
||||
yieldify, do_one, identity)
|
||||
|
||||
|
||||
def posdec(x):
|
||||
if x > 0:
|
||||
yield x - 1
|
||||
else:
|
||||
yield x
|
||||
|
||||
|
||||
def branch5(x):
|
||||
if 0 < x < 5:
|
||||
yield x - 1
|
||||
elif 5 < x < 10:
|
||||
yield x + 1
|
||||
elif x == 5:
|
||||
yield x + 1
|
||||
yield x - 1
|
||||
else:
|
||||
yield x
|
||||
|
||||
|
||||
def even(x):
|
||||
return x % 2 == 0
|
||||
|
||||
|
||||
def inc(x):
|
||||
yield x + 1
|
||||
|
||||
|
||||
def one_to_n(n):
|
||||
yield from range(n)
|
||||
|
||||
|
||||
def test_exhaust():
|
||||
brl = exhaust(branch5)
|
||||
assert set(brl(3)) == {0}
|
||||
assert set(brl(7)) == {10}
|
||||
assert set(brl(5)) == {0, 10}
|
||||
|
||||
|
||||
def test_debug():
|
||||
from io import StringIO
|
||||
file = StringIO()
|
||||
rl = debug(posdec, file)
|
||||
list(rl(5))
|
||||
log = file.getvalue()
|
||||
file.close()
|
||||
|
||||
assert posdec.__name__ in log
|
||||
assert '5' in log
|
||||
assert '4' in log
|
||||
|
||||
|
||||
def test_multiplex():
|
||||
brl = multiplex(posdec, branch5)
|
||||
assert set(brl(3)) == {2}
|
||||
assert set(brl(7)) == {6, 8}
|
||||
assert set(brl(5)) == {4, 6}
|
||||
|
||||
|
||||
def test_condition():
|
||||
brl = condition(even, branch5)
|
||||
assert set(brl(4)) == set(branch5(4))
|
||||
assert set(brl(5)) == set()
|
||||
|
||||
|
||||
def test_sfilter():
|
||||
brl = sfilter(even, one_to_n)
|
||||
assert set(brl(10)) == {0, 2, 4, 6, 8}
|
||||
|
||||
|
||||
def test_notempty():
|
||||
def ident_if_even(x):
|
||||
if even(x):
|
||||
yield x
|
||||
|
||||
brl = notempty(ident_if_even)
|
||||
assert set(brl(4)) == {4}
|
||||
assert set(brl(5)) == {5}
|
||||
|
||||
|
||||
def test_chain():
|
||||
assert list(chain()(2)) == [2] # identity
|
||||
assert list(chain(inc, inc)(2)) == [4]
|
||||
assert list(chain(branch5, inc)(4)) == [4]
|
||||
assert set(chain(branch5, inc)(5)) == {5, 7}
|
||||
assert list(chain(inc, branch5)(5)) == [7]
|
||||
|
||||
|
||||
def test_onaction():
|
||||
L = []
|
||||
|
||||
def record(fn, input, output):
|
||||
L.append((input, output))
|
||||
|
||||
list(onaction(inc, record)(2))
|
||||
assert L == [(2, 3)]
|
||||
|
||||
list(onaction(identity, record)(2))
|
||||
assert L == [(2, 3)]
|
||||
|
||||
|
||||
def test_yieldify():
|
||||
yinc = yieldify(lambda x: x + 1)
|
||||
assert list(yinc(3)) == [4]
|
||||
|
||||
|
||||
def test_do_one():
|
||||
def bad(expr):
|
||||
raise ValueError
|
||||
|
||||
assert list(do_one(inc)(3)) == [4]
|
||||
assert list(do_one(inc, bad)(3)) == [4]
|
||||
assert list(do_one(inc, posdec)(3)) == [4]
|
||||
@@ -0,0 +1,42 @@
|
||||
from sympy.strategies.branch.tools import canon
|
||||
from sympy.core.basic import Basic
|
||||
from sympy.core.numbers import Integer
|
||||
from sympy.core.singleton import S
|
||||
|
||||
|
||||
def posdec(x):
|
||||
if isinstance(x, Integer) and x > 0:
|
||||
yield x - 1
|
||||
else:
|
||||
yield x
|
||||
|
||||
|
||||
def branch5(x):
|
||||
if isinstance(x, Integer):
|
||||
if 0 < x < 5:
|
||||
yield x - 1
|
||||
elif 5 < x < 10:
|
||||
yield x + 1
|
||||
elif x == 5:
|
||||
yield x + 1
|
||||
yield x - 1
|
||||
else:
|
||||
yield x
|
||||
|
||||
|
||||
def test_zero_ints():
|
||||
expr = Basic(S(2), Basic(S(5), S(3)), S(8))
|
||||
expected = {Basic(S(0), Basic(S(0), S(0)), S(0))}
|
||||
|
||||
brl = canon(posdec)
|
||||
assert set(brl(expr)) == expected
|
||||
|
||||
|
||||
def test_split5():
|
||||
expr = Basic(S(2), Basic(S(5), S(3)), S(8))
|
||||
expected = {
|
||||
Basic(S(0), Basic(S(0), S(0)), S(10)),
|
||||
Basic(S(0), Basic(S(10), S(0)), S(10))}
|
||||
|
||||
brl = canon(branch5)
|
||||
assert set(brl(expr)) == expected
|
||||
@@ -0,0 +1,53 @@
|
||||
from sympy.core.basic import Basic
|
||||
from sympy.core.numbers import Integer
|
||||
from sympy.core.singleton import S
|
||||
from sympy.strategies.branch.traverse import top_down, sall
|
||||
from sympy.strategies.branch.core import do_one, identity
|
||||
|
||||
|
||||
def inc(x):
|
||||
if isinstance(x, Integer):
|
||||
yield x + 1
|
||||
|
||||
|
||||
def test_top_down_easy():
|
||||
expr = Basic(S(1), S(2))
|
||||
expected = Basic(S(2), S(3))
|
||||
brl = top_down(inc)
|
||||
|
||||
assert set(brl(expr)) == {expected}
|
||||
|
||||
|
||||
def test_top_down_big_tree():
|
||||
expr = Basic(S(1), Basic(S(2)), Basic(S(3), Basic(S(4)), S(5)))
|
||||
expected = Basic(S(2), Basic(S(3)), Basic(S(4), Basic(S(5)), S(6)))
|
||||
brl = top_down(inc)
|
||||
|
||||
assert set(brl(expr)) == {expected}
|
||||
|
||||
|
||||
def test_top_down_harder_function():
|
||||
def split5(x):
|
||||
if x == 5:
|
||||
yield x - 1
|
||||
yield x + 1
|
||||
|
||||
expr = Basic(Basic(S(5), S(6)), S(1))
|
||||
expected = {Basic(Basic(S(4), S(6)), S(1)), Basic(Basic(S(6), S(6)), S(1))}
|
||||
brl = top_down(split5)
|
||||
|
||||
assert set(brl(expr)) == expected
|
||||
|
||||
|
||||
def test_sall():
|
||||
expr = Basic(S(1), S(2))
|
||||
expected = Basic(S(2), S(3))
|
||||
brl = sall(inc)
|
||||
|
||||
assert list(brl(expr)) == [expected]
|
||||
|
||||
expr = Basic(S(1), S(2), Basic(S(3), S(4)))
|
||||
expected = Basic(S(2), S(3), Basic(S(3), S(4)))
|
||||
brl = sall(do_one(inc, identity))
|
||||
|
||||
assert list(brl(expr)) == [expected]
|
||||
@@ -0,0 +1,12 @@
|
||||
from .core import exhaust, multiplex
|
||||
from .traverse import top_down
|
||||
|
||||
|
||||
def canon(*rules):
|
||||
""" Strategy for canonicalization
|
||||
|
||||
Apply each branching rule in a top-down fashion through the tree.
|
||||
Multiplex through all branching rule traversals
|
||||
Keep doing this until there is no change.
|
||||
"""
|
||||
return exhaust(multiplex(*map(top_down, rules)))
|
||||
@@ -0,0 +1,25 @@
|
||||
""" Branching Strategies to Traverse a Tree """
|
||||
from itertools import product
|
||||
from sympy.strategies.util import basic_fns
|
||||
from .core import chain, identity, do_one
|
||||
|
||||
|
||||
def top_down(brule, fns=basic_fns):
|
||||
""" Apply a rule down a tree running it on the top nodes first """
|
||||
return chain(do_one(brule, identity),
|
||||
lambda expr: sall(top_down(brule, fns), fns)(expr))
|
||||
|
||||
|
||||
def sall(brule, fns=basic_fns):
|
||||
""" Strategic all - apply rule to args """
|
||||
op, new, children, leaf = map(fns.get, ('op', 'new', 'children', 'leaf'))
|
||||
|
||||
def all_rl(expr):
|
||||
if leaf(expr):
|
||||
yield expr
|
||||
else:
|
||||
myop = op(expr)
|
||||
argss = product(*map(brule, children(expr)))
|
||||
for args in argss:
|
||||
yield new(myop, *args)
|
||||
return all_rl
|
||||
Reference in New Issue
Block a user