mathai 0.2.9__py3-none-any.whl → 0.3.1__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 +17 -16
- mathai/apart.py +103 -103
- mathai/base.py +355 -355
- 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 +158 -154
- mathai/printeq.py +34 -34
- mathai/search.py +111 -0
- 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 -410
- {mathai-0.2.9.dist-info → mathai-0.3.1.dist-info}/METADATA +231 -231
- mathai-0.3.1.dist-info/RECORD +25 -0
- {mathai-0.2.9.dist-info → mathai-0.3.1.dist-info}/WHEEL +1 -1
- mathai-0.2.9.dist-info/RECORD +0 -24
- {mathai-0.2.9.dist-info → mathai-0.3.1.dist-info}/top_level.txt +0 -0
mathai/logic.py
CHANGED
@@ -1,224 +1,224 @@
|
|
1
|
-
import itertools
|
2
|
-
from .base import *
|
3
|
-
|
4
|
-
def logic0(eq):
|
5
|
-
if eq.children is None or len(eq.children)==0:
|
6
|
-
return eq
|
7
|
-
if eq.name in ["f_eq", "f_lt", "f_gt" "f_ge"] and eq.children[1].name[:2]=="d_" and eq.children[0].name[:2]=="d_":
|
8
|
-
a, b = int(eq.children[0].name[2:]), int(eq.children[1].name[2:])
|
9
|
-
if eq.name == "f_eq":
|
10
|
-
return tree_form("s_true") if a==b else tree_form("s_false")
|
11
|
-
if eq.name == "f_ge":
|
12
|
-
return tree_form("s_true") if a>=b else tree_form("s_false")
|
13
|
-
if eq.name == "f_lt":
|
14
|
-
return tree_form("s_true") if a < b else tree_form("s_false")
|
15
|
-
if eq.name == "f_ge":
|
16
|
-
return TreeNode("f_gt", eq.children) | TreeNode("f_eq", eq.children)
|
17
|
-
|
18
|
-
if eq.name == "f_gt":
|
19
|
-
return TreeNode("f_lt", eq.children).fx("not") & TreeNode("f_eq", eq.children).fx("not")
|
20
|
-
|
21
|
-
if eq.name == "f_le":
|
22
|
-
return TreeNode("f_lt", eq.children) | TreeNode("f_eq", eq.children)
|
23
|
-
return TreeNode(eq.name, [logic0(child) for child in eq.children])
|
24
|
-
def logic3(eq):
|
25
|
-
if eq.name == "f_forall" and eq.children[1] in [tree_form("s_true"), tree_form("s_false")]:
|
26
|
-
return eq.children[1]
|
27
|
-
if eq.name == "f_not" and eq.children[0].name == "f_exist":
|
28
|
-
return TreeNode("f_forall", [eq.children[0].children[0], eq.children[0].children[1].fx("not")])
|
29
|
-
if eq.name == "f_exist" and eq.children[1].name == "f_or":
|
30
|
-
return TreeNode("f_or", [TreeNode("f_exist", [eq.children[0], child]) for child in eq.children[1].children])
|
31
|
-
if eq.name == "f_forall" and eq.children[1].name == "f_and":
|
32
|
-
return TreeNode("f_and", [TreeNode("f_forall", [eq.children[0], child]) for child in eq.children[1].children])
|
33
|
-
if eq.name == "f_exist":
|
34
|
-
return TreeNode("f_forall", [eq.children[0], eq.children[1].fx("not")]).fx("not")
|
35
|
-
return TreeNode(eq.name, [logic3(child) for child in eq.children])
|
36
|
-
def logic2(eq):
|
37
|
-
if eq.name in ["f_exist", "f_forall"]:
|
38
|
-
return TreeNode(eq.name, [eq.children[0], logic2(eq.children[1])])
|
39
|
-
if eq.name not in ["f_and", "f_or", "f_not", "f_imply", "f_equiv"]:
|
40
|
-
return eq
|
41
|
-
def convv(eq):
|
42
|
-
if eq == tree_form("s_true"):
|
43
|
-
return True
|
44
|
-
if eq == tree_form("s_false"):
|
45
|
-
return False
|
46
|
-
return None
|
47
|
-
def conv2(val):
|
48
|
-
if val:
|
49
|
-
return tree_form("s_true")
|
50
|
-
return tree_form("s_false")
|
51
|
-
if all(convv(child) is not None for child in eq.children):
|
52
|
-
if eq.name == "f_not":
|
53
|
-
return conv2(not convv(eq.children[0]))
|
54
|
-
elif eq.name == "f_or":
|
55
|
-
return conv2(convv(eq.children[0]) or convv(eq.children[1]))
|
56
|
-
elif eq.name == "f_and":
|
57
|
-
return conv2(convv(eq.children[0]) and convv(eq.children[1]))
|
58
|
-
if eq == tree_form("s_false").fx("not"):
|
59
|
-
return tree_form("s_true")
|
60
|
-
if eq.name == "f_not":
|
61
|
-
if eq.children[0].name == "f_not":
|
62
|
-
return eq.children[0].children[0]
|
63
|
-
elif eq.children[0].name in ["f_or", "f_and"]:
|
64
|
-
out = TreeNode({"f_or":"f_and", "f_and":"f_or"}[eq.children[0].name], [])
|
65
|
-
for child in eq.children[0].children:
|
66
|
-
out.children.append(child.fx("not"))
|
67
|
-
return out
|
68
|
-
if eq.name in ["f_and", "f_or"]:
|
69
|
-
for i in range(len(eq.children)):
|
70
|
-
for j in range(len(eq.children)):
|
71
|
-
if i ==j:
|
72
|
-
continue
|
73
|
-
if eq.children[i] == eq.children[j].fx("not"):
|
74
|
-
eq2 = copy.deepcopy(eq)
|
75
|
-
eq2.children.pop(max(i, j))
|
76
|
-
eq2.children.pop(min(i, j))
|
77
|
-
eq2.children.append({"f_or":tree_form("s_true"), "f_and":tree_form("s_false")}[eq.name])
|
78
|
-
if len(eq2.children) == 1:
|
79
|
-
return eq2.children[0]
|
80
|
-
return eq2
|
81
|
-
if eq.name in ["f_and", "f_or"]:
|
82
|
-
for i in range(len(eq.children)):
|
83
|
-
if eq.children[i] == tree_form("s_false"):
|
84
|
-
eq2 = copy.deepcopy(eq)
|
85
|
-
eq2.children.pop(i)
|
86
|
-
if eq.name == "f_and":
|
87
|
-
return tree_form("s_false")
|
88
|
-
if len(eq2.children) == 1:
|
89
|
-
return eq2.children[0]
|
90
|
-
return eq2
|
91
|
-
elif eq.children[i] == tree_form("s_true"):
|
92
|
-
eq2 = copy.deepcopy(eq)
|
93
|
-
eq2.children.pop(i)
|
94
|
-
if eq.name == "f_or":
|
95
|
-
return tree_form("s_true")
|
96
|
-
if len(eq2.children) == 1:
|
97
|
-
return eq2.children[0]
|
98
|
-
return eq2
|
99
|
-
if eq.name in ["f_and", "f_or"]:
|
100
|
-
lst = remove_duplicates_custom(eq.children, lambda x,y: x==y)
|
101
|
-
if len(lst) < len(eq.children):
|
102
|
-
if len(lst) == 1:
|
103
|
-
return lst[0]
|
104
|
-
return TreeNode(eq.name, lst)
|
105
|
-
|
106
|
-
if eq.name in ["f_and", "f_or"] and any(child.children is not None and len(child.children)!=0 for child in eq.children):
|
107
|
-
for i in range(len(eq.children),1,-1):
|
108
|
-
for item in itertools.combinations(enumerate(eq.children), i):
|
109
|
-
op = "f_and"
|
110
|
-
if eq.name == "f_and":
|
111
|
-
op = "f_or"
|
112
|
-
item3 = []
|
113
|
-
for item4 in item:
|
114
|
-
item3.append(item4[0])
|
115
|
-
item5 = []
|
116
|
-
for item4 in item:
|
117
|
-
item5.append(item4[1])
|
118
|
-
item = item5
|
119
|
-
out = None
|
120
|
-
for j in range(len(item)):
|
121
|
-
out = set(item[j].children)
|
122
|
-
for item2 in item:
|
123
|
-
if item2.name == op:
|
124
|
-
out = out & set(item2.children)
|
125
|
-
else:
|
126
|
-
out = out & set([item2])
|
127
|
-
if out == set(item[j].children):
|
128
|
-
break
|
129
|
-
out = None
|
130
|
-
if out is None:
|
131
|
-
continue
|
132
|
-
out = list(out)
|
133
|
-
if out == []:
|
134
|
-
continue
|
135
|
-
if len(out) != 1:
|
136
|
-
out = [TreeNode(op, out)]
|
137
|
-
for item4 in list(set(range(len(eq.children))) - set(item3)):
|
138
|
-
out.append(eq.children[item4])
|
139
|
-
if len(out) == 1:
|
140
|
-
return out[0]
|
141
|
-
output = flatten_tree(TreeNode(eq.name, out))
|
142
|
-
return output
|
143
|
-
return TreeNode(eq.name, [flatten_tree(logic2(child)) for child in eq.children])
|
144
|
-
def logic1(eq):
|
145
|
-
def helper(eq):
|
146
|
-
if eq.name in ["f_exist", "f_forall"]:
|
147
|
-
return TreeNode(eq.name, [eq.children[0], logic1(eq.children[1])])
|
148
|
-
if eq.name not in ["f_and", "f_or", "f_not", "f_imply", "f_equiv"]:
|
149
|
-
return eq
|
150
|
-
if eq.name == "f_equiv":
|
151
|
-
A, B = eq.children
|
152
|
-
A, B = logic1(A), logic1(B)
|
153
|
-
A, B = dowhile(A, logic2), dowhile(B, logic2)
|
154
|
-
return flatten_tree((A & B) | (A.fx("not") & B.fx("not")))
|
155
|
-
if eq.name == "f_imply":
|
156
|
-
|
157
|
-
A, B = eq.children
|
158
|
-
A, B = logic1(A), logic1(B)
|
159
|
-
A, B = dowhile(A, logic2), dowhile(B, logic2)
|
160
|
-
return flatten_tree(A.fx("not") | B)
|
161
|
-
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
162
|
-
if eq.name in ["f_exist", "f_forall"]:
|
163
|
-
return TreeNode(eq.name, [eq.children[0], logic1(eq.children[1])])
|
164
|
-
if eq.name not in ["f_and", "f_or", "f_not", "f_imply", "f_equiv"]:
|
165
|
-
return eq
|
166
|
-
eq = helper(eq)
|
167
|
-
eq = flatten_tree(eq)
|
168
|
-
|
169
|
-
if len(eq.children) > 2:
|
170
|
-
lst = []
|
171
|
-
l = len(eq.children)
|
172
|
-
|
173
|
-
# Handle last odd child directly
|
174
|
-
if l % 2 == 1:
|
175
|
-
last_child = eq.children[-1]
|
176
|
-
# expand/simplify only if needed
|
177
|
-
if isinstance(last_child, TreeNode):
|
178
|
-
last_child = dowhile(last_child, logic2)
|
179
|
-
lst.append(last_child)
|
180
|
-
l -= 1
|
181
|
-
|
182
|
-
# Pairwise combine children
|
183
|
-
for i in range(0, l, 2):
|
184
|
-
left, right = eq.children[i], eq.children[i+1]
|
185
|
-
pair = TreeNode(eq.name, [left, right])
|
186
|
-
simplified = dowhile(logic1(pair), logic2)
|
187
|
-
lst.append(simplified)
|
188
|
-
|
189
|
-
# If only one element left, just return it instead of nesting
|
190
|
-
if len(lst) == 1:
|
191
|
-
return flatten_tree(lst[0])
|
192
|
-
|
193
|
-
# Otherwise rewrap
|
194
|
-
return flatten_tree(TreeNode(eq.name, lst))
|
195
|
-
|
196
|
-
if eq.name == "f_and":
|
197
|
-
lst= []
|
198
|
-
for child in eq.children:
|
199
|
-
if child.name == "f_or":
|
200
|
-
lst.append(child.children)
|
201
|
-
else:
|
202
|
-
lst.append([child])
|
203
|
-
out = TreeNode("f_or", [])
|
204
|
-
for item in itertools.product(*lst):
|
205
|
-
c = TreeNode("f_and", list(item))
|
206
|
-
out.children.append(c)
|
207
|
-
if len(out.children) == 1:
|
208
|
-
out = out.children[0]
|
209
|
-
return flatten_tree(out)
|
210
|
-
elif eq.name == "f_or":
|
211
|
-
lst= []
|
212
|
-
for child in eq.children:
|
213
|
-
if child.name == "f_and":
|
214
|
-
lst.append(child.children)
|
215
|
-
else:
|
216
|
-
lst.append([child])
|
217
|
-
out = TreeNode("f_and", [])
|
218
|
-
for item in itertools.product(*lst):
|
219
|
-
c = TreeNode("f_or", list(item))
|
220
|
-
out.children.append(c)
|
221
|
-
if len(out.children) == 1:
|
222
|
-
out = out.children[0]
|
223
|
-
return flatten_tree(out)
|
224
|
-
return TreeNode(eq.name, [logic1(child) for child in eq.children])
|
1
|
+
import itertools
|
2
|
+
from .base import *
|
3
|
+
|
4
|
+
def logic0(eq):
|
5
|
+
if eq.children is None or len(eq.children)==0:
|
6
|
+
return eq
|
7
|
+
if eq.name in ["f_eq", "f_lt", "f_gt" "f_ge"] and eq.children[1].name[:2]=="d_" and eq.children[0].name[:2]=="d_":
|
8
|
+
a, b = int(eq.children[0].name[2:]), int(eq.children[1].name[2:])
|
9
|
+
if eq.name == "f_eq":
|
10
|
+
return tree_form("s_true") if a==b else tree_form("s_false")
|
11
|
+
if eq.name == "f_ge":
|
12
|
+
return tree_form("s_true") if a>=b else tree_form("s_false")
|
13
|
+
if eq.name == "f_lt":
|
14
|
+
return tree_form("s_true") if a < b else tree_form("s_false")
|
15
|
+
if eq.name == "f_ge":
|
16
|
+
return TreeNode("f_gt", eq.children) | TreeNode("f_eq", eq.children)
|
17
|
+
|
18
|
+
if eq.name == "f_gt":
|
19
|
+
return TreeNode("f_lt", eq.children).fx("not") & TreeNode("f_eq", eq.children).fx("not")
|
20
|
+
|
21
|
+
if eq.name == "f_le":
|
22
|
+
return TreeNode("f_lt", eq.children) | TreeNode("f_eq", eq.children)
|
23
|
+
return TreeNode(eq.name, [logic0(child) for child in eq.children])
|
24
|
+
def logic3(eq):
|
25
|
+
if eq.name == "f_forall" and eq.children[1] in [tree_form("s_true"), tree_form("s_false")]:
|
26
|
+
return eq.children[1]
|
27
|
+
if eq.name == "f_not" and eq.children[0].name == "f_exist":
|
28
|
+
return TreeNode("f_forall", [eq.children[0].children[0], eq.children[0].children[1].fx("not")])
|
29
|
+
if eq.name == "f_exist" and eq.children[1].name == "f_or":
|
30
|
+
return TreeNode("f_or", [TreeNode("f_exist", [eq.children[0], child]) for child in eq.children[1].children])
|
31
|
+
if eq.name == "f_forall" and eq.children[1].name == "f_and":
|
32
|
+
return TreeNode("f_and", [TreeNode("f_forall", [eq.children[0], child]) for child in eq.children[1].children])
|
33
|
+
if eq.name == "f_exist":
|
34
|
+
return TreeNode("f_forall", [eq.children[0], eq.children[1].fx("not")]).fx("not")
|
35
|
+
return TreeNode(eq.name, [logic3(child) for child in eq.children])
|
36
|
+
def logic2(eq):
|
37
|
+
if eq.name in ["f_exist", "f_forall"]:
|
38
|
+
return TreeNode(eq.name, [eq.children[0], logic2(eq.children[1])])
|
39
|
+
if eq.name not in ["f_and", "f_or", "f_not", "f_imply", "f_equiv"]:
|
40
|
+
return eq
|
41
|
+
def convv(eq):
|
42
|
+
if eq == tree_form("s_true"):
|
43
|
+
return True
|
44
|
+
if eq == tree_form("s_false"):
|
45
|
+
return False
|
46
|
+
return None
|
47
|
+
def conv2(val):
|
48
|
+
if val:
|
49
|
+
return tree_form("s_true")
|
50
|
+
return tree_form("s_false")
|
51
|
+
if all(convv(child) is not None for child in eq.children):
|
52
|
+
if eq.name == "f_not":
|
53
|
+
return conv2(not convv(eq.children[0]))
|
54
|
+
elif eq.name == "f_or":
|
55
|
+
return conv2(convv(eq.children[0]) or convv(eq.children[1]))
|
56
|
+
elif eq.name == "f_and":
|
57
|
+
return conv2(convv(eq.children[0]) and convv(eq.children[1]))
|
58
|
+
if eq == tree_form("s_false").fx("not"):
|
59
|
+
return tree_form("s_true")
|
60
|
+
if eq.name == "f_not":
|
61
|
+
if eq.children[0].name == "f_not":
|
62
|
+
return eq.children[0].children[0]
|
63
|
+
elif eq.children[0].name in ["f_or", "f_and"]:
|
64
|
+
out = TreeNode({"f_or":"f_and", "f_and":"f_or"}[eq.children[0].name], [])
|
65
|
+
for child in eq.children[0].children:
|
66
|
+
out.children.append(child.fx("not"))
|
67
|
+
return out
|
68
|
+
if eq.name in ["f_and", "f_or"]:
|
69
|
+
for i in range(len(eq.children)):
|
70
|
+
for j in range(len(eq.children)):
|
71
|
+
if i ==j:
|
72
|
+
continue
|
73
|
+
if eq.children[i] == eq.children[j].fx("not"):
|
74
|
+
eq2 = copy.deepcopy(eq)
|
75
|
+
eq2.children.pop(max(i, j))
|
76
|
+
eq2.children.pop(min(i, j))
|
77
|
+
eq2.children.append({"f_or":tree_form("s_true"), "f_and":tree_form("s_false")}[eq.name])
|
78
|
+
if len(eq2.children) == 1:
|
79
|
+
return eq2.children[0]
|
80
|
+
return eq2
|
81
|
+
if eq.name in ["f_and", "f_or"]:
|
82
|
+
for i in range(len(eq.children)):
|
83
|
+
if eq.children[i] == tree_form("s_false"):
|
84
|
+
eq2 = copy.deepcopy(eq)
|
85
|
+
eq2.children.pop(i)
|
86
|
+
if eq.name == "f_and":
|
87
|
+
return tree_form("s_false")
|
88
|
+
if len(eq2.children) == 1:
|
89
|
+
return eq2.children[0]
|
90
|
+
return eq2
|
91
|
+
elif eq.children[i] == tree_form("s_true"):
|
92
|
+
eq2 = copy.deepcopy(eq)
|
93
|
+
eq2.children.pop(i)
|
94
|
+
if eq.name == "f_or":
|
95
|
+
return tree_form("s_true")
|
96
|
+
if len(eq2.children) == 1:
|
97
|
+
return eq2.children[0]
|
98
|
+
return eq2
|
99
|
+
if eq.name in ["f_and", "f_or"]:
|
100
|
+
lst = remove_duplicates_custom(eq.children, lambda x,y: x==y)
|
101
|
+
if len(lst) < len(eq.children):
|
102
|
+
if len(lst) == 1:
|
103
|
+
return lst[0]
|
104
|
+
return TreeNode(eq.name, lst)
|
105
|
+
|
106
|
+
if eq.name in ["f_and", "f_or"] and any(child.children is not None and len(child.children)!=0 for child in eq.children):
|
107
|
+
for i in range(len(eq.children),1,-1):
|
108
|
+
for item in itertools.combinations(enumerate(eq.children), i):
|
109
|
+
op = "f_and"
|
110
|
+
if eq.name == "f_and":
|
111
|
+
op = "f_or"
|
112
|
+
item3 = []
|
113
|
+
for item4 in item:
|
114
|
+
item3.append(item4[0])
|
115
|
+
item5 = []
|
116
|
+
for item4 in item:
|
117
|
+
item5.append(item4[1])
|
118
|
+
item = item5
|
119
|
+
out = None
|
120
|
+
for j in range(len(item)):
|
121
|
+
out = set(item[j].children)
|
122
|
+
for item2 in item:
|
123
|
+
if item2.name == op:
|
124
|
+
out = out & set(item2.children)
|
125
|
+
else:
|
126
|
+
out = out & set([item2])
|
127
|
+
if out == set(item[j].children):
|
128
|
+
break
|
129
|
+
out = None
|
130
|
+
if out is None:
|
131
|
+
continue
|
132
|
+
out = list(out)
|
133
|
+
if out == []:
|
134
|
+
continue
|
135
|
+
if len(out) != 1:
|
136
|
+
out = [TreeNode(op, out)]
|
137
|
+
for item4 in list(set(range(len(eq.children))) - set(item3)):
|
138
|
+
out.append(eq.children[item4])
|
139
|
+
if len(out) == 1:
|
140
|
+
return out[0]
|
141
|
+
output = flatten_tree(TreeNode(eq.name, out))
|
142
|
+
return output
|
143
|
+
return TreeNode(eq.name, [flatten_tree(logic2(child)) for child in eq.children])
|
144
|
+
def logic1(eq):
|
145
|
+
def helper(eq):
|
146
|
+
if eq.name in ["f_exist", "f_forall"]:
|
147
|
+
return TreeNode(eq.name, [eq.children[0], logic1(eq.children[1])])
|
148
|
+
if eq.name not in ["f_and", "f_or", "f_not", "f_imply", "f_equiv"]:
|
149
|
+
return eq
|
150
|
+
if eq.name == "f_equiv":
|
151
|
+
A, B = eq.children
|
152
|
+
A, B = logic1(A), logic1(B)
|
153
|
+
A, B = dowhile(A, logic2), dowhile(B, logic2)
|
154
|
+
return flatten_tree((A & B) | (A.fx("not") & B.fx("not")))
|
155
|
+
if eq.name == "f_imply":
|
156
|
+
|
157
|
+
A, B = eq.children
|
158
|
+
A, B = logic1(A), logic1(B)
|
159
|
+
A, B = dowhile(A, logic2), dowhile(B, logic2)
|
160
|
+
return flatten_tree(A.fx("not") | B)
|
161
|
+
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
162
|
+
if eq.name in ["f_exist", "f_forall"]:
|
163
|
+
return TreeNode(eq.name, [eq.children[0], logic1(eq.children[1])])
|
164
|
+
if eq.name not in ["f_and", "f_or", "f_not", "f_imply", "f_equiv"]:
|
165
|
+
return eq
|
166
|
+
eq = helper(eq)
|
167
|
+
eq = flatten_tree(eq)
|
168
|
+
|
169
|
+
if len(eq.children) > 2:
|
170
|
+
lst = []
|
171
|
+
l = len(eq.children)
|
172
|
+
|
173
|
+
# Handle last odd child directly
|
174
|
+
if l % 2 == 1:
|
175
|
+
last_child = eq.children[-1]
|
176
|
+
# expand/simplify only if needed
|
177
|
+
if isinstance(last_child, TreeNode):
|
178
|
+
last_child = dowhile(last_child, logic2)
|
179
|
+
lst.append(last_child)
|
180
|
+
l -= 1
|
181
|
+
|
182
|
+
# Pairwise combine children
|
183
|
+
for i in range(0, l, 2):
|
184
|
+
left, right = eq.children[i], eq.children[i+1]
|
185
|
+
pair = TreeNode(eq.name, [left, right])
|
186
|
+
simplified = dowhile(logic1(pair), logic2)
|
187
|
+
lst.append(simplified)
|
188
|
+
|
189
|
+
# If only one element left, just return it instead of nesting
|
190
|
+
if len(lst) == 1:
|
191
|
+
return flatten_tree(lst[0])
|
192
|
+
|
193
|
+
# Otherwise rewrap
|
194
|
+
return flatten_tree(TreeNode(eq.name, lst))
|
195
|
+
|
196
|
+
if eq.name == "f_and":
|
197
|
+
lst= []
|
198
|
+
for child in eq.children:
|
199
|
+
if child.name == "f_or":
|
200
|
+
lst.append(child.children)
|
201
|
+
else:
|
202
|
+
lst.append([child])
|
203
|
+
out = TreeNode("f_or", [])
|
204
|
+
for item in itertools.product(*lst):
|
205
|
+
c = TreeNode("f_and", list(item))
|
206
|
+
out.children.append(c)
|
207
|
+
if len(out.children) == 1:
|
208
|
+
out = out.children[0]
|
209
|
+
return flatten_tree(out)
|
210
|
+
elif eq.name == "f_or":
|
211
|
+
lst= []
|
212
|
+
for child in eq.children:
|
213
|
+
if child.name == "f_and":
|
214
|
+
lst.append(child.children)
|
215
|
+
else:
|
216
|
+
lst.append([child])
|
217
|
+
out = TreeNode("f_and", [])
|
218
|
+
for item in itertools.product(*lst):
|
219
|
+
c = TreeNode("f_or", list(item))
|
220
|
+
out.children.append(c)
|
221
|
+
if len(out.children) == 1:
|
222
|
+
out = out.children[0]
|
223
|
+
return flatten_tree(out)
|
224
|
+
return TreeNode(eq.name, [logic1(child) for child in eq.children])
|