Beispiel #1
0
def build_linear_extent_selector(interpreter, speaker, location_d):
    """ 
    builds a MemoryFilter that selects by a linear_extent dict 
    chooses memory location nearest to 
    the linear_extent dict interpreted as a location
    """

    # FIXME this is being done at construction time, rather than execution
    mems = interpreter.subinterpret["reference_locations"](interpreter,
                                                           speaker, location_d)
    steps, reldir = interpret_relative_direction(interpreter, location_d)
    pos, _ = interpreter.subinterpret["specify_locations"](interpreter,
                                                           speaker, mems,
                                                           steps, reldir)

    class dummy_loc_mem:
        def get_pos(self):
            return pos

    selector_attribute = LinearExtentAttribute(interpreter.agent,
                                               {"relative_direction": "AWAY"},
                                               mem=dummy_loc_mem())
    polarity = "argmin"
    sa = ApplyAttribute(interpreter.agent.memory, selector_attribute)
    selector = ExtremeValueMemorySelector(interpreter.agent.memory,
                                          polarity=polarity,
                                          ordinal=1)
    selector.append(sa)
    mems_filter = MemidList(interpreter.agent.memory, [mems[0].memid])
    not_mems_filter = NotFilter(interpreter.agent.memory, [mems_filter])
    selector.append(not_mems_filter)
    #    selector.append(build_radius_comparator(interpreter, speaker, location_d))

    return selector
Beispiel #2
0
    def handle_move(self, speaker, d) -> Tuple[Optional[str], Any]:
        Move = self.task_objects["move"]
        Control = self.task_objects["control"]

        def new_tasks():
            # TODO if we do this better will be able to handle "stay between the x"
            default_loc = getattr(self, "default_loc", SPEAKERLOOK)
            location_d = d.get("location", default_loc)
            # FIXME! this loop_data trick can now be done more properly with
            # a fixed mem filter
            if self.loop_data and hasattr(self.loop_data, "get_pos"):
                mems = [self.loop_data]
            else:
                mems = self.subinterpret["reference_locations"](self, speaker,
                                                                location_d)
            # FIXME this should go in the ref_location subinterpret:
            steps, reldir = interpret_relative_direction(self, location_d)
            pos, _ = self.subinterpret["specify_locations"](self, speaker,
                                                            mems, steps,
                                                            reldir)
            # TODO: can this actually happen?
            if pos is None:
                raise ErrorWithResponse(
                    "I don't understand where you want me to move.")
            pos = self.post_process_loc(pos, self)
            task_data = {"target": pos, "action_dict": d}
            task = Move(self.agent, task_data)
            return task

        if "stop_condition" in d:
            condition = self.subinterpret["condition"](self, speaker,
                                                       d["stop_condition"])
            location_d = d.get("location", SPEAKERLOOK)
            mems = self.subinterpret["reference_locations"](self, speaker,
                                                            location_d)
            if mems:
                self.loop_data = mems[0]
            steps, reldir = interpret_relative_direction(self, location_d)

            # FIXME grammar to handle "remove" vs "stop"
            loop_task_data = {
                "new_tasks": new_tasks,
                "remove_condition":
                condition,  #!!! semantic parser + GT need updating
                "action_dict": d,
            }
            return Control(self.agent, loop_task_data), None, None
        else:
            return new_tasks(), None, None
Beispiel #3
0
 def new_tasks():
     # TODO if we do this better will be able to handle "stay between the x"
     default_loc = getattr(self, "default_loc", SPEAKERLOOK)
     location_d = d.get("location", default_loc)
     if self.loop_data and hasattr(self.loop_data, "get_pos"):
         mems = [self.loop_data]
     else:
         mems = self.subinterpret["reference_locations"](self, speaker, location_d)
     # FIXME this should go in the ref_location subinterpret:
     steps, reldir = interpret_relative_direction(self, location_d)
     pos, _ = self.subinterpret["specify_locations"](self, speaker, mems, steps, reldir)
     # TODO: can this actually happen?
     if pos is None:
         raise ErrorWithResponse("I don't understand where you want me to move.")
     pos = self.post_process_loc(pos, self)
     task_data = {"target": pos, "action_dict": d}
     task = Move(self.agent, task_data)
     return [task]
Beispiel #4
0
    def handle_move(self, speaker, d) -> Tuple[Optional[str], Any]:
        Move = self.task_objects["move"]
        Loop = self.task_objects["loop"]

        def new_tasks():
            # TODO if we do this better will be able to handle "stay between the x"
            default_loc = getattr(self, "default_loc", SPEAKERLOOK)
            location_d = d.get("location", default_loc)
            if self.loop_data and hasattr(self.loop_data, "get_pos"):
                mems = [self.loop_data]
            else:
                mems = self.subinterpret["reference_locations"](self, speaker, location_d)
            # FIXME this should go in the ref_location subinterpret:
            steps, reldir = interpret_relative_direction(self, location_d)
            pos, _ = self.subinterpret["specify_locations"](self, speaker, mems, steps, reldir)
            # TODO: can this actually happen?
            if pos is None:
                raise ErrorWithResponse("I don't understand where you want me to move.")
            pos = self.post_process_loc(pos, self)
            task_data = {"target": pos, "action_dict": d}
            task = Move(self.agent, task_data)
            return [task]

        if "stop_condition" in d:
            condition = self.subinterpret["condition"](self, speaker, d["stop_condition"])
            location_d = d.get("location", SPEAKERLOOK)
            mems = self.subinterpret["reference_locations"](self, speaker, location_d)
            if mems:
                self.loop_data = mems[0]
            steps, reldir = interpret_relative_direction(self, location_d)

            loop_task_data = {
                "new_tasks_fn": new_tasks,
                "stop_condition": condition,
                "action_dict": d,
            }
            self.append_new_task(Loop, loop_task_data)
        else:
            for t in new_tasks():
                self.append_new_task(t)

        self.finished = True
        return None, None
Beispiel #5
0
def filter_by_sublocation(
    interpreter,
    speaker,
    candidates: List[Tuple[XYZ, T]],
    d: Dict,
    limit=1,
    all_proximity=10,
    loose=False,
) -> List[Tuple[XYZ, T]]:
    """Select from a list of candidate (xyz, object) tuples given a sublocation

    If limit == 'ALL', return all matching candidates

    Returns a list of (xyz, mem) tuples
    """
    F = d.get("filters")
    assert F is not None, "no filters: {}".format(d)
    default_loc = getattr(interpreter, "default_loc", SPEAKERLOOK)
    location = F.get("location", default_loc)
    #    if limit == 1:
    #        limit = get_repeat_num(d)

    reldir = location.get("relative_direction")
    if reldir:
        if reldir == "INSIDE":
            # FIXME formalize this better, make extensible
            if location.get("reference_object"):
                # should probably return from interpret_reference_location...
                ref_mems = interpret_reference_object(
                    interpreter, speaker, location["reference_object"])
                for l, candidate_mem in candidates:
                    I = interpreter.agent.on_demand_perception.get[
                        "check_inside"]
                    if I:
                        if I([candidate_mem, ref_mems[0]]):
                            return [(l, candidate_mem)]
                    else:
                        raise ErrorWithResponse(
                            "I don't know how to check inside")
            raise ErrorWithResponse("I can't find something inside that")
        elif reldir == "AWAY":
            raise ErrorWithResponse("I don't know which object you mean")
        elif reldir == "NEAR":
            pass  # fall back to no reference direction
        elif reldir == "BETWEEN":
            mems = interpreter.subinterpret["reference_locations"](interpreter,
                                                                   speaker,
                                                                   location)
            steps, reldir = interpret_relative_direction(interpreter, d)
            ref_loc, _ = interpreter.subinterpret["specify_locations"](
                interpreter, speaker, mems, steps, reldir)
            candidates.sort(key=lambda c: euclid_dist(c[0], ref_loc))
            return candidates[:limit]
        else:
            # FIXME need some tests here
            # reference object location, i.e. the "X" in "left of X"
            mems = interpreter.subinterpret["reference_locations"](interpreter,
                                                                   speaker,
                                                                   location)

            # FIXME!!! handle frame better, might want agent's frame instead
            eid = interpreter.agent.memory.get_player_by_name(speaker).eid
            self_mem = interpreter.agent.memory.get_mem_by_id(
                interpreter.agent.memory.self_memid)
            L = LinearExtentAttribute(interpreter.agent, {
                "frame": eid,
                "relative_direction": reldir
            },
                                      mem=self_mem)
            proj = L([c[1] for c in candidates])

            # filter by relative dir, e.g. "left of Y"
            proj_cands = [(p, c) for (p, c) in zip(proj, candidates) if p > 0]

            # "the X left of Y" = the right-most X that is left of Y
            if limit == "ALL":
                limit = len(proj_cands)
            return [c for (_, c) in sorted(proj_cands, key=lambda p: p[0])
                    ][:limit]
    else:
        # no reference direction: choose the closest
        mems = interpreter.subinterpret["reference_locations"](interpreter,
                                                               speaker,
                                                               location)
        steps, reldir = interpret_relative_direction(interpreter, d)
        ref_loc, _ = interpreter.subinterpret["specify_locations"](interpreter,
                                                                   speaker,
                                                                   mems, steps,
                                                                   reldir)
        if limit == "ALL":
            return list(
                filter(lambda c: euclid_dist(c[0], ref_loc) <= all_proximity,
                       candidates))
        else:
            candidates.sort(key=lambda c: euclid_dist(c[0], ref_loc))
            return candidates[:limit]
    return []  # this fixes flake but seems awful?