def __query__(self, q): # The ordered set is needed for deterministic optimization. variables = OrderedSet() for tag in q.include: variables.update(self.__db__[tag]) for tag in q.require: variables.intersection_update(self.__db__[tag]) for tag in q.exclude: variables.difference_update(self.__db__[tag]) remove = OrderedSet() add = OrderedSet() for obj in variables: if isinstance(obj, OptimizationDatabase): def_sub_query = q if q.extra_optimizations: def_sub_query = copy.copy(q) def_sub_query.extra_optimizations = [] sq = q.subquery.get(obj.name, def_sub_query) replacement = obj.query(sq) replacement.name = obj.name remove.add(obj) add.add(replacement) variables.difference_update(remove) variables.update(add) return variables
def _build_droot_impact(destroy_handler): droot = {} # destroyed view + nonview variables -> foundation impact = {} # destroyed nonview variable -> it + all views of it root_destroyer = {} # root -> destroyer apply for app in destroy_handler.destroyers: for output_idx, input_idx_list in app.op.destroy_map.items(): if len(input_idx_list) != 1: raise NotImplementedError() input_idx = input_idx_list[0] input = app.inputs[input_idx] # Find non-view variable which is ultimatly viewed by input. view_i = destroy_handler.view_i _r = input while _r is not None: r = _r _r = view_i.get(r) input_root = r if input_root in droot: raise InconsistencyError( f"Multiple destroyers of {input_root}") droot[input_root] = input_root root_destroyer[input_root] = app # The code here add all the variables that are views of r into # an OrderedSet input_impact input_impact = OrderedSet() q = deque() q.append(input_root) while len(q) > 0: v = q.popleft() for n in destroy_handler.view_o.get(v, []): input_impact.add(n) q.append(n) for v in input_impact: assert v not in droot droot[v] = input_root impact[input_root] = input_impact impact[input_root].add(input_root) return droot, impact, root_destroyer