def make_comp_maint_func(clausetools, fresh_var_prefix, fresh_join_names, comp, result_var, rel, op, *, counted): """Make maintenance function for a comprehension.""" assert isinstance(op, (L.SetAdd, L.SetRemove)) op_name = L.set_update_name(op) func_name = N.get_maint_func_name(result_var, rel, op_name) update = L.RelUpdate(rel, op, '_elem') code = clausetools.get_maint_code(fresh_var_prefix, fresh_join_names, comp, result_var, update, counted=counted) func = L.Parser.ps(''' def _FUNC(_elem): _CODE ''', subst={ '_FUNC': func_name, '<c>_CODE': code }) return func
def make_wrap_maint_func(fresh_vars, wrapinv: WrapInvariant, op: L.setupop): fresh_var_prefix = next(fresh_vars) v = fresh_var_prefix + '_v' update_code = (L.RelUpdate(wrapinv.rel, op, v), ) func_name = wrapinv.get_maint_func_name(op) if wrapinv.unwrap: v_code = L.Parser.pc('_V = index(_elem, 0)', subst={'_V': v}) else: v_code = L.Parser.pc('_V = (_elem,)', subst={'_V': v}) func = L.Parser.ps(''' def _FUNC(_elem): _V_CODE _UPDATE ''', subst={ '_FUNC': func_name, '<c>_V_CODE': v_code, '<c>_UPDATE': update_code }) return func
def visit_AttrAssign(self, node): if node.attr not in self.objrels.Fs: return pair = L.Tuple([node.obj, node.value]) var = next(self.fresh_vars) return (L.Assign(var, pair), L.RelUpdate(N.F(node.attr), L.SetAdd(), var))
def visit_DictAssign(self, node): if not self.objrels.MAP: return triple = L.Tuple([node.target, node.key, node.value]) var = next(self.fresh_vars) return (L.Assign(var, triple), L.RelUpdate(N.MAP, L.SetAdd(), var))
def visit_AttrDelete(self, node): if node.attr not in self.objrels.Fs: return lookup = L.Attribute(node.obj, node.attr) pair = L.Tuple([node.obj, lookup]) var = next(self.fresh_vars) return (L.Assign(var, pair), L.RelUpdate(N.F(node.attr), L.SetRemove(), var))
def visit_DictDelete(self, node): if not self.objrels.MAP: return lookup = L.DictLookup(node.target, node.key, None) triple = L.Tuple([node.target, node.key, lookup]) var = next(self.fresh_vars) return (L.Assign(var, triple), L.RelUpdate(N.MAP, L.SetRemove(), var))
def visit_SetUpdate(self, node): if not isinstance(node.op, (L.SetAdd, L.SetRemove)): return if not self.objrels.M: return pair = L.Tuple([node.target, node.value]) var = next(self.fresh_vars) return (L.Assign(var, pair), L.RelUpdate(N.M, node.op, var))
def make_setfrommap_maint_func(fresh_vars, setfrommap: SetFromMapInvariant, op: str): mask = setfrommap.mask nb = L.break_mapmask(mask) # Fresh variables for components of the key and value. key_vars = N.get_subnames('_key', nb) decomp_code = (L.DecompAssign(key_vars, L.Name('_key')), ) vars = L.combine_by_mask(mask, key_vars, ['_val']) elem = L.tuplify(vars) fresh_var_prefix = next(fresh_vars) elem_var = fresh_var_prefix + '_elem' decomp_code += (L.Assign(elem_var, elem), ) setopcls = {'assign': L.SetAdd, 'delete': L.SetRemove}[op] update_code = (L.RelUpdate(setfrommap.rel, setopcls(), elem_var), ) func_name = setfrommap.get_maint_func_name(op) if op == 'assign': func = L.Parser.ps(''' def _FUNC(_key, _val): _DECOMP _UPDATE ''', subst={ '_FUNC': func_name, '<c>_DECOMP': decomp_code, '<c>_UPDATE': update_code }) elif op == 'delete': lookup_expr = L.DictLookup(L.Name(setfrommap.map), L.Name('_key'), None) func = L.Parser.ps(''' def _FUNC(_key): _val = _LOOKUP _DECOMP _UPDATE ''', subst={ '_FUNC': func_name, '_LOOKUP': lookup_expr, '<c>_DECOMP': decomp_code, '<c>_UPDATE': update_code }) else: assert () return func
def visit_SetUpdate(self, node): if not (isinstance(node.target, L.Name) and node.target.id in self.rels): return node code = () if isinstance(node.value, L.Name): elem_var = node.value.id else: elem_var = next(self.fresh_vars) code += L.Parser.pc('_VAR = _VALUE', subst={ '_VAR': elem_var, '_VALUE': node.value }) update = L.RelUpdate(node.target.id, node.op, elem_var) code += (update, ) return code