예제 #1
0
def test_create_programs_with_vanilla_salience_model(data_dir: str):
    """Tests creating programs with a vanilla salience model.
    """
    utterance_tokenizer = UtteranceTokenizer()
    salience_model = VanillaSalienceModel()
    expected_num_refer_calls = {
        "MUL1626.json": 1,
        "PMUL3166.json": 0,
        "MUL2258.json": 1,
        "MUL2199.json": 1,
        "MUL2096.json": 0,
        "PMUL3470.json": 0,
        "PMUL4478.json": 0,
    }
    for trade_dialogue in load_test_trade_dialogues(data_dir):
        dataflow_dialogue, num_refer_calls, _ = create_programs_for_trade_dialogue(
            trade_dialogue=trade_dialogue,
            keep_all_domains=True,
            remove_none=False,
            fill_none=False,
            salience_model=salience_model,
            no_revise=False,
            avoid_empty_plan=False,
            utterance_tokenizer=utterance_tokenizer,
        )
        dialogue_id = dataflow_dialogue.dialogue_id
        assert (num_refer_calls == expected_num_refer_calls[dialogue_id]
                ), "{} failed".format(dialogue_id)
예제 #2
0
def build_user_utterance(
        text: str, utterance_tokenizer: UtteranceTokenizer) -> UserUtterance:
    text = clean_utterance_text(text)
    if not text:
        return UserUtterance(original_text=SpecialStrings.NULL,
                             tokens=[SpecialStrings.NULL])
    return UserUtterance(original_text=text,
                         tokens=utterance_tokenizer.tokenize(text))
def test_tokenize_utterance():
    utterance_tokenizer = UtteranceTokenizer()

    data = [
        (
            "Reschedule meeting with Barack Obama to 5/30/2019 at 3:00pm",
            [
                "Reschedule",
                "meeting",
                "with",
                "Barack",
                "Obama",
                "to",
                "5",
                "/",
                "30",
                "/",
                "2019",
                "at",
                "3",
                ":",
                "00",
                "pm",
            ],
        ),
        (
            "Can you also add icecream birthday tomorrow at 6PM?",
            [
                "Can",
                "you",
                "also",
                "add",
                "icecream",
                "birthday",
                "tomorrow",
                "at",
                "6",
                "PM",
                "?",
            ],
        ),
    ]
    for text, expected in data:
        assert utterance_tokenizer.tokenize(text) == expected
예제 #4
0
def build_agent_utterance(text: str, utterance_tokenizer: UtteranceTokenizer,
                          described_entities: List[str]) -> AgentUtterance:
    text = clean_utterance_text(text)
    if not text:
        return AgentUtterance(
            original_text=SpecialStrings.NULL,
            tokens=[SpecialStrings.NULL],
            described_entities=described_entities,
        )
    return AgentUtterance(
        original_text=text,
        tokens=utterance_tokenizer.tokenize(text),
        described_entities=described_entities,
    )
예제 #5
0
def test_create_programs_with_revise_with_fill_none(
        trade_dialogue_1: Dict[str, Any]):
    utterance_tokenizer = UtteranceTokenizer()
    salience_model = VanillaSalienceModel()

    expected_plans: List[str] = [
        # turn 1
        """(find (Constraint[Hotel] :area (?= #(String "none")) :book-day (?= #(String "none")) :book-people (?= #(String "none")) :book-stay (?= #(String "none")) :internet (?= #(String "none")) :name (?= #(String "none")) :parking (?= #(String "none")) :pricerange (?= #(String "none")) :stars (?= #(String "none")) :type (?= #(String "none"))))""",
        #  turn 2
        """(ReviseConstraint :new (Constraint[Hotel] :name (?= #(String "hilton")) :pricerange (?= #(String "cheap")) :type (?= #(String "guest house"))) :oldLocation (Constraint[Constraint[Hotel]]) :rootLocation (roleConstraint #(Path "output")))""",
        # turn 3
        """(ReviseConstraint :new (Constraint[Hotel] :name (?= #(String "none"))) :oldLocation (Constraint[Constraint[Hotel]]) :rootLocation (roleConstraint #(Path "output")))""",
        # turn 4
        """(abandon (Constraint[Hotel]))""",
        # turn 5
        """(find (Constraint[Hotel] :area (?= #(String "west")) :book-day (?= #(String "none")) :book-people (?= #(String "none")) :book-stay (?= #(String "none")) :internet (?= #(String "none")) :name (?= #(String "none")) :parking (?= #(String "none")) :pricerange (?= #(String "none")) :stars (?= #(String "none")) :type (?= #(String "none"))))""",
        # turn 6
        """(find (Constraint[Restaurant] :area (refer (Constraint[Area])) :book-day (?= #(String "none")) :book-people (?= #(String "none")) :book-time (?= #(String "none")) :food (?= #(String "none")) :name (?= #(String "none")) :pricerange (?= #(String "none"))))""",
        # turn 7
        """(ReviseConstraint :new (Constraint[Restaurant] :pricerange (refer (Constraint[Pricerange]))) :oldLocation (Constraint[Constraint[Restaurant]]) :rootLocation (roleConstraint #(Path "output")))""",
        # turn 8
        "()",
        # turn 9
        """(find (Constraint[Taxi] :arriveby (?= #(String "none")) :departure (?= #(String "none")) :destination (?= #(String "none")) :leaveat (?= #(String "none"))))""",
        # turn 10
        "()",
    ]
    dataflow_dialogue, _, _ = create_programs_for_trade_dialogue(
        trade_dialogue=trade_dialogue_1,
        keep_all_domains=True,
        remove_none=False,
        fill_none=True,
        salience_model=salience_model,
        no_revise=False,
        avoid_empty_plan=False,
        utterance_tokenizer=utterance_tokenizer,
    )
    for turn, expected_plan in zip(
            dataflow_dialogue.turns,
            expected_plans  # pylint: disable=no-member
    ):
        lispress = turn.lispress
        assert lispress == expected_plan
예제 #6
0
def test_create_programs_without_revise(data_dir: str):
    """Tests creating programs without revise calls.

    It should not use refer calls even with a valid salience model.
    """
    utterance_tokenizer = UtteranceTokenizer()
    salience_model = VanillaSalienceModel()

    for trade_dialogue in load_test_trade_dialogues(data_dir):
        for avoid_empty_plan in [True, False]:
            _, num_refer_calls, _ = create_programs_for_trade_dialogue(
                trade_dialogue=trade_dialogue,
                keep_all_domains=True,
                remove_none=False,
                fill_none=False,
                salience_model=salience_model,
                no_revise=True,
                avoid_empty_plan=avoid_empty_plan,
                utterance_tokenizer=utterance_tokenizer,
            )
            assert num_refer_calls == 0
예제 #7
0
def main(
    trade_data_file: str,
    keep_all_domains: bool,
    remove_none: bool,
    fill_none: bool,
    no_refer: bool,
    no_revise: bool,
    avoid_empty_plan: bool,
    outbase: str,
) -> str:
    utterance_tokenizer = UtteranceTokenizer()

    salience_model: SalienceModelBase
    if no_refer:
        salience_model = DummySalienceModel()
    else:
        salience_model = VanillaSalienceModel()

    total_num_refer_calls = 0
    num_dialogues = 0
    num_dialogues_without_refer_calls = 0
    num_turns_with_refer: int = 0
    num_turns: int = 0

    trade_dialogues = json.load(open(trade_data_file, "r"))
    dataflow_dialogues_file = outbase + ".dataflow_dialogues.jsonl"
    dataflow_dialogues_jsonl_fp = open(dataflow_dialogues_file, "w")
    refer_call_reports_jsonl_fp = open(outbase + ".refer_call_reports.jsonl",
                                       "w")
    refer_call_reports_txt_fp = open(outbase + ".refer_call_reports.txt", "w")

    for trade_dialogue in tqdm(trade_dialogues, unit=" dialogues"):
        (
            dataflow_dialogue,
            num_refer_calls,
            refer_call_reports,
        ) = create_programs_for_trade_dialogue(
            trade_dialogue=trade_dialogue,
            keep_all_domains=keep_all_domains,
            remove_none=remove_none,
            fill_none=fill_none,
            salience_model=salience_model,
            no_revise=no_revise,
            avoid_empty_plan=avoid_empty_plan,
            utterance_tokenizer=utterance_tokenizer,
        )
        dataflow_dialogues_jsonl_fp.write(
            jsons.dumps(dataflow_dialogue) + "\n")
        for refer_call_report in refer_call_reports:
            if refer_call_report["numResolveCalls"] > 0:
                num_turns_with_refer += 1
            num_turns += 1

            refer_call_reports_jsonl_fp.write(json.dumps(refer_call_report))
            refer_call_reports_jsonl_fp.write("\n")
            save_refer_call_report_txt(refer_call_report,
                                       refer_call_reports_txt_fp)

        total_num_refer_calls += num_refer_calls
        num_dialogues += 1
        if num_refer_calls == 0:
            num_dialogues_without_refer_calls += 1
    dataflow_dialogues_jsonl_fp.close()
    refer_call_reports_jsonl_fp.close()
    refer_call_reports_txt_fp.close()

    # print some basic statistics
    print(f"Converted {num_dialogues} dialogues")
    print(
        f"Number of dialogues without refer calls: {num_dialogues_without_refer_calls}"
    )
    print(f"Number of turns: {num_turns}")
    print(f"Number of turns with refer calls: {num_turns_with_refer}")
    print(f"Total number of refer calls: {total_num_refer_calls}")

    return dataflow_dialogues_file
예제 #8
0
def test_execute_programs(trade_dialogue_1: Dict[str, Any]):
    utterance_tokenizer = UtteranceTokenizer()
    salience_model = VanillaSalienceModel()

    # ============================
    # get cheating execution results
    # ============================
    dataflow_dialogue, _, _ = create_programs_for_trade_dialogue(
        trade_dialogue=trade_dialogue_1,
        keep_all_domains=True,
        remove_none=False,
        fill_none=False,
        salience_model=salience_model,
        no_revise=False,
        avoid_empty_plan=False,
        utterance_tokenizer=utterance_tokenizer,
    )
    complete_execution_results, cheating_turn_indices = execute_programs_for_dialogue(
        dialogue=dataflow_dialogue,
        salience_model=salience_model,
        no_revise=False,
        cheating_mode="never",
        cheating_execution_results=None,
    )
    assert not cheating_turn_indices
    for trade_turn, complete_execution_result in zip(
            trade_dialogue_1["dialogue"], complete_execution_results):
        assert build_belief_state_from_trade_turn(
            trade_turn) == build_belief_state_from_belief_dict(
                complete_execution_result.belief_dict, strict=True)
    # pylint: disable=no-member
    cheating_execution_results = {
        turn.turn_index: complete_execution_result
        for turn, complete_execution_result in zip(dataflow_dialogue.turns,
                                                   complete_execution_results)
    }

    # ============================
    # mock the belief state predictions
    # ============================
    mock_belief_states = [
        # turn 1: correct
        {
            "hotel-name": "none",
            "hotel-type": "none"
        },
        # turn 2: correct
        {
            "hotel-name": "hilton",
            "hotel-pricerange": "cheap",
            "hotel-type": "guest house",
        },
        # turn 3: change a slot
        {
            "hotel-name": "none",
            "hotel-pricerange": "_cheap",
            "hotel-type": "guest house",
        },
        # turn 4: add a slot
        {
            "hotel-type": "_added"
        },
        # turn 5: correct
        {
            "hotel-area": "west"
        },
        # turn 6: correct
        {
            "hotel-area": "west",
            "restaurant-area": "west"
        },
        # turn 7: correct
        {
            "hotel-area": "west",
            "restaurant-area": "west",
            "restaurant-pricerange": "cheap",
        },
        # turn 8: change two slots
        {
            "hotel-area": "_west",
            "restaurant-area": "_west",
            "restaurant-pricerange": "cheap",
        },
        # turn 9: correct
        {
            "hotel-area": "west",
            "restaurant-area": "west",
            "restaurant-pricerange": "cheap",
            "taxi-departure": "none",
        },
        # turn 10: drop a slot
        {
            "hotel-area": "west",
            "restaurant-area": "west",
            "restaurant-pricerange": "cheap",
        },
    ]
    mock_trade_dialogue = build_trade_dialogue(
        dialogue_id="mock",
        turns=[("", "", belief_state) for belief_state in mock_belief_states],
    )

    mock_dataflow_dialogue, _, _ = create_programs_for_trade_dialogue(
        trade_dialogue=mock_trade_dialogue,
        keep_all_domains=True,
        remove_none=False,
        fill_none=False,
        salience_model=salience_model,
        no_revise=False,
        avoid_empty_plan=False,
        utterance_tokenizer=utterance_tokenizer,
    )
    _, mock_cheating_turn_indices = execute_programs_for_dialogue(
        dialogue=mock_dataflow_dialogue,
        salience_model=salience_model,
        no_revise=False,
        cheating_mode="always",
        cheating_execution_results=cheating_execution_results,
    )
    assert mock_cheating_turn_indices == [
        turn.turn_index for turn in dataflow_dialogue.turns
    ]

    _, mock_cheating_turn_indices = execute_programs_for_dialogue(
        dialogue=mock_dataflow_dialogue,
        salience_model=salience_model,
        no_revise=False,
        cheating_mode="dynamic",
        cheating_execution_results=cheating_execution_results,
    )
    assert mock_cheating_turn_indices == [3, 4, 8, 10]