def __init__(self): self.builder = StatementBuilder() self.adder = StatementSafeAdder() self.question_handler = QuestionHandler() self.sfactory = SentenceFactory() self.output_sentence = []
def __init__(self): self.builder = StatementBuilder() self.adder = StatementSafeAdder() self.question_handler = QuestionHandler() self.sfactory = SentenceFactory() self.output_sentence = []
class ContentAnalyser(object): def __init__(self): self.builder = StatementBuilder() self.adder = StatementSafeAdder() self.question_handler = QuestionHandler() self.sfactory = SentenceFactory() self.output_sentence = [] def analyse(self, sentence, current_speaker): """Analyse a sentence intent and perform the corresponding behaviour. :returns: a pair with - a list of symbolic statements produced during the analyse. Note that these statements have already been sent to the knowledge base - a situation ID that identifies a situation the speaker is desiring (for an imperative sentence or an order) or experiencing (like an 'InterrogativeState' for a question). These two values can be None. Note also that an answer to the speaker is stored in self.output_sentence after analyse() completes. It can be used to tell the human to acknowledge an order, answer a gratulation, the answer a question (or the fact the answer is not known), etc. """ self.builder.clear_all() self.output_sentence = [] sentence = self.pre_analyse_content(sentence) if sentence.data_type == [INTERJECTION, EXCLAMATION]: pass if sentence.data_type in [START, END]: self.output_sentence.append(sentence) if sentence.data_type == GRATULATION: self.output_sentence.extend( self.sfactory.create_gratulation_reply()) if sentence.data_type in [AGREEMENT, DISAGREEMENT]: self.output_sentence.extend(self.sfactory.create_agree_reply()) if sentence.data_type in [IMPERATIVE, STATEMENT]: logger.debug( colored_print( "Processing the content of " + ("an imperative sentence" if sentence.data_type == IMPERATIVE else "a statement "), "magenta")) return self.process_sentence(sentence, current_speaker) if sentence.data_type in [W_QUESTION, YES_NO_QUESTION]: logger.debug( colored_print( "Processing the content of " + ("a W question " if sentence.data_type == W_QUESTION else "a YES/NO question"), "magenta")) return self.process_question(sentence, current_speaker) return None, None # default: no statement generated, no situation ID def process_sentence(self, sentence, current_speaker): self.builder.set_current_speaker(current_speaker) stmts, situation_id = self.builder.process_sentence(sentence) if stmts: self.add_stmts(stmts) emotions.satisfied() if situation_id: # If a new situation has been created, mark it as # active. self.output_sentence.extend(self.sfactory.create_agree_reply()) ResourcePool().mark_active(situation_id) else: logger.info("No statements produced") # Class grounding if self.builder.lear_more_concept: self.output_sentence.extend( self.sfactory.create_what_is_a_reference( sentence, self.builder.lear_more_concept)) return stmts, situation_id def process_question(self, sentence, current_speaker): self.question_handler.set_current_speaker(current_speaker) # 'stmts' contains a list of statement describing the current # 'interrogative state' of the interactor. answer, stmts, situation_id = self.question_handler.process_sentence( sentence) if stmts: self.add_stmts(stmts) else: logger.info("No statements produced") if answer: emotions.satisfied() logger.info( level_marker(level=2, color="yellow") + "Found: \n" + colored_print(str(answer), None, "magenta")) else: emotions.sorry() logger.info( level_marker(level=2, color="yellow") + "Couldn't find anything!") if sentence.data_type == W_QUESTION: self.output_sentence.extend( self.sfactory.create_w_question_answer( sentence, answer, self.question_handler._current_speaker, self.question_handler.get_query_on_field())) if sentence.data_type == YES_NO_QUESTION: self.output_sentence.extend( self.sfactory.create_yes_no_answer(sentence, answer)) return stmts, situation_id def add_stmts(self, stmts): logger.info("Generated statements: ") for s in stmts: logger.info(">> " + colored_print(s, None, 'magenta')) self.adder._current_speaker = self.builder._current_speaker self.adder._unclarified_ids = self.builder._unclarified_ids self.adder._statements = stmts self.adder._statements_to_remove = self.builder._statements_to_remove stmts = self.adder.process() logger.debug("...added to the ontology") def analyse_output(self): return self.output_sentence def pre_analyse_content(self, sentence): """ this method analyse the content of a sentence and possibly changes its purpose. E.g: Can you give me the bottle? The sentence above is of YES_NO_QUESTION type but should actually be processed as an order in which the current speaker desires 'the bottle'. Therefore, we turn it into 'give me the bottle'. """ # Case of : # -INPUT: Yes_no_question + can + action verb # -OUTPUT: Imperative + action verb # if sentence.data_type == YES_NO_QUESTION: for sv in sentence.sv: for verb in sv.vrb_main: if 'can+' in verb: vrb_main = verb.lstrip('can+') if not vrb_main in ResourcePool().state + ResourcePool( ).action_verb_with_passive_behaviour.keys( ) + ResourcePool().goal_verbs: logger.debug( colored_print( "Interpreting the <can + action verb> sequence as a desire.\nApplying transformation:", "magenta")) sv.vrb_main[sv.vrb_main.index(verb)] = verb.lstrip( 'can+') sentence.data_type = IMPERATIVE logger.debug(str(sentence)) return sentence return sentence
def setUp(self): ResourcePool().ontology_server.reset() ResourcePool().ontology_server.add(['SPEAKER rdf:type Human', 'SPEAKER rdfs:label "Patrick"', 'blue_cube rdf:type Cube', 'blue_cube hasColor blue', 'blue_cube isOn table1', 'another_cube rdf:type Cube', 'another_cube isAt shelf1', 'another_cube belongsTo SPEAKER', 'another_cube hasSize small', 'shelf1 rdf:type Shelf', 'table1 rdf:type Table', 'myself sees shelf1', 'take_blue_cube performedBy myself', 'take_blue_cube rdf:type Get', 'take_blue_cube actsOnObject blue_cube', 'take_my_cube canBePerformedBy SPEAKER', 'take_my_cube involves another_cube', 'take_my_cube rdf:type Take', 'SPEAKER focusesOn another_cube', 'id_danny rdfs:label "Danny"', 'give_another_cube rdf:type Give', 'give_another_cube performedBy id_danny', 'give_another_cube receivedBy SPEAKER', 'give_another_cube actsOnObject another_cube', 'id_danny sees SPEAKER', ]) ResourcePool().ontology_server.addForAgent(ResourcePool().get_model_mapping('SPEAKER'), [ 'SPEAKER rdf:type Human', 'SPEAKER rdfs:label "Patrick"', 'blue_cube rdf:type Cube', 'blue_cube hasColor blue', 'blue_cube isOn table1', 'another_cube rdf:type Cube', 'another_cube isAt shelf1', 'another_cube belongsTo SPEAKER', 'another_cube hasSize small', 'shelf1 rdf:type Shelf', 'table1 rdf:type Table', 'myself sees shelf1', 'take_blue_cube performedBy myself', 'take_blue_cube rdf:type Get', 'take_blue_cube actsOnObject blue_cube', 'take_my_cube canBePerformedBy SPEAKER', 'take_my_cube involves another_cube', 'take_my_cube rdf:type Take', 'SPEAKER focusesOn another_cube', 'id_danny rdfs:label "Danny"', 'give_another_cube rdf:type Give', 'give_another_cube performedBy id_danny', 'give_another_cube receivedBy SPEAKER', 'give_another_cube actsOnObject another_cube', 'id_danny sees SPEAKER', ]) self.qhandler = QuestionHandler("SPEAKER") self.resolver = Resolver()
class TestQuestionHandler(unittest.TestCase): def setUp(self): ResourcePool().ontology_server.reset() ResourcePool().ontology_server.add(['SPEAKER rdf:type Human', 'SPEAKER rdfs:label "Patrick"', 'blue_cube rdf:type Cube', 'blue_cube hasColor blue', 'blue_cube isOn table1', 'another_cube rdf:type Cube', 'another_cube isAt shelf1', 'another_cube belongsTo SPEAKER', 'another_cube hasSize small', 'shelf1 rdf:type Shelf', 'table1 rdf:type Table', 'myself sees shelf1', 'take_blue_cube performedBy myself', 'take_blue_cube rdf:type Get', 'take_blue_cube actsOnObject blue_cube', 'take_my_cube canBePerformedBy SPEAKER', 'take_my_cube involves another_cube', 'take_my_cube rdf:type Take', 'SPEAKER focusesOn another_cube', 'id_danny rdfs:label "Danny"', 'give_another_cube rdf:type Give', 'give_another_cube performedBy id_danny', 'give_another_cube receivedBy SPEAKER', 'give_another_cube actsOnObject another_cube', 'id_danny sees SPEAKER', ]) ResourcePool().ontology_server.addForAgent(ResourcePool().get_model_mapping('SPEAKER'), [ 'SPEAKER rdf:type Human', 'SPEAKER rdfs:label "Patrick"', 'blue_cube rdf:type Cube', 'blue_cube hasColor blue', 'blue_cube isOn table1', 'another_cube rdf:type Cube', 'another_cube isAt shelf1', 'another_cube belongsTo SPEAKER', 'another_cube hasSize small', 'shelf1 rdf:type Shelf', 'table1 rdf:type Table', 'myself sees shelf1', 'take_blue_cube performedBy myself', 'take_blue_cube rdf:type Get', 'take_blue_cube actsOnObject blue_cube', 'take_my_cube canBePerformedBy SPEAKER', 'take_my_cube involves another_cube', 'take_my_cube rdf:type Take', 'SPEAKER focusesOn another_cube', 'id_danny rdfs:label "Danny"', 'give_another_cube rdf:type Give', 'give_another_cube performedBy id_danny', 'give_another_cube receivedBy SPEAKER', 'give_another_cube actsOnObject another_cube', 'id_danny sees SPEAKER', ]) self.qhandler = QuestionHandler("SPEAKER") self.resolver = Resolver() def test_1_where_question(self): logger.info("\n************* test_1_where_question ******************") logger.info("Where is the blue cube?") sentence = Sentence(W_QUESTION, "place", [NominalGroup(['the'], ['cube'], [['blue', []]], [], [])], [VerbalGroup(['be'], [], 'present_simple', [], [], [], [], VerbalGroup.affirmative, [])]) expected_result = 'table1' self.process(sentence, expected_result) def test_2_where_question(self): logger.info("\n************* test_2_where_question ******************") logger.info("Where is the small cube?") sentence = Sentence(W_QUESTION, "place", [NominalGroup(['the'], ['cube'], [['small', []]], [], [])], [VerbalGroup(['be'], [], 'present_simple', [], [], [], [], VerbalGroup.affirmative, [])]) expected_result = 'shelf1' self.process(sentence, expected_result) def test_3_what_question(self): logger.info("\n************* test_3_what_question ******************") logger.info("What do you see?") sentence = Sentence(W_QUESTION, "thing", [NominalGroup([], ['you'], [], [], [])], [VerbalGroup(['see'], [], 'present_simple', [], [], [], [], VerbalGroup.affirmative, [])]) expected_result = 'shelf1' self.process(sentence, expected_result) def test_8_what_question(self): logger.info("\n************* test_8_what_question ******************") logger.info("what is blue?") sentence = Sentence(W_QUESTION, "thing", [], [VerbalGroup(['be'], [], 'present simple', [NominalGroup([], [], [['blue', []]], [], [])], [], [], [], VerbalGroup.affirmative, [])]) expected_result = 'blue_cube' self.process(sentence, expected_result) def test_9_what_question_this(self): logger.info("\n************* test_9_what_question_this ******************") logger.info("what is this?") sentence = Sentence(W_QUESTION, "thing", [NominalGroup(['this'], [], [], [], [])], [VerbalGroup(['be'], [], 'present simple', [], [], [], [], VerbalGroup.affirmative, [])]) expected_result = 'another_cube' self.process(sentence, expected_result) def test_10_what_question(self): logger.info("\n************* test_10_w_question ******************") logger.info("what object is blue?") sentence = Sentence(W_QUESTION, "object", [], [VerbalGroup(['be'], [], 'present simple', [NominalGroup([], [], [['blue', []]], [], [])], [], [], [], VerbalGroup.affirmative, [])]) expected_result = 'blue_cube' self.process(sentence, expected_result) def test_11_what_question(self): logger.info("\n************* test_11_w_question ******************") logger.info("what size is this?") sentence = Sentence(W_QUESTION, "size", [NominalGroup(['this'], [], [], [], [])], [VerbalGroup(['be'], [], 'present simple', [], [], [], [], VerbalGroup.affirmative, [])]) expected_result = 'small' self.process(sentence, expected_result) def test_12_what_question(self): logger.info("\n************* test_12_what_question ******************") logger.info("what color is the blue_cube?") sentence = Sentence(W_QUESTION, "color", [NominalGroup(['the'], ['blue_cube'], [], [], [])], [VerbalGroup(['be'], [], 'present simple', [], [], [], [], VerbalGroup.affirmative, [])]) expected_result = 'blue' self.process(sentence, expected_result) def test_13_who_question(self): logger.info("\n************* test_13_who_question ******************") logger.info("who is the SPEAKER?") sentence = Sentence(W_QUESTION, "people", [NominalGroup(['the'], ['SPEAKER'], [], [], [])], [VerbalGroup(['be'], [], 'present simple', [], [], [], [], VerbalGroup.affirmative, [])]) expected_result = 'SPEAKER' self.process(sentence, expected_result) def test_14_who_question(self): logger.info("\n************* test_14_who_question ******************") logger.info("who sees Patrick?") sentence = Sentence(W_QUESTION, "people", [], [VerbalGroup(['see'], [], 'present simple', [NominalGroup([], ['Patrick'], [], [], [])], [], [], [], VerbalGroup.affirmative, [])]) expected_result = 'id_danny' self.process(sentence, expected_result) def test_15_who_question(self): logger.info("\n************* test_15_who_question ******************") logger.info("who does Danny give the small cube?") sentence = Sentence(W_QUESTION, "people", [NominalGroup([], ['Danny'], [], [], [])], [VerbalGroup(['give'], [], 'present simple', [NominalGroup(['the'], ['cube'], [['small', []]], [], [])], [], [], [], VerbalGroup.affirmative, [])]) expected_result = 'SPEAKER' self.process(sentence, expected_result) def test_4_y_n_question(self): logger.info("\n************* test_4_y_n_question action verb******************") logger.info("Did you get the blue cube?") sentence = Sentence(YES_NO_QUESTION, "", [NominalGroup([], ['you'], [''], [], [])], [VerbalGroup(['get'], [], 'past simple', [NominalGroup(['the'], ['cube'], [['blue', []]], [], [])], [], [], [], VerbalGroup.affirmative, [])]) expected_result = True self.process(sentence, expected_result) def test_5_y_n_question(self): logger.info("\n************* test_5_y_n_question verb to be followed by complement******************") logger.info("Is the blue cube on the table1?") sentence = Sentence(YES_NO_QUESTION, "", [NominalGroup(['the'], ['cube'], [['blue', []]], [], [])], [VerbalGroup(['be'], [], 'present simple', [], [IndirectComplement(['on'], [NominalGroup(['the'], ['table1'], [], [], [])])], [], [], VerbalGroup.affirmative, [])]) expected_result = True self.process(sentence, expected_result) def test_6_y_n_question(self): logger.info("\n************* test_6_y_n_question ******************") logger.info("Is the small cube blue?") sentence = Sentence(YES_NO_QUESTION, "", [NominalGroup(['the'], ['cube'], [['small', []]], [], [])], [VerbalGroup(['be'], [], 'present simple', [NominalGroup([], [], [['blue', []]], [], [])], [], [], [], VerbalGroup.affirmative, [])]) expected_result = False self.process(sentence, expected_result) def test_7_y_n_question(self): logger.info("\n************* test_7_y_n_question verb to be ******************") logger.info("Is my cube on the table1?") sentence = Sentence(YES_NO_QUESTION, "", [NominalGroup(['my'], ['cube'], [], [], [])], [VerbalGroup(['be'], [], 'present simple', [], [IndirectComplement(['on'], [NominalGroup(['the'], ['table1'], [], [], [])])], [], [], VerbalGroup.affirmative, [])]) expected_result = False self.process(sentence, expected_result) def test_9_how_question(self): logger.info("\n************* test_9_how_question ******************") logger.info("How is my car?") sentence = Sentence(W_QUESTION, "manner", [NominalGroup(['my'], ['cube'], [], [], [])], [VerbalGroup(['be'], [], 'present simple', [], [], [], [], VerbalGroup.affirmative, [])]) expected_result = [['blue', []]] self.process(sentence, expected_result) def process(self, sentence, expected_result): sentence = dump_resolved(sentence, 'SPEAKER', 'myself', self.resolver) res = self.qhandler.process_sentence(sentence) #Statements Built for querying Ontology logger.info("Query Statement ...") for s in self.qhandler._statements: logger.info("\t>>" + s) logger.info("--------------- >>\n") #Result from the ontology logger.info("Expected Result:" + str(expected_result)) logger.debug("Result Found in the Ontology: " + str(self.qhandler._answer)) self.qhandler.clear_statements() if sentence.data_type == W_QUESTION: self.assertTrue(expected_result in val[1] for val in res) # res may be a list of several IDs that match the question. Here the result succeed if the expected one is among them if sentence.data_type == YES_NO_QUESTION: self.assertEquals(expected_result, res[0])
class ContentAnalyser(object): def __init__(self): self.builder = StatementBuilder() self.adder = StatementSafeAdder() self.question_handler = QuestionHandler() self.sfactory = SentenceFactory() self.output_sentence = [] def analyse(self, sentence, current_speaker): """Analyse a sentence intent and perform the corresponding behaviour. :returns: a pair with - a list of symbolic statements produced during the analyse. Note that these statements have already been sent to the knowledge base - a situation ID that identifies a situation the speaker is desiring (for an imperative sentence or an order) or experiencing (like an 'InterrogativeState' for a question). These two values can be None. Note also that an answer to the speaker is stored in self.output_sentence after analyse() completes. It can be used to tell the human to acknowledge an order, answer a gratulation, the answer a question (or the fact the answer is not known), etc. """ self.builder.clear_all() self.output_sentence = [] sentence = self.pre_analyse_content(sentence) if sentence.data_type == [INTERJECTION, EXCLAMATION]: pass if sentence.data_type in [START, END]: self.output_sentence.append(sentence) if sentence.data_type == GRATULATION: self.output_sentence.extend(self.sfactory.create_gratulation_reply()) if sentence.data_type in [AGREEMENT, DISAGREEMENT]: self.output_sentence.extend(self.sfactory.create_agree_reply()) if sentence.data_type in [IMPERATIVE, STATEMENT]: logger.debug(colored_print("Processing the content of " + ( "an imperative sentence" if sentence.data_type == IMPERATIVE else "a statement "), "magenta")) return self.process_sentence(sentence, current_speaker) if sentence.data_type in [W_QUESTION, YES_NO_QUESTION]: logger.debug(colored_print("Processing the content of " + ( "a W question " if sentence.data_type == W_QUESTION else "a YES/NO question"), "magenta")) return self.process_question(sentence, current_speaker) return None, None # default: no statement generated, no situation ID def process_sentence(self, sentence, current_speaker): self.builder.set_current_speaker(current_speaker) stmts, situation_id = self.builder.process_sentence(sentence) if stmts: self.add_stmts(stmts) emotions.satisfied() if situation_id: # If a new situation has been created, mark it as # active. self.output_sentence.extend(self.sfactory.create_agree_reply()) ResourcePool().mark_active(situation_id) else: logger.info("No statements produced") # Class grounding if self.builder.lear_more_concept: self.output_sentence.extend( self.sfactory.create_what_is_a_reference(sentence, self.builder.lear_more_concept)) return stmts, situation_id def process_question(self, sentence, current_speaker): self.question_handler.set_current_speaker(current_speaker) # 'stmts' contains a list of statement describing the current # 'interrogative state' of the interactor. answer, stmts, situation_id = self.question_handler.process_sentence(sentence) if stmts: self.add_stmts(stmts) else: logger.info("No statements produced") if answer: emotions.satisfied() logger.info( level_marker(level=2, color="yellow") + "Found: \n" + colored_print(str(answer), None, "magenta")) else: emotions.sorry() logger.info(level_marker(level=2, color="yellow") + "Couldn't find anything!") if sentence.data_type == W_QUESTION: self.output_sentence.extend(self.sfactory.create_w_question_answer(sentence, answer, self.question_handler._current_speaker, self.question_handler.get_query_on_field())) if sentence.data_type == YES_NO_QUESTION: self.output_sentence.extend(self.sfactory.create_yes_no_answer(sentence, answer)) return stmts, situation_id def add_stmts(self, stmts): logger.info("Generated statements: ") for s in stmts: logger.info(">> " + colored_print(s, None, 'magenta')) self.adder._current_speaker = self.builder._current_speaker self.adder._unclarified_ids = self.builder._unclarified_ids self.adder._statements = stmts self.adder._statements_to_remove = self.builder._statements_to_remove stmts = self.adder.process() logger.debug("...added to the ontology") def analyse_output(self): return self.output_sentence def pre_analyse_content(self, sentence): """ this method analyse the content of a sentence and possibly changes its purpose. E.g: Can you give me the bottle? The sentence above is of YES_NO_QUESTION type but should actually be processed as an order in which the current speaker desires 'the bottle'. Therefore, we turn it into 'give me the bottle'. """ # Case of : # -INPUT: Yes_no_question + can + action verb # -OUTPUT: Imperative + action verb # if sentence.data_type == YES_NO_QUESTION: for sv in sentence.sv: for verb in sv.vrb_main: if 'can+' in verb: vrb_main = verb.lstrip('can+') if not vrb_main in ResourcePool().state + ResourcePool().action_verb_with_passive_behaviour.keys() + ResourcePool().goal_verbs: logger.debug(colored_print( "Interpreting the <can + action verb> sequence as a desire.\nApplying transformation:", "magenta")) sv.vrb_main[sv.vrb_main.index(verb)] = verb.lstrip('can+') sentence.data_type = IMPERATIVE logger.debug(str(sentence)) return sentence return sentence