Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

118

""" Generic SymPy-Independent Strategies """ 

from __future__ import print_function, division 

 

from sympy.core.compatibility import get_function_name 

 

identity = lambda x: x 

 

def exhaust(rule): 

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

def exhaustive_rl(expr): 

new, old = rule(expr), expr 

while(new != old): 

new, old = rule(new), new 

return new 

return exhaustive_rl 

 

def memoize(rule): 

""" Memoized version of a rule """ 

cache = {} 

def memoized_rl(expr): 

if expr in cache: 

return cache[expr] 

else: 

result = rule(expr) 

cache[expr] = result 

return result 

return memoized_rl 

 

def condition(cond, rule): 

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

def conditioned_rl(expr): 

if cond(expr): 

return rule(expr) 

else: 

return expr 

return conditioned_rl 

 

def chain(*rules): 

""" 

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

""" 

def chain_rl(expr): 

for rule in rules: 

expr = rule(expr) 

return expr 

return chain_rl 

 

def debug(rule, file=None): 

""" Print out before and after expressions each time rule is used """ 

if file is None: 

from sys import stdout 

file = stdout 

def debug_rl(*args, **kwargs): 

expr = args[0] 

result = rule(*args, **kwargs) 

if result != expr: 

file.write("Rule: %s\n" % get_function_name(rule)) 

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

return result 

return debug_rl 

 

def null_safe(rule): 

""" Return original expr if rule returns None """ 

def null_safe_rl(expr): 

result = rule(expr) 

if result is None: 

return expr 

else: 

return result 

return null_safe_rl 

 

def tryit(rule): 

""" Return original expr if rule raises exception """ 

def try_rl(expr): 

try: 

return rule(expr) 

except Exception: 

return expr 

return try_rl 

 

def do_one(*rules): 

""" Try each of the rules until one works. Then stop. """ 

def do_one_rl(expr): 

for rl in rules: 

result = rl(expr) 

if result != expr: 

return result 

return expr 

return do_one_rl 

 

def switch(key, ruledict): 

""" Select a rule based on the result of key called on the function """ 

def switch_rl(expr): 

rl = ruledict.get(key(expr), identity) 

return rl(expr) 

return switch_rl 

 

identity = lambda x: x 

 

def minimize(*rules, **kwargs): 

""" Select result of rules that minimizes objective 

 

>>> from sympy.strategies import minimize 

>>> inc = lambda x: x + 1 

>>> dec = lambda x: x - 1 

>>> rl = minimize(inc, dec) 

>>> rl(4) 

3 

 

>>> rl = minimize(inc, dec, objective=lambda x: -x) # maximize 

>>> rl(4) 

5 

""" 

 

objective = kwargs.get('objective', identity) 

def minrule(expr): 

return min([rule(expr) for rule in rules], key=objective) 

return minrule