Пример #1
0
 def new_project(self):
     self.project = MLNProject()
     self.project.addlistener(self.project_setdirty)
     self.project.name = DEFAULTNAME.format('.pracmln')
     self.reset_gui()
     self.set_config(self.project.learnconf)
     self.mln_container.update_file_choices()
     self.db_container.update_file_choices()
     self.settings_setdirty()
Пример #2
0
 def load_project(self, filename):
     if filename and os.path.exists(filename):
         projdir, _ = ntpath.split(filename)
         self.dir = os.path.abspath(projdir)
         self.project_dir = os.path.abspath(projdir)
         self.project = MLNProject.open(filename)
         self.project.addlistener(self.project_setdirty)
         self.reset_gui()
         self.set_config(self.project.learnconf.config)
         self.mln_container.update_file_choices()
         self.db_container.update_file_choices()
         if len(self.project.mlns) > 0:
             self.mln_container.selected_file.set(self.project.learnconf['mln'] or self.project.mlns.keys()[0])
         self.mln_container.dirty = False
         if len(self.project.dbs) > 0:
             self.db_container.selected_file.set(self.project.learnconf['db'] or self.project.dbs.keys()[0])
         self.db_container.dirty = False
         self.write_gconfig(savegeometry=False)
         self.settings_dirty.set(0)
         self.project_setdirty(dirty=False)
         self.changewindowtitle()
     else:
         logger.error(
             'File {} does not exist. Creating new project...'.format(
                 filename))
         self.new_project()
Пример #3
0
 def load_project(self, filename):
     if filename and os.path.exists(filename):
         projdir, _ = ntpath.split(filename)
         self.dir = os.path.abspath(projdir)
         self.project_dir = os.path.abspath(projdir)
         self.project = MLNProject.open(filename)
         self.project.addlistener(self.project_setdirty)
         self.reset_gui()
         self.set_config(self.project.learnconf.config)
         self.mln_container.update_file_choices()
         self.db_container.update_file_choices()
         if len(self.project.mlns) > 0:
             self.mln_container.selected_file.set(self.project.learnconf['mln'] or list(self.project.mlns.keys())[0])
         self.mln_container.dirty = False
         if len(self.project.dbs) > 0:
             self.db_container.selected_file.set(self.project.learnconf['db'] or list(self.project.dbs.keys())[0])
         self.db_container.dirty = False
         self.write_gconfig(savegeometry=False)
         self.settings_dirty.set(0)
         self.project_setdirty(dirty=False)
         self.changewindowtitle()
     else:
         logger.error(
             'File {} does not exist. Creating new project...'.format(
                 filename))
         self.new_project()
Пример #4
0
 def new_project(self):
     self.project = MLNProject()
     self.project.addlistener(self.project_setdirty)
     self.project.name = DEFAULTNAME.format('.pracmln')
     self.reset_gui()
     self.set_config(self.project.learnconf)
     self.mln_container.update_file_choices()
     self.db_container.update_file_choices()
     self.settings_setdirty()
Пример #5
0
    def __call__(self, pracinference, **params):
        logger.info('Running {}'.format(self.name))

        print prac_heading('Recognizing Objects')

        # load default project
        projectpath = os.path.join(pracloc.pracmodules, self.name, self.defproject)
        project = MLNProject.open(projectpath)

        inf_step = PRACInferenceStep(pracinference, self)
        dbs = pracinference.inference_steps[-1].output_dbs

        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'))

        wordnet_module = self.prac.module('wn_senses')

        # adding evidence properties to new query db
        for db in dbs:
            # find properties and add word similarities
            logger.error(db.domains)
            logger.error(mln.domains)
            output_db = wordnet_module.add_similarities(db, mln)
            output_db.write()

            # infer and update output dbs
            infer = self.mlnquery(config=project.queryconf,
                                  db=output_db, mln=mln)
            result_db = infer.resultdb

            inf_step.outdbs.append(result_db)

        return inf_step
Пример #6
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
Пример #7
0
class MLNLearnGUI:
    def __init__(self, master, gconf, directory=None):
        self.master = master
        # icon = Tkinter.Image("photo", file=os.path.join(PRACMLN_HOME,
        #                                                 'doc',
        #                                                 '_static',
        #                                                 'favicon.ico'))
        # self.master.tk.call('wm', 'iconphoto', self.master._w, icon)

        self.initialized = False

        self.master.bind('<Return>', self.learn)
        self.master.bind('<Escape>', lambda a: self.master.quit())
        self.master.protocol('WM_DELETE_WINDOW', self.quit)

        # logo = Label(self.master, image=img)
        # logo.pack(side = "right", anchor='ne')
        self.dir = os.path.abspath(ifNone(directory, ifNone(gconf['prev_learnwts_path'], os.getcwd())))

        self.frame = Frame(master)
        self.frame.pack(fill=BOTH, expand=1)
        self.frame.columnconfigure(1, weight=1)

        row = 0
        # pracmln project options
        Label(self.frame, text='PRACMLN Project: ').grid(row=row, column=0,
                                                         sticky='ES')
        project_container = Frame(self.frame)
        project_container.grid(row=row, column=1, sticky="NEWS")

        # new proj file
        self.btn_newproj = Button(project_container, text='New Project...',
                                  command=self.new_project)
        self.btn_newproj.grid(row=0, column=1, sticky="WS")

        # open proj file
        self.btn_openproj = Button(project_container, text='Open Project...',
                                   command=self.ask_load_project)
        self.btn_openproj.grid(row=0, column=2, sticky="WS")

        # save proj file
        self.btn_saveproj = Button(project_container, text='Save Project',
                                   command=self.noask_save_project)
        self.btn_saveproj.grid(row=0, column=3, sticky="WS")

        # save proj file as...
        self.btn_saveproj = Button(project_container,
                                   text='Save Project as...',
                                   command=self.ask_save_project)
        self.btn_saveproj.grid(row=0, column=4, sticky="WS")

        # grammar selection
        row += 1
        Label(self.frame, text='Grammar: ').grid(row=row, column=0, sticky='E')
        grammars = ['StandardGrammar', 'PRACGrammar']
        self.selected_grammar = StringVar(master)
        self.selected_grammar.trace('w', self.settings_setdirty)
        l = apply(OptionMenu,
                  (self.frame, self.selected_grammar) + tuple(grammars))
        l.grid(row=row, column=1, sticky='NWE')

        # logic selection
        row += 1
        Label(self.frame, text='Logic: ').grid(row=row, column=0, sticky='E')
        logics = ['FirstOrderLogic', 'FuzzyLogic']
        self.selected_logic = StringVar(master)
        self.selected_logic.trace('w', self.settings_setdirty)
        l = apply(OptionMenu,
                  (self.frame, self.selected_logic) + tuple(logics))
        l.grid(row=row, column=1, sticky='NWE')

        # mln section
        row += 1
        Label(self.frame, text="MLN: ").grid(row=row, column=0, sticky='NE')
        self.mln_container = FileEditBar(self.frame, dir=self.dir,
                                         filesettings={'extension': '.mln', 'ftypes': [('MLN files', '.mln')]},
                                         defaultname='*unknown{}',
                                         importhook=self.import_mln,
                                         deletehook=self.delete_mln,
                                         projecthook=self.save_proj,
                                         filecontenthook=self.mlnfilecontent,
                                         fileslisthook=self.mlnfiles,
                                         updatehook=self.update_mln,
                                         onchangehook=self.project_setdirty)
        self.mln_container.grid(row=row, column=1, sticky="NEWS")
        self.mln_container.columnconfigure(1, weight=2)
        self.frame.rowconfigure(row, weight=1)

        # method selection
        row += 1
        Label(self.frame, text="Method: ").grid(row=row, column=0, sticky=E)
        self.selected_method = StringVar(master)
        methodnames = sorted(LearningMethods.names())
        self.list_methods = apply(OptionMenu, (self.frame, self.selected_method) + tuple(methodnames))
        self.list_methods.grid(row=row, column=1, sticky="NWE")
        self.selected_method.trace("w", self.select_method)

        # additional parametrization
        row += 1
        frame = Frame(self.frame)
        frame.grid(row=row, column=1, sticky="NEW")

        # use prior
        self.use_prior = IntVar()
        self.cb_use_prior = Checkbutton(frame, text="use prior with mean of ",
                                        variable=self.use_prior,
                                        command=self.onchange_useprior)
        self.cb_use_prior.pack(side=LEFT)

        # set prior 
        self.priorMean = StringVar(master)
        self.en_prior_mean = Entry(frame, textvariable=self.priorMean, width=5)
        self.en_prior_mean.pack(side=LEFT)
        self.priorMean.trace('w', self.settings_setdirty)
        Label(frame, text="and std dev of").pack(side=LEFT)

        # std. dev.
        self.priorStdDev = StringVar(master)
        self.en_stdev = Entry(frame, textvariable=self.priorStdDev, width=5)
        self.priorStdDev.trace('w', self.settings_setdirty)
        self.en_stdev.pack(side=LEFT)

        # use initial weights in MLN 
        self.use_initial_weights = IntVar()
        self.cb_use_initial_weights = Checkbutton(frame,
                                                  text="use initial weights",
                                                  variable=self.use_initial_weights,
                                                  command=self.settings_setdirty)
        self.cb_use_initial_weights.pack(side=LEFT)

        # use incremental learning
        self.incremental = IntVar()
        self.cb_incremental = Checkbutton(frame, text="learn incrementally",
                                          variable=self.incremental,
                                          command=self.onchange_incremental)
        self.cb_incremental.pack(side=LEFT)

        # shuffle databases
        self.shuffle = IntVar()
        self.cb_shuffle = Checkbutton(frame, text="shuffle databases",
                                      variable=self.shuffle, state='disabled')
        self.cb_shuffle.pack(side=LEFT)

        # discriminative learning settings
        row += 1
        self.discrPredicates = IntVar()
        self.discrPredicates.trace('w', self.change_discr_preds)
        self.discrPredicates.set(1)
        frame = Frame(self.frame)
        frame.grid(row=row, column=1, sticky="NEWS")
        self.rbQueryPreds = Radiobutton(frame, text="Query preds:",
                                        variable=self.discrPredicates,
                                        value=QUERY_PREDS)
        self.rbQueryPreds.grid(row=0, column=0, sticky="NE")

        self.queryPreds = StringVar(master)
        frame.columnconfigure(1, weight=1)
        self.entry_nePreds = Entry(frame, textvariable=self.queryPreds)
        self.entry_nePreds.grid(row=0, column=1, sticky="NEW")

        self.rbEvidencePreds = Radiobutton(frame, text='Evidence preds',
                                           variable=self.discrPredicates,
                                           value=EVIDENCE_PREDS)
        self.rbEvidencePreds.grid(row=0, column=2, sticky='NEWS')

        self.evidencePreds = StringVar(master)
        self.entryEvidencePreds = Entry(frame, textvariable=self.evidencePreds)
        self.entryEvidencePreds.grid(row=0, column=3, sticky='NEWS')

        # db section
        row += 1
        Label(self.frame, text="Evidence: ").grid(row=row, column=0, sticky='NE')
        self.db_container = FileEditBar(self.frame, dir=self.dir,
                                        filesettings={'extension': '.db', 'ftypes': [('Database files', '.db')]},
                                        defaultname='*unknown{}',
                                        importhook=self.import_db,
                                        deletehook=self.delete_db,
                                        projecthook=self.save_proj,
                                        filecontenthook=self.dbfilecontent,
                                        fileslisthook=self.dbfiles,
                                        updatehook=self.update_db,
                                        onchangehook=self.project_setdirty)
        self.db_container.grid(row=row, column=1, sticky="NEWS")
        self.db_container.columnconfigure(1, weight=2)
        self.frame.rowconfigure(row, weight=1)

        # file patterns
        row += 1
        frame = Frame(self.frame)
        frame.grid(row=row, column=1, sticky="NEW")
        col = 0
        Label(frame, text="OR file pattern:").grid(row=0, column=col, sticky="W")
        # - pattern entry
        col += 1
        frame.columnconfigure(col, weight=1)
        self.pattern = StringVar(master)
        self.pattern.trace('w', self.onchange_pattern)
        self.entry_pattern = Entry(frame, textvariable=self.pattern)
        self.entry_pattern.grid(row=0, column=col, sticky="NEW")

        # add. parameters
        row += 1
        Label(self.frame, text="Add. Params: ").grid(row=row, column=0, sticky="E")
        self.params = StringVar(master)
        Entry(self.frame, textvariable=self.params).grid(row=row, column=1, sticky="NEW")

        # options
        row += 1
        Label(self.frame, text="Options: ").grid(row=row, column=0, sticky="E")
        option_container = Frame(self.frame)
        option_container.grid(row=row, column=1, sticky="NEWS")

        # multicore
        self.multicore = IntVar()
        self.cb_multicore = Checkbutton(option_container, text="Use all CPUs",
                                        variable=self.multicore,
                                        command=self.settings_setdirty)
        self.cb_multicore.grid(row=0, column=1, sticky=E)

        # profiling
        self.profile = IntVar()
        self.cb_profile = Checkbutton(option_container, text='Use Profiler',
                                      variable=self.profile,
                                      command=self.settings_setdirty)
        self.cb_profile.grid(row=0, column=3, sticky=W)

        # verbose
        self.verbose = IntVar()
        self.cb_verbose = Checkbutton(option_container, text='verbose',
                                      variable=self.verbose, 
                                      command=self.settings_setdirty)
        self.cb_verbose.grid(row=0, column=4, sticky=W)

        self.ignore_zero_weight_formulas = IntVar()
        self.cb_ignore_zero_weight_formulas = Checkbutton(option_container, text='remove 0-weight formulas',
                                                          variable=self.ignore_zero_weight_formulas, command=self.settings_setdirty)
        self.cb_ignore_zero_weight_formulas.grid(row=0, column=5, sticky=W)

        # ignore unknown preds
        self.ignore_unknown_preds = IntVar(master)
        self.ignore_unknown_preds.trace('w', self.settings_setdirty)
        self.cb_ignore_unknown_preds = \
            Checkbutton(option_container, text='ignore unkown predicates', variable=self.ignore_unknown_preds)
        self.cb_ignore_unknown_preds.grid(row=0, column=6, sticky="W")

        row += 1
        output_cont = Frame(self.frame)
        output_cont.grid(row=row, column=1, sticky='NEWS')
        output_cont.columnconfigure(0, weight=1)

        Label(self.frame, text="Output: ").grid(row=row, column=0, sticky="E")
        self.output_filename = StringVar(master)
        self.entry_output_filename = Entry(output_cont, textvariable=self.output_filename)
        self.entry_output_filename.grid(row=0, column=0, sticky="EW")

        self.save = IntVar(self.master)
        self.cb_save = Checkbutton(output_cont, text='save', variable=self.save)
        self.cb_save.grid(row=0, column=1, sticky='W')

        row += 1
        learn_button = Button(self.frame, text=" >> Start Learning << ", command=self.learn)
        learn_button.grid(row=row, column=1, sticky="EW")

        self.settings_dirty = IntVar()
        self.project_dirty = IntVar()

        self.gconf = gconf
        self.project = None
        self.project_dir = os.path.abspath(ifNone(directory, ifNone(gconf['prev_learnwts_path'], os.getcwd())))
        if gconf['prev_learnwts_project': self.project_dir] is not None:
            self.load_project(os.path.join(self.project_dir, gconf['prev_learnwts_project':self.project_dir]))
        else:
            self.new_project()
        self.config = self.project.learnconf
        self.project.addlistener(self.project_setdirty)

        self.mln_container.dirty = False
        self.db_container.dirty = False
        self.project_setdirty(dirty=False)

        self.master.geometry(gconf['window_loc_learn'])

        self.initialized = True


    def quit(self):
        if self.settings_dirty.get() or self.project_dirty.get():
            savechanges = tkMessageBox.askyesnocancel("Save changes", "You have unsaved project changes. Do you want to save them before quitting?")
            if savechanges is None:
                return
            elif savechanges:
                self.noask_save_project()
            self.master.destroy()
        else:
            # write gui settings and destroy
            self.write_gconfig()
            self.master.destroy()


    ####################### PROJECT FUNCTIONS #################################

    def new_project(self):
        self.project = MLNProject()
        self.project.addlistener(self.project_setdirty)
        self.project.name = DEFAULTNAME.format('.pracmln')
        self.reset_gui()
        self.set_config(self.project.learnconf)
        self.mln_container.update_file_choices()
        self.db_container.update_file_choices()
        self.settings_setdirty()


    def project_setdirty(self, dirty=False, *args):
        self.project_dirty.set(
            dirty or self.mln_container.dirty or self.db_container.dirty)
        self.changewindowtitle()


    def settings_setdirty(self, *args):
        self.settings_dirty.set(1)
        self.changewindowtitle()


    def changewindowtitle(self):
        title = (WINDOWTITLEEDITED if (self.settings_dirty.get() or self.project_dirty.get()) else WINDOWTITLE).format(self.project_dir, self.project.name)
        self.master.title(title)


    def ask_load_project(self):
        filename = askopenfilename(initialdir=self.dir, filetypes=[('PRACMLN project files', '.pracmln')], defaultextension=".pracmln")
        if filename and os.path.exists(filename):
            self.load_project(filename)
        else:
            logger.info('No file selected.')
            return


    def load_project(self, filename):
        if filename and os.path.exists(filename):
            projdir, _ = ntpath.split(filename)
            self.dir = os.path.abspath(projdir)
            self.project_dir = os.path.abspath(projdir)
            self.project = MLNProject.open(filename)
            self.project.addlistener(self.project_setdirty)
            self.reset_gui()
            self.set_config(self.project.learnconf.config)
            self.mln_container.update_file_choices()
            self.db_container.update_file_choices()
            if len(self.project.mlns) > 0:
                self.mln_container.selected_file.set(self.project.learnconf['mln'] or self.project.mlns.keys()[0])
            self.mln_container.dirty = False
            if len(self.project.dbs) > 0:
                self.db_container.selected_file.set(self.project.learnconf['db'] or self.project.dbs.keys()[0])
            self.db_container.dirty = False
            self.write_gconfig(savegeometry=False)
            self.settings_dirty.set(0)
            self.project_setdirty(dirty=False)
            self.changewindowtitle()
        else:
            logger.error(
                'File {} does not exist. Creating new project...'.format(
                    filename))
            self.new_project()


    def noask_save_project(self):
        if self.project.name and not self.project.name == DEFAULTNAME .format('.pracmln'):
            self.save_project(
                os.path.join(self.project_dir, self.project.name))
        else:
            self.ask_save_project()


    def ask_save_project(self):
        fullfilename = asksaveasfilename(initialdir=self.project_dir,
                                         confirmoverwrite=True,
                                         filetypes=[('PRACMLN project files', '.pracmln')],
                                         defaultextension=".pracmln")
        self.save_project(fullfilename)


    def save_project(self, fullfilename):
        if fullfilename:
            fpath, fname = ntpath.split(fullfilename)
            fname = fname.split('.')[0]
            self.project.name = fname
            self.dir = os.path.abspath(fpath)
            self.project_dir = os.path.abspath(fpath)

            self.mln_container.save_all_files()
            self.db_container.save_all_files()

            self.update_config()
            self.project.save(dirpath=self.project_dir)
            self.write_gconfig()

            self.load_project(fullfilename)
            self.settings_dirty.set(0)


    def save_proj(self):
        self.project.save(dirpath=self.project_dir)
        self.write_gconfig()
        self.project_setdirty(dirty=False)

    ####################### MLN FUNCTIONS #####################################

    def import_mln(self, name, content):
        self.project.add_mln(name, content)


    def delete_mln(self, fname):
        if fname in self.project.mlns:
            self.project.rm_mln(fname)
        fnamestr = fname.strip('*')
        if fnamestr in self.project.mlns:
            self.project.rm_mln(fnamestr)


    def update_mln(self, old=None, new=None, content=None, askoverwrite=True):
        if old is None:
            old = self.mln_container.selected_file.get()
        if new is None:
            new = self.mln_container.selected_file.get().strip('*')
        if content is None:
            content = self.mln_container.editor.get("1.0", END).strip()

        if old == new and askoverwrite:
            savechanges = tkMessageBox.askyesno("Save changes",
                                                "A file '{}' already exists. "
                                                "Overwrite?".format(new))
            if savechanges:
                self.project.mlns[old] = content
            else:
                logger.error('no name specified!')
                return -1
        elif old == new and not askoverwrite:
            self.project.mlns[old] = content
        else:
            if new in self.project.mlns:
                if askoverwrite:
                    savechanges = tkMessageBox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new))
                    if savechanges:
                        self.project.mlns[new] = content
                    else:
                        logger.error('no name specified!')
                        return -1
            else:
                self.project.mlns[new] = content
        return 1


    def mlnfiles(self):
        return self.project.mlns.keys()


    def mlnfilecontent(self, filename):
        return self.project.mlns.get(filename, '').strip()


    # /MLN FUNCTIONS ###################################

    ####################### DB FUNCTIONS #####################################

    def import_db(self, name, content):
        self.project.add_db(name, content)


    def delete_db(self, fname):
        if fname in self.project.dbs:
            self.project.rm_db(fname)
        fnamestr = fname.strip('*')
        if fnamestr in self.project.dbs:
            self.project.rm_db(fnamestr)


    def update_db(self, old=None, new=None, content=None, askoverwrite=True):
        if old is None:
            old = self.db_container.selected_file.get()
        if new is None:
            new = self.db_container.selected_file.get().strip('*')
        if content is None:
            content = self.db_container.editor.get("1.0", END).strip()

        if old == new and askoverwrite:
            savechanges = tkMessageBox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new))
            if savechanges:
                self.project.dbs[old] = content
            else:
                logger.error('no name specified!')
                return -1
        elif old == new and not askoverwrite:
            self.project.dbs[old] = content
        else:
            if new in self.project.dbs:
                if askoverwrite:
                    savechanges = tkMessageBox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new))
                    if savechanges:
                        self.project.dbs[new] = content
                    else:
                        logger.error('no name specified!')
                        return -1
            else:
                self.project.dbs[new] = content
        return 1


    def dbfiles(self):
        return self.project.dbs.keys()


    def dbfilecontent(self, filename):
        return self.project.dbs.get(filename, '').strip()


    # /DB FUNCTIONS #####################################

    # GENERAL FUNCTIONS #################################

    def onchange_incremental(self):
        if self.incremental.get() == 1:
            self.cb_shuffle.configure(state="normal")
        else:
            self.cb_shuffle.configure(state="disabled")
            self.cb_shuffle.deselect()
        self.settings_setdirty()


    def onchange_pattern(self, *args):
        self.db_container.editor.disable(self.pattern.get())
        self.db_container.list_files.config(
            state=DISABLED if self.pattern.get() else NORMAL)
        self.settings_setdirty()


    def onchange_useprior(self, *args):
        self.en_prior_mean.configure(
            state=NORMAL if self.use_prior.get() else DISABLED)
        self.en_stdev.configure(
            state=NORMAL if self.use_prior.get() else DISABLED)
        self.settings_setdirty()


    def isfile(self, f):
        return os.path.exists(os.path.join(self.dir, f))


    def set_outputfilename(self):
        if not hasattr(self, "output_filename") or not hasattr(self, "db_filename") or not hasattr(self, "mln_filename"):
            return
        mln = self.mln_container.selected_file.get()
        db = self.db_container.selected_file.get()
        if "" in (mln, db):
            return
        if self.selected_method.get():
            method = LearningMethods.clazz(self.selected_method.get())
            methodid = LearningMethods.id(method)
            filename = config.learnwts_output_filename(mln, methodid.lower(), db)
            self.output_filename.set(filename)


    def select_method(self, *args):
        self.change_discr_preds()
        self.set_outputfilename()
        self.settings_setdirty()


    def change_discr_preds(self, *args):
        methodname = self.selected_method.get()
        if methodname:
            method = LearningMethods.clazz(methodname)
            state = NORMAL if issubclass(method, DiscriminativeLearner) else DISABLED
            self.entry_nePreds.configure(state=state if self.discrPredicates.get() == 0 else DISABLED)
            self.entryEvidencePreds.configure(state=state if self.discrPredicates.get() == 1 else DISABLED)
            self.rbEvidencePreds.configure(state=state)
            self.rbQueryPreds.configure(state=state)


    def reset_gui(self):
        self.set_config({})
        self.db_container.clear()
        self.mln_container.clear()


    def set_config(self, newconf):
        self.config = newconf
        self.selected_grammar.set(ifNone(newconf.get('grammar'), 'PRACGrammar'))
        self.selected_logic.set(ifNone(newconf.get('logic'), 'FirstOrderLogic'))
        self.mln_container.selected_file.set(ifNone(newconf.get('mln'), ''))
        self.db_container.selected_file.set(ifNone(newconf.get('db'), ""))
        self.selected_method.set(ifNone(newconf.get("method"), LearningMethods.name('BPLL'), transform=LearningMethods.name))
        self.pattern.set(ifNone(newconf.get('pattern'), ''))
        self.multicore.set(ifNone(newconf.get('multicore'), 0))
        self.use_prior.set(ifNone(newconf.get('use_prior'), 0))
        self.priorMean.set(ifNone(newconf.get('prior_mean'), 0))
        self.priorStdDev.set(ifNone(newconf.get('prior_stdev'), 5))
        self.incremental.set(ifNone(newconf.get('incremental'), 0))
        self.shuffle.set(ifNone(newconf.get('shuffle'), 0))
        self.use_initial_weights.set(ifNone(newconf.get('use_initial_weights'), 0))
        self.profile.set(ifNone(newconf.get('profile'), 0))
        self.params.set(ifNone(newconf.get('params'), ''))
        self.verbose.set(ifNone(newconf.get('verbose'), 1))
        self.ignore_unknown_preds.set(ifNone(newconf.get('ignore_unknown_preds'), 0))
        self.output_filename.set(ifNone(newconf.get('output_filename'), ''))
        self.queryPreds.set(ifNone(newconf.get('qpreds'), ''))
        self.evidencePreds.set(ifNone(newconf.get('epreds'), ''))
        self.discrPredicates.set(ifNone(newconf.get('discr_preds'), 0))
        self.ignore_zero_weight_formulas.set(ifNone(newconf.get('ignore_zero_weight_formulas'), 0))
        self.save.set(ifNone(newconf.get('save'), 0))


    def get_training_db_paths(self, pattern):
        '''
        determine training databases(s)
        '''
        local = False
        dbs = []
        if pattern is not None and pattern.strip():
            fpath, pat = ntpath.split(pattern)
            if not os.path.exists(fpath):
                logger.debug('{} does not exist. Searching for pattern {} in project {}...'.format(fpath, pat, self.project.name))
                local = True
                dbs = [db for db in self.project.dbs if fnmatch.fnmatch(db, pattern)]
                if len(dbs) == 0:
                    raise Exception("The pattern '{}' matches no files in your project {}".format(pat, self.project.name))
            else:
                local = False
                patternpath = os.path.join(self.dir, pattern)

                d, mask = os.path.split(os.path.abspath(patternpath))
                for fname in os.listdir(d):
                    print fname
                    if fnmatch.fnmatch(fname, mask):
                        dbs.append(os.path.join(d, fname))
                if len(dbs) == 0:
                    raise Exception("The pattern '%s' matches no files in %s" % (pat, fpath))
            logger.debug(
                'loading training databases from pattern %s:' % pattern)
            for p in dbs: logger.debug('  %s' % p)
        if not dbs:
            raise Exception("No training data given; A training database must be selected or a pattern must be specified")
        else:
            return local, dbs


    def update_config(self):
        out('update_config')

        self.config = PRACMLNConfig()
        self.config['mln'] = self.mln_container.selected_file.get().strip().lstrip('*')
        self.config["db"] = self.db_container.selected_file.get().strip().lstrip('*')
        self.config["output_filename"] = self.output_filename.get()
        self.config["params"] = self.params.get().strip()
        self.config["method"] = LearningMethods.id(self.selected_method.get().strip())
        self.config["pattern"] = self.pattern.get()
        self.config["use_prior"] = int(self.use_prior.get())
        self.config["prior_mean"] = self.priorMean.get()
        self.config["prior_stdev"] = self.priorStdDev.get()
        self.config["incremental"] = int(self.incremental.get())
        self.config["shuffle"] = int(self.shuffle.get())
        self.config["use_initial_weights"] = int(self.use_initial_weights.get())
        self.config["qpreds"] = self.queryPreds.get().strip()
        self.config["epreds"] = self.evidencePreds.get().strip()
        self.config["discr_preds"] = self.discrPredicates.get()
        self.config['logic'] = self.selected_logic.get()
        self.config['grammar'] = self.selected_grammar.get()
        self.config['multicore'] = self.multicore.get()
        self.config['profile'] = self.profile.get()
        self.config['verbose'] = self.verbose.get()
        self.config['ignore_unknown_preds'] = self.ignore_unknown_preds.get()
        self.config['ignore_zero_weight_formulas'] = self.ignore_zero_weight_formulas.get()
        self.config['save'] = self.save.get()
        self.config["output_filename"] = self.output_filename.get().strip()
        self.project.learnconf = PRACMLNConfig()
        self.project.learnconf.update(self.config.config.copy())


    def write_gconfig(self, savegeometry=True):
        self.gconf['prev_learnwts_path'] = self.project_dir
        self.gconf['prev_learnwts_project': self.project_dir] = self.project.name

        # save geometry
        if savegeometry:
            self.gconf['window_loc_learn'] = self.master.geometry()
        self.gconf.dump()


    def learn(self, savegeometry=True, options={}, *args):
        mln_content = self.mln_container.editor.get("1.0", END).encode('utf8').strip()
        db_content = self.db_container.editor.get("1.0", END).encode('utf8').strip()

        # create conf from current gui settings
        self.update_config()

        # write gui settings
        self.write_gconfig(savegeometry=savegeometry)

        # hide gui
        self.master.withdraw()

        try:
            print headline('PRAC LEARNING TOOL')
            print

            if options.get('mlnarg') is not None:
                mlnobj = MLN(mlnfile=os.path.abspath(options.get('mlnarg')),
                             logic=self.config.get('logic', 'FirstOrderLogic'),
                             grammar=self.config.get('grammar', 'PRACGrammar'))
            else:
                mlnobj = parse_mln(mln_content, searchpaths=[self.project_dir],
                                   projectpath=os.path.join(self.project_dir, self.project.name),
                                   logic=self.config.get('logic', 'FirstOrderLogic'),
                                   grammar=self.config.get('grammar', 'PRACGrammar'))

            if options.get('dbarg') is not None:
                dbobj = Database.load(mlnobj, dbfiles=[options.get('dbarg')], ignore_unknown_preds=self.config.get('ignore_unknown_preds', True))
            else:
                if self.config.get('pattern'):
                    local, dblist = self.get_training_db_paths(self.config.get('pattern').strip())
                    dbobj = []
                    # build database list from project dbs
                    if local:
                        for dbname in dblist:
                            dbobj.extend(parse_db(mlnobj, self.project.dbs[dbname].strip(),
                                         ignore_unknown_preds=self.config.get('ignore_unknown_preds', True),
                                         projectpath=os.path.join(self.dir, self.project.name)))
                        out(dbobj)
                    # build database list from filesystem dbs
                    else:
                        for dbpath in dblist:
                            dbobj.extend(Database.load(mlnobj, dbpath, ignore_unknown_preds= self.config.get('ignore_unknown_preds', True)))
                # build single db from currently selected db
                else:
                    dbobj = parse_db(mlnobj, db_content, projectpath=os.path.join(self.dir, self.project.name), dirs=[self.dir])

            learning = MLNLearn(config=self.config, mln=mlnobj, db=dbobj)
            result = learning.run()

            # write to file if run from commandline, otherwise save result
            # to project results
            if options.get('outputfile') is not None:
                output = StringIO.StringIO()
                result.write(output)
                with open(os.path.abspath(options.get('outputfile')), 'w') as f:
                    f.write(output.getvalue())
                logger.info('saved result to {}'.format(os.path.abspath(options.get('outputfile'))))
            elif self.save.get():
                output = StringIO.StringIO()
                result.write(output)
                self.project.add_mln(self.output_filename.get(), output.getvalue())
                self.mln_container.update_file_choices()
                self.project.save(dirpath=self.project_dir)
                logger.info('saved result to file mln/{} in project {}'.format(self.output_filename.get(), self.project.name))
            else:
                logger.debug("No output file given - results have not been saved.")
        except:
            traceback.print_exc()

        # restore gui
        sys.stdout.flush()
        self.master.deiconify()
Пример #8
0
    def __call__(self, node, **params):

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

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

        if self.prac.verbose > 0:
            print prac_heading('Resolving Coreferences')

        preds = list(
            node.rdfs(
                goaltest=lambda n: isinstance(n, FrameNode) and not n.children,
                all=True))[:2]
        dbs = node.outdbs
        infstep = PRACInferenceStep(node, self)
        projectpath = os.path.join(pracloc.pracmodules, self.name)
        ac = None
        pngs = {}

        #         if not preds: return []
        # ======================================================================
        # Preprocessing
        # ======================================================================

        # merge output dbs from senses_and_roles step, containing
        # roles inferred from multiple sentences.
        if not preds:
            # no coreferencing required - forward dbs and settings
            # from previous module
            infstep.indbs = [db.copy() for db in dbs]
            infstep.outdbs = [db.copy() for db in infstep.indbs]
            logger.debug(
                '%s has no predecessors. Nothing to do here. Passing db...' %
                node)
            return [node]

        # retrieve all words from the dbs to calculate distances.
        # Do not use pracinference.instructions as they are not
        # annotated by the Stanford parser.
        sentences = [db.words() for pred in preds for db in pred.indbs]
        infstep.indbs = [db.copy() for db in dbs]
        #         infstep.outdbs = [db.copy() for db in infstep.indbs]
        # query action core to load corresponding project

        actioncore = node.frame.actioncore
        # clear corefdb and unify current db with the two preceding ones
        corefdb = PRACDatabase(self.prac)
        corefdb = corefdb.union(dbs, self.prac.mln)
        #         for s in range(max(0, i - 2), i+1):
        #             corefdb = corefdb.union(dbs[s], self.prac.mln)
        for pred in preds:
            logger.debug('unifying with %s' % pred)
            for db in pred.indbs:
                corefdb = corefdb.union(db, self.prac.mln)

        # remove all senses from the databases' domain that are not
        # assigned to any word.
        for q in corefdb.query('!(EXIST ?w (has_sense(?w,?sense)))'):
            corefdb.rmval('sense', q['?sense'])
        try:
            # preprocessing: adding distance information for each
            # word in the instructions
            #             s = words[max(0, i - 2):i+1]
            #             snts = list(enumerate(s))
            #             idx = len(snts) - 1  # idx of current sentence
            #             for s in snts[:-1]:
            #                 idx2 = s[0]
            #                 for w in s[1]:
            #                     corefdb << 'distance({},DIST{})'.format(w, idx - idx2)
            for sidx, s in enumerate(sentences):
                for w in s:
                    cont = True
                    for q in corefdb.query('distance({}, ?w)'.format(w)):
                        cont = False
                        break
                    if not cont: continue
                    corefdb << 'distance({},DIST{})'.format(w, sidx)
#                     print 'distance({},DIST{})'.format(w, sidx)

            logger.debug('loading Project: {}'.format(
                colorize(actioncore, (None, 'cyan', True), True)))
            project = MLNProject.open(
                os.path.join(projectpath, '{}.pracmln'.format(actioncore)))
            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'))
        except MLNParsingError:
            logger.warning(
                'Could not use MLN in project {} for coreference resolution'.
                format(colorize(actioncore, (None, 'cyan', True), True)))
            infstep.outdbs = [db.copy(self.prac.mln) for db in dbs]
            infstep.png = node.parent.laststep.png
            infstep.applied_settings = node.parent.laststep.applied_settings
            return [node]
        except Exception:
            infstep.outdbs = [db.copy(self.prac.mln) for db in dbs]
            infstep.png = node.parent.laststep.png
            infstep.applied_settings = node.parent.laststep.applied_settings
            logger.warning(
                'Could not load project "{}". Passing dbs to next module...'.
                format(ac))
            return [node]

        # adding similarities
        wnmod = self.prac.module('wn_senses')
        newdatabase = wnmod.add_sims(corefdb, mln)

        # update queries depending on missing roles
        acroles = filter(lambda role: role != 'action_verb',
                         self.prac.actioncores[actioncore].roles)
        missingroles = [
            ar for ar in acroles
            if len(list(newdatabase.query('{}(?w,{})'.format(ar, actioncore))))
            == 0
        ]
        conf = project.queryconf
        conf.update({'queries': ','.join(missingroles)})
        print colorize('querying for missing roles {}'.format(conf['queries']),
                       (None, 'green', True), True)

        # asserting impossible role-ac combinations, leaving previously
        # inferred roles untouched
        fulldom = mergedom(mln.domains, newdatabase.domains)
        ac_domains = [dom for dom in fulldom if '_ac' in dom]
        acs = list(set([v for a in ac_domains for v in fulldom[a]]))
        acs = filter(lambda ac_: ac_ != actioncore, acs)

        for ac1 in acs:
            for r in missingroles:
                for w in newdatabase.domains['word']:
                    # words with no sense are asserted false
                    if list(
                            corefdb.query(
                                '!(EXIST ?sense (has_sense({},?sense)))'.
                                format(w))):
                        newdatabase << '!{}({},{})'.format(r, w, actioncore)
                    # leave previously inferred information roles
                    # untouched
                    if list(newdatabase.query('{}({},{})'.format(r, w, ac1))):
                        continue
                    else:
                        newdatabase << '!{}({},{})'.format(r, w, ac1)
        try:
            # ==========================================================
            # Inference
            # ==========================================================
            infer = self.mlnquery(config=conf,
                                  verbose=self.prac.verbose > 2,
                                  db=newdatabase,
                                  mln=mln)
            if self.prac.verbose == 2:
                print
                print prac_heading('INFERENCE RESULTS')
                infer.write()
            # ==========================================================
            # Postprocessing
            # ==========================================================
            # merge initial db with results
            for db in infstep.indbs:
                resultdb = db.copy()
                for res in infer.results.keys():
                    if infer.results[res] != 1.0:
                        continue
                    resultdb << str(res)
                    _, _, args = self.prac.mln.logic.parse_literal(res)
                    w = args[0]
                    for q in newdatabase.query(
                            'has_sense({0},?s) ^ has_pos({0},?pos)'.format(w)):
                        resultdb << 'has_sense({},{})'.format(w, q['?s'])
                        resultdb << 'is_a({0},{0})'.format(q['?s'])
                        resultdb << 'has_pos({},{})'.format(w, q['?pos'])
                resultdb = wnmod.add_sims(resultdb, mln)
                # enhance the frame data
                for mrole in missingroles:
                    for q in resultdb.query(
                            '{role}(?w, {actioncore}) ^ has_sense(?w, ?s)'.
                            format(role=mrole, actioncore=actioncore)):
                        for p in preds:
                            if p.frame.object(q['?w']) is not None:
                                node.frame.actionroles[mrole] = p.frame.object(
                                    q['?w'])
                                break
                infstep.outdbs.append(resultdb)
            pprint(node.frame.tojson())
        except NoConstraintsError:
            logger.debug('No coreferences found. Passing db...')
            infstep.outdbs.append(db)
        except Exception:
            logger.error('Something went wrong')
            traceback.print_exc()

        pngs['Coref - ' + str(node)] = get_cond_prob_png(project.queryconf.get(
            'queries', ''),
                                                         dbs,
                                                         filename=self.name)
        infstep.png = pngs
        infstep.applied_settings = project.queryconf.config
        return [node]
Пример #9
0
class MLNLearnGUI:
    def __init__(self, master, gconf, directory=None):
        self.master = master

        self.initialized = False

        self.master.bind('<Return>', self.learn)
        self.master.bind('<Escape>', lambda a: self.master.quit())
        self.master.protocol('WM_DELETE_WINDOW', self.quit)

        # logo = Label(self.master, image=img)
        # logo.pack(side = "right", anchor='ne')
        self.dir = os.path.abspath(ifnone(directory, ifnone(gconf['prev_learnwts_path'], os.getcwd())))

        self.frame = Frame(master)
        self.frame.pack(fill=BOTH, expand=1)
        self.frame.columnconfigure(1, weight=1)

        row = 0
        # pracmln project options
        Label(self.frame, text='PRACMLN Project: ').grid(row=row, column=0,
                                                         sticky='ES')
        project_container = Frame(self.frame)
        project_container.grid(row=row, column=1, sticky="NEWS")

        # new proj file
        self.btn_newproj = Button(project_container, text='New Project...',
                                  command=self.new_project)
        self.btn_newproj.grid(row=0, column=1, sticky="WS")

        # open proj file
        self.btn_openproj = Button(project_container, text='Open Project...',
                                   command=self.ask_load_project)
        self.btn_openproj.grid(row=0, column=2, sticky="WS")

        # save proj file
        self.btn_saveproj = Button(project_container, text='Save Project',
                                   command=self.noask_save_project)
        self.btn_saveproj.grid(row=0, column=3, sticky="WS")

        # save proj file as...
        self.btn_saveproj = Button(project_container,
                                   text='Save Project as...',
                                   command=self.ask_save_project)
        self.btn_saveproj.grid(row=0, column=4, sticky="WS")

        # grammar selection
        row += 1
        Label(self.frame, text='Grammar: ').grid(row=row, column=0, sticky='E')
        grammars = ['StandardGrammar', 'PRACGrammar']
        self.selected_grammar = StringVar(master)
        self.selected_grammar.trace('w', self.settings_setdirty)
        l = OptionMenu(*(self.frame, self.selected_grammar) + tuple(grammars))
        l.grid(row=row, column=1, sticky='NWE')

        # logic selection
        row += 1
        Label(self.frame, text='Logic: ').grid(row=row, column=0, sticky='E')
        logics = ['FirstOrderLogic', 'FuzzyLogic']
        self.selected_logic = StringVar(master)
        self.selected_logic.trace('w', self.settings_setdirty)
        l = OptionMenu(*(self.frame, self.selected_logic) + tuple(logics))
        l.grid(row=row, column=1, sticky='NWE')

        # mln section
        row += 1
        Label(self.frame, text="MLN: ").grid(row=row, column=0, sticky='NE')
        self.mln_container = FileEditBar(self.frame, directory=self.dir,
                                         filesettings={'extension': '.mln', 'ftypes': [('MLN files', '.mln')]},
                                         defaultname='*unknown{}',
                                         importhook=self.import_mln,
                                         deletehook=self.delete_mln,
                                         projecthook=self.save_proj,
                                         filecontenthook=self.mlnfilecontent,
                                         fileslisthook=self.mlnfiles,
                                         selectfilehook=self.set_outputfilename,
                                         updatehook=self.update_mln,
                                         onchangehook=self.project_setdirty)
        self.mln_container.grid(row=row, column=1, sticky="NEWS")
        self.mln_container.editor.bind("<FocusIn>", self._got_focus)
        self.mln_container.columnconfigure(1, weight=2)
        self.frame.rowconfigure(row, weight=1)

        # method selection
        row += 1
        Label(self.frame, text="Method: ").grid(row=row, column=0, sticky=E)
        self.selected_method = StringVar(master)
        methodnames = sorted(LearningMethods.names())
        self.list_methods = OptionMenu(*(self.frame, self.selected_method) + tuple(methodnames))
        self.list_methods.grid(row=row, column=1, sticky="NWE")
        self.selected_method.trace("w", self.select_method)

        # additional parametrization
        row += 1
        frame = Frame(self.frame)
        frame.grid(row=row, column=1, sticky="NEW")

        # use prior
        self.use_prior = IntVar()
        self.cb_use_prior = Checkbutton(frame, text="use prior with mean of ",
                                        variable=self.use_prior,
                                        command=self.onchange_useprior)
        self.cb_use_prior.pack(side=LEFT)

        # set prior 
        self.priorMean = StringVar(master)
        self.en_prior_mean = Entry(frame, textvariable=self.priorMean, width=5)
        self.en_prior_mean.pack(side=LEFT)
        self.priorMean.trace('w', self.settings_setdirty)
        Label(frame, text="and std dev of").pack(side=LEFT)

        # std. dev.
        self.priorStdDev = StringVar(master)
        self.en_stdev = Entry(frame, textvariable=self.priorStdDev, width=5)
        self.priorStdDev.trace('w', self.settings_setdirty)
        self.en_stdev.pack(side=LEFT)

        # use initial weights in MLN 
        self.use_initial_weights = IntVar()
        self.cb_use_initial_weights = Checkbutton(frame,
                                                  text="use initial weights",
                                                  variable=self.use_initial_weights,
                                                  command=self.settings_setdirty)
        self.cb_use_initial_weights.pack(side=LEFT)

        # use incremental learning
        self.incremental = IntVar()
        self.cb_incremental = Checkbutton(frame, text="learn incrementally",
                                          variable=self.incremental,
                                          command=self.onchange_incremental)
        self.cb_incremental.pack(side=LEFT)

        # shuffle databases
        self.shuffle = IntVar()
        self.cb_shuffle = Checkbutton(frame, text="shuffle databases",
                                      variable=self.shuffle, state='disabled')
        self.cb_shuffle.pack(side=LEFT)

        # discriminative learning settings
        row += 1
        self.discrPredicates = IntVar()
        self.discrPredicates.trace('w', self.change_discr_preds)
        self.discrPredicates.set(1)
        frame = Frame(self.frame)
        frame.grid(row=row, column=1, sticky="NEWS")
        self.rbQueryPreds = Radiobutton(frame, text="Query preds:",
                                        variable=self.discrPredicates,
                                        value=QUERY_PREDS)
        self.rbQueryPreds.grid(row=0, column=0, sticky="NE")

        self.queryPreds = StringVar(master)
        frame.columnconfigure(1, weight=1)
        self.entry_nePreds = Entry(frame, textvariable=self.queryPreds)
        self.entry_nePreds.grid(row=0, column=1, sticky="NEW")

        self.rbEvidencePreds = Radiobutton(frame, text='Evidence preds',
                                           variable=self.discrPredicates,
                                           value=EVIDENCE_PREDS)
        self.rbEvidencePreds.grid(row=0, column=2, sticky='NEWS')

        self.evidencePreds = StringVar(master)
        self.entryEvidencePreds = Entry(frame, textvariable=self.evidencePreds)
        self.entryEvidencePreds.grid(row=0, column=3, sticky='NEWS')

        # db section
        row += 1
        Label(self.frame, text="Evidence: ").grid(row=row, column=0, sticky='NE')
        self.db_container = FileEditBar(self.frame, directory=self.dir,
                                        filesettings={'extension': '.db', 'ftypes': [('Database files', '.db')]},
                                        defaultname='*unknown{}',
                                        importhook=self.import_db,
                                        deletehook=self.delete_db,
                                        projecthook=self.save_proj,
                                        filecontenthook=self.dbfilecontent,
                                        fileslisthook=self.dbfiles,
                                        selectfilehook=self.set_outputfilename,
                                        updatehook=self.update_db,
                                        onchangehook=self.project_setdirty)
        self.db_container.grid(row=row, column=1, sticky="NEWS")
        self.db_container.editor.bind("<FocusIn>", self._got_focus)
        self.db_container.columnconfigure(1, weight=2)
        self.frame.rowconfigure(row, weight=1)

        # file patterns
        row += 1
        frame = Frame(self.frame)
        frame.grid(row=row, column=1, sticky="NEW")
        col = 0
        Label(frame, text="OR file pattern:").grid(row=0, column=col, sticky="W")
        # - pattern entry
        col += 1
        frame.columnconfigure(col, weight=1)
        self.pattern = StringVar(master)
        self.pattern.trace('w', self.onchange_pattern)
        self.entry_pattern = Entry(frame, textvariable=self.pattern)
        self.entry_pattern.grid(row=0, column=col, sticky="NEW")

        # add. parameters
        row += 1
        Label(self.frame, text="Add. Params: ").grid(row=row, column=0, sticky="E")
        self.params = StringVar(master)
        Entry(self.frame, textvariable=self.params).grid(row=row, column=1, sticky="NEW")

        # options
        row += 1
        Label(self.frame, text="Options: ").grid(row=row, column=0, sticky="E")
        option_container = Frame(self.frame)
        option_container.grid(row=row, column=1, sticky="NEWS")

        # multicore
        self.multicore = IntVar()
        self.cb_multicore = Checkbutton(option_container, text="Use all CPUs",
                                        variable=self.multicore,
                                        command=self.settings_setdirty)
        self.cb_multicore.grid(row=0, column=1, sticky=E)

        # profiling
        self.profile = IntVar()
        self.cb_profile = Checkbutton(option_container, text='Use Profiler',
                                      variable=self.profile,
                                      command=self.settings_setdirty)
        self.cb_profile.grid(row=0, column=3, sticky=W)

        # verbose
        self.verbose = IntVar()
        self.cb_verbose = Checkbutton(option_container, text='verbose',
                                      variable=self.verbose, 
                                      command=self.settings_setdirty)
        self.cb_verbose.grid(row=0, column=4, sticky=W)

        self.ignore_zero_weight_formulas = IntVar()
        self.cb_ignore_zero_weight_formulas = Checkbutton(option_container, text='remove 0-weight formulas',
                                                          variable=self.ignore_zero_weight_formulas, command=self.settings_setdirty)
        self.cb_ignore_zero_weight_formulas.grid(row=0, column=5, sticky=W)

        # ignore unknown preds
        self.ignore_unknown_preds = IntVar(master)
        self.ignore_unknown_preds.trace('w', self.settings_setdirty)
        self.cb_ignore_unknown_preds = \
            Checkbutton(option_container, text='ignore unkown predicates', variable=self.ignore_unknown_preds)
        self.cb_ignore_unknown_preds.grid(row=0, column=6, sticky="W")

        row += 1
        output_cont = Frame(self.frame)
        output_cont.grid(row=row, column=1, sticky='NEWS')
        output_cont.columnconfigure(0, weight=1)

        Label(self.frame, text="Output: ").grid(row=row, column=0, sticky="E")
        self.output_filename = StringVar(master)
        self.entry_output_filename = Entry(output_cont, textvariable=self.output_filename)
        self.entry_output_filename.grid(row=0, column=0, sticky="EW")

        self.save = IntVar(self.master)
        self.cb_save = Checkbutton(output_cont, text='save', variable=self.save)
        self.cb_save.grid(row=0, column=1, sticky='W')

        row += 1
        learn_button = Button(self.frame, text=" >> Start Learning << ", command=self.learn)
        learn_button.grid(row=row, column=1, sticky="EW")

        self.settings_dirty = IntVar()
        self.project_dirty = IntVar()

        self.gconf = gconf
        self.project = None
        self.project_dir = os.path.abspath(ifnone(directory, ifnone(gconf['prev_learnwts_path'], os.getcwd())))
        if gconf['prev_learnwts_project': self.project_dir] is not None:
            self.load_project(os.path.join(self.project_dir, gconf['prev_learnwts_project':self.project_dir]))
        else:
            self.new_project()
        self.config = self.project.learnconf
        self.project.addlistener(self.project_setdirty)

        self.mln_container.dirty = False
        self.db_container.dirty = False
        self.project_setdirty(dirty=False)

        self.master.geometry(gconf['window_loc_learn'])

        self.initialized = True

    def _got_focus(self, *_):
        if self.master.focus_get() == self.mln_container.editor:
            if not self.project.mlns and not self.mln_container.file_buffer:
                self.mln_container.new_file()
        elif self.master.focus_get() == self.db_container.editor:
            if not self.project.dbs and not self.db_container.file_buffer:
                self.db_container.new_file()

    def quit(self):
        if self.settings_dirty.get() or self.project_dirty.get():
            savechanges = tkinter.messagebox.askyesnocancel("Save changes", "You have unsaved project changes. Do you want to save them before quitting?")
            if savechanges is None:
                return
            elif savechanges:
                self.noask_save_project()
            self.master.destroy()
        else:
            # write gui settings and destroy
            self.write_gconfig()
            self.master.destroy()


    ####################### PROJECT FUNCTIONS #################################

    def new_project(self):
        self.project = MLNProject()
        self.project.addlistener(self.project_setdirty)
        self.project.name = DEFAULTNAME.format('.pracmln')
        self.reset_gui()
        self.set_config(self.project.learnconf)
        self.mln_container.update_file_choices()
        self.db_container.update_file_choices()
        self.settings_setdirty()


    def project_setdirty(self, dirty=False, *_):
        self.project_dirty.set(
            dirty or self.mln_container.dirty or self.db_container.dirty)
        self.changewindowtitle()


    def settings_setdirty(self, *_):
        self.settings_dirty.set(1)
        self.changewindowtitle()


    def changewindowtitle(self):
        title = (WINDOWTITLEEDITED if (self.settings_dirty.get() or self.project_dirty.get()) else WINDOWTITLE).format(self.project_dir, self.project.name)
        self.master.title(title)


    def ask_load_project(self):
        filename = askopenfilename(initialdir=self.dir, filetypes=[('PRACMLN project files', '.pracmln')], defaultextension=".pracmln")
        if filename and os.path.exists(filename):
            self.load_project(filename)
        else:
            logger.info('No file selected.')
            return


    def load_project(self, filename):
        if filename and os.path.exists(filename):
            projdir, _ = ntpath.split(filename)
            self.dir = os.path.abspath(projdir)
            self.project_dir = os.path.abspath(projdir)
            self.project = MLNProject.open(filename)
            self.project.addlistener(self.project_setdirty)
            self.reset_gui()
            self.set_config(self.project.learnconf.config)
            self.mln_container.update_file_choices()
            self.db_container.update_file_choices()
            if len(self.project.mlns) > 0:
                self.mln_container.selected_file.set(self.project.learnconf['mln'] or list(self.project.mlns.keys())[0])
            self.mln_container.dirty = False
            if len(self.project.dbs) > 0:
                self.db_container.selected_file.set(self.project.learnconf['db'] or list(self.project.dbs.keys())[0])
            self.db_container.dirty = False
            self.write_gconfig(savegeometry=False)
            self.settings_dirty.set(0)
            self.project_setdirty(dirty=False)
            self.changewindowtitle()
        else:
            logger.error(
                'File {} does not exist. Creating new project...'.format(
                    filename))
            self.new_project()


    def noask_save_project(self):
        if self.project.name and not self.project.name == DEFAULTNAME .format('.pracmln'):
            self.save_project(
                os.path.join(self.project_dir, self.project.name))
        else:
            self.ask_save_project()


    def ask_save_project(self):
        fullfilename = asksaveasfilename(initialdir=self.project_dir,
                                         confirmoverwrite=True,
                                         filetypes=[('PRACMLN project files', '.pracmln')],
                                         defaultextension=".pracmln")
        self.save_project(fullfilename)


    def save_project(self, fullfilename):
        if fullfilename:
            fpath, fname = ntpath.split(fullfilename)
            fname = fname.split('.')[0]
            self.project.name = fname
            self.dir = os.path.abspath(fpath)
            self.project_dir = os.path.abspath(fpath)

            self.mln_container.save_all_files()
            self.db_container.save_all_files()

            self.update_config()
            self.project.save(dirpath=self.project_dir)
            self.write_gconfig()

            self.load_project(fullfilename)
            self.settings_dirty.set(0)


    def save_proj(self):
        self.project.save(dirpath=self.project_dir)
        self.write_gconfig()
        self.project_setdirty(dirty=False)

    ####################### MLN FUNCTIONS #####################################

    def import_mln(self, name, content):
        self.project.add_mln(name, content)


    def delete_mln(self, fname):
        if fname in self.project.mlns:
            self.project.rm_mln(fname)
        fnamestr = fname.strip('*')
        if fnamestr in self.project.mlns:
            self.project.rm_mln(fnamestr)


    def update_mln(self, old=None, new=None, content=None, askoverwrite=True):
        if old is None:
            old = self.mln_container.selected_file.get()
        if new is None:
            new = self.mln_container.selected_file.get().strip('*')
        if content is None:
            content = self.mln_container.editor.get("1.0", END).strip()

        if old == new and askoverwrite:
            savechanges = tkinter.messagebox.askyesno("Save changes",
                                                "A file '{}' already exists. "
                                                "Overwrite?".format(new))
            if savechanges:
                self.project.mlns[old] = content
            else:
                logger.error('no name specified!')
                return -1
        elif old == new and not askoverwrite:
            self.project.mlns[old] = content
        else:
            if new in self.project.mlns:
                if askoverwrite:
                    savechanges = tkinter.messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new))
                    if savechanges:
                        self.project.mlns[new] = content
                    else:
                        logger.error('no name specified!')
                        return -1
            else:
                self.project.mlns[new] = content
        return 1


    def mlnfiles(self):
        return list(self.project.mlns.keys())


    def mlnfilecontent(self, filename):
        return self.project.mlns.get(filename, '').strip()


    # /MLN FUNCTIONS ###################################

    ####################### DB FUNCTIONS #####################################

    def import_db(self, name, content):
        self.project.add_db(name, content)


    def delete_db(self, fname):
        if fname in self.project.dbs:
            self.project.rm_db(fname)
        fnamestr = fname.strip('*')
        if fnamestr in self.project.dbs:
            self.project.rm_db(fnamestr)


    def update_db(self, old=None, new=None, content=None, askoverwrite=True):
        if old is None:
            old = self.db_container.selected_file.get()
        if new is None:
            new = self.db_container.selected_file.get().strip('*')
        if content is None:
            content = self.db_container.editor.get("1.0", END).strip()

        if old == new and askoverwrite:
            savechanges = tkinter.messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new))
            if savechanges:
                self.project.dbs[old] = content
            else:
                logger.error('no name specified!')
                return -1
        elif old == new and not askoverwrite:
            self.project.dbs[old] = content
        else:
            if new in self.project.dbs:
                if askoverwrite:
                    savechanges = tkinter.messagebox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new))
                    if savechanges:
                        self.project.dbs[new] = content
                    else:
                        logger.error('no name specified!')
                        return -1
            else:
                self.project.dbs[new] = content
        return 1


    def dbfiles(self):
        return list(self.project.dbs.keys())


    def dbfilecontent(self, filename):
        return self.project.dbs.get(filename, '').strip()


    # /DB FUNCTIONS #####################################

    # GENERAL FUNCTIONS #################################

    def onchange_incremental(self):
        if self.incremental.get() == 1:
            self.cb_shuffle.configure(state="normal")
        else:
            self.cb_shuffle.configure(state="disabled")
            self.cb_shuffle.deselect()
        self.settings_setdirty()


    def onchange_pattern(self, *_):
        self.db_container.editor.disable(self.pattern.get())
        self.db_container.list_files.config(
            state=DISABLED if self.pattern.get() else NORMAL)
        self.settings_setdirty()


    def onchange_useprior(self, *_):
        self.en_prior_mean.configure(
            state=NORMAL if self.use_prior.get() else DISABLED)
        self.en_stdev.configure(
            state=NORMAL if self.use_prior.get() else DISABLED)
        self.settings_setdirty()


    def isfile(self, f):
        return os.path.exists(os.path.join(self.dir, f))


    def set_outputfilename(self):
        mln = self.mln_container.selected_file.get() or 'unknown.mln'
        db = self.db_container.selected_file.get() or 'unknown.db'
        if self.selected_method.get():
            method = LearningMethods.clazz(self.selected_method.get())
            methodid = LearningMethods.id(method)
            filename = config.learnwts_output_filename(mln, methodid.lower(), db)
            self.output_filename.set(filename)


    def select_method(self, *_):
        self.change_discr_preds()
        self.set_outputfilename()
        self.settings_setdirty()


    def change_discr_preds(self, *_):
        methodname = self.selected_method.get()
        if methodname:
            method = LearningMethods.clazz(methodname)
            state = NORMAL if issubclass(method, DiscriminativeLearner) else DISABLED
            self.entry_nePreds.configure(state=state if self.discrPredicates.get() == 0 else DISABLED)
            self.entryEvidencePreds.configure(state=state if self.discrPredicates.get() == 1 else DISABLED)
            self.rbEvidencePreds.configure(state=state)
            self.rbQueryPreds.configure(state=state)


    def reset_gui(self):
        self.set_config({})
        self.db_container.clear()
        self.mln_container.clear()


    def set_config(self, newconf):
        self.config = newconf
        self.selected_grammar.set(ifnone(newconf.get('grammar'), 'PRACGrammar'))
        self.selected_logic.set(ifnone(newconf.get('logic'), 'FirstOrderLogic'))
        self.mln_container.selected_file.set(ifnone(newconf.get('mln'), ''))
        self.db_container.selected_file.set(ifnone(newconf.get('db'), ""))
        self.selected_method.set(ifnone(newconf.get("method"), LearningMethods.name('BPLL'), transform=LearningMethods.name))
        self.pattern.set(ifnone(newconf.get('pattern'), ''))
        self.multicore.set(ifnone(newconf.get('multicore'), 0))
        self.use_prior.set(ifnone(newconf.get('use_prior'), 0))
        self.priorMean.set(ifnone(newconf.get('prior_mean'), 0))
        self.priorStdDev.set(ifnone(newconf.get('prior_stdev'), 5))
        self.incremental.set(ifnone(newconf.get('incremental'), 0))
        self.shuffle.set(ifnone(newconf.get('shuffle'), 0))
        self.use_initial_weights.set(ifnone(newconf.get('use_initial_weights'), 0))
        self.profile.set(ifnone(newconf.get('profile'), 0))
        self.params.set(ifnone(newconf.get('params'), ''))
        self.verbose.set(ifnone(newconf.get('verbose'), 1))
        self.ignore_unknown_preds.set(ifnone(newconf.get('ignore_unknown_preds'), 0))
        self.output_filename.set(ifnone(newconf.get('output_filename'), ''))
        self.queryPreds.set(ifnone(newconf.get('qpreds'), ''))
        self.evidencePreds.set(ifnone(newconf.get('epreds'), ''))
        self.discrPredicates.set(ifnone(newconf.get('discr_preds'), 0))
        self.ignore_zero_weight_formulas.set(ifnone(newconf.get('ignore_zero_weight_formulas'), 0))
        self.save.set(ifnone(newconf.get('save'), 0))


    def get_training_db_paths(self, pattern):
        '''
        determine training databases(s)
        '''
        local = False
        dbs = []
        if pattern is not None and pattern.strip():
            fpath, pat = ntpath.split(pattern)
            if not os.path.exists(fpath):
                logger.debug('{} does not exist. Searching for pattern {} in project {}...'.format(fpath, pat, self.project.name))
                local = True
                dbs = [db for db in self.project.dbs if fnmatch.fnmatch(db, pattern)]
                if len(dbs) == 0:
                    raise Exception("The pattern '{}' matches no files in your project {}".format(pat, self.project.name))
            else:
                local = False
                patternpath = os.path.join(self.dir, pattern)

                d, mask = os.path.split(os.path.abspath(patternpath))
                for fname in os.listdir(d):
                    print(fname)
                    if fnmatch.fnmatch(fname, mask):
                        dbs.append(os.path.join(d, fname))
                if len(dbs) == 0:
                    raise Exception("The pattern '%s' matches no files in %s" % (pat, fpath))
            logger.debug(
                'loading training databases from pattern %s:' % pattern)
            for p in dbs: logger.debug('  %s' % p)
        if not dbs:
            raise Exception("No training data given; A training database must be selected or a pattern must be specified")
        else:
            return local, dbs


    def update_config(self):
        out('update_config')

        self.config = PRACMLNConfig()
        self.config['mln'] = self.mln_container.selected_file.get().strip().lstrip('*')
        self.config["db"] = self.db_container.selected_file.get().strip().lstrip('*')
        self.config["output_filename"] = self.output_filename.get()
        self.config["params"] = self.params.get().strip()
        self.config["method"] = LearningMethods.id(self.selected_method.get().strip())
        self.config["pattern"] = self.pattern.get()
        self.config["use_prior"] = int(self.use_prior.get())
        self.config["prior_mean"] = self.priorMean.get()
        self.config["prior_stdev"] = self.priorStdDev.get()
        self.config["incremental"] = int(self.incremental.get())
        self.config["shuffle"] = int(self.shuffle.get())
        self.config["use_initial_weights"] = int(self.use_initial_weights.get())
        self.config["qpreds"] = self.queryPreds.get().strip()
        self.config["epreds"] = self.evidencePreds.get().strip()
        self.config["discr_preds"] = self.discrPredicates.get()
        self.config['logic'] = self.selected_logic.get()
        self.config['grammar'] = self.selected_grammar.get()
        self.config['multicore'] = self.multicore.get()
        self.config['profile'] = self.profile.get()
        self.config['verbose'] = self.verbose.get()
        self.config['ignore_unknown_preds'] = self.ignore_unknown_preds.get()
        self.config['ignore_zero_weight_formulas'] = self.ignore_zero_weight_formulas.get()
        self.config['save'] = self.save.get()
        self.config["output_filename"] = self.output_filename.get().strip()
        self.project.learnconf = PRACMLNConfig()
        self.project.learnconf.update(self.config.config.copy())


    def write_gconfig(self, savegeometry=True):
        self.gconf['prev_learnwts_path'] = self.project_dir
        self.gconf['prev_learnwts_project': self.project_dir] = self.project.name

        # save geometry
        if savegeometry:
            self.gconf['window_loc_learn'] = self.master.geometry()
        self.gconf.dump()


    def learn(self, savegeometry=True, options=None, *_):
        if options is None:
            options = {}
        mln_content = self.mln_container.editor.get("1.0", END).strip()
        db_content = self.db_container.editor.get("1.0", END).strip()

        # create conf from current gui settings
        self.update_config()

        # write gui settings
        self.write_gconfig(savegeometry=savegeometry)

        # hide gui
        self.master.withdraw()

        try:
            print((headline('PRAC LEARNING TOOL')))
            print()

            if options.get('mlnarg') is not None:
                mlnobj = MLN(mlnfile=os.path.abspath(options.get('mlnarg')),
                             logic=self.config.get('logic', 'FirstOrderLogic'),
                             grammar=self.config.get('grammar', 'PRACGrammar'))
            else:
                mlnobj = parse_mln(mln_content, searchpaths=[self.project_dir],
                                   projectpath=os.path.join(self.project_dir, self.project.name),
                                   logic=self.config.get('logic', 'FirstOrderLogic'),
                                   grammar=self.config.get('grammar', 'PRACGrammar'))

            if options.get('dbarg') is not None:
                dbobj = Database.load(mlnobj, dbfiles=[options.get('dbarg')], ignore_unknown_preds=self.config.get('ignore_unknown_preds', True))
            else:
                if self.config.get('pattern'):
                    local, dblist = self.get_training_db_paths(self.config.get('pattern').strip())
                    dbobj = []
                    # build database list from project dbs
                    if local:
                        for dbname in dblist:
                            dbobj.extend(parse_db(mlnobj, self.project.dbs[dbname].strip(),
                                         ignore_unknown_preds=self.config.get('ignore_unknown_preds', True),
                                         projectpath=os.path.join(self.dir, self.project.name)))
                        out(dbobj)
                    # build database list from filesystem dbs
                    else:
                        for dbpath in dblist:
                            dbobj.extend(Database.load(mlnobj, dbpath, ignore_unknown_preds= self.config.get('ignore_unknown_preds', True)))
                # build single db from currently selected db
                else:
                    dbobj = parse_db(mlnobj, db_content, projectpath=os.path.join(self.dir, self.project.name), dirs=[self.dir])

            learning = MLNLearn(config=self.config, mln=mlnobj, db=dbobj)
            result = learning.run()

            # write to file if run from commandline, otherwise save result
            # to project results
            if options.get('outputfile') is not None:
                output = io.StringIO()
                result.write(output)
                with open(os.path.abspath(options.get('outputfile')), 'w') as f:
                    f.write(output.getvalue())
                logger.info('saved result to {}'.format(os.path.abspath(options.get('outputfile'))))
            elif self.save.get():
                output = io.StringIO()
                result.write(output)
                self.project.add_mln(self.output_filename.get(), output.getvalue())
                self.mln_container.update_file_choices()
                self.project.save(dirpath=self.project_dir)
                logger.info('saved result to file mln/{} in project {}'.format(self.output_filename.get(), self.project.name))
            else:
                logger.debug("No output file given - results have not been saved.")
        except:
            traceback.print_exc()

        # restore gui
        sys.stdout.flush()
        self.master.deiconify()
Пример #10
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)
Пример #11
0
    def __call__(self, node, **params):
        # ======================================================================
        # Initialization
        # ======================================================================
        logger.debug('inference on {}'.format(self.name))

        if self.prac.verbose > 0:
            print(prac_heading('Recognizing Action Cores'))

        if params.get('project', None) is None:
            # load default project
            projectpath = os.path.join(pracloc.pracmodules, self.name,
                                       self.defproject)
            ac_project = MLNProject.open(projectpath)
        else:
            logger.info(
                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)
            ac_project = params.get('project')

        dbs = node.outdbs

        mlntext = ac_project.mlns.get(ac_project.queryconf['mln'], None)
        mln = parse_mln(mlntext,
                        searchpaths=[self.module_path],
                        projectpath=projectpath,
                        logic=ac_project.queryconf.get('logic',
                                                       'FirstOrderLogic'),
                        grammar=ac_project.queryconf.get(
                            'grammar', 'PRACGrammar'))
        known_concepts = mln.domains.get('concept', [])
        infstep = PRACInferenceStep(node, self)
        wnmod = self.prac.module('wn_senses')

        pngs = {}
        nlinstr = node.nlinstr()
        sidx = nlinstr.idx()
        sentence = nlinstr.instr

        for db_ in dbs:
            # ==================================================================
            # Preprocessing
            # ==================================================================
            db = wnmod.get_senses_and_similarities(db_, known_concepts)
            tmp_union_db = db.union(db_, mln=self.prac.mln)
            infstep.indbs.append(tmp_union_db)

            # ==================================================================
            # Inference
            # ==================================================================
            infer = self.mlnquery(config=ac_project.queryconf,
                                  verbose=self.prac.verbose > 2,
                                  db=tmp_union_db,
                                  mln=mln)
            resultdb = infer.resultdb
            if self.prac.verbose == 2:
                print()
                print(prac_heading('INFERENCE RESULTS'))
                infer.write()
            # ==================================================================
            # Postprocessing
            # ==================================================================
            unified_db = resultdb.union(tmp_union_db, mln=self.prac.mln)

            #             infstep.outdbs
            infstep.outdbs.extend(
                self.extract_multiple_action_cores(self.prac, unified_db,
                                                   wnmod, known_concepts))

            pngs[unified_db.domains.get('actioncore',
                                        [None])[0]] = get_cond_prob_png(
                                            ac_project.queryconf.get(
                                                'queries', ''),
                                            dbs,
                                            filename=self.name)
        infstep.png = pngs
        infstep.applied_settings = ac_project.queryconf.config
        pred = None
        for outdb in infstep.outdbs:
            #             out('in ac rec:')
            #             for w, ac in outdb.actioncores():
            #                 out(w, ac)
            for frame in node.pracinfer.buildframes(outdb, sidx, sentence):
                node_ = FrameNode(node.pracinfer,
                                  frame,
                                  node,
                                  pred,
                                  indbs=[outdb],
                                  prevmod=self.name)
                pred = node_
                yield node_
                break
            else:
                logger.error('no actioncore recognized in %s' % node)
                raise Exception('no actioncore recognized in %s' % node)
Пример #12
0
class MLNQueryGUI(object):
    def __init__(self, master, gconf, directory=None):
        self.master = master
        # icon = Tkinter.Image("photo", file=os.path.join(PRACMLN_HOME, 'doc', '_static', 'favicon.ico'))
        # self.master.tk.call('wm', 'iconphoto', self.master._w, icon)

        self.initialized = False

        self.master.bind('<Return>', self.infer)
        self.master.bind('<Escape>', lambda a: self.master.quit())
        self.master.protocol('WM_DELETE_WINDOW', self.quit)

        self.dir = os.path.abspath(ifNone(directory, ifNone(gconf['prev_query_path'], os.getcwd())))

        self.frame = Frame(master)
        self.frame.pack(fill=BOTH, expand=1)
        self.frame.columnconfigure(1, weight=1)

        row = 0
        # pracmln project options
        Label(self.frame, text='PRACMLN Project: ').grid(row=row, column=0,
                                                         sticky='ES')
        project_container = Frame(self.frame)
        project_container.grid(row=row, column=1, sticky="NEWS")

        # new proj file
        self.btn_newproj = Button(project_container, text='New Project...', command=self.new_project)
        self.btn_newproj.grid(row=0, column=1, sticky="WS")

        # open proj file
        self.btn_openproj = Button(project_container, text='Open Project...', command=self.ask_load_project)
        self.btn_openproj.grid(row=0, column=2, sticky="WS")

        # save proj file
        self.btn_updateproj = Button(project_container, text='Save Project...', command=self.noask_save_project)
        self.btn_updateproj.grid(row=0, column=3, sticky="WS")

        # save proj file as...
        self.btn_saveproj = Button(project_container, text='Save Project as...', command=self.ask_save_project)
        self.btn_saveproj.grid(row=0, column=4, sticky="WS")

        # grammar selection
        row += 1
        Label(self.frame, text='Grammar: ').grid(row=row, column=0, sticky='E')
        grammars = ['StandardGrammar', 'PRACGrammar']
        self.selected_grammar = StringVar(master)
        self.selected_grammar.trace('w', self.settings_setdirty)
        l = apply(OptionMenu, (self.frame, self.selected_grammar) + tuple(grammars))
        l.grid(row=row, column=1, sticky='NWE')

        # logic selection
        row += 1
        Label(self.frame, text='Logic: ').grid(row=row, column=0, sticky='E')
        logics = ['FirstOrderLogic', 'FuzzyLogic']
        self.selected_logic = StringVar(master)
        self.selected_logic.trace('w', self.settings_setdirty)
        l = apply(OptionMenu, (self.frame, self.selected_logic) + tuple(logics))
        l.grid(row=row, column=1, sticky='NWE')

        # mln section
        row += 1
        Label(self.frame, text="MLN: ").grid(row=row, column=0, sticky='NE')
        self.mln_container = FileEditBar(self.frame, dir=self.dir,
                                         filesettings={'extension': '.mln', 'ftypes': [('MLN files', '.mln')]},
                                         defaultname='*unknown{}',
                                         importhook=self.import_mln,
                                         deletehook=self.delete_mln,
                                         projecthook=self.save_proj,
                                         filecontenthook=self.mlnfilecontent,
                                         fileslisthook=self.mlnfiles,
                                         updatehook=self.update_mln,
                                         onchangehook=self.project_setdirty)
        self.mln_container.grid(row=row, column=1, sticky="NEWS")
        self.mln_container.columnconfigure(1, weight=2)
        self.frame.rowconfigure(row, weight=1)

        row += 1
        self.use_emln = IntVar()
        self.use_emln.set(0)
        self.cb_use_emln = Checkbutton(self.frame, text="use model extension",
                                       variable=self.use_emln,
                                       command=self.onchange_use_emln)
        self.cb_use_emln.grid(row=row, column=1, sticky="W")

        # mln extension section
        row += 1
        self.emlncontainerrow = row
        self.emln_label = Label(self.frame, text="EMLN: ")
        self.emln_label.grid(row=self.emlncontainerrow, column=0, sticky='NE')
        self.emln_container = FileEditBar(self.frame,
                                          dir=self.dir,
                                          filesettings={'extension': '.emln', 'ftypes': [('MLN extension files','.emln')]},
                                          defaultname='*unknown{}',
                                          importhook=self.import_emln,
                                          deletehook=self.delete_emln,
                                          projecthook=self.save_proj,
                                          filecontenthook=self.emlnfilecontent,
                                          fileslisthook=self.emlnfiles,
                                          updatehook=self.update_emln,
                                          onchangehook=self.project_setdirty)
        self.emln_container.grid(row=self.emlncontainerrow, column=1, sticky="NEWS")
        self.emln_container.columnconfigure(1, weight=2)
        self.onchange_use_emln(dirty=False)
        self.frame.rowconfigure(row, weight=1)

        # db section
        row += 1
        Label(self.frame, text="Evidence: ").grid(row=row, column=0, sticky='NE')
        self.db_container = FileEditBar(self.frame, dir=self.dir,
                                        filesettings={'extension': '.db', 'ftypes': [('Database files', '.db')]},
                                        defaultname='*unknown{}',
                                        importhook=self.import_db,
                                        deletehook=self.delete_db,
                                        projecthook=self.save_proj,
                                        filecontenthook=self.dbfilecontent,
                                        fileslisthook=self.dbfiles,
                                        updatehook=self.update_db,
                                        onchangehook=self.project_setdirty)
        self.db_container.grid(row=row, column=1, sticky="NEWS")
        self.db_container.columnconfigure(1, weight=2)
        self.frame.rowconfigure(row, weight=1)

        # inference method selection
        row += 1
        self.list_methods_row = row
        Label(self.frame, text="Method: ").grid(row=row, column=0, sticky=E)
        self.selected_method = StringVar(master)
        self.selected_method.trace('w', self.select_method)
        methodnames = sorted(InferenceMethods.names())
        self.list_methods = apply(OptionMenu, (self.frame, self.selected_method) + tuple(methodnames))
        self.list_methods.grid(row=self.list_methods_row, column=1, sticky="NWE")

        # options
        row += 1
        option_container = Frame(self.frame)
        option_container.grid(row=row, column=1, sticky="NEWS")

        # Multiprocessing
        self.multicore = IntVar()
        self.cb_multicore = Checkbutton(option_container, text="Use all CPUs",
                                        variable=self.multicore,
                                        command=self.settings_setdirty)
        self.cb_multicore.grid(row=0, column=2, sticky=W)

        # profiling
        self.profile = IntVar()
        self.cb_profile = Checkbutton(option_container, text='Use Profiler',
                                      variable=self.profile,
                                      command=self.settings_setdirty)
        self.cb_profile.grid(row=0, column=3, sticky=W)

        # verbose
        self.verbose = IntVar()
        self.cb_verbose = Checkbutton(option_container, text='verbose',
                                      variable=self.verbose,
                                      command=self.settings_setdirty)
        self.cb_verbose.grid(row=0, column=4, sticky=W)

        # options
        self.ignore_unknown_preds = IntVar(master)
        self.cb_ignore_unknown_preds = Checkbutton(option_container,
                                                   text='ignore unkown predicates',
                                                   variable=self.ignore_unknown_preds,
                                                   command=self.settings_setdirty)
        self.cb_ignore_unknown_preds.grid(row=0, column=5, sticky="W")

        # queries
        row += 1
        Label(self.frame, text="Queries: ").grid(row=row, column=0, sticky=E)
        self.query = StringVar(master)
        self.query.trace('w', self.settings_setdirty)
        Entry(self.frame, textvariable=self.query).grid(row=row, column=1, sticky="NEW")

        # additional parameters
        row += 1
        Label(self.frame, text="Add. params: ").grid(row=row, column=0, sticky="NE")
        self.params = StringVar(master)
        self.params.trace('w', self.settings_setdirty)
        self.entry_params = Entry(self.frame, textvariable=self.params)
        self.entry_params.grid(row=row, column=1, sticky="NEW")

        # closed-world predicates
        row += 1
        Label(self.frame, text="CW preds: ").grid(row=row, column=0, sticky="E")

        cw_container = Frame(self.frame)
        cw_container.grid(row=row, column=1, sticky='NEWS')
        cw_container.columnconfigure(0, weight=1)

        self.cwPreds = StringVar(master)
        self.cwPreds.trace('w', self.settings_setdirty)
        self.entry_cw = Entry(cw_container, textvariable=self.cwPreds)
        self.entry_cw.grid(row=0, column=0, sticky="NEWS")

        self.closed_world = IntVar()
        self.cb_closed_world = Checkbutton(cw_container, text="CW Assumption",
                                           variable=self.closed_world,
                                           command=self.onchange_cw)
        self.cb_closed_world.grid(row=0, column=1, sticky='W')

        # output filename
        row += 1
        output_cont = Frame(self.frame)
        output_cont.grid(row=row, column=1, sticky='NEWS')
        output_cont.columnconfigure(0, weight=1)

        # - filename
        Label(self.frame, text="Output: ").grid(row=row, column=0, sticky="NE")
        self.output_filename = StringVar(master)
        self.entry_output_filename = Entry(output_cont, textvariable=self.output_filename)
        self.entry_output_filename.grid(row=0, column=0, sticky="NEW")

        # - save option
        self.save = IntVar()
        self.cb_save = Checkbutton(output_cont, text="save", variable=self.save)
        self.cb_save.grid(row=0, column=1, sticky=W)

        # start button
        row += 1
        start_button = Button(self.frame, text=">> Start Inference <<", command=self.infer)
        start_button.grid(row=row, column=1, sticky="NEW")

        self.settings_dirty = IntVar()
        self.project_dirty = IntVar()

        self.gconf = gconf
        self.project = None
        self.project_dir = os.path.abspath(ifNone(directory, ifNone(gconf['prev_query_path'], os.getcwd())))
        if gconf['prev_query_project': self.project_dir] is not None:
            self.load_project(os.path.join(self.project_dir, gconf['prev_query_project':self.project_dir]))
        else:
            self.new_project()

        self.config = self.project.queryconf
        self.project.addlistener(self.project_setdirty)

        self.mln_container.dirty = False
        self.emln_container.dirty = False
        self.db_container.dirty = False
        self.project_setdirty(dirty=False)

        self.master.geometry(gconf['window_loc_query'])

        self.initialized = True


    def quit(self):
        if self.settings_dirty.get() or self.project_dirty.get():
            savechanges = tkMessageBox.askyesnocancel("Save changes", "You have unsaved project changes. Do you want to save them before quitting?")
            if savechanges is None:
                return
            elif savechanges:
                self.noask_save_project()
            self.master.destroy()
        else:
            # write gui settings and destroy
            self.write_gconfig()
            self.master.destroy()


    ####################### PROJECT FUNCTIONS #################################

    def new_project(self):
        self.project = MLNProject()
        self.project.addlistener(self.project_setdirty)
        self.project.name = DEFAULTNAME.format('.pracmln')
        self.reset_gui()
        self.set_config(self.project.queryconf)
        self.mln_container.update_file_choices()
        self.emln_container.update_file_choices()
        self.db_container.update_file_choices()
        self.project_setdirty(dirty=True)


    def project_setdirty(self, dirty=False, *args):
        self.project_dirty.set(dirty or self.mln_container.dirty or self.db_container.dirty or
            self.emln_container.dirty)
        self.changewindowtitle()


    def settings_setdirty(self, *args):
        self.settings_dirty.set(1)
        self.changewindowtitle()


    def changewindowtitle(self):
        title = (WINDOWTITLEEDITED if (self.settings_dirty.get() or self.project_dirty.get()) else WINDOWTITLE).format(self.project_dir, self.project.name)
        self.master.title(title)


    def ask_load_project(self):
        filename = askopenfilename(initialdir=self.dir, filetypes=[('PRACMLN project files', '.pracmln')], defaultextension=".pracmln")
        if filename and os.path.exists(filename):
            self.load_project(filename)
        else:
            logger.info('No file selected.')
            return


    def load_project(self, filename):
        if filename and os.path.exists(filename):
            projdir, _ = ntpath.split(filename)
            self.dir = os.path.abspath(projdir)
            self.project_dir = os.path.abspath(projdir)
            self.project = MLNProject.open(filename)
            self.project.addlistener(self.project_setdirty)
            self.reset_gui()
            self.set_config(self.project.queryconf.config)
            self.mln_container.update_file_choices()
            self.db_container.update_file_choices()
            if len(self.project.mlns) > 0:
                self.mln_container.selected_file.set(self.project.queryconf['mln'] or self.project.mlns.keys()[0])
            self.mln_container.dirty = False
            if len(self.project.emlns) > 0:
                self.emln_container.selected_file.set(self.project.queryconf['emln'] or self.project.emlns.keys()[0])
            self.emln_container.dirty = False
            if len(self.project.dbs) > 0:
                self.db_container.selected_file.set(self.project.queryconf['db'] or self.project.dbs.keys()[0])
            self.db_container.dirty = False
            self.write_gconfig(savegeometry=False)
            self.settings_dirty.set(0)
            self.project_setdirty(dirty=False)
            self.changewindowtitle()
        else:
            logger.error('File {} does not exist. Creating new project...'.format(filename))
            self.new_project()


    def noask_save_project(self):
        if self.project.name and not self.project.name == DEFAULTNAME.format('.pracmln'):
            self.save_project(os.path.join(self.project_dir, self.project.name))
        else:
            self.ask_save_project()


    def ask_save_project(self):
        fullfilename = asksaveasfilename(initialdir=self.project_dir,
                                         confirmoverwrite=True,
                                         filetypes=[('PRACMLN project files','.pracmln')],
                                         defaultextension=".pracmln")
        self.save_project(fullfilename)


    def save_project(self, fullfilename):
        if fullfilename:
            fpath, fname = ntpath.split(fullfilename)
            fname = fname.split('.')[0]
            self.project.name = fname
            self.dir = os.path.abspath(fpath)
            self.project_dir = os.path.abspath(fpath)

            self.mln_container.save_all_files()
            self.emln_container.save_all_files()
            self.db_container.save_all_files()

            self.update_config()
            self.project.save(dirpath=self.project_dir)
            self.write_gconfig()

            self.load_project(fullfilename)
            self.settings_dirty.set(0)


    def save_proj(self):
        self.project.save(dirpath=self.project_dir)
        self.write_gconfig()
        self.project_setdirty(dirty=False)


    ####################### MLN FUNCTIONS #####################################

    def import_mln(self, name, content):
        self.project.add_mln(name, content)


    def delete_mln(self, fname):
        if fname in self.project.mlns:
            self.project.rm_mln(fname)
        fnamestr = fname.strip('*')
        if fnamestr in self.project.mlns:
            self.project.rm_mln(fnamestr)


    def update_mln(self, old=None, new=None, content=None, askoverwrite=True):
        if old is None:
            old = self.mln_container.selected_file.get()
        if new is None:
            new = self.mln_container.selected_file.get().strip('*')
        if content is None:
            content = self.mln_container.editor.get("1.0", END).strip()

        if old == new and askoverwrite:
            savechanges = tkMessageBox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new))
            if savechanges:
                self.project.mlns[old] = content
            else:
                logger.error('no name specified!')
                return -1
        elif old == new and not askoverwrite:
            self.project.mlns[old] = content
        else:
            if new in self.project.mlns:
                if askoverwrite:
                    savechanges = tkMessageBox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new))
                    if savechanges:
                        self.project.mlns[new] = content
                    else:
                        logger.error('no name specified!')
                        return -1
            else:
                self.project.mlns[new] = content
        return 1


    def mlnfiles(self):
        return self.project.mlns.keys()


    def mlnfilecontent(self, filename):
        return self.project.mlns.get(filename, '').strip()

    # /MLN FUNCTIONS #####################################


    ####################### EMLN FUNCTIONS #####################################

    def import_emln(self, name, content):
        self.project.add_emln(name, content)


    def delete_emln(self, fname):
        if fname in self.project.emlns:
            self.project.rm_emln(fname)
        fnamestr = fname.strip('*')
        if fnamestr in self.project.emlns:
            self.project.rm_emln(fnamestr)


    def update_emln(self, old=None, new=None, content=None, askoverwrite=True):
        if old is None:
            old = self.emln_container.selected_file.get()
        if new is None:
            new = self.emln_container.selected_file.get().strip('*')
        if content is None:
            content = self.emln_container.editor.get("1.0", END).strip()

        if old == new and askoverwrite:
            savechanges = tkMessageBox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new))
            if savechanges:
                self.project.emlns[old] = content
            else:
                logger.error('no name specified!')
                return -1
        elif old == new and not askoverwrite:
            self.project.emlns[old] = content
        else:
            if new in self.project.emlns:
                if askoverwrite:
                    savechanges = tkMessageBox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new))
                    if savechanges:
                        self.project.emlns[new] = content
                    else:
                        logger.error('no name specified!')
                        return -1
            else:
                self.project.emlns[new] = content
        return 1


    def emlnfiles(self):
        return self.project.emlns.keys()


    def emlnfilecontent(self, filename):
        return self.project.emlns.get(filename, '').strip()

    # /EMLN FUNCTIONS #####################################

    # DB FUNCTIONS #####################################
    def import_db(self, name, content):
        self.project.add_db(name, content)


    def delete_db(self, fname):
        if fname in self.project.dbs:
            self.project.rm_db(fname)
        fnamestr = fname.strip('*')
        if fnamestr in self.project.dbs:
            self.project.rm_db(fnamestr)


    def update_db(self, old=None, new=None, content=None, askoverwrite=True):
        if old is None:
            old = self.db_container.selected_file.get()
        if new is None:
            new = self.db_container.selected_file.get().strip('*')
        if content is None:
            content = self.db_container.editor.get("1.0", END).strip()

        if old == new and askoverwrite:
            savechanges = tkMessageBox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new))
            if savechanges:
                self.project.dbs[old] = content
            else:
                logger.error('no name specified!')
                return -1
        elif old == new and not askoverwrite:
            self.project.dbs[old] = content
        else:
            if new in self.project.dbs:
                if askoverwrite:
                    savechanges = tkMessageBox.askyesno("Save changes", "A file '{}' already exists. Overwrite?".format(new))
                    if savechanges:
                        self.project.dbs[new] = content
                    else:
                        logger.error('no name specified!')
                        return -1
            else:
                self.project.dbs[new] = content
        return 1


    def dbfiles(self):
        return self.project.dbs.keys()


    def dbfilecontent(self, filename):
        return self.project.dbs.get(filename, '').strip()

    # /DB FUNCTIONS #####################################

    # GENERAL FUNCTIONS #################################

    def select_method(self, *args):
        self.set_outputfilename()
        self.settings_setdirty()


    def onchange_use_emln(self, dirty=True, *args):
        if not self.use_emln.get():
            self.emln_label.grid_forget()
            self.emln_container.grid_forget()
        else:
            self.emln_label.grid(row=self.emlncontainerrow, column=0, sticky="NE")
            self.emln_container.grid(row=self.emlncontainerrow, column=1, sticky="NWES")
        if dirty:
            self.settings_setdirty()


    def onchange_cw(self, *args):
        if self.closed_world.get():
            self.entry_cw.configure(state=DISABLED)
        else:
            self.entry_cw.configure(state=NORMAL)
        self.settings_setdirty()


    def reset_gui(self):
        self.set_config({})
        self.db_container.clear()
        self.emln_container.clear()
        self.mln_container.clear()


    def set_config(self, newconf):
        self.config = newconf
        self.selected_grammar.set(ifNone(newconf.get('grammar'), 'PRACGrammar'))
        self.selected_logic.set(ifNone(newconf.get('logic'), 'FirstOrderLogic'))
        self.mln_container.selected_file.set(ifNone(newconf.get('mln'), ''))
        if self.use_emln.get():
            self.emln_container.selected_file.set(ifNone(newconf.get('mln'), ''))
        self.db_container.selected_file.set(ifNone(newconf.get('db'), ""))
        self.selected_method.set(ifNone(newconf.get("method"), InferenceMethods.name('MCSAT'), transform=InferenceMethods.name))
        self.multicore.set(ifNone(newconf.get('multicore'), 0))
        self.profile.set(ifNone(newconf.get('profile'), 0))
        self.params.set(ifNone(newconf.get('params'), ''))
        self.use_emln.set(ifNone(newconf.get('use_emln'), 0))
        self.verbose.set(ifNone(newconf.get('verbose'), 1))
        self.ignore_unknown_preds.set(ifNone(newconf.get('ignore_unknown_preds'), 0))
        self.output_filename.set(ifNone(newconf.get('output_filename'), ''))
        self.cwPreds.set(ifNone(newconf.get('cw_preds'), ''))
        self.closed_world.set(ifNone(newconf.get('cw'), 0))
        self.save.set(ifNone(newconf.get('save'), 0))
        self.query.set(ifNone(newconf.get('queries'), ''))
        self.onchange_cw()


    def set_outputfilename(self):
        if not hasattr(self, "output_filename") or not hasattr(self, "db_filename") or not hasattr(self, "mln_filename"):
            return
        mln = self.mln_container.selected_file.get()
        db = self.db_container.selected_file.get()
        if "" in (mln, db):
            return
        if self.selected_method.get():
            method = InferenceMethods.clazz(self.selected_method.get())
            methodid = InferenceMethods.id(method)
            filename = config.query_output_filename(mln, methodid, db)
            self.output_filename.set(filename)


    def update_config(self):

        self.config = PRACMLNConfig()
        self.config["use_emln"] = self.use_emln.get()
        self.config['mln'] = self.mln_container.selected_file.get().strip().lstrip('*')
        self.config['emln'] = self.emln_container.selected_file.get().strip().lstrip('*')
        self.config["db"] = self.db_container.selected_file.get().strip().lstrip('*')
        self.config["method"] = InferenceMethods.id(self.selected_method.get().strip())
        self.config["params"] = self.params.get().strip()
        self.config["queries"] = self.query.get()
        self.config["output_filename"] = self.output_filename.get().strip()
        self.config["cw"] = self.closed_world.get()
        self.config["cw_preds"] = self.cwPreds.get()
        self.config['profile'] = self.profile.get()
        self.config['logic'] = self.selected_logic.get()
        self.config['grammar'] = self.selected_grammar.get()
        self.config['multicore'] = self.multicore.get()
        self.config['save'] = self.save.get()
        self.config['ignore_unknown_preds'] = self.ignore_unknown_preds.get()
        self.config['verbose'] = self.verbose.get()
        self.config['window_loc'] = self.master.winfo_geometry()
        self.config['dir'] = self.dir
        self.project.queryconf = PRACMLNConfig()
        self.project.queryconf.update(self.config.config.copy())


    def write_gconfig(self, savegeometry=True):
        self.gconf['prev_query_path'] = self.dir
        self.gconf['prev_query_project': self.dir] = self.project.name

        # save geometry
        if savegeometry:
            self.gconf['window_loc_query'] = self.master.geometry()
        self.gconf.dump()


    def infer(self, savegeometry=True, options={}, *args):
        mln_content = self.mln_container.editor.get("1.0", END).encode('utf8').strip()
        db_content = self.db_container.editor.get("1.0", END).encode('utf8').strip()

        # create conf from current gui settings
        self.update_config()

        # write gui settings
        self.write_gconfig(savegeometry=savegeometry)

        # hide gui
        self.master.withdraw()

        try:
            print headline('PRACMLN QUERY TOOL')
            print

            if options.get('mlnarg') is not None:
                mlnobj = MLN(mlnfile=os.path.abspath(options.get('mlnarg')),
                             logic=self.config.get('logic', 'FirstOrderLogic'),
                             grammar=self.config.get('grammar', 'PRACGrammar'))
            else:
                mlnobj = parse_mln(mln_content, searchpaths=[self.dir],
                                   projectpath=os.path.join(self.dir, self.project.name),
                                   logic=self.config.get('logic', 'FirstOrderLogic'),
                                   grammar=self.config.get('grammar', 'PRACGrammar'))

            if options.get('emlnarg') is not None:
                emln_content = mlnpath(options.get('emlnarg')).content
            else:
                emln_content = self.emln_container.editor.get("1.0", END).encode('utf8').strip()

            if options.get('dbarg') is not None:
                dbobj = Database.load(mlnobj, dbfiles=[options.get('dbarg')], ignore_unknown_preds=self.config.get('ignore_unknown_preds', True))
            else:
                out(self.config.get('ignore_unknown_preds', True))
                dbobj = parse_db(mlnobj, db_content, ignore_unknown_preds=self.config.get('ignore_unknown_preds', True))

            if options.get('queryarg') is not None:
                self.config["queries"] = options.get('queryarg')

            infer = MLNQuery(config=self.config, mln=mlnobj, db=dbobj, emln=emln_content)
            result = infer.run()


            # write to file if run from commandline, otherwise save result to project results
            if options.get('outputfile') is not None:
                output = StringIO.StringIO()
                result.write(output)
                with open(os.path.abspath(options.get('outputfile')), 'w') as f:
                    f.write(output.getvalue())
                logger.info('saved result to {}'.format(os.path.abspath(options.get('outputfile'))))
            elif self.save.get():
                output = StringIO.StringIO()
                result.write(output)
                fname = self.output_filename.get()
                self.project.add_result(fname, output.getvalue())
                self.project.save(dirpath=self.dir)
                logger.info('saved result to file results/{} in project {}'.format(fname, self.project.name))
            else:
                logger.debug('No output file given - results have not been saved.')
        except:
            traceback.print_exc()

        # restore main window
        sys.stdout.flush()
        self.master.deiconify()
Пример #13
0
class MLNQueryGUI(object):
    def __init__(self, master, gconf, directory=None):
        self.master = master

        self.initialized = False

        self.master.bind('<Return>', self.infer)
        self.master.bind('<Escape>', lambda a: self.master.quit())
        self.master.protocol('WM_DELETE_WINDOW', self.quit)

        self.dir = os.path.abspath(
            ifnone(directory, ifnone(gconf['prev_query_path'], os.getcwd())))

        self.frame = Frame(master)
        self.frame.pack(fill=BOTH, expand=1)
        self.frame.columnconfigure(1, weight=1)

        row = 0
        # pracmln project options
        Label(self.frame, text='PRACMLN Project: ').grid(row=row,
                                                         column=0,
                                                         sticky='ES')
        project_container = Frame(self.frame)
        project_container.grid(row=row, column=1, sticky="NEWS")

        # new proj file
        self.btn_newproj = Button(project_container,
                                  text='New Project...',
                                  command=self.new_project)
        self.btn_newproj.grid(row=0, column=1, sticky="WS")

        # open proj file
        self.btn_openproj = Button(project_container,
                                   text='Open Project...',
                                   command=self.ask_load_project)
        self.btn_openproj.grid(row=0, column=2, sticky="WS")

        # save proj file
        self.btn_updateproj = Button(project_container,
                                     text='Save Project...',
                                     command=self.noask_save_project)
        self.btn_updateproj.grid(row=0, column=3, sticky="WS")

        # save proj file as...
        self.btn_saveproj = Button(project_container,
                                   text='Save Project as...',
                                   command=self.ask_save_project)
        self.btn_saveproj.grid(row=0, column=4, sticky="WS")

        # grammar selection
        row += 1
        Label(self.frame, text='Grammar: ').grid(row=row, column=0, sticky='E')
        grammars = ['StandardGrammar', 'PRACGrammar']
        self.selected_grammar = StringVar()
        self.selected_grammar.trace('w', self.settings_setdirty)
        l = OptionMenu(*(self.frame, self.selected_grammar) + tuple(grammars))
        l.grid(row=row, column=1, sticky='NWE')

        # logic selection
        row += 1
        Label(self.frame, text='Logic: ').grid(row=row, column=0, sticky='E')
        logics = ['FirstOrderLogic', 'FuzzyLogic']
        self.selected_logic = StringVar()
        self.selected_logic.trace('w', self.settings_setdirty)
        l = OptionMenu(*(self.frame, self.selected_logic) + tuple(logics))
        l.grid(row=row, column=1, sticky='NWE')

        # mln section
        row += 1
        Label(self.frame, text="MLN: ").grid(row=row, column=0, sticky='NE')
        self.mln_container = FileEditBar(self.frame,
                                         directory=self.dir,
                                         filesettings={
                                             'extension': '.mln',
                                             'ftypes': [('MLN files', '.mln')]
                                         },
                                         defaultname='*unknown{}',
                                         importhook=self.import_mln,
                                         deletehook=self.delete_mln,
                                         projecthook=self.save_proj,
                                         filecontenthook=self.mlnfilecontent,
                                         fileslisthook=self.mlnfiles,
                                         updatehook=self.update_mln,
                                         onchangehook=self.project_setdirty)
        self.mln_container.editor.bind("<FocusIn>", self._got_focus)
        self.mln_container.grid(row=row, column=1, sticky="NEWS")
        self.mln_container.columnconfigure(1, weight=2)
        self.frame.rowconfigure(row, weight=1)

        row += 1
        self.use_emln = IntVar()
        self.use_emln.set(0)
        self.cb_use_emln = Checkbutton(self.frame,
                                       text="use model extension",
                                       variable=self.use_emln,
                                       command=self.onchange_use_emln)
        self.cb_use_emln.grid(row=row, column=1, sticky="W")

        # mln extension section
        row += 1
        self.emlncontainerrow = row
        self.emln_label = Label(self.frame, text="EMLN: ")
        self.emln_label.grid(row=self.emlncontainerrow, column=0, sticky='NE')
        self.emln_container = FileEditBar(self.frame,
                                          directory=self.dir,
                                          filesettings={
                                              'extension':
                                              '.emln',
                                              'ftypes':
                                              [('MLN extension files', '.emln')
                                               ]
                                          },
                                          defaultname='*unknown{}',
                                          importhook=self.import_emln,
                                          deletehook=self.delete_emln,
                                          projecthook=self.save_proj,
                                          filecontenthook=self.emlnfilecontent,
                                          fileslisthook=self.emlnfiles,
                                          updatehook=self.update_emln,
                                          onchangehook=self.project_setdirty)
        self.emln_container.grid(row=self.emlncontainerrow,
                                 column=1,
                                 sticky="NEWS")
        self.emln_container.editor.bind("<FocusIn>", self._got_focus)
        self.emln_container.columnconfigure(1, weight=2)
        self.onchange_use_emln(dirty=False)
        self.frame.rowconfigure(row, weight=1)

        # db section
        row += 1
        Label(self.frame, text="Evidence: ").grid(row=row,
                                                  column=0,
                                                  sticky='NE')
        self.db_container = FileEditBar(self.frame,
                                        directory=self.dir,
                                        filesettings={
                                            'extension': '.db',
                                            'ftypes':
                                            [('Database files', '.db')]
                                        },
                                        defaultname='*unknown{}',
                                        importhook=self.import_db,
                                        deletehook=self.delete_db,
                                        projecthook=self.save_proj,
                                        filecontenthook=self.dbfilecontent,
                                        fileslisthook=self.dbfiles,
                                        updatehook=self.update_db,
                                        onchangehook=self.project_setdirty)
        self.db_container.grid(row=row, column=1, sticky="NEWS")
        self.db_container.editor.bind("<FocusIn>", self._got_focus)
        self.db_container.columnconfigure(1, weight=2)
        self.frame.rowconfigure(row, weight=1)

        # inference method selection
        row += 1
        self.list_methods_row = row
        Label(self.frame, text="Method: ").grid(row=row, column=0, sticky=E)
        self.selected_method = StringVar()
        self.selected_method.trace('w', self.select_method)
        methodnames = sorted(InferenceMethods.names())
        self.list_methods = OptionMenu(*(self.frame, self.selected_method) +
                                       tuple(methodnames))
        self.list_methods.grid(row=self.list_methods_row,
                               column=1,
                               sticky="NWE")

        # options
        row += 1
        option_container = Frame(self.frame)
        option_container.grid(row=row, column=1, sticky="NEWS")

        # Multiprocessing
        self.multicore = IntVar()
        self.cb_multicore = Checkbutton(option_container,
                                        text="Use all CPUs",
                                        variable=self.multicore,
                                        command=self.settings_setdirty)
        self.cb_multicore.grid(row=0, column=2, sticky=W)

        # profiling
        self.profile = IntVar()
        self.cb_profile = Checkbutton(option_container,
                                      text='Use Profiler',
                                      variable=self.profile,
                                      command=self.settings_setdirty)
        self.cb_profile.grid(row=0, column=3, sticky=W)

        # verbose
        self.verbose = IntVar()
        self.cb_verbose = Checkbutton(option_container,
                                      text='verbose',
                                      variable=self.verbose,
                                      command=self.settings_setdirty)
        self.cb_verbose.grid(row=0, column=4, sticky=W)

        # options
        self.ignore_unknown_preds = IntVar()
        self.cb_ignore_unknown_preds = Checkbutton(
            option_container,
            text='ignore unkown predicates',
            variable=self.ignore_unknown_preds,
            command=self.settings_setdirty)
        self.cb_ignore_unknown_preds.grid(row=0, column=5, sticky="W")

        # queries
        row += 1
        Label(self.frame, text="Queries: ").grid(row=row, column=0, sticky=E)
        self.query = StringVar()
        self.query.trace('w', self.settings_setdirty)
        Entry(self.frame, textvariable=self.query).grid(row=row,
                                                        column=1,
                                                        sticky="NEW")

        # additional parameters
        row += 1
        Label(self.frame, text="Add. params: ").grid(row=row,
                                                     column=0,
                                                     sticky="NE")
        self.params = StringVar()
        self.params.trace('w', self.settings_setdirty)
        self.entry_params = Entry(self.frame, textvariable=self.params)
        self.entry_params.grid(row=row, column=1, sticky="NEW")

        # closed-world predicates
        row += 1
        Label(self.frame, text="CW preds: ").grid(row=row,
                                                  column=0,
                                                  sticky="E")

        cw_container = Frame(self.frame)
        cw_container.grid(row=row, column=1, sticky='NEWS')
        cw_container.columnconfigure(0, weight=1)

        self.cwPreds = StringVar()
        self.cwPreds.trace('w', self.settings_setdirty)
        self.entry_cw = Entry(cw_container, textvariable=self.cwPreds)
        self.entry_cw.grid(row=0, column=0, sticky="NEWS")

        self.closed_world = IntVar()
        self.cb_closed_world = Checkbutton(cw_container,
                                           text="CW Assumption",
                                           variable=self.closed_world,
                                           command=self.onchange_cw)
        self.cb_closed_world.grid(row=0, column=1, sticky='W')

        # output filename
        row += 1
        output_cont = Frame(self.frame)
        output_cont.grid(row=row, column=1, sticky='NEWS')
        output_cont.columnconfigure(0, weight=1)

        # - filename
        Label(self.frame, text="Output: ").grid(row=row, column=0, sticky="NE")
        self.output_filename = StringVar()
        self.entry_output_filename = Entry(output_cont,
                                           textvariable=self.output_filename)
        self.entry_output_filename.grid(row=0, column=0, sticky="NEW")

        # - save option
        self.save = IntVar()
        self.cb_save = Checkbutton(output_cont,
                                   text="save",
                                   variable=self.save)
        self.cb_save.grid(row=0, column=1, sticky=W)

        # start button
        row += 1
        start_button = Button(self.frame,
                              text=">> Start Inference <<",
                              command=self.infer)
        start_button.grid(row=row, column=1, sticky="NEW")

        self.settings_dirty = IntVar()
        self.project_dirty = IntVar()

        self.gconf = gconf
        self.project = None
        self.project_dir = os.path.abspath(
            ifnone(directory, ifnone(gconf['prev_query_path'], os.getcwd())))
        if gconf['prev_query_project':self.project_dir] is not None:
            self.load_project(
                os.path.join(self.project_dir,
                             gconf['prev_query_project':self.project_dir]))
        else:
            self.new_project()

        self.config = self.project.queryconf
        self.project.addlistener(self.project_setdirty)

        self.mln_container.dirty = False
        self.emln_container.dirty = False
        self.db_container.dirty = False
        self.project_setdirty(dirty=False)

        self.master.geometry(gconf['window_loc_query'])

        self.initialized = True

    def _got_focus(self, *_):
        if self.master.focus_get() == self.mln_container.editor:
            if not self.project.mlns and not self.mln_container.file_buffer:
                self.mln_container.new_file()
        elif self.master.focus_get() == self.db_container.editor:
            if not self.project.dbs and not self.db_container.file_buffer:
                self.db_container.new_file()
        elif self.master.focus_get() == self.emln_container.editor:
            if not self.project.emlns and not self.emln_container.file_buffer:
                self.emln_container.new_file()

    def quit(self):
        if self.settings_dirty.get() or self.project_dirty.get():
            savechanges = messagebox.askyesnocancel(
                "Save changes",
                "You have unsaved project changes. Do you want to save them before quitting?"
            )
            if savechanges is None:
                return
            elif savechanges:
                self.noask_save_project()
            self.master.destroy()
        else:
            # write gui settings and destroy
            self.write_gconfig()
            self.master.destroy()

    ####################### PROJECT FUNCTIONS #################################

    def new_project(self):
        self.project = MLNProject()
        self.project.addlistener(self.project_setdirty)
        self.project.name = DEFAULTNAME.format('.pracmln')
        self.reset_gui()
        self.set_config(self.project.queryconf)
        self.mln_container.update_file_choices()
        self.emln_container.update_file_choices()
        self.db_container.update_file_choices()
        self.project_setdirty(dirty=True)

    def project_setdirty(self, dirty=False, *args):
        self.project_dirty.set(dirty or self.mln_container.dirty
                               or self.db_container.dirty
                               or self.emln_container.dirty)
        self.changewindowtitle()

    def settings_setdirty(self, *args):
        self.settings_dirty.set(1)
        self.changewindowtitle()

    def changewindowtitle(self):
        title = (WINDOWTITLEEDITED if
                 (self.settings_dirty.get() or self.project_dirty.get()) else
                 WINDOWTITLE).format(self.project_dir, self.project.name)
        self.master.title(title)

    def ask_load_project(self):
        filename = askopenfilename(initialdir=self.dir,
                                   filetypes=[('PRACMLN project files',
                                               '.pracmln')],
                                   defaultextension=".pracmln")
        if filename and os.path.exists(filename):
            self.load_project(filename)
        else:
            logger.info('No file selected.')
            return

    def load_project(self, filename):
        if filename and os.path.exists(filename):
            projdir, _ = ntpath.split(filename)
            self.dir = os.path.abspath(projdir)
            self.project_dir = os.path.abspath(projdir)
            self.project = MLNProject.open(filename)
            self.project.addlistener(self.project_setdirty)
            self.reset_gui()
            self.set_config(self.project.queryconf.config)
            self.mln_container.update_file_choices()
            self.db_container.update_file_choices()
            if len(self.project.mlns) > 0:
                self.mln_container.selected_file.set(
                    self.project.queryconf['mln']
                    or list(self.project.mlns.keys())[0])
            self.mln_container.dirty = False
            if len(self.project.emlns) > 0:
                self.emln_container.selected_file.set(
                    self.project.queryconf['emln']
                    or list(self.project.emlns.keys())[0])
            self.emln_container.dirty = False
            if len(self.project.dbs) > 0:
                self.db_container.selected_file.set(
                    self.project.queryconf['db']
                    or list(self.project.dbs.keys())[0])
            self.db_container.dirty = False
            self.write_gconfig(savegeometry=False)
            self.settings_dirty.set(0)
            self.project_setdirty(dirty=False)
            self.changewindowtitle()
        else:
            logger.error(
                'File {} does not exist. Creating new project...'.format(
                    filename))
            self.new_project()

    def noask_save_project(self):
        if self.project.name and not self.project.name == DEFAULTNAME.format(
                '.pracmln'):
            self.save_project(os.path.join(self.project_dir,
                                           self.project.name))
        else:
            self.ask_save_project()

    def ask_save_project(self):
        fullfilename = asksaveasfilename(initialdir=self.project_dir,
                                         confirmoverwrite=True,
                                         filetypes=[('PRACMLN project files',
                                                     '.pracmln')],
                                         defaultextension=".pracmln")
        self.save_project(fullfilename)

    def save_project(self, fullfilename):
        if fullfilename:
            fpath, fname = ntpath.split(fullfilename)
            fname = fname.split('.')[0]
            self.project.name = fname
            self.dir = os.path.abspath(fpath)
            self.project_dir = os.path.abspath(fpath)

            self.mln_container.save_all_files()
            self.emln_container.save_all_files()
            self.db_container.save_all_files()

            self.update_config()
            self.project.save(dirpath=self.project_dir)
            self.write_gconfig()

            self.load_project(fullfilename)
            self.settings_dirty.set(0)

    def save_proj(self):
        self.project.save(dirpath=self.project_dir)
        self.write_gconfig()
        self.project_setdirty(dirty=False)

    ####################### MLN FUNCTIONS #####################################

    def import_mln(self, name, content):
        self.project.add_mln(name, content)

    def delete_mln(self, fname):
        if fname in self.project.mlns:
            self.project.rm_mln(fname)
        fnamestr = fname.strip('*')
        if fnamestr in self.project.mlns:
            self.project.rm_mln(fnamestr)

    def update_mln(self, old=None, new=None, content=None, askoverwrite=True):
        if old is None:
            old = self.mln_container.selected_file.get()
        if new is None:
            new = self.mln_container.selected_file.get().strip('*')
        if content is None:
            content = self.mln_container.editor.get("1.0", END).strip()

        if old == new and askoverwrite:
            savechanges = messagebox.askyesno(
                "Save changes",
                "A file '{}' already exists. Overwrite?".format(new))
            if savechanges:
                self.project.mlns[old] = content
            else:
                logger.error('no name specified!')
                return -1
        elif old == new and not askoverwrite:
            self.project.mlns[old] = content
        else:
            if new in self.project.mlns:
                if askoverwrite:
                    savechanges = messagebox.askyesno(
                        "Save changes",
                        "A file '{}' already exists. Overwrite?".format(new))
                    if savechanges:
                        self.project.mlns[new] = content
                    else:
                        logger.error('no name specified!')
                        return -1
            else:
                self.project.mlns[new] = content
        return 1

    def mlnfiles(self):
        return list(self.project.mlns.keys())

    def mlnfilecontent(self, filename):
        return self.project.mlns.get(filename, '').strip()

    # /MLN FUNCTIONS #####################################

    ####################### EMLN FUNCTIONS #####################################

    def import_emln(self, name, content):
        self.project.add_emln(name, content)

    def delete_emln(self, fname):
        if fname in self.project.emlns:
            self.project.rm_emln(fname)
        fnamestr = fname.strip('*')
        if fnamestr in self.project.emlns:
            self.project.rm_emln(fnamestr)

    def update_emln(self, old=None, new=None, content=None, askoverwrite=True):
        if old is None:
            old = self.emln_container.selected_file.get()
        if new is None:
            new = self.emln_container.selected_file.get().strip('*')
        if content is None:
            content = self.emln_container.editor.get("1.0", END).strip()

        if old == new and askoverwrite:
            savechanges = messagebox.askyesno(
                "Save changes",
                "A file '{}' already exists. Overwrite?".format(new))
            if savechanges:
                self.project.emlns[old] = content
            else:
                logger.error('no name specified!')
                return -1
        elif old == new and not askoverwrite:
            self.project.emlns[old] = content
        else:
            if new in self.project.emlns:
                if askoverwrite:
                    savechanges = messagebox.askyesno(
                        "Save changes",
                        "A file '{}' already exists. Overwrite?".format(new))
                    if savechanges:
                        self.project.emlns[new] = content
                    else:
                        logger.error('no name specified!')
                        return -1
            else:
                self.project.emlns[new] = content
        return 1

    def emlnfiles(self):
        return list(self.project.emlns.keys())

    def emlnfilecontent(self, filename):
        return self.project.emlns.get(filename, '').strip()

    # /EMLN FUNCTIONS #####################################

    # DB FUNCTIONS #####################################
    def import_db(self, name, content):
        self.project.add_db(name, content)

    def delete_db(self, fname):
        if fname in self.project.dbs:
            self.project.rm_db(fname)
        fnamestr = fname.strip('*')
        if fnamestr in self.project.dbs:
            self.project.rm_db(fnamestr)

    def update_db(self, old=None, new=None, content=None, askoverwrite=True):
        if old is None:
            old = self.db_container.selected_file.get()
        if new is None:
            new = self.db_container.selected_file.get().strip('*')
        if content is None:
            content = self.db_container.editor.get("1.0", END).strip()

        if old == new and askoverwrite:
            savechanges = messagebox.askyesno(
                "Save changes",
                "A file '{}' already exists. Overwrite?".format(new))
            if savechanges:
                self.project.dbs[old] = content
            else:
                logger.error('no name specified!')
                return -1
        elif old == new and not askoverwrite:
            self.project.dbs[old] = content
        else:
            if new in self.project.dbs:
                if askoverwrite:
                    savechanges = messagebox.askyesno(
                        "Save changes",
                        "A file '{}' already exists. Overwrite?".format(new))
                    if savechanges:
                        self.project.dbs[new] = content
                    else:
                        logger.error('no name specified!')
                        return -1
            else:
                self.project.dbs[new] = content
        return 1

    def dbfiles(self):
        return list(self.project.dbs.keys())

    def dbfilecontent(self, filename):
        return self.project.dbs.get(filename, '').strip()

    # /DB FUNCTIONS #####################################

    # GENERAL FUNCTIONS #################################

    def select_method(self, *args):
        self.set_outputfilename()
        self.settings_setdirty()

    def onchange_use_emln(self, dirty=True, *args):
        if not self.use_emln.get():
            self.emln_label.grid_forget()
            self.emln_container.grid_forget()
        else:
            self.emln_label.grid(row=self.emlncontainerrow,
                                 column=0,
                                 sticky="NE")
            self.emln_container.grid(row=self.emlncontainerrow,
                                     column=1,
                                     sticky="NWES")
        if dirty:
            self.settings_setdirty()

    def onchange_cw(self, *args):
        if self.closed_world.get():
            self.entry_cw.configure(state=DISABLED)
        else:
            self.entry_cw.configure(state=NORMAL)
        self.settings_setdirty()

    def reset_gui(self):
        self.set_config({})
        self.db_container.clear()
        self.emln_container.clear()
        self.mln_container.clear()

    def set_config(self, newconf):
        self.config = newconf
        self.selected_grammar.set(ifnone(newconf.get('grammar'),
                                         'PRACGrammar'))
        self.selected_logic.set(ifnone(newconf.get('logic'),
                                       'FirstOrderLogic'))
        self.mln_container.selected_file.set(ifnone(newconf.get('mln'), ''))
        if self.use_emln.get():
            self.emln_container.selected_file.set(
                ifnone(newconf.get('mln'), ''))
        self.db_container.selected_file.set(ifnone(newconf.get('db'), ""))
        self.selected_method.set(
            ifnone(newconf.get("method"),
                   InferenceMethods.name('MCSAT'),
                   transform=InferenceMethods.name))
        self.multicore.set(ifnone(newconf.get('multicore'), 0))
        self.profile.set(ifnone(newconf.get('profile'), 0))
        self.params.set(ifnone(newconf.get('params'), ''))
        self.use_emln.set(ifnone(newconf.get('use_emln'), 0))
        self.verbose.set(ifnone(newconf.get('verbose'), 1))
        self.ignore_unknown_preds.set(
            ifnone(newconf.get('ignore_unknown_preds'), 0))
        self.output_filename.set(ifnone(newconf.get('output_filename'), ''))
        self.cwPreds.set(ifnone(newconf.get('cw_preds'), ''))
        self.closed_world.set(ifnone(newconf.get('cw'), 0))
        self.save.set(ifnone(newconf.get('save'), 0))
        self.query.set(ifnone(newconf.get('queries'), ''))
        self.onchange_cw()

    def set_outputfilename(self):
        if not hasattr(self, "output_filename") or not hasattr(
                self, "db_filename") or not hasattr(self, "mln_filename"):
            return
        mln = self.mln_container.selected_file.get()
        db = self.db_container.selected_file.get()
        if "" in (mln, db):
            return
        if self.selected_method.get():
            method = InferenceMethods.clazz(self.selected_method.get())
            methodid = InferenceMethods.id(method)
            filename = config.query_output_filename(mln, methodid, db)
            self.output_filename.set(filename)

    def update_config(self):

        self.config = PRACMLNConfig()
        self.config["use_emln"] = self.use_emln.get()
        self.config['mln'] = self.mln_container.selected_file.get().strip(
        ).lstrip('*')
        self.config['emln'] = self.emln_container.selected_file.get().strip(
        ).lstrip('*')
        self.config["db"] = self.db_container.selected_file.get().strip(
        ).lstrip('*')
        self.config["method"] = InferenceMethods.id(
            self.selected_method.get().strip())
        self.config["params"] = self.params.get().strip()
        self.config["queries"] = self.query.get()
        self.config["output_filename"] = self.output_filename.get().strip()
        self.config["cw"] = self.closed_world.get()
        self.config["cw_preds"] = self.cwPreds.get()
        self.config['profile'] = self.profile.get()
        self.config['logic'] = self.selected_logic.get()
        self.config['grammar'] = self.selected_grammar.get()
        self.config['multicore'] = self.multicore.get()
        self.config['save'] = self.save.get()
        self.config['ignore_unknown_preds'] = self.ignore_unknown_preds.get()
        self.config['verbose'] = self.verbose.get()
        self.config['window_loc'] = self.master.winfo_geometry()
        self.config['dir'] = self.dir
        self.project.queryconf = PRACMLNConfig()
        self.project.queryconf.update(self.config.config.copy())

    def write_gconfig(self, savegeometry=True):
        self.gconf['prev_query_path'] = self.dir
        self.gconf['prev_query_project':self.dir] = self.project.name

        # save geometry
        if savegeometry:
            self.gconf['window_loc_query'] = self.master.geometry()
        self.gconf.dump()

    def infer(self, savegeometry=True, options={}, *args):
        mln_content = self.mln_container.editor.get("1.0", END).strip()
        db_content = self.db_container.editor.get("1.0", END).strip()

        # create conf from current gui settings
        self.update_config()

        # write gui settings
        self.write_gconfig(savegeometry=savegeometry)

        # hide gui
        self.master.withdraw()

        try:
            print((headline('PRACMLN QUERY TOOL')))
            print()

            if options.get('mlnarg') is not None:
                mlnobj = MLN(mlnfile=os.path.abspath(options.get('mlnarg')),
                             logic=self.config.get('logic', 'FirstOrderLogic'),
                             grammar=self.config.get('grammar', 'PRACGrammar'))
            else:
                mlnobj = parse_mln(
                    mln_content,
                    searchpaths=[self.dir],
                    projectpath=os.path.join(self.dir, self.project.name),
                    logic=self.config.get('logic', 'FirstOrderLogic'),
                    grammar=self.config.get('grammar', 'PRACGrammar'))

            if options.get('emlnarg') is not None:
                emln_content = mlnpath(options.get('emlnarg')).content
            else:
                emln_content = self.emln_container.editor.get("1.0",
                                                              END).strip()

            if options.get('dbarg') is not None:
                dbobj = Database.load(mlnobj,
                                      dbfiles=[options.get('dbarg')],
                                      ignore_unknown_preds=self.config.get(
                                          'ignore_unknown_preds', True))
            else:
                out(self.config.get('ignore_unknown_preds', True))
                dbobj = parse_db(mlnobj,
                                 db_content,
                                 ignore_unknown_preds=self.config.get(
                                     'ignore_unknown_preds', True))

            if options.get('queryarg') is not None:
                self.config["queries"] = options.get('queryarg')

            infer = MLNQuery(config=self.config,
                             mln=mlnobj,
                             db=dbobj,
                             emln=emln_content)
            result = infer.run()

            # write to file if run from commandline, otherwise save result to project results
            if options.get('outputfile') is not None:
                output = io.StringIO()
                result.write(output)
                with open(os.path.abspath(options.get('outputfile')),
                          'w') as f:
                    f.write(output.getvalue())
                logger.info('saved result to {}'.format(
                    os.path.abspath(options.get('outputfile'))))
            elif self.save.get():
                output = io.StringIO()
                result.write(output)
                fname = self.output_filename.get()
                self.project.add_result(fname, output.getvalue())
                self.project.save(dirpath=self.dir)
                logger.info(
                    'saved result to file results/{} in project {}'.format(
                        fname, self.project.name))
            else:
                logger.debug(
                    'No output file given - results have not been saved.')
        except:
            traceback.print_exc()

        # restore main window
        sys.stdout.flush()
        self.master.deiconify()
Пример #14
0
    def role_distributions(self, step):
        '''
        TODO

        :param step:
        :return:
        '''
        distrs = {}
        for db_ in step.output_dbs:
            for word in db_.domains['word']:
                for q in db_.query('action_core(?w,?ac)'):

                    # ==========================================================
                    # Initializaton
                    # ==========================================================

                    actioncore = q['?ac']
                    projectpath = os.path.join(self.module_path,
                                               '{}.pracmln'.format(actioncore))
                    project = MLNProject.open(projectpath)
                    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'))

                    # ==========================================================
                    # Preprocessing
                    # ==========================================================

                    # add inferred concepts to known_concepts to display
                    # them in the graph. Ignore verbs and adjectives,
                    # as they do not have hypernym relations to nouns
                    concepts = self.prac.config.getlist('wordnet', 'concepts')
                    for con in db_.query('has_sense(?w,?s)'):
                        if con['?s'].split('.')[1] in ['a', 's', 'v']:
                            continue
                        concepts.append(con['?s'])
                    wn = WordNet(concepts=concepts)

                    db = db_.copy(mln=mln)
                    for qs in db_.query('!(EXIST ?w (has_sense(?w,?s)))'):
                        db.rmval('sense', qs['?s'])
                    for concept in db_.domains['concept']:
                        if concept not in mln.domains['concept']:
                            db.rmval('concept', concept)
                    for res in db_.query('has_sense({}, ?s)'.format(word)):
                        sense = res['?s']
                        if sense == 'null': continue
                        roles = self.prac.actioncores[actioncore].roles
                        role = None
                        for r in roles:
                            vars = [
                                '?v{}'.format(i) for i in range(
                                    len(db_.mln.predicate(r).argdoms) - 1)
                            ]
                            br = False
                            for qr in db_.query('{}({},{})'.format(
                                    r, ','.join(vars), actioncore)):
                                for v in vars:
                                    if qr[v] == word:
                                        role = r
                                        br = True
                                        break
                                if br: break
                            if br: break
                        if role is None: continue
                        db.retract('has_sense({},{})'.format(word, sense))
                        add_all_wordnet_similarities(db, wn)

                        # ======================================================
                        # Inference
                        # ======================================================

                        infer = self.mlnquery(method='EnumerationAsk',
                                              mln=mln,
                                              db=db,
                                              queries='has_sense',
                                              cw=True,
                                              multicore=True,
                                              verbose=self.prac.verbose > 2)

                        result = infer.resultdb

                        if self.prac.verbose == 2:
                            print
                            print prac_heading('INFERENCE RESULTS')
                            print
                            infer.write()

                        # ======================================================
                        # Graph generation
                        # ======================================================

                        g = wn.to_dot()
                        maxprob = 0.
                        for atom, truth in result.gndatoms():
                            _, predname, args = db.mln.logic.parse_literal(
                                atom)
                            concept = args[1]
                            if predname == 'has_sense' and args[
                                    0] == word and concept != 'null':
                                maxprob = max(maxprob, truth)

                        for atom, truth in result.gndatoms():
                            _, predname, args = db.mln.logic.parse_literal(
                                atom)
                            concept = args[1]
                            if predname == 'has_sense' and args[
                                    0] == word and concept != 'null':
                                if concept in concepts:
                                    g.node(concept,
                                           fillcolor=get_prob_color(truth /
                                                                    maxprob))
                        distrs[role] = render_gv(g)
        return distrs
Пример #15
0
    (options, args) = parser.parse_args()
    folds = options.folds
    percent = options.percent
    verbose = options.verbose
    multicore = options.multicore
    dirname = options.folder
    predname = args[0]
    mlnproject = args[1]
    dbfiles = args[2:]
    startTime = time.time()

    #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  
    # set up the directory    
    #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #
    timestamp = time.strftime("%Y-%b-%d-%H-%M-%S", time.localtime())
    project = MLNProject.open(os.path.abspath(os.path.join(os.getcwd(), mlnproject)))
    project.write()
    if dirname is None:  
        mlnname = project.queryconf['mln'][:-4]
        idx = 1
        while True:
            dirname = '%s-%d' % (mlnname, idx)
            idx += 1
            if not os.path.exists(dirname): break
        dirname += '-' + timestamp
    
    expdir = os.getenv('PRACMLN_EXPERIMENTS', '.')
    expdir = os.path.join(expdir, dirname)
    if os.path.exists(expdir):
        print 'Directory "%s" exists. Overwrite? ([y]/n)' % expdir,
        answer = sys.stdin.read(1)
Пример #16
0
    (options, args) = parser.parse_args()
    folds = options.folds
    percent = options.percent
    verbose = options.verbose
    multicore = options.multicore
    dirname = options.folder
    predname = args[0]
    mlnproject = args[1]
    dbfiles = args[2:]
    startTime = time.time()

    #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #
    # set up the directory
    #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #  #
    timestamp = time.strftime("%Y-%b-%d-%H-%M-%S", time.localtime())
    project = MLNProject.open(
        os.path.abspath(os.path.join(os.getcwd(), mlnproject)))
    project.write()
    if dirname is None:
        mlnname = project.queryconf['mln'][:-4]
        idx = 1
        while True:
            dirname = '%s-%d' % (mlnname, idx)
            idx += 1
            if not os.path.exists(dirname): break
        dirname += '-' + timestamp

    expdir = os.getenv('PRACMLN_EXPERIMENTS', '.')
    expdir = os.path.join(expdir, dirname)
    if os.path.exists(expdir):
        print 'Directory "%s" exists. Overwrite? ([y]/n)' % expdir,
        answer = sys.stdin.read(1)
Пример #17
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]
Пример #18
0
    def __call__(self, pracinference, **params):

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

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

        if self.prac.verbose > 0:
            print(prac_heading('Recognizing Control Structures'))

        if params.get('project', None) is None:
            # load default project
            projectpath = os.path.join(pracloc.pracmodules, self.name,
                                       self.defproject)
            ac_project = MLNProject.open(projectpath)
        else:
            logger.info(
                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)
            ac_project = params.get('project')

        dbs = pracinference.inference_steps[-1].output_dbs

        mlntext = ac_project.mlns.get(ac_project.queryconf['mln'], None)
        mln = parse_mln(mlntext,
                        searchpaths=[self.module_path],
                        projectpath=projectpath,
                        logic=ac_project.queryconf.get('logic',
                                                       'FirstOrderLogic'),
                        grammar=ac_project.queryconf.get(
                            'grammar', 'PRACGrammar'))
        inf_step = PRACInferenceStep(pracinference, self)

        pngs = {}
        for i, db in enumerate(dbs):
            db_ = db.copy()

            # ======================================================================
            # Inference
            # ======================================================================

            infer = self.mlnquery(config=ac_project.queryconf, db=db, mln=mln)
            result_db = infer.resultdb

            if self.prac.verbose == 2:
                print()
                print(prac_heading('INFERENCE RESULTS'))
                infer.write()

            # ==========================================================
            # Postprocessing
            # ==========================================================

            for q in result_db.query('event(?w,?ac)'):
                db_ << 'event({},{})'.format(q['?w'], q['?ac'])
            for q in result_db.query('condition(?w)'):
                db_ << 'condition({})'.format(q['?w'])

            inf_step.output_dbs.append(db_)
            pngs['CS' + str(i)] = get_cond_prob_png(ac_project.queryconf.get(
                'queries', ''),
                                                    dbs,
                                                    filename=self.name)
            inf_step.png = pngs

        inf_step.applied_settings = ac_project.queryconf.config

        return inf_step
Пример #19
0
class PRACQueryGUI(object):
    def __init__(self, master, prac, node, gconf, directory='.'):
        self.logger = logs.getlogger(self.__class__.__name__, level=logs.DEBUG)
        self.master = master

        self.initialized = False

        self.master.bind('<Return>', self.start)
        self.master.bind('<Escape>', lambda a: self.master.quit())
        self.master.protocol('WM_DELETE_WINDOW', self.quit)

        self.prac = prac
        self.prac_inference = node.pracinfer
        self.infStep = None

        self.module_dir = os.path.join(locations.pracmodules, 'wnsenses')

        self.frame = Frame(master)
        self.frame.pack(fill=BOTH, expand=1)
        self.frame.columnconfigure(1, weight=1)

        # module selection
        row = 0
        Label(self.frame, text="Module: ").grid(row=row, column=0, sticky="E")
        modules = sorted([module for module in self.prac._manifests_by_name])
        self.selected_module = StringVar(master)
        self.selected_module.trace("w", self.select_module)
        self.list_modules = OptionMenu(*(self.frame, self.selected_module) +
                                       tuple(modules))
        self.list_modules.grid(row=row, column=1, sticky="NWE")

        # Project selection
        row += 1
        Label(self.frame, text="Project: ").grid(row=row, column=0, sticky="E")
        saveprojectcontainer = Frame(self.frame)
        saveprojectcontainer.grid(row=row, column=1, sticky="NEWS")
        saveprojectcontainer.columnconfigure(0, weight=1)

        self.selected_project = StringVar(master)
        projectfiles = ['']
        self.list_projects = OptionMenu(
            *(saveprojectcontainer, self.selected_project) +
            tuple(projectfiles))
        self.list_projects.grid(row=0, column=0, sticky="NWES")
        self.selected_project.trace("w", self.select_project)

        # save proj file
        self.btn_saveproj = Button(saveprojectcontainer,
                                   text='Save Project...',
                                   command=self.noask_save_project)
        self.btn_saveproj.grid(row=0, column=1, sticky="E")

        # save proj file as...
        self.btn_saveproj = Button(saveprojectcontainer,
                                   text='Save Project as...',
                                   command=self.ask_save_project)
        self.btn_saveproj.grid(row=0, column=2, sticky="E")

        # logic selection
        row += 1
        Label(self.frame, text='Logic: ').grid(row=row, column=0, sticky='E')
        logics = ['FirstOrderLogic', 'FuzzyLogic']
        self.selected_logic = StringVar(master)
        self.selected_logic.trace('w', self.settings_setdirty)
        l = OptionMenu(*(self.frame, self.selected_logic) + tuple(logics))
        l.grid(row=row, column=1, sticky='NWE')

        # mln section
        row += 1
        Label(self.frame, text="MLN: ").grid(row=row, column=0, sticky='NE')
        self.mln_container = FileEditBar(self.frame,
                                         dir=self.module_dir,
                                         filesettings={
                                             'extension': '.mln',
                                             'ftypes': [('MLN files', '.mln')]
                                         },
                                         defaultname='*unknown{}',
                                         importhook=self.import_mln,
                                         deletehook=self.delete_mln,
                                         projecthook=self.save_proj,
                                         filecontenthook=self.mlnfilecontent,
                                         fileslisthook=self.mlnfiles,
                                         updatehook=self.update_mln,
                                         onchangehook=self.project_setdirty)
        self.mln_container.grid(row=row, column=1, sticky="NEWS")
        self.mln_container.columnconfigure(1, weight=2)
        self.frame.rowconfigure(row, weight=1)

        row += 1
        self.use_emln = IntVar()
        self.use_emln.set(0)
        self.cb_use_emln = Checkbutton(self.frame,
                                       text="use model extension",
                                       variable=self.use_emln,
                                       command=self.onchange_use_emln)
        self.cb_use_emln.grid(row=row, column=1, sticky="W")

        # mln extension section
        row += 1
        self.emlncontainerrow = row
        self.emln_label = Label(self.frame, text="EMLN: ")
        self.emln_label.grid(row=self.emlncontainerrow, column=0, sticky='NE')
        self.emln_container = FileEditBar(self.frame,
                                          dir=self.module_dir,
                                          filesettings={
                                              'extension':
                                              '.emln',
                                              'ftypes':
                                              [('MLN extension files', '.emln')
                                               ]
                                          },
                                          defaultname='*unknown{}',
                                          importhook=self.import_emln,
                                          deletehook=self.delete_emln,
                                          projecthook=self.save_proj,
                                          filecontenthook=self.emlnfilecontent,
                                          fileslisthook=self.emlnfiles,
                                          updatehook=self.update_emln,
                                          onchangehook=self.project_setdirty)
        self.emln_container.grid(row=self.emlncontainerrow,
                                 column=1,
                                 sticky="NEWS")
        self.emln_container.columnconfigure(1, weight=2)
        self.onchange_use_emln(dirty=False)
        self.frame.rowconfigure(row, weight=1)

        # db section
        row += 1
        Label(self.frame, text="Evidence: ").grid(row=row,
                                                  column=0,
                                                  sticky='NE')
        self.db_container = FileEditBar(self.frame,
                                        dir=self.module_dir,
                                        filesettings={
                                            'extension': '.db',
                                            'ftypes':
                                            [('Database files', '.db')]
                                        },
                                        defaultname='*unknown{}',
                                        importhook=self.import_db,
                                        deletehook=self.delete_db,
                                        projecthook=self.save_proj,
                                        filecontenthook=self.dbfilecontent,
                                        fileslisthook=self.dbfiles,
                                        updatehook=self.update_db,
                                        onchangehook=self.project_setdirty)
        self.db_container.grid(row=row, column=1, sticky="NEWS")
        self.db_container.columnconfigure(1, weight=2)
        self.frame.rowconfigure(row, weight=1)

        # inference method selection
        row += 1
        self.list_methods_row = row
        Label(self.frame, text="Method: ").grid(row=row, column=0, sticky=E)
        self.selected_method = StringVar(master)
        self.selected_method.trace('w', self.settings_setdirty)
        self.list_methods = OptionMenu(self.frame, self.selected_method,
                                       *InferenceMethods.names())
        self.list_methods.grid(row=self.list_methods_row,
                               column=1,
                               sticky="NWE")

        # queries
        row += 1
        Label(self.frame, text="Queries: ").grid(row=row, column=0, sticky=E)
        self.query = StringVar(master)
        Entry(self.frame, textvariable=self.query).grid(row=row,
                                                        column=1,
                                                        sticky="NEW")

        #  parameters
        row += 1
        Label(self.frame, text="Parameters: ").grid(row=row,
                                                    column=0,
                                                    sticky="NE")
        self.params = StringVar(master)
        self.entry_params = Entry(self.frame, textvariable=self.params)
        self.entry_params.grid(row=row, column=1, sticky="NEW")

        # closed-world predicates
        row += 1
        Label(self.frame, text="CW preds: ").grid(row=row,
                                                  column=0,
                                                  sticky="NE")
        self.cwpreds = StringVar(master)
        self.entry_cw = Entry(self.frame, textvariable=self.cwpreds)
        self.entry_cw.grid(row=row, column=1, sticky="NEW")

        # all preds open-world
        cw_container = Frame(self.frame)
        cw_container.grid(row=row, column=1, sticky="NES")
        self.closed_world = IntVar()
        self.cb_closed_world = Checkbutton(
            cw_container,
            text="Apply CW assumption to all except queries",
            variable=self.closed_world)
        self.cb_closed_world.grid(row=row, column=2, sticky='E')

        # Multiprocessing and verbose
        row += 1
        options_container = Frame(self.frame)
        options_container.grid(row=row, column=1, sticky='NEWS')

        self.multicore = IntVar()
        self.cb_multicore = Checkbutton(options_container,
                                        text="Use all CPUs",
                                        variable=self.multicore)
        self.cb_multicore.grid(row=0, column=0, sticky=W)

        self.verbose = IntVar()
        self.cb_verbose = Checkbutton(options_container,
                                      text="verbose",
                                      variable=self.verbose)
        self.cb_verbose.grid(row=0, column=1, sticky=W)

        self.keep_evidence = IntVar()
        self.cb_keep_evidence = Checkbutton(options_container,
                                            text="keep result",
                                            variable=self.keep_evidence)
        self.cb_keep_evidence.grid(row=0, column=2, sticky=W)
        self.keep_evidence.set(True)

        # start and continue buttons
        row += 1
        self.btn_container = Frame(self.frame)
        self.btn_container.grid(row=row, column=1, sticky='EW')

        start_button = Button(self.btn_container,
                              text="Start Inference",
                              command=self.start)
        start_button.grid(row=0, column=1, sticky='E')

        continue_button = Button(self.btn_container,
                                 text="Continue >",
                                 command=self.oncontinue)
        continue_button.grid(row=0, column=2, sticky='W')

        self.settings_dirty = IntVar()
        self.project_dirty = IntVar()

        self.gconf = gconf
        self.project = None
        self.dir = os.path.abspath(
            ifnone(gconf['prev_query_path'], DEFAULT_CONFIG))
        if gconf['prev_query_project':self.dir] is not None:
            self.load_project(
                os.path.join(self.dir, gconf['prev_query_project':self.dir]))
        else:
            self.new_project()

        self.config = self.project.queryconf
        self.project.addlistener(self.project_setdirty)

        self.selected_module.set(self.gconf.get("module", modules[0]))
        self.update_dbeditor_from_result(node.outdbs)
        self.mln_container.dirty = False
        self.emln_container.dirty = False
        self.db_container.dirty = False
        self.project_setdirty(dirty=False)

        self.master.geometry(gconf['window_loc_query'])

        self.initialized = True

    def quit(self):
        if self.settings_dirty.get() or self.project_dirty.get():
            savechanges = tkinter.messagebox.askyesnocancel(
                "Save changes",
                "You have unsaved project changes. Do you want to save them before quitting?"
            )
            if savechanges is None:
                return
            elif savechanges:
                self.noask_save_project()
            self.master.destroy()
        else:
            # write gui settings and destroy
            self.write_gconfig()
            self.master.destroy()

    ####################### PROJECT FUNCTIONS #################################
    def new_project(self):
        self.project = MLNProject()
        self.project.addlistener(self.project_setdirty)
        self.project.name = DEFAULTNAME.format('.pracmln')
        self.reset_gui()
        self.set_config(self.project.queryconf)
        self.mln_container.update_file_choices()
        self.emln_container.update_file_choices()
        self.db_container.update_file_choices()
        self.settings_setdirty()

    def project_setdirty(self, dirty=False, *args):
        self.project_dirty.set(dirty or self.mln_container.dirty
                               or self.db_container.dirty
                               or self.emln_container.dirty)
        self.changewindowtitle()

    def settings_setdirty(self, *args):
        self.settings_dirty.set(1)
        self.changewindowtitle()

    def changewindowtitle(self):
        title = (WINDOWTITLEEDITED if
                 (self.settings_dirty.get() or self.project_dirty.get()) else
                 WINDOWTITLE).format(self.dir, self.project.name)
        self.master.title(title)

    def select_project(self, *args):
        filename = os.path.join(
            self.prac.manifest(self.selected_module.get()).module_path,
            self.selected_project.get())
        if filename and os.path.exists(filename):
            self.load_project(filename)
        else:
            self.logger.info('No file selected.')
            return

    def load_project(self, filename):
        if filename and os.path.exists(filename):
            projdir, _ = ntpath.split(filename)
            self.dir = os.path.abspath(projdir)
            self.module_dir = os.path.abspath(projdir)
            self.project = MLNProject.open(filename)
            self.project.addlistener(self.project_setdirty)
            self.reset_gui(keepdb=True)
            self.set_config(self.project.queryconf.config)
            self.mln_container.update_file_choices()
            self.db_container.update_file_choices()
            if len(self.project.mlns) > 0:
                self.mln_container.selected_file.set(
                    self.project.queryconf['mln']
                    or list(self.project.mlns.keys())[0])
                self.mln_container.dirty = False
            if len(self.project.emlns) > 0:
                self.emln_container.selected_file.set(
                    self.project.queryconf['emln']
                    or list(self.project.emlns.keys())[0])
                self.emln_container.dirty = False
            if len(self.project.dbs) > 0 and not self.keep_evidence.get():
                self.db_container.selected_file.set(
                    self.project.queryconf['db']
                    or list(self.project.dbs.keys())[0])
            self.write_gconfig(savegeometry=False)
            self.settings_dirty.set(0)
            self.changewindowtitle()
        else:
            self.logger.error(
                'File {} does not exist. Creating new project...'.format(
                    filename))
            self.new_project()

    def noask_save_project(self):
        if self.project.name and not self.project.name == DEFAULTNAME.format(
                '.pracmln'):
            self.save_project(os.path.join(self.module_dir, self.project.name))
        else:
            self.ask_save_project()

    def ask_save_project(self):
        fullfilename = asksaveasfilename(initialdir=self.module_dir,
                                         confirmoverwrite=True,
                                         filetypes=[('PRACMLN project files',
                                                     '.pracmln')],
                                         defaultextension=".pracmln")
        self.save_project(fullfilename)

    def save_project(self, fullfilename):
        if fullfilename is not None:
            fpath, fname = ntpath.split(fullfilename)
            fname = fname.split('.')[0]
            self.project.name = fname
            self.dir = os.path.abspath(fpath)
            self.module_dir = os.path.abspath(fpath)

            self.mln_container.save_all_files()
            self.emln_container.save_all_files()
            self.db_container.save_all_files()

            self.update_config()
            self.project.save(dirpath=self.module_dir)
            self.write_gconfig()

            self.load_project(fullfilename)
            self.settings_dirty.set(0)

    def save_proj(self):
        self.project.save(dirpath=self.module_dir)
        self.write_gconfig()
        self.project_setdirty()

    ####################### MLN FUNCTIONS #####################################
    def import_mln(self, name, content):
        self.project.add_mln(name, content)

    def delete_mln(self, fname):
        if fname in self.project.mlns:
            self.project.rm_mln(fname)
        fnamestr = fname.strip('*')
        if fnamestr in self.project.mlns:
            self.project.rm_mln(fnamestr)

    def update_mln(self, old=None, new=None, content=None, askoverwrite=True):
        if old is None:
            old = self.mln_container.selected_file.get()
        if new is None:
            new = self.mln_container.selected_file.get().strip('*')
        if content is None:
            content = self.mln_container.editor.get("1.0", END).strip()

        if old == new and askoverwrite:
            savechanges = tkinter.messagebox.askyesno(
                "Save changes",
                "A file '{}' already exists. Overwrite?".format(new))
            if savechanges:
                self.project.mlns[old] = content
            else:
                self.logger.error('no name specified!')
                return -1
        elif old == new and not askoverwrite:
            self.project.mlns[old] = content
        else:
            if new in self.project.mlns:
                if askoverwrite:
                    savechanges = tkinter.messagebox.askyesno(
                        "Save changes",
                        "A file '{}' already exists. Overwrite?".format(new))
                    if savechanges:
                        self.project.mlns[new] = content
                    else:
                        self.logger.error('no name specified!')
                        return -1
            else:
                self.project.mlns[new] = content
        return 1

    def mlnfiles(self):
        return list(self.project.mlns.keys())

    def mlnfilecontent(self, filename):
        return self.project.mlns.get(filename, '').strip()

    ####################### /MLN FUNCTIONS #####################################

    ####################### EMLN FUNCTIONS #####################################
    def import_emln(self, name, content):
        self.project.add_emln(name, content)

    def delete_emln(self, fname):
        if fname in self.project.emlns:
            self.project.rm_emln(fname)
        fnamestr = fname.strip('*')
        if fnamestr in self.project.emlns:
            self.project.rm_emln(fnamestr)

    def update_emln(self, old=None, new=None, content=None, askoverwrite=True):
        if old is None:
            old = self.emln_container.selected_file.get()
        if new is None:
            new = self.emln_container.selected_file.get().strip('*')
        if content is None:
            content = self.emln_container.editor.get("1.0", END).strip()

        if old == new and askoverwrite:
            savechanges = tkinter.messagebox.askyesno(
                "Save changes",
                "A file '{}' already exists. Overwrite?".format(new))
            if savechanges:
                self.project.emlns[old] = content
            else:
                self.logger.error('no name specified!')
                return -1
        elif old == new and not askoverwrite:
            self.project.emlns[old] = content
        else:
            if new in self.project.emlns:
                if askoverwrite:
                    savechanges = tkinter.messagebox.askyesno(
                        "Save changes",
                        "A file '{}' already exists. Overwrite?".format(new))
                    if savechanges:
                        self.project.emlns[new] = content
                    else:
                        self.logger.error('no name specified!')
                        return -1
            else:
                self.project.emlns[new] = content
        return 1

    def emlnfiles(self):
        return list(self.project.emlns.keys())

    def emlnfilecontent(self, filename):
        return self.project.emlns.get(filename, '').strip()

    ####################### /EMLN FUNCTIONS #####################################

    ####################### DB FUNCTIONS #####################################
    def import_db(self, name, content):
        self.project.add_db(name, content)

    def delete_db(self, fname):
        if fname in self.project.dbs:
            self.project.rm_db(fname)
        fnamestr = fname.strip('*')
        if fnamestr in self.project.dbs:
            self.project.rm_db(fnamestr)

    def update_db(self, old=None, new=None, content=None, askoverwrite=True):
        if old is None:
            old = self.db_container.selected_file.get()
        if new is None:
            new = self.db_container.selected_file.get().strip('*')
        if content is None:
            content = self.db_container.editor.get("1.0", END).strip()

        if old == new and askoverwrite:
            savechanges = tkinter.messagebox.askyesno(
                "Save changes",
                "A file '{}' already exists. Overwrite?".format(new))
            if savechanges:
                self.project.dbs[old] = content
            else:
                self.logger.error('no name specified!')
                return -1
        elif old == new and not askoverwrite:
            self.project.dbs[old] = content
        else:
            if new in self.project.dbs:
                if askoverwrite:
                    savechanges = tkinter.messagebox.askyesno(
                        "Save changes",
                        "A file '{}' already exists. Overwrite?".format(new))
                    if savechanges:
                        self.project.dbs[new] = content
                    else:
                        self.logger.error('no name specified!')
                        return -1
            else:
                self.project.dbs[new] = content
        return 1

    def dbfiles(self):
        return list(self.project.dbs.keys())

    def dbfilecontent(self, filename):
        return self.project.dbs.get(filename, '').strip()

    ####################### /DB FUNCTIONS #####################################

    ####################### GENERAL FUNCTIONS #################################

    def onchange_use_emln(self, dirty=True, *args):
        if not self.use_emln.get():
            self.emln_label.grid_forget()
            self.emln_container.grid_forget()
        else:
            self.emln_label.grid(row=self.emlncontainerrow,
                                 column=0,
                                 sticky="NE")
            self.emln_container.grid(row=self.emlncontainerrow,
                                     column=1,
                                     sticky="NWES")
        if dirty:
            self.settings_setdirty()

    def onchange_cw(self, *args):
        if self.closed_world.get():
            self.entry_cw.configure(state=DISABLED)
        else:
            self.entry_cw.configure(state=NORMAL)
        self.settings_setdirty()

    def reset_gui(self, keepdb=False):
        self.set_config({})
        self.db_container.clear(keep=keepdb)
        self.emln_container.clear()
        self.mln_container.clear()

    def set_config(self, conf):
        self.config = conf
        self.selected_logic.set(ifnone(conf.get('logic'), 'FirstOrderLogic'))
        self.mln_container.selected_file.set(ifnone(conf.get('mln'), ''))
        if not self.keep_evidence:
            self.db_container.selected_file.set(ifnone(conf.get('db'), ''))
        self.selected_method.set(
            ifnone(self.config.get("method"),
                   InferenceMethods.name('MCSAT'),
                   transform=InferenceMethods.name))
        self.use_emln.set(ifnone(conf.get('use_emln'), False))
        if self.use_emln.get():
            self.emln_container.selected_file.set(ifnone(conf.get('emln'), ""))
        self.multicore.set(ifnone(conf.get('multicore'), False))
        self.verbose.set(ifnone(conf.get('verbose'), False))
        self.params.set(ifnone(conf.get('params'), ''))
        self.cwpreds.set(ifnone(conf.get('cw_preds'), ''))
        self.closed_world.set(ifnone(conf.get('cw'), False))
        self.query.set(ifnone(conf.get('queries'), 'foo, bar'))

    def update_config(self):

        self.config = PRACMLNConfig()
        self.config['mln'] = self.mln_container.selected_file.get().strip(
        ).lstrip('*')
        self.config['emln'] = self.emln_container.selected_file.get().strip(
        ).lstrip('*')
        self.config["db"] = self.db_container.selected_file.get().strip(
        ).lstrip('*')
        self.config["method"] = InferenceMethods.id(
            self.selected_method.get().strip())
        self.config["params"] = self.params.get().strip()
        self.config["queries"] = self.query.get()
        self.config["cw"] = self.closed_world.get()
        self.config["cw_preds"] = self.cwpreds.get()
        self.config["use_emln"] = self.use_emln.get()
        self.config['logic'] = self.selected_logic.get()
        self.config['multicore'] = self.multicore.get()
        self.config['verbose'] = self.verbose.get()
        self.config['window_loc'] = self.master.winfo_geometry()
        self.config['dir'] = self.dir
        self.project.queryconf = PRACMLNConfig()
        self.project.queryconf.update(self.config.config.copy())

    def write_gconfig(self, savegeometry=True):
        self.gconf['prev_query_path'] = self.dir
        self.gconf['prev_query_project':self.dir] = self.project.name

        # save geometry
        if savegeometry:
            self.gconf['window_loc_query'] = self.master.geometry()
        self.gconf.dump()

    def select_module(self, *args):
        module = self.selected_module.get()
        module_path = self.prac.manifest(module).module_path
        dirpath = os.path.abspath(module_path)
        self.module_dir = dirpath
        self.update_project_choices()
        if self.gconf['prev_query_project':dirpath] is not None:
            self.selected_project.set(self.gconf['prev_query_project':dirpath])

    def update_project_choices(self):
        modulename = self.selected_module.get()
        module_path = self.prac.manifest(modulename).module_path

        # remove all items
        self.list_projects['menu'].delete(0, 'end')

        projects = [
            y for y in os.listdir(module_path)
            if os.path.isfile(os.path.join(module_path, y))
            and y.endswith('.pracmln')
        ]
        for p in projects:
            self.list_projects['menu'].add_command(label=p,
                                                   command=_setit(
                                                       self.selected_project,
                                                       p))

    def oncontinue(self):
        if self.infStep is None:
            self.start()

        curstep = self.prac_inference.lastnode.infchain[-1]
        evidence = curstep.outdbs

        self.update_dbeditor_from_result(evidence)
        self.logger.info(
            'Input databases have been replaced by the latest results.')

    def update_dbeditor_from_result(self, dbs):
        self.db_container.selected_file.set('')
        strbuf = io.StringIO()
        for i, db in enumerate(dbs):
            db.write(strbuf, bars=False, color=False)
            if i < len(dbs) - 1:
                strbuf.write('---\n')

        self.db_container.editor.delete("1.0", END)
        self.db_container.editor.insert(INSERT,
                                        strbuf.getvalue().encode('utf-8'))
        strbuf.close()
        self.db_container._editor_dirty = True

    def update_result_from_dbeditor(self):
        dbtext = self.db_container.editor.get("1.0",
                                              END).encode('utf8').strip()
        dbobj = parse_db(self.prac.mln,
                         dbtext,
                         ignore_unknown_preds=self.config.get(
                             'ignore_unknown_preds', True))

        self.prac_inference.inference_steps[-1].output_dbs = dbobj

    def start(self, savegeometry=True):

        # create conf from current gui settings
        self.update_config()
        self.update_mln(askoverwrite=False)

        # write gui settings
        self.write_gconfig(savegeometry=savegeometry)

        # hide gui
        self.master.withdraw()

        # if evidence was modified in gui, update dbs for next inference step
        self.update_result_from_dbeditor()

        # runinference
        try:
            print(headline('PRAC QUERY TOOL'))
            print()

            next_step = self.prac_inference.runstep()
            curstep = self.prac_inference.lastnode.infchain[-1]
            evidence = curstep.outdbs

            module = self.prac.module(self.selected_module.get())

            self.infStep = module(self.prac_inference,
                                  project=self.project,
                                  projectpath=os.path.join(
                                      self.module_dir, self.project.name))

        except:
            cls, e, tb = sys.exc_info()
            sys.stderr.write("Error: %s\n" % str(e))
            traceback.print_tb(tb)

        # restore main window
        self.master.deiconify()
Пример #20
0
    def __call__(self, node, **params):

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

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

        if self.prac.verbose > 0:
            print(prac_heading('Property Extraction'))

        if params.get('project', None) is None:
            # load default project
            projectpath = os.path.join(pracloc.pracmodules, self.name,
                                       self.defproject)
            project = MLNProject.open(projectpath)
        else:
            # load project from params
            projectpath = os.path.join(
                params.get('projectpath', None)
                or os.path.join(pracloc.pracmodules, self.name),
                params.get('project').name)
            project = params.get('project')

        dbs = node.outdbs
        infstep = PRACInferenceStep(node, self)

        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'))
        wnmod = self.prac.module('wn_senses')

        pngs = {}
        for i, db in enumerate(dbs):
            # ==================================================================
            # Preprocessing
            # ==================================================================
            db_ = wnmod.add_sims(db, mln)
            infstep.indbs.append(db_)
            try:
                # ==============================================================
                # Inference
                # ==============================================================

                infer = self.mlnquery(config=project.queryconf,
                                      verbose=self.prac.verbose > 2,
                                      db=db_,
                                      mln=mln)
                result_db = infer.resultdb

                if self.prac.verbose == 2:
                    print()
                    print(prac_heading('INFERENCE RESULTS'))
                    print()
                    infer.write()

                # ==============================================================
                # Postprocessing
                # ==============================================================
                unified_db = db.copy(self.prac.mln)
                props = [
                    p for p in project.queryconf.get('queries', '').split(',')
                    if p != 'has_sense'
                ]
                for p in props:
                    for q in result_db.query(
                            '{}(?w1,?w2) ^ has_sense(?w2,?s2)'.format(p)):
                        unified_db << '{}({},{})'.format(p, q['?w1'], q['?w2'])
                        unified_db << 'has_sense({},{})'.format(
                            q['?w2'], q['?s2'])

                infstep.outdbs.append(unified_db)
            except NoConstraintsError:
                logger.debug('No properties found. Passing db...')
                infstep.outdbs.append(db.copy())
            except Exception:
                logger.error('Something went wrong')
                traceback.print_exc()

            pngs['PropExtraction - ' + str(i)] = get_cond_prob_png(
                project.queryconf.get('queries', ''),
                infstep.indbs,
                filename=self.name)
            infstep.png = pngs

        infstep.applied_settings = project.queryconf.config
        return [node]