示例#1
0
def the_person_who_is(predicate, with_this, new_predicate, assign_this, state):
    """
    If the person matches a predicate then assing another predicate.
    
    eg.  The brit lives in a red house.
    
    If you find a brit assign the house red.
    Else if you find a red house assign the brit.
    Else propose the following
        If a house has no british posibilities remove red.
        If a house has no red possibilities remove british.
        
    :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 assign_this: Value to assign.
    :param dict state: The current state of the universe.
    """
    house_is_this = einstein.get_position(with_this, state)
    house_assigned_this = einstein.get_position(assign_this, state)
    if house_is_this and house_assigned_this:
        return state
    elif house_is_this:
        return einstein.assign_value(house_is_this, new_predicate, assign_this,
                                     state)
    elif house_assigned_this:
        return einstein.assign_value(house_assigned_this, predicate, with_this,
                                     state)
    else:
        return einstein.propose_link(predicate, with_this, new_predicate,
                                     assign_this, state)
示例#2
0
    def test_propose_link(self):
        """
        Proposing a value doesn't officially make an assignment.

        If the Swede keeps a bird then no one else can.
        If the Swede doesn't live in that house then neither can the bird.
        """
        # Proposing a value with no assignments made won't change state
        new_state = deepcopy(einstein.START_STATE)
        new_state = einstein.propose_link('nationality', 'swedish', 'pet',
                                          'bird', new_state)
        self.assertEqual(new_state, einstein.START_STATE)

        # The norweigen cannot own a bird, because the swede does.
        new_state = einstein.assign_value('1', 'nationality', 'norweigen',
                                          new_state)
        new_state = einstein.propose_link('nationality', 'swedish', 'pet',
                                          'bird', new_state)
        self.assertNotIn('bird', new_state['1']['pet'])

        # If house 3 owns a horse then the swede cannot live there, because he owns a bird.
        new_state = einstein.assign_value('3', 'pet', 'horse', new_state)
        new_state = einstein.propose_link('nationality', 'swedish', 'pet',
                                          'bird', new_state)
        self.assertNotIn('swedish', new_state['3']['nationality'])
示例#3
0
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
示例#4
0
 def test_double_assignment(self):
     """
     If we attempt to assign the same value to two places we have gone
     wrong and should raise an error.
     """
     new_state = einstein.assign_value('1', 'nationality', 'norweigen',
                                       einstein.START_STATE)
     self.assertEqual(new_state['1']['nationality'], set(['norweigen']))
     self.assertNotIn('blue', new_state['2']['nationality'])
     self.assertNotIn('blue', new_state['3']['nationality'])
     self.assertNotIn('blue', new_state['4']['nationality'])
     self.assertNotIn('blue', new_state['5']['nationality'])
     # We whould see state error on a double assignment
     with self.assertRaises(einstein.StateError):
         new_state = einstein.assign_value('2', 'nationality', 'norweigen',
                                           new_state)
示例#5
0
def rule4(state):
    """The green house is on the left of the white house."""
    green_house = einstein.get_position('green', state)
    white_house = einstein.get_position('white', state)
    # Green and white are already defined
    if green_house and white_house:
        return state
    # Green is defined so we can define white
    elif green_house:
        return einstein.assign_value(einstein.right_of(house), 'house_color',
                                     'white', state)
    # White is defined so we can define green
    elif white_house:
        return einstein.assign_value(einstein.right_of(house), 'house_color',
                                     'white', state)
    # Neither Green or White are defined
    else:
        # Go through all houses and make the following assertions
        for house in state.keys():
            house_to_right = einstein.right_of(house)
            house_to_left = einstein.left_of(house)
            # Nothing on the left so this cannot be the white house
            if not house_to_left:
                state = einstein.remove_value(house, 'house_color', 'white',
                                              state)
            # nothing o the right so this cannot be the green house
            elif not house_to_right:
                state = einstein.remove_value(house, 'house_color', 'green',
                                              state)
            if house_to_right:
                has_green = 'green' in state[house]['house_color']
                white_to_right = 'white' in state[house_to_right][
                    'house_color']
                # If this house_color is green
                # BUT the house on the right is not white
                # THEN green must be removed from this house
                if has_green and not white_to_right:
                    state = einstein.remove_value(house, 'house_color',
                                                  'green', state)
                # If this house is NOT green
                # THEN the house to the right cannot be white
                elif not has_green and white_to_right:
                    state = einstein.remove_value(house_to_right,
                                                  'house_color', 'white',
                                                  state)
        return state
示例#6
0
 def test_duplicate_assignment(self):
     """
     If we make the same assignment twice it won't cause a problem.
     We will however like to see a message logged.
     """
     new_state = einstein.assign_value('1', 'nationality', 'norweigen',
                                       einstein.START_STATE)
     self.assertEqual(new_state['1']['nationality'], set(['norweigen']))
     self.assertNotIn('blue', new_state['2']['nationality'])
     self.assertNotIn('blue', new_state['3']['nationality'])
     self.assertNotIn('blue', new_state['4']['nationality'])
     self.assertNotIn('blue', new_state['5']['nationality'])
     new_state = einstein.assign_value('1', 'nationality', 'norweigen',
                                       new_state)
     self.assertEqual(new_state['1']['nationality'], set(['norweigen']))
     self.assertNotIn('blue', new_state['2']['nationality'])
     self.assertNotIn('blue', new_state['3']['nationality'])
     self.assertNotIn('blue', new_state['4']['nationality'])
     self.assertNotIn('blue', new_state['5']['nationality'])
示例#7
0
 def test_assign_norweigen_to_first_house(self):
     """
     Assert rule 9 the norweigen lives in the first house.
     """
     # How do we represent this rule using a step from one state to the next
     new_state = einstein.assign_value('1', 'nationality', 'norweigen',
                                       einstein.START_STATE)
     self.assertEqual(new_state['1']['nationality'], set(['norweigen']))
     self.assertNotIn('blue', new_state['2']['nationality'])
     self.assertNotIn('blue', new_state['3']['nationality'])
     self.assertNotIn('blue', new_state['4']['nationality'])
     self.assertNotIn('blue', new_state['5']['nationality'])
示例#8
0
    def test_get_position(self):
        """
        If a value like 'norweigen' or 'dog' is the only value in a set of
        potential values then its been assigned.

        In this case return the house.

        If there is no such case return None
        """
        new_state = deepcopy(einstein.START_STATE)
        # Not assigned so it won't be found
        self.assertIsNone(einstein.get_position('norweigen', new_state))

        # Assign it and we will find it
        new_state = einstein.assign_value('1', 'nationality', 'norweigen',
                                          new_state)
        self.assertEqual(new_state['1']['nationality'], set(['norweigen']))
        self.assertEqual(einstein.get_position('norweigen', new_state), '1')

        # It also won't feature anywhere else
        self.assertNotIn('blue', new_state['2']['nationality'])
        self.assertNotIn('blue', new_state['3']['nationality'])
        self.assertNotIn('blue', new_state['4']['nationality'])
        self.assertNotIn('blue', new_state['5']['nationality'])
示例#9
0
def rule9(state):
    """The Norwegian lives in the first house."""
    if einstein.get_position('norweigen', state):  # Don't set twice
        return state
    else:
        return einstein.assign_value('1', 'nationality', 'norweigen', state)
示例#10
0
def rule8(state):
    """The man living in the house right in the center drinks milk."""
    if einstein.get_position('milk', state):  # Don't set twice
        return state
    else:
        return einstein.assign_value('3', 'drink', 'milk', state)
示例#11
0
 def test_bogus_assignment(self):
     """
     If we attemp to assign a bogus value we gat a KeyError
     """
     with self.assertRaises(KeyError):
         einstein.assign_value('1', 'vehicle', 'car', einstein.START_STATE)