def the_neighbour_of(predicate, with_this, new_predicate, can_have_this, state): """ If the house contains a predicate then the neighbouring house can have another predicate eg. The man who keeps horses lives next to the one who plays hockey. If this house has horses THEN next door can have hockeybut not horses AND this house cannot have hockey :param str predicate: The predicate we are looking for. :param str with_this: Value to search with. :param str predicate: The predicate we will asign. :param str can_have_this: Value to the neighbour can have. :param dict state: The current state of the universe. """ found_with_this = einstein.get_position(with_this, state) found_have_this = einstein.get_position(can_have_this, state) if found_with_this and found_have_this: #We have assigned these rules already return state elif found_with_this: #We only know where the horse lives houses = einstein.next_to(found_with_this) if len(houses) == 1: return einstein.assign_value(houses[0], new_predicate, can_have_this, state) else: return einstein.propose_house(houses, new_predicate, can_have_this, state) elif found_have_this: #We only know where the hockey is played houses = einstein.next_to(found_have_this) if len(houses) == 1: return einstein.assign_value(houses[0], predicate, with_this, state) else: return einstein.propose_house(houses, predicate, with_this, state) else: #We don't know where either the hockey or horse live return state
def test_next_to_houses(self): """ Some rules tell you that next to a house a certain condition is true. The white house is to the left of the green house. House 2 is to the right of house 1. 1, 2, 3, 4, 5 """ self.assertIsNone(einstein.left_of('1')) self.assertIsNone(einstein.right_of('5')) self.assertIsNone(einstein.left_of('20')) self.assertEqual('1', einstein.left_of('2')) self.assertEqual('3', einstein.left_of('4')) self.assertEqual('3', einstein.right_of('2')) self.assertEqual(['2', '4'], einstein.next_to('3')) self.assertEqual(['2'], einstein.next_to('1')) self.assertEqual(['4'], einstein.next_to('5'))