@@ 0,0 1,22 @@
+
+
+from type_stack_calc.sets.intersection import do_op_2
+from type_stack_calc.tp.intersection import the_no_ans, TpIntersection as ti
+from type_stack_calc.sets.range import SetRange as r
+
+print(ti(the_no_ans, the_no_ans))
+print(ti(the_no_ans, 4))
+print(ti(1).smoosh(ti(2)))
+print(ti(1, 4))
+
+print(ti(r(0, 5), 3))
+print(ti(5, r(0, 5), 3))
+
+print("MIAUW")
+x = ti(2, the_no_ans, the_no_ans)
+y = ti(3)
+
+print(x.set_union(y))
+
+print('...', ti(r(2,3)).set_union(ti(the_no_ans)))
+print('...', ti(the_no_ans).smoosh(ti(r(2,3))))
@@ 42,7 42,7 @@ def merge_1(into, add, meth_name):
yield from gen
yield add # And finally the potentially merged remains.
-from type_stack_calc.util.various import list_flatten
+from type_stack_calc.util.various import list_flatten, filter_none
def merge(gen, meth_name):
"""Merges the sets and simplifies."""
@@ 60,39 60,52 @@ def _do_op_1(self, opkey):
"""Operation for one argument.. NOTE: if no function, it's dropped.."""
for set in self:
fun = getattr(type(set), opkey, None)
- got = fun and fun(set)
- if type(got) == list:
- yield from got
- elif got is not None:
- assert not isinstance(got, (int, float)), (opkey, got)
- yield got
+ if fun:
+ yield fun(set)
def _do_op_2(x, opkey, y):
"""Do the operation with the given single other argument. Raw generator version."""
# NOTE: used to be code here to keep untouched stuff. Unsure of utility to removed.(8d1b363)
+ for ex in x:
+ assert not isinstance(ex, (int, float)), (opkey, ex)
+ fun = getattr(type(ex), opkey, None)
+ if fun is not None: # Has a function, for this operation try each,
+ yield from filter_none(fun(ex, ey) for ey in y)
+
+def _do_op_2_track(x, opkey, y, did_i, did_j):
+ """Sometimes no-operation between things means they should stay,
+this function helps with that."""
for i, ex in enumerate(x):
assert not isinstance(ex, (int, float)), (opkey, ex)
fun = getattr(type(ex), opkey, None)
- if fun is not None: # Has a function, for this operation try each.
+ if fun is not None:
for j, ey in enumerate(y):
got = fun(ex, ey)
- if got is not None:
- assert not isinstance(got, (int, float)), (opkey, got)
- if type(got) == list: # Possibly deal with list.
- yield from got
- else:
- yield got
+ if type(got) is list:
+ yield from got
+ elif got is not None:
+ yield got
+ else:
+ continue
+ did_i.add(i)
+ did_j.add(j)
+
+def do_op_1(self, opkey):
+ return filter_none(list_flatten(_do_op_1(self, opkey)))
+
+def do_op_2(x, opkey, y):
+ return filter_none(list_flatten(_do_op_2(x, opkey, y)))
def _m(n, key):
"""Generates function to calculate the new type based on all applicable methods, for one or two arguments. If two arguments it will try iparam and rev_iparam."""
opkey, rev_opkey = f"iparam_{key}", f"rev_iparam_{key}"
if n == 1:
def ret(self):
- return type(self)(*_do_op_1(self, opkey))
+ return type(self)(*do_op_1(self, opkey))
elif n == 2:
def ret(y, x):
- return type(x)(*_do_op_2(x, opkey, y),
- *_do_op_2(y, rev_opkey, x))
+ return type(x)(*do_op_2(x, opkey, y),
+ *do_op_2(y, rev_opkey, x))
else:
assert False, f"Intersection-combination type calculation only for upto 2 arguments. Got {n}"
return ret
@@ 129,10 142,17 @@ class SetIntersection(tuple):
ret = (*self, *y) if isinstance(y, SetIntersection) else (*self, y)
return type(self)(*ret)
+ def _set_union(self, y):
+ did_i, did_j = set(), set()
+ yield from _do_op_2_track(self, 'set_union', y, did_i, did_j)
+ yield from _do_op_2_track(y, 'set_union', self, did_j, did_i)
+ if len(did_i) < len(self): # Non-touched things stay.
+ yield from (ex for i, ex in enumerate(self) if i not in did_i)
+ if len(did_j) < len(y):
+ yield from (ey for j, ey in enumerate(y) if j not in did_j)
+
def set_union(self, y):
- # TODO if neither touches each other, something maybe lost?
- return type(self)(*_do_op_2(self, 'set_union', y),
- *_do_op_2(y, 'set_union', self))
+ return type(self)(*self._set_union(y))
def get_param_final(self, name):
"""Gets out a component.
@@ 23,10 23,6 @@ class TpNoAns(tuple, BaseType):
name, c_name, is_const = 'NoAns', 'NoAns', True
tkey = ('no_ans',)
- def set_union(self, _other):
- """When unioning, it stays."""
- return self
-
def set_intersect(self, other):
"""One no-answer-is-possible indication is sufficient."""
if isinstance(other, TpNoAns): return self