def test_deep_variable_product_with_empty_top_layer(self): x1 = DummyValue(1) v1 = self.prog.NewVariable([x1], [], self.current_location) v2 = self.prog.NewVariable([], [], self.current_location) product = cfg_utils.deep_variable_product([v1, v2]) rows = [{a.data for a in row} for row in product] self.assertCountEqual(rows, [{x1}])
def testDeepVariableProductWithEmptyTopLayer(self): x1 = DummyValue(1) v1 = self.prog.NewVariable([x1], [], self.current_location) v2 = self.prog.NewVariable([], [], self.current_location) product = cfg_utils.deep_variable_product([v1, v2]) rows = [{a.data for a in row} for row in product] six.assertCountEqual(self, rows, [{x1}])
def test_deep_variable_product_with_empty_variables(self): x1 = DummyValue(1) v1 = self.prog.NewVariable([x1], [], self.current_location) v2 = self.prog.NewVariable([], [], self.current_location) x1.set_parameters([v2]) product = cfg_utils.deep_variable_product([v1]) rows = [{a.data for a in row} for row in product] six.assertCountEqual(self, rows, [{x1}])
def testDeepVariableProductWithEmptyVariables(self): x1 = DummyValue(1) v1 = self.prog.NewVariable([x1], [], self.current_location) v2 = self.prog.NewVariable([], [], self.current_location) x1.set_parameters([v2]) product = cfg_utils.deep_variable_product([v1]) rows = [{a.data for a in row} for row in product] self.assertItemsEqual(rows, [{x1}])
def test_deep_variable_product(self): x1, x2, x3, x4, x5, x6 = [DummyValue(i + 1) for i in range(6)] v1 = self.prog.NewVariable([x1, x2], [], self.current_location) v2 = self.prog.NewVariable([x3], [], self.current_location) v3 = self.prog.NewVariable([x4, x5], [], self.current_location) v4 = self.prog.NewVariable([x6], [], self.current_location) x1.set_parameters([v2, v3]) product = cfg_utils.deep_variable_product([v1, v4]) rows = [{a.data for a in row} for row in product] self.assertCountEqual(rows, [ {x1, x3, x4, x6}, {x1, x3, x5, x6}, {x2, x6}, ])
def get_views(variables, node): """Get all possible views of the given variables at a particular node. For performance reasons, this method uses node.CanHaveCombination for filtering. For a more precise check, you can call node.HasCombination(list(view.values())). Do so judiciously, as the latter method can be very slow. This function can be used either as a regular generator or in an optimized way to yield only functionally unique views: views = get_views(...) skip_future = None while True: try: view = views.send(skip_future) except StopIteration: break ... The caller should set `skip_future` to True when it is safe to skip equivalent future views and False otherwise. Args: variables: The variables. node: The node. Yields: A datatypes.AcessTrackingDict mapping variables to bindings. """ try: combinations = cfg_utils.deep_variable_product(variables) except cfg_utils.TooComplexError: combinations = ((var.AddBinding(node.program.default_data, [], node) for var in variables), ) seen = [] # the accessed subsets of previously seen views for combination in combinations: view = {value.variable: value for value in combination} if any(subset <= six.viewitems(view) for subset in seen): # Optimization: This view can be skipped because it matches the accessed # subset of a previous one. log.info("Skipping view (already seen): %r", view) continue combination = list(view.values()) if not node.CanHaveCombination(combination): log.info("Skipping combination (unreachable): %r", combination) continue view = datatypes.AccessTrackingDict(view) skip_future = yield view if skip_future: # Skip future views matching this accessed subset. seen.append(six.viewitems(view.accessed_subset))