def _expand_confirm(self, action_name: str, beliefstate: BeliefState): """ Expand confirm_*slot* action """ act = SysAct() act.type = SysActionType.Confirm conf_slot = self._get_slotnames_from_actionname(action_name)[0] candidates = beliefstate.get_most_probable_inf_beliefs( consider_NONE=False, threshold=0.0, max_results=1) conf_value = candidates[conf_slot] act.add_value(conf_slot, conf_value) return act
def _expand_confirm(self, action_name: str, beliefstate: BeliefState): """ Expand confirm_*slot* action """ act = SysAct() act.type = SysActionType.Confirm conf_slot = self._get_slotnames_from_actionname(action_name)[0] candidates = beliefstate.get_most_probable_inf_beliefs( consider_NONE=False, threshold=0.0, max_results=1) # If the slot isn't in the beliefstate choose a random value from the ontology conf_value = candidates[ conf_slot] if conf_slot in candidates else random.choice( self.domain.get_possible_values(conf_slot)) act.add_value(conf_slot, conf_value) return act
def _expand_informbyalternatives(self, beliefstate: BeliefState): """ Expand inform_byalternatives action """ act = SysAct() act.type = SysActionType.InformByAlternatives # get set of all previously informed primary key values informedPrimKeyValsSinceNone = set( self.sys_state['informedPrimKeyValsSinceNone']) candidates = beliefstate.get_most_probable_inf_beliefs( consider_NONE=True, threshold=0.7, max_results=1) filtered_slot_values = self._remove_dontcare_slots(candidates) # query db by constraints db_matches = self.domain.find_entities(candidates) if not db_matches: # no results found for slot in common.numpy.random.choice( list(filtered_slot_values.keys()), min(5, len(filtered_slot_values)), replace=False): act.add_value(slot, filtered_slot_values[slot]) act.add_value(self.primary_key, 'none') return act # don't inform about already informed entities # -> exclude primary key values from informedPrimKeyValsSinceNone for db_match in db_matches: if db_match[self.primary_key] not in informedPrimKeyValsSinceNone: for slot in common.numpy.random.choice( list(filtered_slot_values.keys()), min(4 - (len(act.slot_values)), len(filtered_slot_values)), replace=False): act.add_value(slot, filtered_slot_values[slot]) additional_constraints = {} for slot, value in candidates.items(): if len(act.slot_values) < 4 and value == 'dontcare': additional_constraints[slot] = value db_match = self.domain.find_info_about_entity( db_match[self.primary_key], requested_slots=self.domain.get_informable_slots())[0] self._db_results_to_sysact(act, additional_constraints, db_match) return act # no alternatives found (that were not already mentioned) act.add_value(self.primary_key, 'none') return act
def _expand_confreq(self, action_name: str, beliefstate: BeliefState): """ Expand confreq_*confirmslot*_*requestslot* action """ act = SysAct() act.type = SysActionType.ConfirmRequest # first slot name is confirmation, second is request slots = self._get_slotnames_from_actionname(action_name) conf_slot = slots[0] req_slot = slots[1] # get value that needs confirmation candidates = beliefstate.get_most_probable_inf_beliefs( consider_NONE=False, threshold=0.0, max_results=1) conf_value = candidates[conf_slot] act.add_value(conf_slot, conf_value) # add request slot act.add_value(req_slot) return act
def _expand_byconstraints(self, beliefstate: BeliefState): """ Create inform act with an entity from the database, if any matches could be found for the constraints, otherwise will return an inform act with primary key=none """ act = SysAct() act.type = SysActionType.Inform # get constraints and query db by them constraints = beliefstate.get_most_probable_inf_beliefs( consider_NONE=True, threshold=0.7, max_results=1) db_matches = self.domain.find_entities(constraints, requested_slots=constraints) if not db_matches: # no matching entity found -> return inform with primary key=none # and other constraints filtered_slot_values = self._remove_dontcare_slots(constraints) filtered_slots = common.numpy.random.choice( list(filtered_slot_values.keys()), min(5, len(filtered_slot_values)), replace=False) for slot in filtered_slots: if not slot == 'name': act.add_value(slot, filtered_slot_values[slot]) act.add_value(self.primary_key, 'none') else: # match found -> return its name # if > 1 match and matches contain last informed entity, # stick to this match = [ db_match for db_match in db_matches if db_match[self.primary_key] == self.sys_state['lastInformedPrimKeyVal'] ] if not match: # none matches last informed venue -> pick first result # match = db_matches[0] match = common.random.choice(db_matches) else: assert len(match) == 1 match = match[0] # fill act with values from db self._db_results_to_sysact(act, constraints, match) return act
def _expand_informbyname(self, beliefstate: BeliefState): """ Expand inform_byname action """ act = SysAct() act.type = SysActionType.InformByName # get most probable entity primary key if self.primary_key in beliefstate['informs']: primkeyval = sorted( beliefstate["informs"][self.primary_key].items(), key=lambda kv: kv[1], reverse=True)[0][0] else: # try to use previously informed name instead primkeyval = self.sys_state['lastInformedPrimKeyVal'] # TODO change behaviour from here, because primkeyval might be "**NONE**" and this might be an entity in the database # find db entry by primary key constraints = beliefstate.get_most_probable_inf_beliefs( consider_NONE=True, threshold=0.7, max_results=1) db_matches = self.domain.find_entities({ **constraints, self.primary_key: primkeyval }) # NOTE usually not needed to give all constraints (shouldn't make a difference) if not db_matches: # select random entity if none could be found primkeyvals = self.domain.get_possible_values(self.primary_key) primkeyval = common.random.choice(primkeyvals) db_matches = self.domain.find_entities( constraints, self.domain.get_requestable_slots()) # use knowledge from current belief state if not db_matches: # no results found filtered_slot_values = self._remove_dontcare_slots(constraints) for slot in common.numpy.random.choice( list(filtered_slot_values.keys()), min(5, len(filtered_slot_values)), replace=False): act.add_value(slot, filtered_slot_values[slot]) act.add_value(self.primary_key, 'none') return act # select random match db_match = common.random.choice(db_matches) db_match = self.domain.find_info_about_entity( db_match[self.primary_key], requested_slots=self.domain.get_requestable_slots())[0] # get slots requested by user usr_requests = beliefstate.get_requested_slots() # remove primary key (to exlude from minimum number) since it is added anyway at the end if self.primary_key in usr_requests: usr_requests.remove(self.primary_key) if usr_requests: # add user requested values into system act using db result for req_slot in common.numpy.random.choice(usr_requests, min( 4, len(usr_requests)), replace=False): if req_slot in db_match: act.add_value(req_slot, db_match[req_slot]) else: act.add_value(req_slot, 'none') else: constraints = self._remove_dontcare_slots(constraints) if constraints: for inform_slot in common.numpy.random.choice( list(constraints.keys()), min(4, len(constraints)), replace=False): value = db_match[inform_slot] act.add_value(inform_slot, value) else: # add random slot and value if no user request was detected usr_requestable_slots = set( self.domain.get_requestable_slots()) usr_requestable_slots.remove(self.primary_key) random_slot = common.random.choice(list(usr_requestable_slots)) value = db_match[random_slot] act.add_value(random_slot, value) # ensure entity primary key is included if self.primary_key not in act.slot_values: act.add_value(self.primary_key, db_match[self.primary_key]) return act
def _expand_informbyalternatives(self, beliefstate: BeliefState): """ Expand inform_byalternatives action """ act = SysAct() act.type = SysActionType.InformByAlternatives # get set of all previously informed primary key values informedPrimKeyValsSinceNone = set( beliefstate['system']['informedPrimKeyValsSinceNone']) candidates = beliefstate.get_most_probable_inf_beliefs( consider_NONE=True, threshold=0.7, max_results=1) filtered_slot_values = self._remove_dontcare_slots(candidates) # query db by constraints db_matches = self.domain.find_entities(candidates) if not db_matches: # no results found for slot in common.numpy.random.choice( list(filtered_slot_values.keys()), min(5, len(filtered_slot_values)), replace=False): act.add_value(slot, filtered_slot_values[slot]) act.add_value(self.primary_key, 'none') return act # don't inform about already informed entities # -> exclude primary key values from informedPrimKeyValsSinceNone for db_match in db_matches: if db_match[self.primary_key] not in informedPrimKeyValsSinceNone: # new entity! # TODO move to _db_results_to_sysact method (including maximum inform slot-values) # get slots requested by user # usr_requests = beliefstate.get_requested_slots(threshold=0.0) # if self.primary_key in usr_requests: # usr_requests.remove(self.primary_key) # if usr_requests: # # add user requested values into system act using db result # for req_slot in common.numpy.random.choice(usr_requests, min(4, # len(usr_requests)), replace=False): # if req_slot in db_match: # act.add_value(req_slot, db_match[req_slot]) # else: # act.add_value(req_slot, 'none') # add slots for which the value != 'dontcare' for slot in common.numpy.random.choice( list(filtered_slot_values.keys()), min(4 - (len(act.slot_values)), len(filtered_slot_values)), replace=False): act.add_value(slot, filtered_slot_values[slot]) additional_constraints = {} for slot, value in candidates.items(): if len(act.slot_values) < 4 and value == 'dontcare': additional_constraints[slot] = value db_match = self.domain.find_info_about_entity( db_match[self.primary_key], requested_slots=self.domain.get_informable_slots())[0] self._db_results_to_sysact(act, additional_constraints, db_match) return act # no alternatives found (that were not already mentioned) act.add_value(self.primary_key, 'none') return act