Exemplo n.º 1
0
    def interpret_comparator(self, interpreter, speaker, d):
        input_left_d = d.get("input_left")
        input_right_d = d.get("input_right")
        if (not input_right_d) or (not input_left_d):
            return None
        value_extractors = {}
        for inp_pos in ["input_left", "input_right"]:
            inp = d[inp_pos]["value_extractor"]
            if type(inp) is str:
                if inp == "NULL":
                    value_extractors[inp_pos] = None
                else:
                    # this is a span
                    cm = d.get("comparison_measure")
                    v = interpret_span_value(interpreter, speaker, inp, comparison_measure=cm)
                    value_extractors[inp_pos] = v
            elif inp.get("output"):
                # this is a filter
                # TODO FIXME! deal with count
                # TODO logical form etc.?
                a = inp["output"]["attribute"]
                if type(a) is str:
                    search_data = {"attribute": TableColumn(interpreter.agent, a)}
                elif a.get("linear_extent"):
                    search_data = {
                        "attribute": interpret_linear_extent(
                            interpreter, speaker, a["linear_extent"]
                        )
                    }
                mem, sd = maybe_specific_mem(interpreter, speaker, {"filters": inp})
                if sd:
                    for k, v in sd.items():
                        search_data[k] = v
                # TODO wrap this in a ScaledValue using condtition.convert_comparison_value
                # and "comparison_measure"
                value_extractors[inp_pos] = MemoryColumnValue(
                    interpreter.agent, search_data, mem=mem
                )
            else:
                raise ErrorWithResponse(
                    "I don't know understand that condition, looks like a comparator but value is not filters or span"
                )
        comparison_type = d.get("comparison_type")
        if not comparison_type:
            ErrorWithResponse(
                "I think you want me to compare two things in a condition, but am not sure what type of comparison"
            )

        return Comparator(
            interpreter.agent,
            value_left=value_extractors["input_left"],
            value_right=value_extractors["input_right"],
            comparison_type=comparison_type,
        )
Exemplo n.º 2
0
 def __call__(self, interpreter, speaker, d) -> Optional[Condition]:
     ct = d.get("condition_type")
     if ct:
         if self.condition_types.get(ct):
             # condition_type NEVER doesn't have a "condition" sibling
             if ct == "NEVER":
                 return self.condition_types[ct](interpreter, speaker, d)
             if not d.get("condition"):
                 raise ErrorWithResponse(
                     "I thought there was a condition but I don't understand it"
                 )
             return self.condition_types[ct](interpreter, speaker, d["condition"])
         else:
             raise ErrorWithResponse("I don't understand that condition")
     else:
         return None
Exemplo n.º 3
0
def maybe_specific_mem(interpreter, speaker, ref_obj_d):
    mem = None
    search_data = None
    if ref_obj_d.get("special_reference"):
        # this is a special ref object, not filters....
        cands = interpreter.subinterpret["reference_objects"](interpreter, speaker, ref_obj_d)
        return cands[0], None
    filters_d = ref_obj_d.get("filters", {})
    coref = filters_d.get("contains_coreference")
    if coref != "NULL":
        # this is a particular entity etc, don't search for the mem at check() time
        if isinstance(coref, ReferenceObjectNode):
            mem = coref
        else:
            cands = interpreter.subinterpret["reference_objects"](interpreter, speaker, ref_obj_d)
        if not cands:
            # FIXME fix this error
            raise ErrorWithResponse("I don't know which objects attribute you are talking about")
        # TODO if more than one? ask?
        else:
            mem = cands[0]
    else:
        # this object is only defined by the filters and might be different at different moments
        tags = tags_from_dict(filters_d)
        # make a function, reuse code with get_reference_objects FIXME
        search_data = [{"pred_text": "has_tag", "obj_text": tag} for tag in tags]

    return mem, search_data
Exemplo n.º 4
0
def interpret_linear_extent(interpreter, speaker, d, force_value=False):
    """
    returns a LinearExtentAttribute or LinearExtentValue.

    the force_value arg forces the output to be a LinearExtentValue
    """
    location_data = {}
    if d.get("normalized"):
        location_data["normalized"] = True
    default_frame = getattr(interpreter, "default_frame", "AGENT")
    frame = d.get("frame", default_frame)
    if frame == "SPEAKER":
        frame = speaker
    if type(frame) is dict:
        frame = frame.get("player_span", "unknown_player")
    if frame == "AGENT":
        location_data["frame"] = "AGENT"
    else:
        p = interpreter.agent.memory.get_player_by_name(frame)
        if p:
            location_data["frame"] = p.eid
        else:
            raise ErrorWithResponse(
                "I don't understand in whose frame of reference you mean")
    location_data["relative_direction"] = d.get("relative_direction", "AWAY")
    # FIXME!!!! has_measure

    rd = d.get("source")
    fixed_role = "source"
    if not rd:
        rd = d.get("destination")
        fixed_role = "destination"
    rd = rd["reference_object"]

    mem, _ = maybe_specific_mem(interpreter, speaker, rd)
    if not mem:
        # FIXME better defaults?
        f = deepcopy(rd.get("filters", {}))
        default_frame = getattr(interpreter.agent, "default_frame", "AGENT")
        # should we do this?
        if not f.get("location"):
            f["location"] = SPEAKERLOOK if default_frame == "SPEAKER" else AGENTPOS
        F = interpreter.subinterpret["filters"](interpreter, speaker, f)
        location_data["filter"] = F
    L = LinearExtentAttribute(interpreter.agent,
                              location_data,
                              mem=mem,
                              fixed_role=fixed_role)

    # TODO some sort of sanity check here, these should be rare:
    if (d.get("source") and d.get("destination")) or force_value:
        rd = d.get("destination")
        mem = None
        sd = None
        if rd:
            mem, sd = maybe_specific_mem(interpreter, speaker, rd["filters"])
        L = LinearExtentValue(interpreter.agent, L, mem=mem, search_data=sd)

    return L
Exemplo n.º 5
0
 def __call__(self, interpreter, speaker, d) -> Optional[Condition]:
     """subinterpreter for Conditions
     args:
     interpreter:  root interpreter.
     speaker (str): The name of the player/human/agent who uttered 
         the chat resulting in this interpreter
     d: logical form from semantic parser
     """
     ct = d.get("condition_type")
     if ct:
         if self.condition_types.get(ct):
             # condition_type NEVER doesn't have a "condition" sibling
             if ct == "NEVER":
                 return self.condition_types[ct](interpreter, speaker, d)
             if not d.get("condition"):
                 raise ErrorWithResponse(
                     "I thought there was a condition but I don't understand it"
                 )
             return self.condition_types[ct](interpreter, speaker,
                                             d["condition"])
         else:
             raise ErrorWithResponse("I don't understand that condition")
     else:
         return None
Exemplo n.º 6
0
    def interpret_time(self, interpreter, speaker, d):
        event = None

        if d.get("special_time_event"):
            return TimeCondition(interpreter.agent, d["special_time_event"])
        else:
            if not d.get("comparator"):
                raise ErrorWithResponse("I don't know how to interpret this time condition")
            dc = d["comparator"]
            dc["input_left"] = {"value_extractor": "NULL"}
            comparator = self.interpret_comparator(interpreter, speaker, dc)

        if d.get("event"):
            event = self(interpreter, speaker, d["event"])

        return TimeCondition(interpreter.agent, comparator, event=event)
Exemplo n.º 7
0
def maybe_specific_mem(interpreter, speaker, ref_obj_d):
    """
    check if the reference object logical form corresponds to a ReferenceObject already
    in memory.  used e.g. in Values and Conditions, to distinguish between a ReferenceObject not in 
    memory now but to be searched for when checking the condition
    """
    mem = None
    search_data = None
    cands = None
    # FIXME! make a "get_special_reference" fn
    if ref_obj_d.get("special_reference"):
        # this is a special ref object, not filters....
        cands = interpreter.subinterpret["reference_objects"](interpreter,
                                                              speaker,
                                                              ref_obj_d)
        return cands[0], None
    filters_d = ref_obj_d.get("filters", {})
    coref = filters_d.get("contains_coreference", "NULL")
    if coref != "NULL":
        # this is a particular entity etc, don't search for the mem at check() time
        if isinstance(coref, ReferenceObjectNode):
            mem = coref
        else:
            sub_ref_obj_d = deepcopy(ref_obj_d)
            # del this to stop recursion, otherwise will end up here again
            del sub_ref_obj_d["filters"]["contains_coreference"]
            cands = interpreter.subinterpret["reference_objects"](
                interpreter, speaker, sub_ref_obj_d)
            if not cands:
                # FIXME fix this error
                raise ErrorWithResponse(
                    "I don't know which objects' attribute you are talking about"
                )
            # TODO if more than one? ask? use the filters?
            else:
                mem = cands[0]
    else:
        # FIXME use FILTERS
        # this object is only defined by the filters and might be different at different moments
        tags = tags_from_dict(filters_d)
        # make a function, reuse code with get_reference_objects FIXME
        search_data = [{
            "pred_text": "has_tag",
            "obj_text": tag
        } for tag in tags]

    return mem, search_data
Exemplo n.º 8
0
def interpret_linear_extent(interpreter, speaker, d, force_value=False):
    location_data = {}
    default_frame = getattr(interpreter.agent, "default_frame") or "AGENT"
    frame = d.get("frame", default_frame)
    if frame == "SPEAKER":
        frame = speaker
    if type(frame) is dict:
        frame = frame.get("player_span", "unknown_player")
    if frame == "AGENT":
        location_data["frame"] = "AGENT"
    else:
        p = interpreter.agent.memory.get_player_by_name(frame)
        if p:
            location_data["frame"] = p.eid
        else:
            raise ErrorWithResponse("I don't understand in whose frame of reference you mean")
    location_data["relative_direction"] = d.get("relative_direction", "AWAY")
    # FIXME!!!! has_measure

    rd = d.get("source")
    fixed_role = "source"
    if not rd:
        rd = d.get("destination")
        fixed_role = "destination"
    mem, sd = maybe_specific_mem(interpreter, speaker, rd)
    L = LinearExtentAttribute(interpreter.agent, location_data, mem=mem, fixed_role=fixed_role)

    # TODO some sort of sanity check here, these should be rare:
    if (d.get("source") and d.get("destination")) or force_value:
        rd = d.get("destination")
        mem = None
        sd = None
        if rd:
            mem, sd = maybe_specific_mem(interpreter, speaker, rd["filters"])
        L = LinearExtentValue(interpreter.agent, L, mem=mem, search_data=sd)

    return L
Exemplo n.º 9
0
def interpret_comparator(interpreter, speaker, d, is_condition=True):
    """subinterpreter to interpret comparators
    args:
    interpreter:  root interpreter.
    speaker (str): The name of the player/human/agent who uttered 
        the chat resulting in this interpreter
    d: logical form from semantic parser
    """
    # TODO add some input checks
    get_attribute = interpreter.subinterpret.get("attributes",
                                                 AttributeInterpreter())
    value_extractors = {}
    for inp_pos in ["input_left", "input_right"]:
        inp = d[inp_pos]["value_extractor"]
        if type(inp) is str:
            if inp == "NULL":
                value_extractors[inp_pos] = None
            else:
                # this is a span
                cm = d.get("comparison_measure")
                v = interpret_span_value(interpreter,
                                         speaker,
                                         inp,
                                         comparison_measure=cm)
                value_extractors[inp_pos] = v
        elif inp.get("filters"):
            # this is a filter
            # TODO FIXME! deal with count
            # TODO logical form etc.?
            # FIXME handle errors/None return in AttributeInterpeter
            inp_filt = inp["filters"]
            if inp_filt["output"].get("attribute"):
                search_data = {
                    "attribute":
                    get_attribute(interpreter, speaker,
                                  inp_filt["output"].get("attribute"))
                }
            mem, sd = maybe_specific_mem(interpreter, speaker, inp)
            if sd:
                for k, v in sd.items():
                    search_data[k] = v
            # TODO wrap this in a ScaledValue using condtition.convert_comparison_value
            # and "comparison_measure"
            value_extractors[inp_pos] = MemoryColumnValue(interpreter.agent,
                                                          search_data,
                                                          mem=mem)
        else:
            raise ErrorWithResponse(
                "I don't know understand that condition, looks like a comparator but value is not filters or span"
            )
    comparison_type = d.get("comparison_type")
    if not comparison_type:
        ErrorWithResponse(
            "I think you want me to compare two things in a condition, but am not sure what type of comparison"
        )
    if is_condition:
        return Comparator(
            interpreter.agent,
            value_left=value_extractors["input_left"],
            value_right=value_extractors["input_right"],
            comparison_type=comparison_type,
        )
    else:
        return ComparatorAttribute(
            interpreter.agent,
            value_left=value_extractors["input_left"],
            value_right=value_extractors["input_right"],
            comparison_type=comparison_type,
        )
Exemplo n.º 10
0
    def __call__(self, interpreter, speaker, d):
        """
        Location dict -> ref obj memories.
        Side effect: adds mems to agent_memory.recent_entities

        args:
        interpreter:  root interpreter.
        speaker (str): The name of the player/human/agent who uttered 
            the chat resulting in this interpreter
        d: logical form from semantic parser
        """
        loose_speakerlook = False
        expected_num = 1
        # FIXME! merge/generalize this, code in spatial_reasoning, and filter_by_sublocation
        if d.get("relative_direction") == "BETWEEN":
            loose_speakerlook = True
            expected_num = 2
            ref_obj_1 = d.get("reference_object_1")
            ref_obj_2 = d.get("reference_object_2")
            if ref_obj_1 and ref_obj_2:
                mem1 = interpreter.subinterpret["reference_objects"](
                    interpreter,
                    speaker,
                    ref_obj_1,
                    loose_speakerlook=loose_speakerlook,
                    allow_clarification=False,
                )[0]
                mem2 = interpreter.subinterpret["reference_objects"](
                    interpreter,
                    speaker,
                    ref_obj_2,
                    loose_speakerlook=loose_speakerlook,
                    allow_clarification=False,
                )[0]
                if mem1 is None or mem2 is None:
                    raise ErrorWithResponse(
                        "I don't know what you're referring to")
                mems = [mem1, mem2]
                interpreter.memory.update_recent_entities(mems)
                return mems

        default_loc = getattr(interpreter, "default_loc", SPEAKERLOOK)
        ref_obj = d.get("reference_object", default_loc["reference_object"])
        mems = interpreter.subinterpret["reference_objects"](
            interpreter,
            speaker,
            ref_obj,
            limit=expected_num,
            loose_speakerlook=loose_speakerlook)

        # FIXME use FILTERS here!!
        if len(mems) < expected_num:
            tags = set(tags_from_dict(ref_obj))
            for memtype in interpreter.workspace_memory_prio:
                cands = interpreter.memory.get_recent_entities(memtype)
                mems = [
                    c for c in cands
                    if any(set.intersection(set(c.get_tags()), tags))
                ]
                if len(mems) >= expected_num:
                    break

        if len(mems) < expected_num:
            raise ErrorWithResponse("I don't know what you're referring to")

        # FIXME:
        mems = mems[:expected_num]
        interpreter.memory.update_recent_entities(mems)

        return mems