Coverage for /usr/lib/python3/dist-packages/sympy/strategies/branch/core.py: 14%

78 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-14 15:55 +0200

1""" Generic SymPy-Independent Strategies """ 

2 

3 

4def identity(x): 

5 yield x 

6 

7 

8def exhaust(brule): 

9 """ Apply a branching rule repeatedly until it has no effect """ 

10 def exhaust_brl(expr): 

11 seen = {expr} 

12 for nexpr in brule(expr): 

13 if nexpr not in seen: 

14 seen.add(nexpr) 

15 yield from exhaust_brl(nexpr) 

16 if seen == {expr}: 

17 yield expr 

18 return exhaust_brl 

19 

20 

21def onaction(brule, fn): 

22 def onaction_brl(expr): 

23 for result in brule(expr): 

24 if result != expr: 

25 fn(brule, expr, result) 

26 yield result 

27 return onaction_brl 

28 

29 

30def debug(brule, file=None): 

31 """ Print the input and output expressions at each rule application """ 

32 if not file: 

33 from sys import stdout 

34 file = stdout 

35 

36 def write(brl, expr, result): 

37 file.write("Rule: %s\n" % brl.__name__) 

38 file.write("In: %s\nOut: %s\n\n" % (expr, result)) 

39 

40 return onaction(brule, write) 

41 

42 

43def multiplex(*brules): 

44 """ Multiplex many branching rules into one """ 

45 def multiplex_brl(expr): 

46 seen = set() 

47 for brl in brules: 

48 for nexpr in brl(expr): 

49 if nexpr not in seen: 

50 seen.add(nexpr) 

51 yield nexpr 

52 return multiplex_brl 

53 

54 

55def condition(cond, brule): 

56 """ Only apply branching rule if condition is true """ 

57 def conditioned_brl(expr): 

58 if cond(expr): 

59 yield from brule(expr) 

60 else: 

61 pass 

62 return conditioned_brl 

63 

64 

65def sfilter(pred, brule): 

66 """ Yield only those results which satisfy the predicate """ 

67 def filtered_brl(expr): 

68 yield from filter(pred, brule(expr)) 

69 return filtered_brl 

70 

71 

72def notempty(brule): 

73 def notempty_brl(expr): 

74 yielded = False 

75 for nexpr in brule(expr): 

76 yielded = True 

77 yield nexpr 

78 if not yielded: 

79 yield expr 

80 return notempty_brl 

81 

82 

83def do_one(*brules): 

84 """ Execute one of the branching rules """ 

85 def do_one_brl(expr): 

86 yielded = False 

87 for brl in brules: 

88 for nexpr in brl(expr): 

89 yielded = True 

90 yield nexpr 

91 if yielded: 

92 return 

93 return do_one_brl 

94 

95 

96def chain(*brules): 

97 """ 

98 Compose a sequence of brules so that they apply to the expr sequentially 

99 """ 

100 def chain_brl(expr): 

101 if not brules: 

102 yield expr 

103 return 

104 

105 head, tail = brules[0], brules[1:] 

106 for nexpr in head(expr): 

107 yield from chain(*tail)(nexpr) 

108 

109 return chain_brl 

110 

111 

112def yieldify(rl): 

113 """ Turn a rule into a branching rule """ 

114 def brl(expr): 

115 yield rl(expr) 

116 return brl