def visit_IndefImgset(self, cost): # Check for constant-time relations. if cost.rel in const_rels: return Unit() # Field lookups are constant time. if N.is_F(cost.rel) and cost.mask == L.mask('bu'): return Unit() sym = symtab.get_symbols().get(cost.rel, None) if sym is None: return cost # Get types for unbound components. t = sym.type if t is None: return cost if not (isinstance(t, T.Set) and isinstance(t.elt, T.Tuple) and len(t.elt.elts) == len(cost.mask.m)): return cost mask = cost.mask elts = t.elt.elts # Process out aggregate SetFromMap result components, # which are functionally determined by the map keys. if N.is_SA(cost.rel) and mask.m[-1] == 'u': mask = mask._replace(m=mask.m[:-1]) elts = elts[:-1] _b_elts, u_elts = L.split_by_mask(mask, elts) new_cost = type_to_cost(T.Tuple(u_elts)) new_cost = normalize(new_cost) if not isinstance(new_cost, Unknown): cost = new_cost return cost
def visit_RelUpdate(self, node): if isinstance(node.op, L.SetAdd): is_add = True elif isinstance(node.op, L.SetRemove): is_add = False else: return rel = node.rel elem = L.Name(node.elem) if N.is_M(rel): set_ = L.Subscript(elem, L.Num(0)) value = L.Subscript(elem, L.Num(1)) code = (L.SetUpdate(set_, node.op, value),) elif N.is_F(rel): attr = N.get_F(rel) obj = L.Subscript(elem, L.Num(0)) value = L.Subscript(elem, L.Num(1)) if is_add: code = (L.AttrAssign(obj, attr, value),) else: code = (L.AttrDelete(obj, attr),) elif N.is_MAP(rel): map = L.Subscript(elem, L.Num(0)) key = L.Subscript(elem, L.Num(1)) value = L.Subscript(elem, L.Num(2)) if is_add: code = (L.DictAssign(map, key, value),) else: code = (L.DictDelete(map, key),) else: code = node return code