def test_chemistries(): """Return a subset of chemistries to test conversion.""" chems = [ utils.Chemistry(potion_map=stones_and_potions.all_fixed_potion_map(), stone_map=stones_and_potions.all_fixed_stone_map(), graph=graphs.create_graph_from_constraint( graphs.no_bottleneck_constraints()[0]), rotation=np.eye(3)), utils.Chemistry(potion_map=stones_and_potions.PotionMap([1, 0, 2], [1, 1, -1]), stone_map=stones_and_potions.StoneMap( np.array([-1, 1, -1])), graph=graphs.create_graph_from_constraint( graphs.bottleneck1_constraints()[0]), rotation=stones_and_potions.possible_rotations()[-1]) ] for r in stones_and_potions.possible_rotations(): for sm in stones_and_potions.possible_stone_maps(): chems.append( utils.Chemistry( potion_map=stones_and_potions.all_fixed_potion_map(), stone_map=sm, graph=graphs.create_graph_from_constraint( graphs.no_bottleneck_constraints()[0]), rotation=r)) return chems
def make_fixed_chem_env( constraint=None, potion_map=_FIXED_POTION_MAP, stone_map=_FIXED_STONE_MAP, rotation=_FIXED_ROTATION, test_stones=None, test_potions=None, **kwargs): if constraint is None: constraint = graphs.no_bottleneck_constraints()[0] env = symbolic_alchemy.get_symbolic_alchemy_fixed( episode_items=utils.EpisodeItems( potions=test_potions or _TEST_POTIONS, stones=test_stones or _TEST_STONES), chemistry=utils.Chemistry( graph=graphs.create_graph_from_constraint(constraint), potion_map=potion_map, stone_map=stone_map, rotation=rotation), reward_weights=reward_fcn(), max_steps_per_trial=_MAX_STEPS_PER_TRIAL, **kwargs) return env
def test_see_chem_before_reset(self): env = self._make_env( see_chemistry=utils.ChemistrySeen( content=utils.ElementContent.GROUND_TRUTH), constraint=graphs.no_bottleneck_constraints()[0]) obs = env.observation() # Observation should be all unknown because we have not reset the # environment yet. np.testing.assert_allclose(obs[_CHEM_NAME], [0.5] * 28) # After resetting none of the chem should be unknown. env.reset() obs = env.observation() np.testing.assert_array_less( 0.01 * np.ones((28,)), np.abs(obs[_CHEM_NAME] - np.array([0.5] * 28)))
def get_potion_tests(): """Test cases for converting between potions and unity potion properties.""" potion_tests = [] for pm in stones_and_potions.possible_potion_maps( precomputed_maps.get_perm_index_conversion()[1]): potion_tests.append(( [(pm.apply_inverse(l), l) for l in stones_and_potions.possible_latent_potions()], functools.partial( unity_python_conversion.to_potion_unity_properties, # It shouldn't matter what graph we use for testing this part. graph=graphs.create_graph_from_constraint( graphs.no_bottleneck_constraints()[0])), unity_python_conversion._potions_from_potion_unity_properties, lambda x: x, _make_tuple)) return potion_tests
def setUp(self): super().setUp() self.env3d_mock = Mock3DEnv() self.chemistry = utils.Chemistry( potion_map=stones_and_potions.all_fixed_potion_map(), stone_map=stones_and_potions.all_fixed_stone_map(), graph=graphs.create_graph_from_constraint( graphs.no_bottleneck_constraints()[0]), rotation=np.eye(3)) self.items = utils.EpisodeItems(potions=[[Potion(0, 0, 1)], [Potion(1, 2, -1)]], stones=[[Stone(2, [-1, -1, -1])], [Stone(3, [1, 1, 1])]]) self.env3d_mock.set_chemistry_and_items(self.chemistry, self.items) self.wrapper = symbolic_alchemy_wrapper.SymbolicAlchemyWrapper( self.env3d_mock, 'alchemy/perceptual_mapping_randomized_with_random_bottleneck')
Counter = collections.Counter AlignedStone = stones_and_potions.AlignedStone PerceivedPotion = stones_and_potions.PerceivedPotion PotionMap = stones_and_potions.PotionMap StoneMap = stones_and_potions.StoneMap Stone = stones_and_potions.Stone Potion = stones_and_potions.Potion AddMatrixEventTracker = symbolic_alchemy_trackers.AddMatrixEventTracker ScoreTracker = symbolic_alchemy_trackers.ScoreTracker BeliefStateTracker = symbolic_alchemy_trackers.BeliefStateTracker _ALL_FIXED_POTION_MAP = stones_and_potions.all_fixed_potion_map() _ALL_FIXED_STONE_MAP = stones_and_potions.all_fixed_stone_map() _ALL_FIXED_GRAPH = graphs.create_graph_from_constraint( graphs.no_bottleneck_constraints()[0]) _BOTTLENECK1_CONSTRAINT = graphs.bottleneck1_constraints()[0] _BOTTLENECK1_GRAPH = graphs.create_graph_from_constraint( _BOTTLENECK1_CONSTRAINT) def add_trackers_to_env(env, reward_weights, precomputed, init_belief_state): env.add_trackers({ AddMatrixEventTracker.NAME: AddMatrixEventTracker(), ScoreTracker.NAME: ScoreTracker(reward_weights), BeliefStateTracker.NAME: BeliefStateTracker(precomputed, env, init_belief_state) })
class SymbolicAlchemySeeChemistryTest(parameterized.TestCase): """We don't do the full mixin tests for the chemistry observation.""" def _make_env(self, see_chemistry, constraint, **kwargs): return make_fixed_chem_env( constraint=constraint, see_chemistries={_CHEM_NAME: see_chemistry}, observe_used=True, end_trial_action=False, **kwargs) @parameterized.parameters( # In the graph observations edges are in the following order: # _________11__________ # /| /| # 9/ | 10/ | # / | / | # /___|_____8_________/ | # | |6 | |7 # | | | | # |2 | |4 | # | |_______5_______|___| # | / | / # | /1 | /3 # | / | / # |/________0_________|/ # # With coordinate system: # | # |z / # | /y # | / # |/___x___ # {'see_chemistry': utils.ChemistrySeen( potion_map=utils.PotionMapElement(present=False), stone_map=utils.StoneMapElement(present=False), rotation=utils.RotationElement(present=False), content=utils.ElementContent.GROUND_TRUTH), 'constraint': graphs.no_bottleneck_constraints()[0], # With no constraints all edges should be present 'expected_obs': np.ones((12,), np.float32), 'expected_len': 12}, {'see_chemistry': utils.ChemistrySeen( potion_map=utils.PotionMapElement(present=False), stone_map=utils.StoneMapElement(present=False), rotation=utils.RotationElement(present=False), content=utils.ElementContent.GROUND_TRUTH), 'constraint': graphs.bottleneck1_constraints()[0], # For bottleneck1 constraint the only x direction edge that exists is 8, # so 0, 5 and 11 are missing. 'expected_obs': np.array([0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0], np.float32), 'expected_len': 12}, {'see_chemistry': utils.ChemistrySeen( stone_map=utils.StoneMapElement(present=False), graph=utils.GraphElement(present=False), rotation=utils.RotationElement(present=False), content=utils.ElementContent.GROUND_TRUTH), 'constraint': graphs.no_bottleneck_constraints()[0], # First 6 entries are a 1-hot for the dimension map, in this case the # dimension map used is the first one. # The next 3 entries are 0 or 1 for the direction map, in this case all # directions are positive. 'expected_obs': np.array([1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0], np.float32), 'expected_len': 9}, {'see_chemistry': utils.ChemistrySeen( potion_map=utils.PotionMapElement(present=False), graph=utils.GraphElement(present=False), rotation=utils.RotationElement(present=False), content=utils.ElementContent.GROUND_TRUTH), 'constraint': graphs.no_bottleneck_constraints()[0], # 3 entries are 0 or 1 for the direction map, in this case all directions # are positive. 'expected_obs': np.array([1.0, 1.0, 1.0], np.float32), 'expected_len': 3}, {'see_chemistry': utils.ChemistrySeen( content=utils.ElementContent.GROUND_TRUTH), 'constraint': graphs.no_bottleneck_constraints()[0], # Observations are from the previous tests concatenated with graph first, # then potion map then stone map. 'expected_obs': np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, # graph 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, # graph 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, # potion dim map 1.0, 1.0, 1.0, # potion dir map 1.0, 1.0, 1.0, # stone map 1.0, 0.0, 0.0, 0.0], np.float32), # rotation 'expected_len': 28}, # Tests for the belief state observation. {'see_chemistry': utils.ChemistrySeen( potion_map=utils.PotionMapElement(present=False), stone_map=utils.StoneMapElement(present=False), rotation=utils.RotationElement(present=False), content=utils.ElementContent.BELIEF_STATE, precomputed='perceptual_mapping_randomized_with_random_bottleneck'), 'constraint': graphs.no_bottleneck_constraints()[0], # With no actions the belief state should be unknown for all edges. 'expected_obs': 0.5 * np.ones((12,), np.float32), 'expected_len': 12}, {'see_chemistry': utils.ChemistrySeen( potion_map=utils.PotionMapElement(present=False), stone_map=utils.StoneMapElement(present=False), rotation=utils.RotationElement(present=False), content=utils.ElementContent.BELIEF_STATE, precomputed='perceptual_mapping_randomized_with_random_bottleneck'), 'constraint': graphs.bottleneck1_constraints()[0], # It shouldn't make a difference whether the underlying chemistry has a # constraint or not everythin is unknown. 'expected_obs': 0.5 * np.ones((12,), np.float32), 'expected_len': 12}, {'see_chemistry': utils.ChemistrySeen( stone_map=utils.StoneMapElement(present=False), graph=utils.GraphElement(present=False), rotation=utils.RotationElement(present=False), content=utils.ElementContent.BELIEF_STATE, precomputed='perceptual_mapping_randomized_with_random_bottleneck'), 'constraint': graphs.no_bottleneck_constraints()[0], # First 6 entries are a 1-hot for the dimension map, with no actions all # of the dimesnsion maps are possible so the entries are all unknown. # The next 3 entries are 0 or 1 for the direction map, or 0.5 for unknown # which is the case if no actions are taken. 'expected_obs': 0.5 * np.ones((9,), np.float32), 'expected_len': 9}, {'see_chemistry': utils.ChemistrySeen( potion_map=utils.PotionMapElement(present=False), graph=utils.GraphElement(present=False), rotation=utils.RotationElement(present=False), content=utils.ElementContent.BELIEF_STATE, precomputed='perceptual_mapping_randomized_with_random_bottleneck'), 'constraint': graphs.no_bottleneck_constraints()[0], # 3 entries are 0 or 1 for the direction map, in this case all directions # are positive, since the test stones include an instance of the best # stone, the stone map should be known from the start. 'expected_obs': np.array([1.0, 1.0, 1.0], np.float32), 'expected_len': 3}, {'see_chemistry': utils.ChemistrySeen( content=utils.ElementContent.BELIEF_STATE, rotation=utils.RotationElement(present=False), precomputed='perceptual_mapping_randomized_with_random_bottleneck'), 'constraint': graphs.no_bottleneck_constraints()[0], # Observations are from the previous tests concatenated with graph first, # then potion map then stone map. 'expected_obs': np.array([0.5, 0.5, 0.5, 0.5, 0.5, 0.5, # graph 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, # graph 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, # potion dim map 0.5, 0.5, 0.5, # potion dir map 1.0, 1.0, 1.0], np.float32), # stone map 'expected_len': 24}, {'see_chemistry': utils.ChemistrySeen( content=utils.ElementContent.BELIEF_STATE, rotation=utils.RotationElement(present=False), precomputed='perceptual_mapping_randomized_with_random_bottleneck'), 'constraint': graphs.no_bottleneck_constraints()[0], 'actions': [utils.SlotBasedAction(stone_ind=0, potion_ind=0)], # If we put the 0th stone into the 0th potion we will see a change on # axis 1, we will become certain that the dim map is either [0, 1, 2] or # [2, 1, 0], we will become certain that the edge from (-1, -1, 1) to # (-1, 1, 1) exists. 'expected_obs': np.array([0.5, 0.5, 0.5, 0.5, 0.5, 0.5, # graph 0.5, 0.5, 0.5, 1.0, 0.5, 0.5, # graph 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, # potion dim map 0.5, 1.0, 0.5, # potion dir map 1.0, 1.0, 1.0], np.float32), # stone map 'expected_len': 24}, # Tests for a combination of content types {'see_chemistry': utils.ChemistrySeen( potion_map=utils.PotionMapElement(present=False), stone_map=utils.StoneMapElement(present=False), rotation=utils.RotationElement(present=False), groups=[ utils.GroupInChemistry( {utils.ElementType.GRAPH: {0, 1, 2, 3}}, [1.0, 0.0, 0.0]), utils.GroupInChemistry( {utils.ElementType.GRAPH: {4, 5, 6}}, [0.0, 0.0, 1.0]), utils.GroupInChemistry( {utils.ElementType.GRAPH: {7, 8, 9, 10, 11}}, [0.0, 1.0, 0.0]), ], precomputed='perceptual_mapping_randomized_with_random_bottleneck'), 'constraint': graphs.bottleneck1_constraints()[0], 'actions': [utils.SlotBasedAction(stone_ind=0, potion_ind=0)], # With no actions the belief state should be unknown for all edges. 'expected_obs': np.array( [0.0, 1.0, 1.0, 1.0, # ground truth - 0 missing 1, 2, 3 exist 0.5, 0.5, 0.5, # unknown - these are set to 0.5 # belief state - after the action 9 is known, others are unknown 0.5, 0.5, 1.0, 0.5, 0.5], np.float32), 'expected_len': 12}, # Rotation tests {'see_chemistry': utils.ChemistrySeen( potion_map=utils.PotionMapElement(present=False), stone_map=utils.StoneMapElement(present=False), graph=utils.GraphElement(present=False), content=utils.ElementContent.GROUND_TRUTH), 'constraint': graphs.no_bottleneck_constraints()[0], 'make_env_kwargs': { 'rotation': stones_and_potions.rotation_from_angles([0, 0, 0])}, 'expected_obs': np.array([1.0, 0.0, 0.0, 0.0], np.float32), 'expected_len': 4}, {'see_chemistry': utils.ChemistrySeen( potion_map=utils.PotionMapElement(present=False), stone_map=utils.StoneMapElement(present=False), graph=utils.GraphElement(present=False), content=utils.ElementContent.GROUND_TRUTH), 'constraint': graphs.no_bottleneck_constraints()[0], 'make_env_kwargs': { 'rotation': stones_and_potions.rotation_from_angles([0, 0, -45])}, 'expected_obs': np.array([0.0, 1.0, 0.0, 0.0], np.float32), 'expected_len': 4}, {'see_chemistry': utils.ChemistrySeen( potion_map=utils.PotionMapElement(present=False), stone_map=utils.StoneMapElement(present=False), graph=utils.GraphElement(present=False), content=utils.ElementContent.GROUND_TRUTH), 'constraint': graphs.no_bottleneck_constraints()[0], 'make_env_kwargs': { 'rotation': stones_and_potions.rotation_from_angles([0, -45, 0])}, 'expected_obs': np.array([0.0, 0.0, 1.0, 0.0], np.float32), 'expected_len': 4}, {'see_chemistry': utils.ChemistrySeen( potion_map=utils.PotionMapElement(present=False), stone_map=utils.StoneMapElement(present=False), graph=utils.GraphElement(present=False), content=utils.ElementContent.GROUND_TRUTH), 'constraint': graphs.no_bottleneck_constraints()[0], 'make_env_kwargs': { 'rotation': stones_and_potions.rotation_from_angles([-45, 0, 0])}, 'expected_obs': np.array([0.0, 0.0, 0.0, 1.0], np.float32), 'expected_len': 4}, # In belief state if we have stones which are unique to a particular # rotation then the rotation should be known and possibly part of the # stone map. {'see_chemistry': utils.ChemistrySeen( potion_map=utils.PotionMapElement(present=False), graph=utils.GraphElement(present=False), content=utils.ElementContent.BELIEF_STATE, precomputed=('perceptual_mapping_randomized_with_rotation_and_' 'random_bottleneck')), 'constraint': graphs.no_bottleneck_constraints()[0], 'make_env_kwargs': { 'rotation': stones_and_potions.rotation_from_angles([-45, 0, 0]), 'test_stones': [[Stone(0, [1, 1, 1]), Stone(0, [1, 1, -1])]]}, 'expected_obs': np.array( [1.0, 1.0, 1.0, # stone map 0.0, 0.0, 0.0, 1.0], np.float32), # rotation 'expected_len': 7}, # Otherwise rotation and stone map observations should both be unknown. {'see_chemistry': utils.ChemistrySeen( potion_map=utils.PotionMapElement(present=False), graph=utils.GraphElement(present=False), content=utils.ElementContent.BELIEF_STATE, precomputed=('perceptual_mapping_randomized_with_rotation_and_' 'random_bottleneck')), 'constraint': graphs.no_bottleneck_constraints()[0], 'make_env_kwargs': { 'rotation': stones_and_potions.rotation_from_angles([-45, 0, 0]), 'test_stones': [[Stone(0, [1, 1, 1])]]}, 'expected_obs': np.array( [0.5, 0.5, 0.5, # stone map 0.5, 0.5, 0.5, 0.5], np.float32), # rotation 'expected_len': 7}, {'see_chemistry': utils.ChemistrySeen( potion_map=utils.PotionMapElement(present=False), graph=utils.GraphElement(present=False), content=utils.ElementContent.BELIEF_STATE, precomputed=('perceptual_mapping_randomized_with_rotation_and_' 'random_bottleneck')), 'constraint': graphs.no_bottleneck_constraints()[0], 'make_env_kwargs': { 'rotation': stones_and_potions.rotation_from_angles([-45, 0, 0]), 'test_stones': [[Stone(0, [1, 1, 1])]]}, 'actions': [utils.SlotBasedAction(stone_ind=0, potion_ind=6)], 'expected_obs': np.array( [1.0, 1.0, 1.0, # stone map 0.0, 0.0, 0.0, 1.0], np.float32), # rotation 'expected_len': 7}, ) def test_see_chemistry( self, see_chemistry, constraint, expected_obs, expected_len, actions=None, make_env_kwargs=None): """Test the ground truth chemistry observations.""" env = self._make_env( see_chemistry=see_chemistry, constraint=constraint, **(make_env_kwargs or {})) timestep = env.reset() if actions: for action in actions: timestep = env.step_slot_based_action(action) np.testing.assert_allclose( timestep.observation[_CHEM_NAME], expected_obs) self.assertLen( timestep.observation[_CHEM_NAME], expected_len) def test_see_chem_before_reset(self): env = self._make_env( see_chemistry=utils.ChemistrySeen( content=utils.ElementContent.GROUND_TRUTH), constraint=graphs.no_bottleneck_constraints()[0]) obs = env.observation() # Observation should be all unknown because we have not reset the # environment yet. np.testing.assert_allclose(obs[_CHEM_NAME], [0.5] * 28) # After resetting none of the chem should be unknown. env.reset() obs = env.observation() np.testing.assert_array_less( 0.01 * np.ones((28,)), np.abs(obs[_CHEM_NAME] - np.array([0.5] * 28)))