コード例 #1
0
ファイル: inference.py プロジェクト: Trixter9994/lazero
 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)
コード例 #2
0
    def __call__(self, node, **params):

        # ======================================================================
        # Initialization
        # ======================================================================

        logger.debug('inference on {}'.format(self.name))

        if self.prac.verbose > 0:
            print(prac_heading('Refining Actioncores'))
        dbs = node.outdbs
        infstep = PRACInferenceStep(node, self)
        #         if node.previous_module == 'achieved_by':
        #             raise ActionKnowledgeError('I don\'t know how to %s' % node.frame.sentence)
        # ======================================================================
        # Preprocessing
        # ======================================================================
        for olddb in dbs:
            infstep.indbs.append(olddb.copy())
            #To handle multiple acs in one task, we have to check if the single
            # dbs contain achieved_bys which representing already plans
            pngs = {}
            actioncore = node.frame.actioncore
            mod = self.prac.module('complex_achieved_by')
            newnodes = list(mod(node))
            n = None
            parentframes = [
                p.frame for p in node.parentspath()
                if isinstance(p, FrameNode)
            ]
            if any(n.frame in parentframes for n in newnodes):
                logger.error(
                    'aborting reasoning because of infinite loop. (%s)' %
                    node.frame)
                node.children = []
            else:
                for n in newnodes:
                    yield n
            if n is not None: return
            if n is None:
                # This list is used to avoid an infinite loop during the
                # achieved by inference.
                # To avoid this infinite loop, the list contains the pracmlns
                # which were inferenced during the process.
                # Every pracmln should be used only once during the process
                # because the evidence for the inference will always remain
                # the same.
                # So if the pracmln hadnt inferenced a plan in the first time,
                # it will never do it.

                # Need to remove possible achieved_by predicates from
                # previous achieved_by inferences
                db_ = PRACDatabase(self.prac)
                for atom, truth in sorted(olddb.evidence.items()):
                    if 'achieved_by' in atom: continue
                    db_ << (atom, truth)
                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))
                    if os.path.exists(projectpath):
                        project = MLNProject.open(projectpath)
                    else:
                        infstep.outdbs.append(olddb)
                        logger.error(actioncore + ".pracmln does not exist.")
                        return
                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'))
                known_concepts = mln.domains.get('concept', [])
                wnmod = self.prac.module('wn_senses')

                #Merge domains of db and given mln to avoid errors due to role inference and the resulting missing fuzzy perdicates
                known_concepts = list(
                    set(known_concepts).union(
                        set(db_.domains.get('concept', []))))
                db = wnmod.get_senses_and_similarities(db_, known_concepts)

                unified_db = db_.union(db)
                dbnew = wnmod.add_sims(unified_db, unified_db)

                # Inference achieved_by predicate
                db_ = self.extendDBWithAchievedByEvidence(
                    dbnew, mln, actioncore)
                # ==============================================================
                # Inference
                # ==============================================================
                #                 db_.write()
                try:
                    infer = self.mlnquery(config=project.queryconf,
                                          verbose=self.prac.verbose > 2,
                                          db=db_,
                                          mln=mln)
                except NoConstraintsError:
                    logger.error(
                        'achieved_by inference failed due to NoConstraintsError: %s'
                        % node.frame)
                    return
                result_db = infer.resultdb

                if self.prac.verbose == 2:
                    print()
                    print(prac_heading('INFERENCE RESULTS'))
                    infer.write()
                # ==============================================================
                # Postprocessing
                # ==============================================================
                # unified_db = result_db.union(kb.query_mln, db_)
                # only add inferred achieved_by atoms, leave out
                # 0-evidence atoms
                for qa in result_db.query('achieved_by(?ac1,?ac2)'):
                    if qa['?ac2'] == 'Complex': continue
                    unified_db << 'achieved_by({},{})'.format(
                        qa['?ac1'], qa['?ac2'])
                    pngs[qa['?ac2']] = get_cond_prob_png(project.queryconf.get(
                        'queries', ''),
                                                         dbs,
                                                         filename=self.name)
                    newframe = Frame(self.prac,
                                     node.frame.sidx,
                                     '',
                                     words=[],
                                     syntax=[],
                                     actioncore=qa['?ac2'],
                                     actionroles={})
                    #                     out('->', newframe)
                    infstep.outdbs.append(unified_db)
                    yield FrameNode(node.pracinfer,
                                    newframe,
                                    node,
                                    pred=None,
                                    indbs=[unified_db],
                                    prevmod=self.name)
                    return
                infstep.outdbs.append(unified_db)


#             raise ActionKnowledgeError('I don\'t know how to %s' % node.frame.sentence)
コード例 #3
0
    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
コード例 #4
0
    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