mathai 0.2.8__py3-none-any.whl → 0.2.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,410 +1,410 @@
1
- import itertools
2
-
3
- from .base import *
4
- from .inverse import inverse
5
- from collections import Counter
6
- from .factor import factor2
7
- from .simplify import simplify, solve
8
- from .expand import expand
9
- from .fraction import fraction
10
- import copy
11
- from .diff import diff
12
- from .logic import logic0
13
- def intersection2(domain, lst):
14
- domain = copy.deepcopy(domain)
15
- if domain == [True]:
16
- return lst
17
- elif domain == [True]:
18
- return []
19
- lst = [item for item in lst if item not in domain]
20
- out = []
21
- for item2 in lst:
22
- for index in range(len(domain)):
23
-
24
- if isinstance(domain[index], bool) and domain[index]:
25
-
26
- if index == 0 and compute(item2) < compute(domain[index+1]):
27
-
28
- out.append(item2)
29
- break
30
- elif index == len(domain)-1 and compute(domain[index-1]) < compute(item2):
31
- out.append(item2)
32
- break
33
- elif index != 0 and index != len(domain)-1 and compute(domain[index-1]) < compute(item2) and compute(item2) < compute(domain[index+1]):
34
-
35
- out.append(item2)
36
- break
37
-
38
- return list(set(out))
39
- def flip_less_than(inter):
40
- inter = copy.deepcopy(inter)
41
- return [not item if isinstance(item, bool) else item for item in inter]
42
- def intersection(domain_1, domain_2):
43
- domain_1, domain_2 = copy.deepcopy(domain_1), copy.deepcopy(domain_2)
44
- if domain_1 == [True]:
45
- return domain_2
46
- if domain_2 == [True]:
47
- return domain_1
48
- if domain_1 == [False] or domain_2 == [False]:
49
- return [False]
50
- def simplify_ranges(ranges):
51
- simplified_ranges = []
52
- i = 0
53
- while i < len(ranges):
54
- if i + 2 < len(ranges) and ranges[i] is True and ranges[i + 2] is True:
55
- simplified_ranges.append(True)
56
- i += 3
57
- elif i + 2 < len(ranges) and ranges[i] is False and ranges[i + 2] is False:
58
- simplified_ranges.append(False)
59
- i += 3
60
- else:
61
- simplified_ranges.append(ranges[i])
62
- i += 1
63
- return simplified_ranges
64
- result = domain_1 + domain_2
65
- result = [item for item in result if not isinstance(item, bool)]
66
- result = list(set(result))
67
- result = sorted(result, key=lambda x: compute(x))
68
- i = len(result)
69
- while i>=0:
70
- result.insert(i, True)
71
- i = i - 1
72
- result[0] = domain_1[0] and domain_2[0]
73
- result[-1] = domain_1[-1] and domain_2[-1]
74
- def find_fraction_in_list(fraction_list, target_fraction):
75
- for i in range(1, len(fraction_list)-1, 2):
76
- if fraction_list[i] == target_fraction:
77
- return i
78
- return -1
79
- for i in range(2, len(result)-1, 2):
80
- if result[i+1] in domain_1:
81
- result[i] = result[i] and domain_1[find_fraction_in_list(domain_1, result[i+1])-1]
82
- if result[i+1] in domain_2:
83
- result[i] = result[i] and domain_2[find_fraction_in_list(domain_2, result[i+1])-1]
84
- if result[i-1] in domain_1:
85
- result[i] = result[i] and domain_1[find_fraction_in_list(domain_1, result[i-1])+1]
86
- if result[i-1] in domain_2:
87
- result[i] = result[i] and domain_2[find_fraction_in_list(domain_2, result[i-1])+1]
88
-
89
- result = simplify_ranges(result)
90
- return result
91
- class Range:
92
- def __init__(self, r=[True], p=[], z=[]):
93
- self.r = r
94
- self.p = p
95
- self.z = z
96
- self.do = True
97
-
98
- def unfix(self):
99
- self.do = False
100
- return self
101
- def fix(self):
102
- if not self.do:
103
- return
104
- def simplify_ranges(ranges):
105
- simplified_ranges = []
106
- i = 0
107
- while i < len(ranges):
108
- if i + 2 < len(ranges) and ranges[i] is True and ranges[i + 2] is True:
109
- simplified_ranges.append(True)
110
- i += 3
111
- elif i + 2 < len(ranges) and ranges[i] is False and ranges[i + 2] is False:
112
- simplified_ranges.append(False)
113
- i += 3
114
- else:
115
- simplified_ranges.append(ranges[i])
116
- i += 1
117
- return simplified_ranges
118
-
119
- self.r = simplify_ranges(self.r)
120
-
121
- common = set(self.p) & set(self.z)
122
- self.z = list(set(self.z) - common)
123
- self.p = list(set(self.p) - common)
124
-
125
- self.p = list(set(self.p) - set(intersection2(self.r, self.p)))
126
- self.z = list(set(intersection2(self.r, self.z)))
127
- return self
128
-
129
- def __or__(self, other):
130
- return (self.unfix().__invert__().unfix() & other.unfix().__invert__().unfix()).unfix().__invert__().fix()
131
- def __invert__(self):
132
- tmp = Range(flip_less_than(self.r), self.z, list(set(self.p)-set(self.z)))
133
-
134
- return tmp
135
- def __and__(self, other):
136
- a = intersection(self.r, other.r)
137
- b = intersection2(self.r, other.p)
138
- c = intersection2(other.r, self.p)
139
- tmp = Range(a, list(set(b)|set(c)|(set(self.p)&set(other.p))), list(set(self.z)|set(other.z)))
140
- return tmp
141
- def __str__(self):
142
-
143
- if self.r == [False] and self.p == [] and self.z == []:
144
- return "{}"
145
- out = []
146
- out2 = ""
147
- if self.r != [False]:
148
- for i in range(0, len(self.r), 2):
149
- string = ""
150
- if self.r[i]:
151
- if i == 0:
152
- string += "(-inf,"
153
- if len(self.r)==1:
154
- string += "+inf)"
155
- else:
156
- string += str(self.r[i+1])+")"
157
- elif i == len(self.r)-1 and len(self.r)!=1:
158
- string += "("+str(self.r[i-1])+",+inf)"
159
- else:
160
- string += "("+str(self.r[i-1])+","+str(self.r[i+1])+")"
161
- out.append(string)
162
- if self.p != []:
163
- out.append("{"+",".join([str(item) for item in self.p])+"}")
164
- if self.z != []:
165
- out2 = "{"+",".join([str(item) for item in self.z])+"}"
166
- if out2 == "":
167
- return "U".join(out)
168
- else:
169
- return "U".join(out)+"-"+out2
170
-
171
- dic_table = {}
172
- def helper(eq, var="v_0"):
173
- global dic_table
174
-
175
- eq2 = copy.deepcopy(eq)
176
-
177
- if eq2 in dic_table.keys():
178
- return dic_table[eq2]
179
-
180
- if eq.children[0].name == "f_add":
181
-
182
- eq.children[0] = simplify(expand(eq.children[0]))
183
- eq = simplify(factor2(eq))
184
-
185
-
186
- equ = False
187
- sign= True
188
- if eq.name in ["f_gt", "f_ge"]:
189
- sign = True
190
- elif eq.name in ["f_lt", "f_le"]:
191
- sign = False
192
- if eq.name in ["f_ge", "f_le"]:
193
- equ = True
194
- if eq.name == "f_eq":
195
- equ= True
196
- critical = []
197
- equal = []
198
- more = []
199
-
200
- _, d = num_dem(eq.children[0])
201
- d = factor2(d)
202
-
203
- for item in factor_generation(d):
204
-
205
- item = simplify(expand(item))
206
- if len(vlist(item)) != 0:
207
- v = vlist(item)[0]
208
- if diff(diff(item, v), v) != tree_form("d_0"):
209
- continue
210
- out = inverse(item, vlist(item)[0])
211
- more.append(simplify(out))
212
-
213
- eq.children[0] = factor2(eq.children[0])
214
-
215
- for item in factor_generation(eq.children[0]):
216
- item = simplify(expand(item))
217
-
218
- if len(vlist(item)) == 0:
219
- if compute(item) <0:
220
- sign = not sign
221
- continue
222
- v = vlist(item)[0]
223
-
224
- if item.name == "f_pow" and item.children[1].name== "d_-1":
225
-
226
- item = item.children[0]
227
-
228
- if diff(diff(item, v), v) != tree_form("d_0"):
229
-
230
- a = replace(diff(diff(item, v), v), tree_form(v), tree_form("d_0"))/tree_form("d_2")
231
- if "v_" in str_form(a):
232
- return None
233
- if compute(a) < 0:
234
- sign = not sign
235
- continue
236
- else:
237
- tmp2 = diff(copy.deepcopy(item))
238
- if compute(tmp2)<0:
239
- sign = not sign
240
- item = simplify(item * tree_form("d_-1"))
241
- out = inverse(item, vlist(item)[0])
242
- critical.append(out)
243
- else:
244
-
245
-
246
- if diff(diff(item, v), v) != tree_form("d_0"):
247
- a = replace(diff(diff(item, v), v), tree_form(v), tree_form("d_0"))/tree_form("d_2")
248
- if "v_" in str_form(a):
249
- return None
250
- if compute(a) < 0:
251
- sign = not sign
252
- continue
253
- else:
254
- tmp2 = diff(copy.deepcopy(item))
255
- if compute(tmp2)<0:
256
- sign = not sign
257
- item = simplify(item * tree_form("d_-1"))
258
- out = inverse(item, vlist(item)[0])
259
- critical.append(out)
260
- if equ:
261
- equal.append(out)
262
- equal = list(set([simplify(item) for item in equal]))
263
- more = list(set([simplify(item) for item in more]))
264
- critical = [simplify(item) for item in critical]
265
- critical = Counter(critical)
266
-
267
- critical = sorted(critical.items(), key=lambda x: compute(x[0]))
268
-
269
- i = len(critical)
270
- element = sign
271
- while i>=0:
272
- critical.insert(i, element)
273
- if i>0 and critical[i-1][1] % 2 != 0:
274
- element = not element
275
- i = i - 1
276
- for i in range(1, len(critical), 2):
277
- critical[i] = critical[i][0]
278
-
279
-
280
-
281
- if eq.name == "f_eq":
282
- final = Range([False], equal, more)
283
- dic_table[eq2] = final
284
- return final
285
-
286
- final = Range(critical, equal, more)
287
- dic_table[eq2] = final
288
- return final
289
- def wavycurvy(eq):
290
- if eq.name == "s_true":
291
- return Range([True])
292
- if eq.name == "s_false":
293
- return Range([False])
294
- if eq.name not in ["f_and", "f_or", "f_not"]:
295
-
296
- out = helper(eq)
297
- if out is None:
298
- return None
299
- return out
300
- lst= [wavycurvy(child) for child in eq.children]
301
- if None in lst:
302
- return None
303
- ra = lst[0]
304
- if eq.name == "f_and":
305
- for child in lst[1:]:
306
- ra = ra & child
307
- elif eq.name == "f_or":
308
- for child in lst[1:]:
309
- ra = ra | child
310
- elif eq.name == "f_not":
311
- ra = ~ra
312
- return ra
313
-
314
- def absolute(equation):
315
- if equation.name in ["f_and", "f_or", "f_not"]:
316
- tmp = TreeNode(equation.name, [absolute(child) for child in equation.children])
317
- if len(tmp.children)==1:
318
- tmp =tmp.children[0]
319
- return tmp
320
- def mul_abs(eq):
321
- if eq.name == "f_abs" and eq.children[0].name == "f_mul":
322
- return simplify(product([item.fx("abs") for item in factor_generation(eq.children[0])]))
323
- return TreeNode(eq.name, [mul_abs(child) for child in eq.children])
324
- equation = mul_abs(equation)
325
-
326
- def collectabs(eq):
327
- out = []
328
- if eq.name == "f_abs":
329
- out.append(eq.children[0])
330
- return out
331
- for child in eq.children:
332
- out += collectabs(child)
333
- return out
334
- def abc(eq, arr):
335
- def trans(eq):
336
- nonlocal arr
337
- out = {}
338
- if eq.name == "f_abs":
339
- x = arr.pop(0)
340
- if x == 0 or x==2:
341
- return eq.children[0]
342
- else:
343
- return -eq.children[0]
344
- else:
345
- return TreeNode(eq.name, [trans(child) for child in eq.children])
346
- return trans(eq)
347
- out = list(set(collectabs(equation)))
348
-
349
- out2 = []
350
- for item in itertools.product([0,1,2], repeat=len(out)):
351
- out3 = []
352
- for i in range(len(item)):
353
- out3.append(copy.deepcopy(TreeNode({0:"f_gt", 1:"f_lt", 2:"f_eq"}[item[i]], [out[i], tree_form("d_0")])))
354
- out3 = TreeNode("f_and", out3+[abc(copy.deepcopy(equation), list(item))])
355
- if len(out3.children) == 1:
356
- out3 = out3.children[0]
357
- out2.append(out3)
358
- if len(out2) == 1:
359
- return out2[0]
360
- else:
361
- equation = TreeNode("f_or", out2)
362
- return equation
363
- def handle_sqrt(eq):
364
- def helper2(eq):
365
- if eq.name in ["f_lt", "f_gt", "f_le", "f_ge","f_eq"]:
366
- out = []
367
- def helper(eq):
368
- nonlocal out
369
- if eq.name == "f_pow" and frac(eq.children[1]) == Fraction(1,2):
370
- out.append(simplify(eq))
371
- x = [helper(child) for child in eq.children]
372
- helper(eq)
373
- for item in out:
374
- n = tree_form("d_1")
375
- if eq.name == "f_eq":
376
- eq2 = inverse(simplify(eq.children[0]), str_form(item))
377
- else:
378
- eq2, sgn = inverse(simplify(eq.children[0]), str_form(item), True)
379
- if sgn == False:
380
- n = tree_form("d_-1")
381
- eq3 = simplify(expand(simplify(eq2**2)))
382
-
383
- return simplify(TreeNode(eq.name, [simplify(n*item.children[0]-eq3*n), tree_form("d_0")]))
384
- return TreeNode(eq.name, [helper2(child) for child in eq.children])
385
- return helper2(eq)
386
- def domain(eq):
387
- eq = solve(eq, True)
388
- out = []
389
- def helper2(eq):
390
- nonlocal out
391
- if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]).denominator == 2:
392
- if "v_" in str_form(eq.children[0]):
393
- out.append(TreeNode("f_ge", [eq.children[0], tree_form("d_0")]))
394
- out.append(TreeNode("f_ge", [eq, tree_form("d_0")]))
395
- if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]) <0:
396
- tmp = TreeNode("f_eq", [eq.children[0], tree_form("d_0")]).fx("not")
397
- if "v_" in str_form(tmp):
398
- out.append(tmp)
399
- x = [helper2(child) for child in eq.children]
400
- helper2(eq)
401
- out = list(set([simplify(item) for item in out]))
402
- if out == []:
403
- return eq
404
- if len(out)==1:
405
- out = out[0]
406
- else:
407
- out = TreeNode("f_and", list(out))
408
- if eq.name in ["f_lt", "f_gt", "f_le", "f_ge", "f_eq"]:
409
- return eq & out
410
- return out
1
+ import itertools
2
+
3
+ from .base import *
4
+ from .inverse import inverse
5
+ from collections import Counter
6
+ from .factor import factor2
7
+ from .simplify import simplify, solve
8
+ from .expand import expand
9
+ from .fraction import fraction
10
+ import copy
11
+ from .diff import diff
12
+ from .logic import logic0
13
+ def intersection2(domain, lst):
14
+ domain = copy.deepcopy(domain)
15
+ if domain == [True]:
16
+ return lst
17
+ elif domain == [True]:
18
+ return []
19
+ lst = [item for item in lst if item not in domain]
20
+ out = []
21
+ for item2 in lst:
22
+ for index in range(len(domain)):
23
+
24
+ if isinstance(domain[index], bool) and domain[index]:
25
+
26
+ if index == 0 and compute(item2) < compute(domain[index+1]):
27
+
28
+ out.append(item2)
29
+ break
30
+ elif index == len(domain)-1 and compute(domain[index-1]) < compute(item2):
31
+ out.append(item2)
32
+ break
33
+ elif index != 0 and index != len(domain)-1 and compute(domain[index-1]) < compute(item2) and compute(item2) < compute(domain[index+1]):
34
+
35
+ out.append(item2)
36
+ break
37
+
38
+ return list(set(out))
39
+ def flip_less_than(inter):
40
+ inter = copy.deepcopy(inter)
41
+ return [not item if isinstance(item, bool) else item for item in inter]
42
+ def intersection(domain_1, domain_2):
43
+ domain_1, domain_2 = copy.deepcopy(domain_1), copy.deepcopy(domain_2)
44
+ if domain_1 == [True]:
45
+ return domain_2
46
+ if domain_2 == [True]:
47
+ return domain_1
48
+ if domain_1 == [False] or domain_2 == [False]:
49
+ return [False]
50
+ def simplify_ranges(ranges):
51
+ simplified_ranges = []
52
+ i = 0
53
+ while i < len(ranges):
54
+ if i + 2 < len(ranges) and ranges[i] is True and ranges[i + 2] is True:
55
+ simplified_ranges.append(True)
56
+ i += 3
57
+ elif i + 2 < len(ranges) and ranges[i] is False and ranges[i + 2] is False:
58
+ simplified_ranges.append(False)
59
+ i += 3
60
+ else:
61
+ simplified_ranges.append(ranges[i])
62
+ i += 1
63
+ return simplified_ranges
64
+ result = domain_1 + domain_2
65
+ result = [item for item in result if not isinstance(item, bool)]
66
+ result = list(set(result))
67
+ result = sorted(result, key=lambda x: compute(x))
68
+ i = len(result)
69
+ while i>=0:
70
+ result.insert(i, True)
71
+ i = i - 1
72
+ result[0] = domain_1[0] and domain_2[0]
73
+ result[-1] = domain_1[-1] and domain_2[-1]
74
+ def find_fraction_in_list(fraction_list, target_fraction):
75
+ for i in range(1, len(fraction_list)-1, 2):
76
+ if fraction_list[i] == target_fraction:
77
+ return i
78
+ return -1
79
+ for i in range(2, len(result)-1, 2):
80
+ if result[i+1] in domain_1:
81
+ result[i] = result[i] and domain_1[find_fraction_in_list(domain_1, result[i+1])-1]
82
+ if result[i+1] in domain_2:
83
+ result[i] = result[i] and domain_2[find_fraction_in_list(domain_2, result[i+1])-1]
84
+ if result[i-1] in domain_1:
85
+ result[i] = result[i] and domain_1[find_fraction_in_list(domain_1, result[i-1])+1]
86
+ if result[i-1] in domain_2:
87
+ result[i] = result[i] and domain_2[find_fraction_in_list(domain_2, result[i-1])+1]
88
+
89
+ result = simplify_ranges(result)
90
+ return result
91
+ class Range:
92
+ def __init__(self, r=[True], p=[], z=[]):
93
+ self.r = r
94
+ self.p = p
95
+ self.z = z
96
+ self.do = True
97
+
98
+ def unfix(self):
99
+ self.do = False
100
+ return self
101
+ def fix(self):
102
+ if not self.do:
103
+ return
104
+ def simplify_ranges(ranges):
105
+ simplified_ranges = []
106
+ i = 0
107
+ while i < len(ranges):
108
+ if i + 2 < len(ranges) and ranges[i] is True and ranges[i + 2] is True:
109
+ simplified_ranges.append(True)
110
+ i += 3
111
+ elif i + 2 < len(ranges) and ranges[i] is False and ranges[i + 2] is False:
112
+ simplified_ranges.append(False)
113
+ i += 3
114
+ else:
115
+ simplified_ranges.append(ranges[i])
116
+ i += 1
117
+ return simplified_ranges
118
+
119
+ self.r = simplify_ranges(self.r)
120
+
121
+ common = set(self.p) & set(self.z)
122
+ self.z = list(set(self.z) - common)
123
+ self.p = list(set(self.p) - common)
124
+
125
+ self.p = list(set(self.p) - set(intersection2(self.r, self.p)))
126
+ self.z = list(set(intersection2(self.r, self.z)))
127
+ return self
128
+
129
+ def __or__(self, other):
130
+ return (self.unfix().__invert__().unfix() & other.unfix().__invert__().unfix()).unfix().__invert__().fix()
131
+ def __invert__(self):
132
+ tmp = Range(flip_less_than(self.r), self.z, list(set(self.p)-set(self.z)))
133
+
134
+ return tmp
135
+ def __and__(self, other):
136
+ a = intersection(self.r, other.r)
137
+ b = intersection2(self.r, other.p)
138
+ c = intersection2(other.r, self.p)
139
+ tmp = Range(a, list(set(b)|set(c)|(set(self.p)&set(other.p))), list(set(self.z)|set(other.z)))
140
+ return tmp
141
+ def __str__(self):
142
+
143
+ if self.r == [False] and self.p == [] and self.z == []:
144
+ return "{}"
145
+ out = []
146
+ out2 = ""
147
+ if self.r != [False]:
148
+ for i in range(0, len(self.r), 2):
149
+ string = ""
150
+ if self.r[i]:
151
+ if i == 0:
152
+ string += "(-inf,"
153
+ if len(self.r)==1:
154
+ string += "+inf)"
155
+ else:
156
+ string += str(self.r[i+1])+")"
157
+ elif i == len(self.r)-1 and len(self.r)!=1:
158
+ string += "("+str(self.r[i-1])+",+inf)"
159
+ else:
160
+ string += "("+str(self.r[i-1])+","+str(self.r[i+1])+")"
161
+ out.append(string)
162
+ if self.p != []:
163
+ out.append("{"+",".join([str(item) for item in self.p])+"}")
164
+ if self.z != []:
165
+ out2 = "{"+",".join([str(item) for item in self.z])+"}"
166
+ if out2 == "":
167
+ return "U".join(out)
168
+ else:
169
+ return "U".join(out)+"-"+out2
170
+
171
+ dic_table = {}
172
+ def helper(eq, var="v_0"):
173
+ global dic_table
174
+
175
+ eq2 = copy.deepcopy(eq)
176
+
177
+ if eq2 in dic_table.keys():
178
+ return dic_table[eq2]
179
+
180
+ if eq.children[0].name == "f_add":
181
+
182
+ eq.children[0] = simplify(expand(eq.children[0]))
183
+ eq = simplify(factor2(eq))
184
+
185
+
186
+ equ = False
187
+ sign= True
188
+ if eq.name in ["f_gt", "f_ge"]:
189
+ sign = True
190
+ elif eq.name in ["f_lt", "f_le"]:
191
+ sign = False
192
+ if eq.name in ["f_ge", "f_le"]:
193
+ equ = True
194
+ if eq.name == "f_eq":
195
+ equ= True
196
+ critical = []
197
+ equal = []
198
+ more = []
199
+
200
+ _, d = num_dem(eq.children[0])
201
+ d = factor2(d)
202
+
203
+ for item in factor_generation(d):
204
+
205
+ item = simplify(expand(item))
206
+ if len(vlist(item)) != 0:
207
+ v = vlist(item)[0]
208
+ if diff(diff(item, v), v) != tree_form("d_0"):
209
+ continue
210
+ out = inverse(item, vlist(item)[0])
211
+ more.append(simplify(out))
212
+
213
+ eq.children[0] = factor2(eq.children[0])
214
+
215
+ for item in factor_generation(eq.children[0]):
216
+ item = simplify(expand(item))
217
+
218
+ if len(vlist(item)) == 0:
219
+ if compute(item) <0:
220
+ sign = not sign
221
+ continue
222
+ v = vlist(item)[0]
223
+
224
+ if item.name == "f_pow" and item.children[1].name== "d_-1":
225
+
226
+ item = item.children[0]
227
+
228
+ if diff(diff(item, v), v) != tree_form("d_0"):
229
+
230
+ a = replace(diff(diff(item, v), v), tree_form(v), tree_form("d_0"))/tree_form("d_2")
231
+ if "v_" in str_form(a):
232
+ return None
233
+ if compute(a) < 0:
234
+ sign = not sign
235
+ continue
236
+ else:
237
+ tmp2 = diff(copy.deepcopy(item))
238
+ if compute(tmp2)<0:
239
+ sign = not sign
240
+ item = simplify(item * tree_form("d_-1"))
241
+ out = inverse(item, vlist(item)[0])
242
+ critical.append(out)
243
+ else:
244
+
245
+
246
+ if diff(diff(item, v), v) != tree_form("d_0"):
247
+ a = replace(diff(diff(item, v), v), tree_form(v), tree_form("d_0"))/tree_form("d_2")
248
+ if "v_" in str_form(a):
249
+ return None
250
+ if compute(a) < 0:
251
+ sign = not sign
252
+ continue
253
+ else:
254
+ tmp2 = diff(copy.deepcopy(item))
255
+ if compute(tmp2)<0:
256
+ sign = not sign
257
+ item = simplify(item * tree_form("d_-1"))
258
+ out = inverse(item, vlist(item)[0])
259
+ critical.append(out)
260
+ if equ:
261
+ equal.append(out)
262
+ equal = list(set([simplify(item) for item in equal]))
263
+ more = list(set([simplify(item) for item in more]))
264
+ critical = [simplify(item) for item in critical]
265
+ critical = Counter(critical)
266
+
267
+ critical = sorted(critical.items(), key=lambda x: compute(x[0]))
268
+
269
+ i = len(critical)
270
+ element = sign
271
+ while i>=0:
272
+ critical.insert(i, element)
273
+ if i>0 and critical[i-1][1] % 2 != 0:
274
+ element = not element
275
+ i = i - 1
276
+ for i in range(1, len(critical), 2):
277
+ critical[i] = critical[i][0]
278
+
279
+
280
+
281
+ if eq.name == "f_eq":
282
+ final = Range([False], equal, more)
283
+ dic_table[eq2] = final
284
+ return final
285
+
286
+ final = Range(critical, equal, more)
287
+ dic_table[eq2] = final
288
+ return final
289
+ def wavycurvy(eq):
290
+ if eq.name == "s_true":
291
+ return Range([True])
292
+ if eq.name == "s_false":
293
+ return Range([False])
294
+ if eq.name not in ["f_and", "f_or", "f_not"]:
295
+
296
+ out = helper(eq)
297
+ if out is None:
298
+ return None
299
+ return out
300
+ lst= [wavycurvy(child) for child in eq.children]
301
+ if None in lst:
302
+ return None
303
+ ra = lst[0]
304
+ if eq.name == "f_and":
305
+ for child in lst[1:]:
306
+ ra = ra & child
307
+ elif eq.name == "f_or":
308
+ for child in lst[1:]:
309
+ ra = ra | child
310
+ elif eq.name == "f_not":
311
+ ra = ~ra
312
+ return ra
313
+
314
+ def absolute(equation):
315
+ if equation.name in ["f_and", "f_or", "f_not"]:
316
+ tmp = TreeNode(equation.name, [absolute(child) for child in equation.children])
317
+ if len(tmp.children)==1:
318
+ tmp =tmp.children[0]
319
+ return tmp
320
+ def mul_abs(eq):
321
+ if eq.name == "f_abs" and eq.children[0].name == "f_mul":
322
+ return simplify(product([item.fx("abs") for item in factor_generation(eq.children[0])]))
323
+ return TreeNode(eq.name, [mul_abs(child) for child in eq.children])
324
+ equation = mul_abs(equation)
325
+
326
+ def collectabs(eq):
327
+ out = []
328
+ if eq.name == "f_abs":
329
+ out.append(eq.children[0])
330
+ return out
331
+ for child in eq.children:
332
+ out += collectabs(child)
333
+ return out
334
+ def abc(eq, arr):
335
+ def trans(eq):
336
+ nonlocal arr
337
+ out = {}
338
+ if eq.name == "f_abs":
339
+ x = arr.pop(0)
340
+ if x == 0 or x==2:
341
+ return eq.children[0]
342
+ else:
343
+ return -eq.children[0]
344
+ else:
345
+ return TreeNode(eq.name, [trans(child) for child in eq.children])
346
+ return trans(eq)
347
+ out = list(set(collectabs(equation)))
348
+
349
+ out2 = []
350
+ for item in itertools.product([0,1,2], repeat=len(out)):
351
+ out3 = []
352
+ for i in range(len(item)):
353
+ out3.append(copy.deepcopy(TreeNode({0:"f_gt", 1:"f_lt", 2:"f_eq"}[item[i]], [out[i], tree_form("d_0")])))
354
+ out3 = TreeNode("f_and", out3+[abc(copy.deepcopy(equation), list(item))])
355
+ if len(out3.children) == 1:
356
+ out3 = out3.children[0]
357
+ out2.append(out3)
358
+ if len(out2) == 1:
359
+ return out2[0]
360
+ else:
361
+ equation = TreeNode("f_or", out2)
362
+ return equation
363
+ def handle_sqrt(eq):
364
+ def helper2(eq):
365
+ if eq.name in ["f_lt", "f_gt", "f_le", "f_ge","f_eq"]:
366
+ out = []
367
+ def helper(eq):
368
+ nonlocal out
369
+ if eq.name == "f_pow" and frac(eq.children[1]) == Fraction(1,2):
370
+ out.append(simplify(eq))
371
+ x = [helper(child) for child in eq.children]
372
+ helper(eq)
373
+ for item in out:
374
+ n = tree_form("d_1")
375
+ if eq.name == "f_eq":
376
+ eq2 = inverse(simplify(eq.children[0]), str_form(item))
377
+ else:
378
+ eq2, sgn = inverse(simplify(eq.children[0]), str_form(item), True)
379
+ if sgn == False:
380
+ n = tree_form("d_-1")
381
+ eq3 = simplify(expand(simplify(eq2**2)))
382
+
383
+ return simplify(TreeNode(eq.name, [simplify(n*item.children[0]-eq3*n), tree_form("d_0")]))
384
+ return TreeNode(eq.name, [helper2(child) for child in eq.children])
385
+ return helper2(eq)
386
+ def domain(eq):
387
+ eq = solve(eq, True)
388
+ out = []
389
+ def helper2(eq):
390
+ nonlocal out
391
+ if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]).denominator == 2:
392
+ if "v_" in str_form(eq.children[0]):
393
+ out.append(TreeNode("f_ge", [eq.children[0], tree_form("d_0")]))
394
+ out.append(TreeNode("f_ge", [eq, tree_form("d_0")]))
395
+ if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]) <0:
396
+ tmp = TreeNode("f_eq", [eq.children[0], tree_form("d_0")]).fx("not")
397
+ if "v_" in str_form(tmp):
398
+ out.append(tmp)
399
+ x = [helper2(child) for child in eq.children]
400
+ helper2(eq)
401
+ out = list(set([simplify(item) for item in out]))
402
+ if out == []:
403
+ return eq
404
+ if len(out)==1:
405
+ out = out[0]
406
+ else:
407
+ out = TreeNode("f_and", list(out))
408
+ if eq.name in ["f_lt", "f_gt", "f_le", "f_ge", "f_eq"]:
409
+ return eq & out
410
+ return out