# Path: semantics/new_structures.py
# class Assertion(object):
#     """Asserts the existence or property of an Entity in the world."""
# 
#     def __init__(self, theme, location, existential=False):
#         self.theme = theme
#         self.location = location
#         self.existential = existential
# 
#     def readable(self):
#         return '{!r} is/are in {!r}'.format(self.theme.readable(case=True), self.location.readable())
# 
#     def __str__(self, lvl=0):
#         indent = '\t'*(lvl)
#         return 'Assertion: \n' + \
#             (indent + '\tTheme: %s\n' % self.theme.__str__(lvl + 1) if self.theme else '') + \
#             (indent + '\tLocation: %s\n' % self.location.__str__(lvl + 1) if self.location else '')+ \
#             indent + '\tExistential: %s' % str(self.existential)
# 
#     def __repr__(self):
#         return str(self)
# 
# class Query(object):
#     """Base class for all queries"""
#     def __repr__(self):
#         return str(self)
# 
# class YNQuery(Query):
#     """Yes/No queries."""
#     def __init__(self, theme, location):
#         self.theme = theme
#         self.location = location
# 
#     def __str__(self, lvl=0):
#         indent = '\t'*(lvl)
#         return 'YNQuery: \n' + \
#                indent + '\tTheme: %s\n' % self.theme.__str__(lvl + 1) + \
#                indent + '\tLocation: %s' % self.location.__str__(lvl + 1)
# 
# class LocationQuery(Query):
#     """Where queries"""
#     def __init__(self, theme):
#         self.theme = theme
# 
#     def __str__(self, lvl=0):
#         indent = '\t'*(lvl)
#         return '\n' + indent + 'LocationQuery: \n' + \
#                indent + '\tTheme: %s\n' % self.theme.__str__(lvl + 1)
# 
# class EntityQuery(Query):
#     """Who/What queries"""
#     def __init__(self, location):
#         self.location = location
# 
#     def __str__(self, lvl=0):
#         indent = '\t'*(lvl)
#         return 'EntityQuery: \n' + \
#                indent + '\tLocation: %s\n' % self.location.__str__(lvl + 1)
# 
# class Command(object):
#     """A Command for Junior to do something."""
# 
#     def __init__(self, agent, theme, patient, location, source, destination, action,
#                  condition=None, negation=False):
#         self.agent = agent
#         self.theme = theme
#         self.patient = patient
#         self.location = location
#         self.source = source
#         self.destination = destination
#         self.action = action
#         self.condition = condition
#         self.negation = negation
# 
#     def __str__(self, lvl=0):
#         indent = '\t'*(lvl + 1)
#         return 'Command: \n' + \
#                (indent + 'Agent: ' + self.agent.__str__(lvl + 1) + '\n' if self.agent else '') + \
#                indent + 'Action: ' + str(self.action)  + '\n' + \
#                (indent + 'Theme: ' + self.theme.__str__(lvl + 1) + '\n' if self.theme else '') + \
#                (indent + 'Patient:' + self.patient.__str__(lvl + 1) + '\n' if self.patient else '') + \
#                (indent + 'Location: ' + self.location.__str__(lvl + 1) + '\n' if self.location else '') + \
#                (indent + 'Source: ' + self.source.__str__(lvl + 1) + '\n' if self.source else '') + \
#                (indent + 'Destination: ' + self.destination.__str__(lvl + 1) + '\n' if self.destination else '') + \
#                (indent + 'Condition: ' + self.condition.__str__(lvl + 1) + '\n' if self.condition else '') + \
#                indent + 'Negation: ' + str(self.negation)
# 
#     def __repr__(self):
#         return str(self)
# 
#     def readable(self):
#         response = ''
#         if self.negation:
#             response += ' not'
#         if not self.action:
#             return ''
#         else:
#             response += ' %s' % self.action
#         if self.theme:
#             response += ' %s' % self.theme.readable(case=False)
#         elif self.patient:
#             response += ' %s' % self.patient.readable(case=False)
#         if self.location:
#             response += ' in %s' % self.location.readable()
#         if self.source:
#             response += ' from %s' % self.source.readable()
#         if self.destination:
#             response += ' to %s' % self.destination.readable()
#         if self.condition:
#             response += ' if %s' % self.condition.readable()
#         return response
# 
# Path: semantics/util.py
# def is_pronoun(word):
#     """Return whether a word is a pronoun."""
#     return word.lower() in PRONOUNS if word else False


from semantics.new_structures import Assertion, Query, YNQuery, \
    LocationQuery, EntityQuery, Command
from semantics.util import is_pronoun
    def assimilate(self, assertion, source):
        """Override this in subclasses"""
        pass

class MapFact(Fact):
    """Spatial map of the environment"""
    def __init__(self):
        # Mapping from location to a set of entities
        self.env_map = {}

    def query_map(self, location, theme):
        """"Returns the missing argument. 
        If both arguments are present, 
        returns whether that mapping is found"""
        if not location and not theme:
            return None
        elif not theme:
            return self.env_map.get(location, None)
        elif not location:
            return [location for location, entities in \
                        self.env_map.items() if theme in entities]
        else:
            # Both arguments are present
            if location in self.env_map:
                return theme in self.env_map[location]
            else:
                return None

    def query(self, query):
        """Query the database with a semantic structure"""

# Path: semantics/new_structures.py
# class Assertion(object):
#     """Asserts the existence or property of an Entity in the world."""
# 
#     def __init__(self, theme, location, existential=False):
#         self.theme = theme
#         self.location = location
#         self.existential = existential
# 
#     def readable(self):
#         return '{!r} is/are in {!r}'.format(self.theme.readable(case=True), self.location.readable())
# 
#     def __str__(self, lvl=0):
#         indent = '\t'*(lvl)
#         return 'Assertion: \n' + \
#             (indent + '\tTheme: %s\n' % self.theme.__str__(lvl + 1) if self.theme else '') + \
#             (indent + '\tLocation: %s\n' % self.location.__str__(lvl + 1) if self.location else '')+ \
#             indent + '\tExistential: %s' % str(self.existential)
# 
#     def __repr__(self):
#         return str(self)
# 
# class Query(object):
#     """Base class for all queries"""
#     def __repr__(self):
#         return str(self)
# 
# class YNQuery(Query):
#     """Yes/No queries."""
#     def __init__(self, theme, location):
#         self.theme = theme
#         self.location = location
# 
#     def __str__(self, lvl=0):
#         indent = '\t'*(lvl)
#         return 'YNQuery: \n' + \
#                indent + '\tTheme: %s\n' % self.theme.__str__(lvl + 1) + \
#                indent + '\tLocation: %s' % self.location.__str__(lvl + 1)
# 
# class LocationQuery(Query):
#     """Where queries"""
#     def __init__(self, theme):
#         self.theme = theme
# 
#     def __str__(self, lvl=0):
#         indent = '\t'*(lvl)
#         return '\n' + indent + 'LocationQuery: \n' + \
#                indent + '\tTheme: %s\n' % self.theme.__str__(lvl + 1)
# 
# class EntityQuery(Query):
#     """Who/What queries"""
#     def __init__(self, location):
#         self.location = location
# 
#     def __str__(self, lvl=0):
#         indent = '\t'*(lvl)
#         return 'EntityQuery: \n' + \
#                indent + '\tLocation: %s\n' % self.location.__str__(lvl + 1)
# 
# class Command(object):
#     """A Command for Junior to do something."""
# 
#     def __init__(self, agent, theme, patient, location, source, destination, action,
#                  condition=None, negation=False):
#         self.agent = agent
#         self.theme = theme
#         self.patient = patient
#         self.location = location
#         self.source = source
#         self.destination = destination
#         self.action = action
#         self.condition = condition
#         self.negation = negation
# 
#     def __str__(self, lvl=0):
#         indent = '\t'*(lvl + 1)
#         return 'Command: \n' + \
#                (indent + 'Agent: ' + self.agent.__str__(lvl + 1) + '\n' if self.agent else '') + \
#                indent + 'Action: ' + str(self.action)  + '\n' + \
#                (indent + 'Theme: ' + self.theme.__str__(lvl + 1) + '\n' if self.theme else '') + \
#                (indent + 'Patient:' + self.patient.__str__(lvl + 1) + '\n' if self.patient else '') + \
#                (indent + 'Location: ' + self.location.__str__(lvl + 1) + '\n' if self.location else '') + \
#                (indent + 'Source: ' + self.source.__str__(lvl + 1) + '\n' if self.source else '') + \
#                (indent + 'Destination: ' + self.destination.__str__(lvl + 1) + '\n' if self.destination else '') + \
#                (indent + 'Condition: ' + self.condition.__str__(lvl + 1) + '\n' if self.condition else '') + \
#                indent + 'Negation: ' + str(self.negation)
# 
#     def __repr__(self):
#         return str(self)
# 
#     def readable(self):
#         response = ''
#         if self.negation:
#             response += ' not'
#         if not self.action:
#             return ''
#         else:
#             response += ' %s' % self.action
#         if self.theme:
#             response += ' %s' % self.theme.readable(case=False)
#         elif self.patient:
#             response += ' %s' % self.patient.readable(case=False)
#         if self.location:
#             response += ' in %s' % self.location.readable()
#         if self.source:
#             response += ' from %s' % self.source.readable()
#         if self.destination:
#             response += ' to %s' % self.destination.readable()
#         if self.condition:
#             response += ' if %s' % self.condition.readable()
#         return response
# 
# Path: semantics/util.py
# def is_pronoun(word):
#     """Return whether a word is a pronoun."""
#     return word.lower() in PRONOUNS if word else False


# Path: semantics/new_knowledge.py
from semantics.new_structures import Assertion, Query, YNQuery, \
    LocationQuery, EntityQuery, Command
from semantics.util import is_pronoun

    def assimilate(self, assertion, source):
        """Override this in subclasses"""
        pass

class MapFact(Fact):
    """Spatial map of the environment"""
    def __init__(self):
        # Mapping from location to a set of entities
        self.env_map = {}

    def query_map(self, location, theme):
        """"Returns the missing argument. 
        If both arguments are present, 
        returns whether that mapping is found"""
        if not location and not theme:
            return None
        elif not theme:
            return self.env_map.get(location, None)
        elif not location:
            return [location for location, entities in \
                        self.env_map.items() if theme in entities]
        else:
            # Both arguments are present
            if location in self.env_map:
                return theme in self.env_map[location]
            else:
                return None

    def query(self, query):
        """Query the database with a semantic structure"""

        if isinstance(query, YNQuery):