def _get_class_name_from_ontology(self, current_speaker, nominal_group): onto_res = [] noun = "" try: noun = nominal_group.noun[0].replace('+', ' ') onto_res = ResourcePool().ontology_server.lookupForAgent( ResourcePool().get_model_mapping(current_speaker), noun) except IndexError: raise DialogError("We should not have to resolve nominal " + \ "groups with indefinite determiner and only adjectives") except KbError: # The agent does not exist in the ontology pass return get_class_name(noun, onto_res)
def process_verbal_group_part(verbal_group, nominal_group_structure, flag): """ process merge in the verbal part Input=nominal groups, the verbal part and the flag Output= nominal group """ #The direct complement is a nominal group for object in verbal_group.d_obj: concat_gn(nominal_group_structure, object, flag) ind_cmpl = i_cmpl(verbal_group.i_cmpl) #For indirect complement for i in ind_cmpl: if i.prep[0] in ResourcePool().compelement_proposals and ( (not verbal_group) or verbal_group.vrb_main[0] != 'talk'): #If it is an adverbial related to the noun, we have to add it like a relative rltv = Sentence('relative', 'which', [], [verbal_group]) nominal_group_structure.relative = nominal_group_structure.relative + [ rltv ] else: #Else we concatenate with the nominal part of the indirect complement for k in i.gn: concat_gn(nominal_group_structure, k, flag) for i in verbal_group.sv_sec: process_verbal_group_part(i, nominal_group_structure, flag) #For the subsentences nominal_group_remerge(verbal_group.vrb_sub_sentence, flag, nominal_group_structure) return nominal_group_structure
def preposition_concat(sentence): """ concatenate some words to have a preposition Input=sentence Output=sentence """ # init i = 0 # For the case of whom if sentence[0:2] == ['To', 'whom']: sentence = ['To+whom'] + sentence[2:] #For all other prepositions while i < len(sentence): for j in ResourcePool().concatenate_proposals: if i + len(j) <= len(sentence) and sentence[i:i + len(j)] == j: sentence = sentence[:i] + [ other_functions.convert_to_string(j) ] + sentence[i + len(j):] break i += 1 return sentence
def get_all_objects_with_desc(self, description): obj_list = None for agent_desc in description: obj_tmp = [] try: obj_tmp = self.oro.findForAgent( ResourcePool().get_model_mapping(agent_desc[0]), agent_desc[1], agent_desc[2]) except KbError: #The agent does not exist in the ontology pass # if no object found, no need to continue if not obj_tmp: obj_list = [] break else: if obj_list is None: obj_list = obj_tmp else: obj_list = filter(lambda x: x in obj_list, obj_tmp) # intersection return obj_list
def concat_number(sentence): """ concatenate numbers with '+' Input=sentence Output=sentence """ # init i = 0 sentence = delete_and_from_number(sentence) while i < len(sentence): # There is a number if other_functions.number(sentence[i]) == 1: begin_pos = i while i < len(sentence) and other_functions.number( sentence[i]) == 1: i += 1 end_pos = i #We have to concatenate the last number if it is superlative if i < len(sentence) and other_functions.number(sentence[i]) == 2: end_pos += 1 if i < len(sentence) and sentence[i] in ResourcePool( ).adjective_numbers: end_pos += 1 sentence = sentence[:begin_pos] + [ other_functions.convert_to_string(sentence[begin_pos:end_pos]) ] + sentence[end_pos:] i += 1 return sentence
def setUp(self): self.dialog = Dialog() self.dialog.start() self.oro = ResourcePool().ontology_server try: self.oro.reload() self.oro.add([ 'shelf1 rdf:type Shelf', 'table1 rdf:type Table', 'table2 rdf:type Table', 'table2 hasColor blue', 'Banana rdfs:subClassOf Plant', 'y_banana rdf:type Banana', 'y_banana hasColor yellow', 'y_banana isOn shelf1', 'green_banana rdf:type Banana', 'green_banana hasColor green', 'green_banana isOn table2', 'ACCESSKIT rdf:type Gamebox', 'ACCESSKIT hasColor white', 'ACCESSKIT hasSize big', 'ACCESSKIT isOn table1', 'ORANGEBOX rdf:type Gamebox', 'ORANGEBOX hasColor orange', 'ORANGEBOX hasSize big', 'ORANGEBOX isOn ACCESSKIT', 'MYBOX rdf:type Gamebox', 'MYBOX hasColor orange', 'MYBOX hasSize small', 'MYBOX isOn ACCESSKIT', 'SPACENAVBOX rdf:type Gamebox', 'SPACENAVBOX hasColor white', 'SPACENAVBOX hasSize big', 'SPACENAVBOX isOn ACCESSKIT', 'y_bottle rdf:type Bottle', 'y_bottle isLocated RIGHT', 'r_bottle rdf:type Bottle', 'r_bottle isLocated FRONT', 'b_bottle rdf:type Bottle', 'b_bottle isLocated BACK' ]) except AttributeError: #the ontology server is not started of doesn't know the method pass
def _set_situation_id(self, statements): """This attempts to clarify the ID of an action verbs E.g: statement = [?event rdf:type Go, ?event performedBy myself, ?event actsOnObject xxx] We attemtps to find an existing ontology ID matching '?event' """ stmts = [] find_id = False for s in statements: if '?' in s: find_id = True break if find_id: sit_id = ResourcePool().ontology_server.find(['?event'], statements) if sit_id: logger.debug( "\t/Found a staticSituation matching the yes_no_question query to be checked: " + str(sit_id)) for s in statements: #TODO:the ontology might find severals sit ID matching the query. Should we take this consideration? #The longer the query, the better the result of sit_id stmts.append(s.replace('?event', sit_id[0])) else: stmts = statements # Find process on knowing concept for s in statements: if "knows" in s: self.process_on_knowing_concept = True break return stmts
def state_adjective(sentence, vg): """ This function process adjectives after state verb Input=sentence Output=second verb of the sentence """ #In case there is a state verb followed by an adjective if sentence: if vg.vrb_main[0] in ResourcePool( ).state and analyse_nominal_group.adjective_pos(sentence, 0) - 1 != 0: #Here we have juist to process adjectives, nominal groups are processed pos = analyse_nominal_group.adjective_pos(sentence, 0) adj_list = analyse_nominal_group.process_adj_quantifier( sentence[:pos - 1]) vg.d_obj = [NominalGroup([], [], adj_list, [], [])] sentence = sentence[pos - 1:] #Same as nominal groups but with adjectives conjunction = None while sentence[0] == 'or' or sentence[0] == ':but': if sentence[0] == 'or': conjunction = 'OR' elif sentence[0] == ':but': conjunction = 'BUT' sentence = sentence[1:] pos = analyse_nominal_group.adjective_pos(sentence, 0) adj_list = analyse_nominal_group.process_adj_quantifier( sentence[:pos - 1]) #We put all adjectives in the direct complement vg.d_obj = vg.d_obj + [NominalGroup([], [], adj_list, [], [])] vg.d_obj[len(vg.d_obj) - 1]._conjunction = conjunction sentence = sentence[pos - 1:] return sentence
def exclama_sentence(sentence): """ process exclamatively sentence Input=the sentence Output=class Sentence """ for i in ResourcePool().sentence_starts: if i[0] == sentence[0]: if i[1] == '0': analysis = Sentence(INTERJECTION, '', [], []) #We recover the subject sentence = analyse_nominal_structure.recover_ns( sentence, analysis, 1) return analysis elif i[1] == '2': #It is an exclamation sentence analysis = Sentence(EXCLAMATION, '', [], []) #We recover the subject sentence = analyse_nominal_structure.recover_ns( sentence, analysis, 0) return analysis #If we have an imperative it can be forced analysis = other_sentence(INTERJECTION, '', sentence) if analysis.data_type == INTERJECTION and not analysis.sv: pass else: analysis.data_type = IMPERATIVE return analysis
def w_quest_which(type, request, sentence): """ process which question Input=type of sentence, the sentence Output=class Sentence """ #We start by finding the nominal group gr = preprocessing.determination_nominal_group(sentence, 0, 'of') #If the nominal group contain just 2 elements if len(gr) == 2: return y_n_ques(type, sentence[1], sentence[2:]) else: #After the first gr if there is no nominal group if not analyse_nominal_group.find_sn_pos(sentence, len(gr)): for i in ResourcePool().sentence_starts: #If just after we have an a auxiliary if sentence[len(gr)] == i[0] and i[1] == '3': #With subject => it is a yes or no question form if analyse_nominal_group.find_sn_pos( sentence, len(gr) + 1): analysis = y_n_ques(type, request, sentence[len(gr):]) nominal_gr = other_sentence(type, request, gr) analysis.sv[0].d_obj = nominal_gr.sn return analysis #Else it is like a statement return other_sentence(type, request, sentence) #Else if not, the first nominal group is the subject else: analysis = other_sentence(type, request, sentence[len(gr):]) nominal_gr = other_sentence(type, request, gr) analysis.sv[0].d_obj = nominal_gr.sn return analysis
def move_prep(sentence): """ put the preposition before the nominal group Input=sentence Output=sentence """ # init i = 0 while i < len(sentence): for p in ResourcePool().prep_change_place: # If there is a preposal if sentence[i] == p: position = i #If after preposition we have nominal group, it is for this nominal group if not analyse_nominal_group.find_sn_pos(sentence, i + 1): #We have to find the nominal group just before while not analyse_nominal_group.find_sn_pos( sentence, position): position -= 1 sentence = sentence[:position] + [ p ] + sentence[position:i] + sentence[i + 1:] i += 1 return sentence
def get_discriminant(self, agent, obj_list, ignore_descriptors, include_partial): discriminants = self.oro.discriminateForAgent( ResourcePool().get_model_mapping(agent), obj_list) logger.debug(colored_print('Possible discriminants: ', 'magenta') + \ str(colored_print(discriminants[1], 'blue')) + \ colored_print(" (complete discriminants: ", 'magenta') + \ str(colored_print(discriminants[0], 'blue')) + ")") complete_disc = discriminants[0] partial_disc = discriminants[1] if complete_disc: res = filter(lambda x: x not in ignore_descriptors, complete_disc) elif partial_disc and include_partial: res = filter(lambda x: x not in ignore_descriptors, partial_disc) else: res = None if res: # include randomization so the same discriminant is not always returned return choice(res) else: # No discriminant after applying the blacklist. return None
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 get_descriptor(self, description, ignore_features=None, partial_disc=True): if not ignore_features: ignore_features = [] objL = self.get_all_objects_with_desc(description) descriptor = None agent = None #TODO bug in oro doesn't allow to search discriminants base on other agents models!! # we cannot search in all agents, but only in robot's model # for agent_desc in description: # # list current descriptors to not to use them anymore # #currentDescriptors = map(lambda x: x.split()[1], agent_desc[2]) # descriptor = self.get_discriminant(agent_desc[0], objL, ignore_features, partial_disc) # # if descriptor: # agent = agent_desc[0] # break agent = ResourcePool().default_model # list current descriptors to not to use them anymore #currentDescriptors = map(lambda x: x.split()[1], description[0][2]) descriptor = self.get_discriminant(agent, objL, ignore_features, partial_disc) return agent, descriptor
def clarify(self, statements, ids): """This attempts to identify a matching reference of the action described from the statements - statements: the field of statements used to query the ontology - ids: the field of references that are to be identified e.g: Danny doesn't drive the blue car. statements = [?sit rdf:type Drive, ?sit performedBy DANNY, ?sit involves BLUE_CAR] ids = [?sit] Before removing the statements set from the ontology, we determine if there is a matching action to ?sit """ current_s = statements for id in ids: stmts = [] #Attempt to find the unidentified IDs onto = ResourcePool().ontology_server.find([id], current_s) #Replace Matching IDs if onto: logger.info( colored_print("... Found ID " + onto[0] + " matching description given statements.", "magenta")) for s in current_s: stmts.append(s.replace(id, onto[0])) current_s = stmts return current_s
def replace_tuple(sentence): """ This function to replace some tuples Input=sentence Output=sentence """ #init i = 0 while i < len(sentence): #If there is a tuple for j in insertion_tuples: if sentence[i] == j[1]: #To perform this process we need to have a pronoun if i != 0 and sentence[i - 1] in ResourcePool().pronouns: sentence[i - 1] += j[0] sentence = sentence[:i] + sentence[i + 1:] #The replacement includes that cases if i != 0 and sentence[i] == 'is' and (sentence[i - 1] == 'that' or sentence[i - 1] == 'what'): sentence[i - 1] += j[0] sentence = sentence[:i] + sentence[i + 1:] i += 1 return sentence
def find_sn(sentence): """ Returns the first nominal group found in the sentence. :param list sentence: the sentence as a list of words :return: the nominal group """ nb_position = 1 #If sentence is empty if not sentence: return [] for x in sentence: #If there is a pronoun if x in ResourcePool().pronouns: return [sentence[sentence.index(x)]] #If there is a nominal group with determinant if x in ResourcePool().determinants: nb_position += adjective_pos(sentence, sentence.index(x) + 1) return sentence[sentence.index(x):sentence.index(x) + nb_position] #If we have 'something' for k in ResourcePool().composed_nouns: if x.startswith(k): if x in ResourcePool().noun_not_composed: return [] return [sentence[sentence.index(x)]] #If there is a number, it will be the same with determinant if other_functions.number(x) == 1: nb_position += adjective_pos(sentence, sentence.index(x) + 1) return sentence[sentence.index(x):sentence.index(x) + nb_position] #If there is a proper name counter = sentence.index(x) while counter < len(sentence) and other_functions.find_cap_lettre( sentence[counter]) == 1: counter += 1 #Not equal => there is a proper name if counter != sentence.index(x): return sentence[sentence.index(x):counter] #Default case return []
def process_direct_object(self, d_objects, verb, id, quantifier): """This processes the attribute d_obj of a sentence verbal groups.""" # logger.debug("Processing direct object d_obj:") d_obj_stmt_builder = NominalGroupStatementBuilder(d_objects, self._current_speaker) # Retrieve the thematic role of the direct object from the library. # If not defined, use the generic 'involves' predicate. try: d_obj_role = " " + ResourcePool().thematic_roles.verbs[verb].roles[0].id + " " except KeyError: d_obj_role = " involves " if verb.lower() in ResourcePool().action_verb_with_passive_behaviour.keys(): d_obj_role = ' ' + ResourcePool().action_verb_with_passive_behaviour[verb.lower()] + ' ' # Case of know if verb.lower() == 'know': d_obj_role = '' #nominal groups for d_obj in d_objects: #Case 1: The direct object follows the verb 'to be'. # We process the d_obj with the same id as the subject of the sentence if verb in ResourcePool().state: d_obj_id = id d_obj_quantifier = quantifier #Case 2: The direct object follows another stative or action verb. # we process the d_obj as involved by the situation else: if d_obj.id: d_obj_id = d_obj.id else: d_obj_id = d_obj_stmt_builder.set_nominal_group_id(d_obj) if d_obj_role: self._statements.append(id + d_obj_role + d_obj_id) d_obj_quantifier = None d_obj_stmt_builder.process_nominal_group(d_obj, d_obj_id, d_obj_quantifier, self._process_on_negative) self._statements.extend(d_obj_stmt_builder._statements) self._unclarified_ids.extend(d_obj_stmt_builder._unclarified_ids) self.lear_more_concept.extend(d_obj_stmt_builder.lear_more_concept)
def find_cap_lettre(word): """ Function return 1 if the word starts with upper case letter Input=word Output=flag(0 if no upper case or 1 if upper case) """ if word[0] in ResourcePool().capital_letters: return 1 return 0
def _extend_statement_from_sentence_aim(self, current_statements, sn=None): """This extends the statements states so that the query answer matches the w_question aim """ #Concept descriptor # E.g: Human, Object, Color ,Size... concept_descriptor = self.get_concept_descriptor(sn) #Case: the statement is complete from statement builder e.g: what is in the box? =>[?concept isIn ?id_box, ?id_box rdf:type Box] for s in current_statements: if '?concept' in s.split(): return current_statements + concept_descriptor #case: the statement is partially build from statement builder stmts = [] if sn: for sv in self._sentence.sv: for verb in sv.vrb_main: role = self.get_role_from_sentence_aim( self._query_on_field, verb) #Case of looking for the object in a location if role == 'objectFoundInLocation': self._process_on_location = True # Case of state verbs if verb.lower() in ResourcePool().state: stmts.append(sn.id + ' ' + role + ' ?concept') # Case of action verb with a passive behaviour elif verb.lower() in ResourcePool( ).action_verb_with_passive_behaviour.keys(): stmts.append(sn.id + ' ' + ResourcePool( ).action_verb_with_passive_behaviour[verb.lower()] + ' ?concept') # Case of know elif verb.lower() == 'know': self.process_on_knowing_concept = True stmts.append(sn.id + ' knows ?concept') # case of action verbs else: stmts.append('?event ' + role + ' ?concept') return current_statements + stmts + concept_descriptor
def visible_subset(self, agent, id_list): """ Returns the list of visible objects for an agent from a list of objects. """ visible_objects = self.oro.findForAgent( ResourcePool().get_model_mapping(agent), "?o", [agent + " sees ?o"]) return list(set(id_list) & set(visible_objects))
def is_cmpl_pr(word): """ This function return 1 if it is pronoun else 0 Input=word Output=1 or 0 """ if word in ResourcePool().complement_pronouns: return 1 return 0
def take_off_comma(sentences): """ delete ';' if it is before relative or subsentence Input=list of sentence Output=sentence """ # init i = k = 0 while k < len(sentences): while i < len(sentences[k]): if sentences[k][i] == ';': if sentences[k][i + 1] in ResourcePool( ).subsentences + ResourcePool().relatives: sentences[k] = sentences[k][:i] + sentences[k][i + 1:] i += 1 k += 1 return sentences
def find_sn_pos(sentence, begin_pos): """ We will find the nominal group which is in a known position We have to use adjective_pos to return the end position of nominal group :param list sentence: the sentence (list of strings) :param begin_pos:the position of the nominal group :return: the nominal group (as a list of words) """ if begin_pos >= len(sentence): return [] end_pos = 1 #If it is a pronoun if sentence[begin_pos] in ResourcePool().pronouns: return [sentence[begin_pos]] #If there is a nominal group with determinant if sentence[begin_pos] in ResourcePool().determinants: end_pos += adjective_pos(sentence, begin_pos + 1) return sentence[begin_pos:end_pos + begin_pos] #If we have 'something' for k in ResourcePool().composed_nouns: if sentence[begin_pos].startswith(k): if sentence[begin_pos] in ResourcePool().noun_not_composed: return [] return [sentence[begin_pos]] #If there is a number, it will be the same with determinant if other_functions.number(sentence[begin_pos]) == 1: end_pos += adjective_pos(sentence, begin_pos + 1) return sentence[begin_pos:end_pos + begin_pos] #If it is a proper name counter = begin_pos while counter < len(sentence) and other_functions.find_cap_lettre( sentence[counter]) == 1: counter += 1 #Default case return [] => ok if counter=begin_pos return sentence[begin_pos:counter]
def case_apostrophe_s_to_is(word): """ know if we have to expand contraction 's to is (return 1) Input=word Output=flag(0 if no or 1 if yes) """ word = word[0].lower() + word[1:] if word in ResourcePool().be_pronoun: return 1 return 0
def process_conjunctive_sub(phrase, vg): """ process the conjunctive subsentence Input=sentence and verbal class Output=sentence and verbal class """ #init begin_pos = -1 #We will find conjunctive subsentence if there is if len(phrase ) > 0 and phrase[0] == 'that' and analyse_nominal_group.find_sn_pos( phrase, 1) != []: begin_pos = 0 if len(phrase) > 2 and phrase[0] in ResourcePool( ).pronouns and phrase[1] == 'that' and analyse_nominal_group.find_sn_pos( phrase, 2) != []: begin_pos = 1 if begin_pos != -1: #We include the relative's and subsentence's proposal if there are relatives or subsentences in this subsentence phrase = [phrase[0]] + preprocessing.remerge_sentences(phrase[1:]) end_pos = other_functions.recover_end_pos_sub( phrase[begin_pos:], ['that'] + ResourcePool().subsentences + ResourcePool().relatives) #We have to remove the proposal subsentence = phrase[begin_pos + 1:end_pos] subsentence = other_functions.recover_scd_verb_sub(subsentence) #We perform processing vg.vrb_sub_sentence = vg.vrb_sub_sentence + [ analyse_sentence.other_sentence(SUBSENTENCE, 'that', subsentence) ] vg.vrb_sub_sentence[len(vg.vrb_sub_sentence) - 1].data_type += '+statement' #We delete the subsentence phrase = phrase[:phrase.index('that')] phrase = phrase + phrase[end_pos:] + ['.'] return phrase
def number(word): """ Function return 1 if the word is a number and 2 if it is a adjective-number Input=word Output=flag(0 if no number or 1 if number or 2 adjective-number) """ for n in ResourcePool().numbers: if word.startswith(n[1]): return 1 if word.startswith(n[0]): #We have adjective-number if word.endswith('th'): return 2 else: if word in ResourcePool().special_nouns: return 0 return 1 return 0
def quantity_ques(analysis): """ This function verbalises a question about quantity Input=class sentence Output=sentence """ #init phrase = [] #We have to memorise the verb verb = other_functions.list_rebuilding(analysis.sv[0].vrb_main[0]) if analysis.sv: #First case : aim is the subject with verb be if analysis.sv[0].d_obj == [] and (verb[0] == 'be' or (len(verb) > 1 and verb[1] == 'be')): phrase = statement(analysis) return ['how', 'much'] + phrase[1:len(phrase) - 1] + ['?'] #Second case : aim is the subject without verb be elif not analysis.sv[0].d_obj: return ['how', 'much'] + y_o_question(analysis) #Third case : as yes no question without the direct complement else: subject = element_rebuilding.nom_struc_rebuilding(analysis.sn) #Same processing with yes no question phrase = element_rebuilding.vrb_ques_rebuilding(analysis.sv[0].vrb_tense, analysis.sv[0].vrb_main, analysis.sv[0].vrb_adv, analysis.sn, analysis.sv[0].state, analysis.aim) for x in analysis.sv[0].i_cmpl: phrase = phrase + element_rebuilding.indirect_compl_rebuilding(x) phrase = phrase + analysis.sv[0].advrb flag = 0 for j in ResourcePool().verb_need_to: if analysis.sv[0].vrb_main[0] == j: flag = 1 for k in analysis.sv[0].sv_sec: phrase = element_rebuilding.scd_vrb_rebuilding(k, phrase, flag) for s in analysis.sv[0].vrb_sub_sentence: phrase = phrase + sub_process(s) #processing of the state if analysis.sv[0].state == VerbalGroup.negative: phrase = phrase[0:2] + subject + phrase[2:] else: phrase = [phrase[0]] + subject + phrase[1:] return ['how', 'much'] + analysis.sv[0].d_obj[0].noun + phrase + ['?']
def a_which_process(sentence): """ This function delete the determinant after 'which' if it exist Input=class sentence Output=sentence """ if sentence[0] == 'which': #If the w_question is with 'which', we can have determinant that must be deleted if sentence[1] in ResourcePool().determinants: return [sentence[0]] + sentence[2:] return sentence
def delete_unusable_word(phrase): """ deletes the word that is no parssable Input=sentence Output=sentence """ for i in ResourcePool().unusable_words: if phrase[0] == i: phrase = phrase[1:] delete_unusable_word(phrase) return phrase