mathai 0.2.7__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.
- mathai/__init__.py +16 -16
- mathai/apart.py +103 -103
- mathai/base.py +355 -354
- mathai/console.py +84 -84
- mathai/diff.py +65 -65
- mathai/expand.py +58 -58
- mathai/factor.py +125 -125
- mathai/fraction.py +59 -59
- mathai/integrate.py +346 -346
- mathai/inverse.py +65 -65
- mathai/limit.py +130 -130
- mathai/linear.py +152 -152
- mathai/logic.py +224 -224
- mathai/parser.py +154 -154
- mathai/printeq.py +34 -34
- mathai/simplify.py +358 -358
- mathai/structure.py +103 -103
- mathai/tool.py +35 -35
- mathai/trig.py +169 -169
- mathai/univariate_inequality.py +410 -414
- {mathai-0.2.7.dist-info → mathai-0.2.9.dist-info}/METADATA +231 -231
- mathai-0.2.9.dist-info/RECORD +24 -0
- {mathai-0.2.7.dist-info → mathai-0.2.9.dist-info}/WHEEL +1 -1
- mathai-0.2.7.dist-info/RECORD +0 -24
- {mathai-0.2.7.dist-info → mathai-0.2.9.dist-info}/top_level.txt +0 -0
mathai/univariate_inequality.py
CHANGED
@@ -1,414 +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
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
if eq.name
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
if
|
322
|
-
|
323
|
-
return
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
out3
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
out2
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
def
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1])
|
396
|
-
|
397
|
-
|
398
|
-
out.append(
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
if
|
409
|
-
|
410
|
-
|
411
|
-
out = TreeNode("f_and", list(out))
|
412
|
-
if eq.name in ["f_lt", "f_gt", "f_le", "f_ge", "f_eq"]:
|
413
|
-
return eq & out
|
414
|
-
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
|