def buildframes(self, db, sidx, sentence): for _, actioncore in db.actioncores(): roles = defaultdict(list) for role, word in db.rolesw(actioncore): sense = db.sense(word) props = db.properties(word) obj = Object(self.prac, id_=word, type_=sense, props=props, syntax=self.buildword(db, word)) roles[role].append(obj) frames = splitd(roles) for frame in frames: yield Frame(self.prac, sidx, sentence, syntax=list(db.syntax()), words=self.buildwords(db), actioncore=actioncore, actionroles=frame)
def __call__(self, node, **params): # ====================================================================== # Initialization # ====================================================================== logger.debug('inference on {}'.format(self.name)) if self.prac.verbose > 0: print prac_heading('Update roles based on Action Core Refinement') dbs = node.outdbs infstep = PRACInferenceStep(node, self) # planlist = self.getPlanList() # out(node.parent.frame, '->', node.frame) pngs = {} for i, db_ in enumerate(dbs): # db = db_.copy() # db = PRACDatabase(self.prac) # ================================================================== # Preprocessing # ================================================================== actioncore = node.frame.actioncore logger.debug('Action core: {}'.format(actioncore)) if params.get('project', None) is None: logger.debug('Loading Project: {}.pracmln'.format( colorize(actioncore, (None, 'cyan', True), True))) projectpath = os.path.join( pracloc.pracmodules, self.name, '{}Transformation.pracmln'.format(actioncore)) project = MLNProject.open(projectpath) else: logger.debug( colorize('Loading Project from params', (None, 'cyan', True), True)) projectpath = os.path.join( params.get('projectpath', None) or os.path.join(pracloc.pracmodules, self.name), params.get('project').name) project = params.get('project') mlntext = project.mlns.get(project.queryconf['mln'], None) mln = parse_mln( mlntext, searchpaths=[self.module_path], projectpath=projectpath, logic=project.queryconf.get('logic', 'FirstOrderLogic'), grammar=project.queryconf.get('grammar', 'PRACGrammar')) result_db = None for pdb in node.parent.outdbs: db = pdb.copy() db = db.union(db_) objs = {o.id for o in node.parent.frame.actionroles.values()} for w in set(db.domains['word']): if w not in objs: db.rmval('word', w) infstep.indbs.append(db) ac = node.parent.frame.actioncore db << 'achieved_by(%s, %s)' % (ac, actioncore) for role, object_ in node.parent.frame.actionroles.iteritems(): db << '%s(%s, %s)' % (role, object_.id, ac) try: # ========================================================== # Inference # ========================================================== infer = self.mlnquery(config=project.queryconf, db=db, verbose=self.prac.verbose > 2, mln=mln) result_db = infer.resultdb if self.prac.verbose == 2: print print prac_heading('INFERENCE RESULTS') print infer.write() except NoConstraintsError: logger.error( 'no constraints in role transformation: %s -> %s' % (node.parent.frame, node.frame)) result_db = db # ============================================================== # Postprocessing # ============================================================== r_db = PRACDatabase(self.prac) roles = self.prac.actioncores[actioncore].roles for atom, truth in sorted(result_db.evidence.iteritems()): if any(r in atom for r in roles): _, predname, args = self.prac.mln.logic.parse_literal(atom) word, ac = args if ac == actioncore: r_db << (atom, truth) if truth: sense = pdb.sense(word) props = pdb.properties(word) obj = Object(self.prac, id_=word, type_=sense, props=props, syntax=node.pracinfer.buildword( pdb, word)) node.frame.actionroles[predname] = obj # out('->', node.frame) unified_db = db.union(r_db, mln=self.prac.mln) r_db_ = PRACDatabase(self.prac) # It will be assumed that there is only one true action_ # c1ore predicate per database # for actionverb, actioncore in unified_db.actioncores(): break for atom, truth in sorted(unified_db.evidence.iteritems()): if 'action_core' in atom: continue r_db_ << (atom, truth) infstep.outdbs.append(r_db_) pngs['RolesTransformation - ' + str(i)] = get_cond_prob_png( project.queryconf.get('queries', ''), dbs, filename=self.name) infstep.png = pngs infstep.applied_settings = project.queryconf.config return [node]
def determine_missing_roles(self, node, db): ''' Checks if the given database contains all required actionroles to execute the representing actioncore successfully. If this is not the case this module look for frames which contain the missing action roles. :param db: :return: ''' howtodb = self.prac.mongodb.prac.howtos db_ = db.copy() # Assuming there is only one action core for word, actioncore in db.actioncores(): # ================================================================== # Preprocessing & Lookup # ================================================================== missingroles = node.frame.missingroles( ) #set(allroles).difference(givenroles) # Build query: Query should return only frames which have the same actioncore as the instruction # and all required action roles if missingroles: and_conditions = [{ '$eq': [ "$$plan.{}".format(constants.JSON_FRAME_ACTIONCORE), actioncore ] }] # and_conditions.extend([{"$ifNull" : ["$$plan.{}.{}".format(constants.JSON_FRAME_ACTIONCORE_ROLES, r), False]} for r in givenroles]) # and_conditions.extend([{"$eq" : ["$$plan.{}.{}.type".format(constants.JSON_FRAME_ACTIONCORE_ROLES, r), t]} for r, t in givenroles.items()]) roles_query = {"$and": and_conditions} stage_1 = { '$project': { constants.JSON_HOWTO_STEPS: { '$filter': { 'input': "${}".format(constants.JSON_HOWTO_STEPS), 'as': "plan", 'cond': roles_query } }, '_id': 0 } } stage_2 = {"$unwind": "${}".format(constants.JSON_HOWTO_STEPS)} if self.prac.verbose > 2: print("Sending query to MONGO DB ...") cursor_agg = howtodb.aggregate([stage_1, stage_2]) # After once iterating through the query result #it is not possible to iterate again through the result. #Therefore we keep the retrieved results in a separate list. cursor = [] for document in cursor_agg: cursor.append(document[constants.JSON_HOWTO_STEPS]) frames = [Frame.fromjson(self.prac, d) for d in cursor] c = howtodb.find( {constants.JSON_HOWTO_ACTIONCORE: str(actioncore)}) frames.extend([Frame.fromjson(self.prac, d) for d in c]) frames.sort(key=lambda f: f.specifity(), reverse=True) frames.sort(key=lambda f: node.frame.sim(f), reverse=True) if self.prac.verbose >= 2 or logger.level == logs.DEBUG: print('found similar frames in the db:') for f in frames: print('%.2f: %s' % (node.frame.sim(f), f)) if frames: frame = frames[0] if node.frame.sim(frame) >= 0.7: i = 0 for role in [ m for m in missingroles if m in frame.actionroles ]: newword = "{}-{}-skolem-{}".format( frame.actioncore, role, str(i)) if self.prac.verbose: print("Found {} as {}".format( frame.actionroles[role], role)) obj = frame.actionroles[role] newobj = Object(self.prac, newword, obj.type, props=obj.props, syntax=obj.syntax) node.frame.actionroles[role] = newobj atom_role = "{}({}, {})".format( role, newword, actioncore) atom_sense = "has_sense({}, {})".format( newword, obj.type) atom_has_pos = "has_pos({}, {})".format( newword, obj.syntax.pos) db_ << (atom_role, 1.0) db_ << (atom_sense, 1.0) db_ << (atom_has_pos, 1.0) # Need to define that the retrieve role cannot be # asserted to other roles no_roles_set = set( self.prac.actioncores[actioncore].roles) no_roles_set.remove(role) for no_role in no_roles_set: atom_role = "{}({},{})".format( no_role, newword, actioncore) db_ << (atom_role, 0) i += 1 else: if self.prac.verbose > 0: print("Confidence is too low.") else: if self.prac.verbose > 0: print("No suitable frames are available.") else: if self.prac.verbose > 0: print("No suitable frames are available.") # frame_result_list = transform_documents_to_actionrole_dict(cursor) # if len(frame_result_list) > 0: # logger.info("Found suitable frames") # score_frame_matrix = numpy.array(map(lambda x: frame_similarity(roles_senses_dict, x), # frame_result_list)) # confidence_level = 0.7 # # argmax_index = score_frame_matrix.argmax() # current_max_score = score_frame_matrix[argmax_index] # # if current_max_score >= confidence_level: # frame = frame_result_list[argmax_index] # document = cursor[argmax_index] # i = 0 # for role in missingroles: # word = "{}mongo{}".format(str(document[constants.JSON_FRAME_ACTIONCORE_ROLES] # [missing_role] # [constants.JSON_SENSE_WORD]), str(i)) # print "Found {} as {}".format(frame[missing_role], missing_role) # atom_role = "{}({}, {})".format(missing_role, word, actioncore) # atom_sense = "{}({}, {})".format('has_sense', word, frame[missing_role]) # atom_has_pos = "{}({}, {})".format('has_pos', word, str(document[constants.JSON_FRAME_ACTIONCORE_ROLES] # [missing_role] # [constants.JSON_SENSE_PENN_TREEBANK_POS])) # db_ << (atom_role, 1.0) # db_ << (atom_sense, 1.0) # db_ << (atom_has_pos, 1.0) # # # Need to define that the retrieve role cannot be # # asserted to other roles # no_roles_set = set(self.prac.actioncores[actioncore].roles) # no_roles_set.remove(missing_role) # for no_role in no_roles_set: # atom_role = "{}({},{})".format(no_role, word, actioncore) # db_ << (atom_role, 0) # i += 1 return db_, missingroles
def __call__(self, node, **params): # ====================================================================== # Initialization # ====================================================================== logger.debug('inference on {}'.format(self.name)) if self.prac.verbose > 0: print prac_heading('Recognizing {} Roles'.format({ True: 'MISSING', False: 'GIVEN' }[params.get('missing', False)])) dbs = node.outdbs infstep = PRACInferenceStep(node, self) queries = '' wnmod = self.prac.module('wn_senses') actionroles = defaultdict(list) pngs = {} for n, olddb in enumerate(dbs): db_copy = olddb.copy(mln=self.prac.mln) actioncore = node.frame.actioncore logger.debug(actioncore) if params.get('project', None) is None: logger.debug('Loading Project: {}.pracmln'.format( colorize(actioncore, (None, 'cyan', True), True))) projectpath = os.path.join(pracloc.pracmodules, self.name, '{}.pracmln'.format(actioncore)) project = MLNProject.open(projectpath) else: logger.debug( colorize('Loading Project from params', (None, 'cyan', True), True)) projectpath = os.path.join( params.get('projectpath', None) or os.path.join(pracloc.pracmodules, self.name), params.get('project').name) project = params.get('project') queries = project.queryconf.get('queries', '') mlntext = project.mlns.get(project.queryconf['mln'], None) mln = parse_mln(mlntext, searchpaths=[self.module_path], projectpath=projectpath, logic=project.queryconf.get('logic', 'FuzzyLogic'), grammar=project.queryconf.get( 'grammar', 'PRACGrammar')) known_concepts = mln.domains.get('concept', []) # ============================================================== # Preprocessing # ============================================================== # adding senses and similarities. might be obsolete as it has # already been performed in ac recognition logger.debug('adding senses. concepts={}'.format(known_concepts)) db = wnmod.get_senses_and_similarities(db_copy, known_concepts) # we need senses and similarities as well as original evidence tmp_union_db = db.union(db_copy, mln=self.prac.mln) # ignore roles of false ac's new_tmp_union_db = tmp_union_db.copy(mln=self.prac.mln) roles = self.prac.actioncores[actioncore].roles for ac in tmp_union_db.domains['actioncore']: if ac == actioncore: continue for r in roles: for w in new_tmp_union_db.words(): new_tmp_union_db << ('{}({},{})'.format(r, w, ac), 0) infstep.indbs.append(new_tmp_union_db) # ============================================================== # Inference # ============================================================== infer = self.mlnquery(config=project.queryconf, verbose=self.prac.verbose > 2, db=new_tmp_union_db, mln=mln) resultdb = infer.resultdb if self.prac.verbose == 2: print print prac_heading('INFERENCE RESULTS') infer.write() # ============================================================== # Postprocessing # ============================================================== # get query roles for given actioncore and add inference results # for them to final output db. ignore 0-truth results. unified_db = new_tmp_union_db.union(resultdb, mln=self.prac.mln) # node.frame.actionroles = defaultdict(list) for role, word in unified_db.rolesw(actioncore): sense = unified_db.sense(word) props = dict(unified_db.properties(word)) obj = Object(self.prac, id_=word, type_=sense, props=props, syntax=node.pracinfer.buildword(unified_db, word)) actionroles[role].append(obj) # argdoms = kb.query_mln.predicate(role).argdoms roles = self.prac.actioncores[actioncore].roles new_result = PRACDatabase(self.prac) for atom, truth in unified_db.evidence.iteritems(): if any(r in atom for r in roles): (_, predname, args) = self.prac.mln.logic.parse_literal(atom) if not args[-1] == actioncore: continue new_result << (atom, truth) for q in unified_db.query('has_sense(?w, ?s)'): # TODO Add additional formulas to avoid the using of null values if self.prac.verbose > 1: print colorize(' WORD:', (None, 'white', True), True), q['?w'] print colorize(' SENSE:', (None, 'white', True), True), q['?s'] wnmod.printWordSenses( wnmod.get_possible_meanings_of_word( unified_db, q['?w']), q['?s']) print infstep.outdbs.append(new_result) pngs['Recognizing {} roles - {}'.format( 'given', str(n))] = get_cond_prob_png(queries, infstep.indbs, filename=self.name) infstep.png = pngs if 'project' not in locals(): raise Exception('no actioncore in database: %s' % olddb) infstep.applied_settings = project.queryconf.config # pprint(actionroles) newframes = splitd(actionroles) pred = None for newframe in newframes: # pprint(newframe) f = Frame(self.prac, node.frame.sidx, node.frame.sentence, syntax=list(olddb.syntax()), words=node.frame.words, actioncore=node.frame.actioncore, actionroles=newframe) logger.debug('created new frame %s' % f) # for db in infstep.outdbs: # out(db.syntax()) pred = FrameNode(node.pracinfer, f, node, pred, indbs=infstep.outdbs, prevmod=self.name) yield pred