Beispiel #1
0
 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)
Beispiel #2
0
    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]
Beispiel #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
Beispiel #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