How to use the textworld.logic.Variable function in textworld

To help you get started, we’ve selected a few textworld examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github microsoft / TextWorld / textworld / generator / world.py View on Github external
def _update(self) -> None:
        """ Update the internal representation of the world.

        This method will create new entities based on facts. It should be called whenever
        backing facts are changed.
        """
        self._entities = OrderedDict()  # Clear entities.
        self.player = self._get_entity(Variable("P"))
        self.inventory = self._get_entity(Variable("I"))
        self._player_room = None
        self._process_rooms()
        self._process_objects()
        self._rooms = [entity for entity in self._entities.values() if isinstance(entity, WorldRoom)]
        self._objects = [entity for entity in self._entities.values() if isinstance(entity, WorldObject)]

        self._entities_per_type = defaultdict(list)
        for entity in self._entities.values():
            self._entities_per_type[entity.type].append(entity)
github microsoft / TextWorld / textworld / generator / chaining.py View on Github external
def create_variable(self, state, ph, type_counts):
        """Create a new variable of the given type."""

        count = type_counts[ph.type]
        if not self.options.check_new_variable(state, ph.type, count):
            return None

        name = "{}_{}".format(ph.type, count)
        var = Variable(name, ph.type)
        while state.has_variable(var):
            name += "'"
            var = Variable(name, ph.type)

        type_counts[ph.type] += 1
        return var
github microsoft / TextWorld / textworld / generator / vtypes.py View on Github external
def __init__(self, vtypes: List[VariableType]):
        self.variables_types = {vtype.type: vtype for vtype in vtypes}

        # Make some convenient attributes.
        self.types = [vt.type for vt in vtypes]
        self.names = [vt.name for vt in vtypes]
        self.constants = [t for t in self if self.is_constant(t)]
        self.variables = [t for t in self if not self.is_constant(t)]
        self.constants_mapping = {Placeholder(c): Variable(c) for c in self.constants}

        # Adjust variable type's parent and children references.
        for vt in vtypes:
            if vt.parent is not None:
                vt_parent = self[vt.parent]
                vt_parent.children.append(vt.type)
github microsoft / TextWorld / textworld / generator / inform7 / world2inform7.py View on Github external
def get_human_readable_fact(self, fact: Proposition) -> Proposition:
        def _get_name(info):
            return info.name if info.name else info.id

        arguments = [Variable(_get_name(self.entity_infos[var.name]), var.type) for var in fact.arguments]
        return Proposition(fact.name, arguments)
github microsoft / TextWorld / textworld / generator / world.py View on Github external
def from_map(cls, map: networkx.Graph, kb: Optional[KnowledgeBase] = None) -> "World":
        """
        Args:
            map: Graph defining the structure of the world.
        """
        world = cls(kb=kb)
        names = [d.get("name", "r_{}".format(i)) for i, (n, d) in enumerate(map.nodes.items())]
        rooms = OrderedDict((n, Variable(names[i], "r")) for i, n in enumerate(map.nodes()))
        world.add_facts(graph2state(map, rooms))
        return world
github microsoft / TextWorld / textworld / generator / world.py View on Github external
elif self.kb.types.is_descendant_of(obj_holder.type, "I"):
                    state.append(Proposition("in", [obj, obj_holder]))
                elif self.kb.types.is_descendant_of(obj_holder.type, "r"):
                    state.append(Proposition("at", [obj, obj_holder]))
                else:
                    raise ValueError("Unknown type for object holder: {}".format(obj_holder))

            elif self.kb.types.is_descendant_of(obj_type, "s"):
                supporter_name = get_new(obj_type, types_counts)
                supporter = Variable(supporter_name, obj_type)
                state.append(Proposition("at", [supporter, room]))
                objects_holder.append(supporter)

            elif self.kb.types.is_descendant_of(obj_type, "c"):
                container_name = get_new(obj_type, types_counts)
                container = Variable(container_name, obj_type)
                state.append(Proposition("at", [container, room]))
                objects_holder.append(container)

                container_state = rng.choice(["open", "closed", "locked"])
                state.append(Proposition(container_state, [container]))

                lockable_objects.append(container)
                if container_state in ["locked", "closed"]:
                    locked_or_closed_objects.append(container)

            else:
                raise ValueError("Unknown object type: {}".format(obj_type))

            object_id += 1

        self.add_facts(state)
github microsoft / TextWorld / textworld / challenges / treasure_hunter.py View on Github external
types_counts = kb.types.count(world.state)
    obj_type = kb.types.sample(parent_type='o', rng=rng_objects, include_parent=True)
    var_id = get_new(obj_type, types_counts)
    right_obj = Variable(var_id, obj_type)
    world.add_fact(Proposition("in", [right_obj, world.inventory]))

    # Add containers and supporters to the world.
    types_counts = kb.types.count(world.state)
    objects = []
    distractor_types = uniquify(['c', 's']
                                + kb.types.descendants('c')
                                + kb.types.descendants('s'))
    for i in range(n_distractors):
        obj_type = rng_objects.choice(distractor_types)
        var_id = get_new(obj_type, types_counts)  # This update the types_counts.
        objects.append(Variable(var_id, obj_type))

    world.populate_with(objects, rng=rng_objects)

    # Add object the player should not pick up.
    types_counts = kb.types.count(world.state)
    obj_type = kb.types.sample(parent_type='o', rng=rng_objects, include_parent=True)
    var_id = get_new(obj_type, types_counts)
    wrong_obj = Variable(var_id, obj_type)
    # Place it anywhere in the world.
    world.populate_with([wrong_obj], rng=rng_objects)

    # Generate a quest that finishes by taking something (i.e. the right
    #  object since it's the only one in the inventory).
    options.chaining.rules_per_depth = [kb.rules.get_matching("take.*")]
    options.chaining.backward = True
    options.chaining.rng = rng_quest
github microsoft / TextWorld / textworld / generator / maker.py View on Github external
Args:
            type: The type of the entity.
            name: The name of the entity.
            desc: The description of the entity.

        Returns:
            The newly created entity.

            * If the `type` is `'r'`, then a `WorldRoom` object is returned.
            * Otherwise, a `WorldEntity` is returned.
        """
        var_id = type
        if not self._kb.types.is_constant(type):
            var_id = get_new(type, self._types_counts)

        var = Variable(var_id, type)
        if type == "r":
            entity = WorldRoom(var, name, desc)
            self.rooms.append(entity)
        else:
            entity = WorldEntity(var, name, desc, kb=self._kb)

        self._entities[var_id] = entity
        if entity.name:
            self._named_entities[entity.name] = entity

        return entity
github microsoft / TextWorld / textworld / generator / world.py View on Github external
def _update(self) -> None:
        """ Update the internal representation of the world.

        This method will create new entities based on facts. It should be called whenever
        backing facts are changed.
        """
        self._entities = OrderedDict()  # Clear entities.
        self.player = self._get_entity(Variable("P"))
        self.inventory = self._get_entity(Variable("I"))
        self._player_room = None
        self._process_rooms()
        self._process_objects()
        self._rooms = [entity for entity in self._entities.values() if isinstance(entity, WorldRoom)]
        self._objects = [entity for entity in self._entities.values() if isinstance(entity, WorldObject)]

        self._entities_per_type = defaultdict(list)
        for entity in self._entities.values():
            self._entities_per_type[entity.type].append(entity)
github microsoft / TextWorld / textworld / challenges / treasure_hunter.py View on Github external
objects = []
    distractor_types = uniquify(['c', 's']
                                + kb.types.descendants('c')
                                + kb.types.descendants('s'))
    for i in range(n_distractors):
        obj_type = rng_objects.choice(distractor_types)
        var_id = get_new(obj_type, types_counts)  # This update the types_counts.
        objects.append(Variable(var_id, obj_type))

    world.populate_with(objects, rng=rng_objects)

    # Add object the player should not pick up.
    types_counts = kb.types.count(world.state)
    obj_type = kb.types.sample(parent_type='o', rng=rng_objects, include_parent=True)
    var_id = get_new(obj_type, types_counts)
    wrong_obj = Variable(var_id, obj_type)
    # Place it anywhere in the world.
    world.populate_with([wrong_obj], rng=rng_objects)

    # Generate a quest that finishes by taking something (i.e. the right
    #  object since it's the only one in the inventory).
    options.chaining.rules_per_depth = [kb.rules.get_matching("take.*")]
    options.chaining.backward = True
    options.chaining.rng = rng_quest
    # options.chaining.restricted_types = exceptions
    # exceptions = ["r", "c", "s", "d"] if mode == "easy" else ["r"]
    chain = textworld.generator.sample_quest(world.state, options.chaining)

    # Add objects needed for the quest.
    world.state = chain.initial_state
    event = Event(chain.actions)
    quest = Quest(win_events=[event],