def loadmln(self, config, mln=None): if config == 'query': config = self.queryconf elif config == 'learn': config = self.learnconf from pracmln.mln.base import parse_mln path = self.path if hasattr(self, 'path') else None return parse_mln(self.mlns[ifNone(mln, config['mln'])], projectpath=path, logic=config['logic'], grammar=config['grammar'])
def consistent(self, world, strict=False): ''' Checks for this variable if its assignment in the assignment `evidence` is consistent. :param evidence: the assignment to be checked. :param strict: if True, no unknown assignments are allowed, i.e. there must not be any ground atoms in the variable that do not have a truth value assigned. ''' total = 0 evstr = ','.join([ifNone(world[atom.idx], '?', str) for atom in self.gndatoms]) for gnatom in self.gndatoms: val = world[gnatom.idx] if strict and val is None: raise MRFValueException('Not all values have truth assignments: %s: %s' % (repr(self), evstr)) total += ifNone(val, 0) if not (total == 1 if strict else total in Interval('[0,1]')): raise MRFValueException('Invalid value of variable %s: %s' % (repr(self), evstr)) return True
def compose(self): p = '/'.join(self.path) if self.project is not None: p += ('/' if p else '') + self.project if self.file is not None: p += ':' + str(self.file) else: p += ifNone(self.file, '', lambda x: '/' + str(x)) return p
def noisyor(self, world): prod = 1.0 for lit in self.children: p = ifNone(lit(world), 1) if not lit.negated: factor = p else: factor = 1.0 - p prod *= 1.0 - factor return 1.0 - prod
def loaddb(self, mln, config, db=None): if db is None: if config == 'query': config = self.queryconf elif config == 'learn': config = self.learnconf else: raise Exception('Need a database name or config.') from pracmln.mln.database import parse_db path = self.path if hasattr(self, 'path') else None out(db) out(self.dbs[db]) return parse_db(mln, self.dbs[ifNone(db, config['db'])], ignore_unknown_preds=config['ignore_unknown_preds'], projectpath=path)
def __init__(self, mrf, simplify=False, unsatfailure=False, formulas=None, cache=auto, **params): self.mrf = mrf self.formulas = ifNone(formulas, list(self.mrf.formulas)) self.total_gf = 0 for f in self.formulas: self.total_gf += f.countgroundings(self.mrf) self.grounder = None self._cachesize = CACHE_SIZE if cache is auto else cache self._cache = None self.__cacheinit = False self.__cachecomplete = False self._params = params self.watch = StopWatch() self.simplify = simplify self.unsatfailure = unsatfailure
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 exists(self): ''' Checks if the file exists. ''' return os.path.exists( os.path.join(self.resolve_path(), ifNone(self.project, self.file)))
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 exists(self): ''' Checks if the file exists. ''' return os.path.exists(os.path.join(self.resolve_path(), ifNone(self.project, self.file)))
def set_config(self, conf): self.config = conf self.selected_grammar.set(ifNone(conf.get('grammar'), 'PRACGrammar')) self.selected_logic.set(ifNone(conf.get('logic'), 'FirstOrderLogic')) self.mln_container.selected_file.set(ifNone(conf.get('mln'), '')) if self.use_emln.get(): self.emln_container.selected_file.set(ifNone(conf.get('mln'), '')) self.db_container.selected_file.set(ifNone(conf.get('db'), "")) self.selected_method.set( ifNone(conf.get("method"), InferenceMethods.name('MCSAT'), transform=InferenceMethods.name)) self.multicore.set(ifNone(conf.get('multicore'), 0)) self.profile.set(ifNone(conf.get('profile'), 0)) self.params.set(ifNone(conf.get('params'), '')) self.use_emln.set(ifNone(conf.get('use_emln'), 0)) self.verbose.set(ifNone(conf.get('verbose'), 1)) self.ignore_unknown_preds.set( ifNone(conf.get('ignore_unknown_preds'), 0)) self.output_filename.set(ifNone(conf.get('output_filename'), '')) self.cwPreds.set(ifNone(conf.get('cw_preds'), '')) self.closed_world.set(ifNone(conf.get('cw'), 0)) self.save.set(ifNone(conf.get('save'), 0)) self.query.set(ifNone(conf.get('queries'), '')) self.onchange_cw()
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 __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 parse_mln(text, searchpaths=['.'], projectpath=None, logic='FirstOrderLogic', grammar='PRACGrammar', mln=None): ''' Reads an MLN from a stream providing a 'read' method. ''' dirs = [os.path.abspath(os.path.expandvars(os.path.expanduser(p))) for p in searchpaths] formulatemplates = [] text = str(text) if text == "": raise MLNParsingError("No MLN content to construct model from was given; must specify either file/list of files or content string!") # replace some meta-directives in comments text = re.compile(r'//\s*<group>\s*$', re.MULTILINE).sub("#group", text) text = re.compile(r'//\s*</group>\s*$', re.MULTILINE).sub("#group.", text) # remove comments text = stripComments(text) if mln is None: mln = MLN(logic, grammar) # read lines mln.hard_formulas = [] templateIdx2GroupIdx = {} inGroup = False idxGroup = -1 fixWeightOfNextFormula = False fuzzy = False pseudofuzzy = False uniquevars = None fixedWeightTemplateIndices = [] lines = text.split("\n") iLine = 0 while iLine < len(lines): line = lines[iLine] iLine += 1 line = line.strip() try: if len(line) == 0: continue # meta directives if line == "#group": idxGroup += 1 inGroup = True continue elif line == "#group.": inGroup = False continue elif line.startswith("#fixweight"): fixWeightOfNextFormula = True continue elif line.startswith('#fuzzy'): if not isinstance(mln.logic, FuzzyLogic): logger.warning('Fuzzy declarations are not supported in %s. Treated as a binary predicate.' % mln.logic.__class__.__name__) pseudofuzzy = True else: fuzzy = True continue elif line.startswith("#include"): filename = line[len("#include "):].strip() m = re.match(r'"(?P<filename>.+)"', filename) if m is not None: filename = m.group('filename') # if the path is relative, look for the respective file # relatively to all paths specified. Take the first file matching. if not mlnpath(filename).exists: includefilename = None for d in dirs: mlnp = '/'.join([d, filename]) if mlnpath(mlnp).exists: includefilename = mlnp break if includefilename is None: raise Exception('File not found: %s' % filename) else: includefilename = filename else: m = re.match(r'<(?P<filename>.+)>', filename) if m is not None: filename = m.group('filename') else: raise MLNParsingError('Malformed #include statement: %s' % line) if projectpath is None: raise MLNParsingError('No project specified: Cannot locate import from project: %s' % filename) includefilename = ':'.join([projectpath, filename]) logger.debug('Including file: "%s"' % includefilename) p = mlnpath(includefilename) parse_mln(text=mlnpath(includefilename).content, searchpaths=[p.resolve_path()]+dirs, projectpath=ifNone(p.project, projectpath, lambda x: '/'.join(p.path+[x])), logic=logic, grammar=grammar, mln=mln) continue elif line.startswith('#unique'): try: uniVars = re.search('#unique{(.+)}', line) uniVars = uniVars.groups()[0] uniVars = map(str.strip, uniVars.split(',')) uniquevars = uniVars except: raise MLNParsingError('Malformed #unique expression: "%s"' % line) continue elif line.startswith("#AdaptiveMLNDependency"): # declared as "#AdaptiveMLNDependency:pred:domain"; seems to be deprecated depPredicate, domain = line.split(":")[1:3] if hasattr(mln, 'AdaptiveDependencyMap'): if depPredicate in mln.AdaptiveDependencyMap: mln.AdaptiveDependencyMap[depPredicate].add(domain) else: mln.AdaptiveDependencyMap[depPredicate] = set([domain]) else: mln.AdaptiveDependencyMap = {depPredicate:set([domain])} continue # domain decl if '=' in line: # try normal domain definition parse = mln.logic.parse_domain(line) if parse is not None: domName, constants = parse domName = str(domName) constants = map(str, constants) if domName in mln.domains: logger.debug("Domain redefinition: Domain '%s' is being updated with values %s." % (domName, str(constants))) if domName not in mln.domains: mln.domains[domName] = [] mln.constant(domName, *constants) mln.domain_decls.append(line) continue # prior probability requirement if line.startswith("P("): m = re.match(r"P\((.*?)\)\s*=\s*([\.\de]+)", line) if m is None: raise MLNParsingError("Prior probability constraint formatted incorrectly: %s" % line) mln.prior(f=mln.logic.parse_formula(m.group(1)), p=float(m.group(2))) continue # posterior probability requirement/soft evidence if line.startswith("R(") or line.startswith("SE("): m = re.match(r"(?:R|SE)\((.*?)\)\s*=\s*([\.\de]+)", line) if m is None: raise MLNParsingError("Posterior probability constraint formatted incorrectly: %s" % line) mln.posterior(f=mln.logic.parse_formula(m.group(1)), p=float(m.group(2))) continue # variable definition if re.match(r'(\$\w+)\s*=(.+)', line): m = re.match(r'(\$\w+)\s*=(.+)', line) if m is None: raise MLNParsingError("Variable assigment malformed: %s" % line) mln.vars[m.group(1)] = "%s" % m.group(2).strip() continue # predicate decl or formula with weight else: isHard = False isPredDecl = False if line[ -1] == '.': # hard (without explicit weight -> determine later) isHard = True formula = line[:-1] else: # with weight # try predicate declaration isPredDecl = True try: pred = mln.logic.parse_predicate(line) except Exception, e: isPredDecl = False if isPredDecl: predname = str(pred[0]) argdoms = map(str, pred[1]) softmutex = False mutex = None for i, dom in enumerate(argdoms): if dom[-1] in ('!', '?'): if mutex is not None: raise Exception('More than one arguments are specified as (soft-)functional') if fuzzy: raise Exception('(Soft-)functional predicates must not be fuzzy.') mutex = i if dom[-1] == '?': softmutex = True argdoms = map(lambda x: x.strip('!?'), argdoms) pred = None if mutex is not None: if softmutex: pred = SoftFunctionalPredicate(predname, argdoms, mutex) else: pred = FunctionalPredicate(predname, argdoms, mutex) elif fuzzy: pred = FuzzyPredicate(predname, argdoms) fuzzy = False else: pred = Predicate(predname, argdoms) if pseudofuzzy: mln.fuzzypreds.append(predname) pseudofuzzy = False mln.predicate(pred) continue else: # formula (template) with weight or terminated by '.' if not isHard: spacepos = line.find(' ') weight = line[:spacepos] formula = line[spacepos:].strip() try: formula = mln.logic.parse_formula(formula) if isHard: weight = HARD # not set until instantiation when other weights are known idxTemplate = len(formulatemplates) formulatemplates.append(formula) fixweight = False if inGroup: templateIdx2GroupIdx[idxTemplate] = idxGroup if fixWeightOfNextFormula == True: fixWeightOfNextFormula = False fixweight = True fixedWeightTemplateIndices.append(idxTemplate) # expand predicate groups for variant in formula.expandgrouplits(): mln.formula(variant, weight=weight, fixweight=fixweight, unique_templvars=uniquevars) if uniquevars: uniquevars = None except ParseException, e: raise MLNParsingError("Error parsing formula '%s'\n" % formula) if fuzzy and not isPredDecl: raise Exception('"#fuzzy" decorator not allowed at this place: %s' % line)
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 parse_db(mln, content, ignore_unknown_preds=False, db=None, dirs=['.'], projectpath=None): ''' Reads one or more databases in a string representation and returns the respective Database objects. :param mln: the MLN object which should be used to load the database. :param content: the string representation of one or multiple ('---'-separated) databases :param ignore_unknown_preds: by default this function raises an Exception when it encounters a predicate in the DB that has not been declared in the associated MLN. ignore_unknown_preds=True simply ignores such predicates. :param db: the Database object that shall receive the facts stored in the new DB. If None, a new `Database` object will be created. ''' log = logging.getLogger('db') content = stripComments(content) allow_multiple = True if db is None: allow_multiple = True db = Database(mln, ignore_unknown_preds=ignore_unknown_preds) dbs = [] # expand domains with dbtext constants and save evidence for line, l in enumerate(content.split("\n")): l = l.strip() if l == '': continue # separator between independent databases elif l == '---' and not db.isempty(): dbs.append(db) db = Database(mln) continue # domain declaration elif "{" in l: domname, constants = db.mln.logic.parse_domain(l) domnames = [domname for _ in constants] # include elif l.startswith('#include'): filename = l[len("#include "):].strip() m = re.match(r'"(?P<filename>.+)"', filename) if m is not None: filename = m.group('filename') # if the path is relative, look for the respective file # relatively to all paths specified. Take the first file matching. if not mlnpath(filename).exists: includefilename = None for d in dirs: mlnp = '/'.join([d, filename]) if mlnpath(mlnp).exists: includefilename = mlnp break if includefilename is None: raise Exception('File not found: %s' % filename) else: includefilename = filename else: m = re.match(r'<(?P<filename>.+)>', filename) if m is not None: filename = m.group('filename') else: raise MLNParsingError('Malformed #include statement: %s' % line) if projectpath is None: raise MLNParsingError( 'No project specified: Cannot locate import from project: %s' % filename) includefilename = ':'.join([projectpath, filename]) logger.debug('Including file: "%s"' % includefilename) p = mlnpath(includefilename) dbs.extend( parse_db(content=mlnpath(includefilename).content, ignore_unknown_preds=ignore_unknown_preds, dirs=[p.resolve_path()] + dirs, projectpath=ifNone(p.project, projectpath, lambda x: '/'.join(p.path + [x])), mln=mln)) continue # valued evidence elif l[0] in "0123456789": s = l.find(" ") gndatom = l[s + 1:].replace(" ", "") value = float(l[:s]) if value < 0 or value > 1: raise Exception('Valued evidence must be in [0,1]') if gndatom in db.evidence: raise Exception("Duplicate soft evidence for '%s'" % gndatom) try: positive, predname, constants = mln.logic.parse_literal( gndatom ) # TODO Should we allow soft evidence on non-atoms here? (This assumes atoms) except NoSuchPredicateError, e: if ignore_unknown_preds: continue else: raise e domnames = mln.predicate(predname).argdoms db << (gndatom, value) # literal else: if l[0] == "?": raise Exception("Unknown literals not supported (%s)" % l) # this is an Alchemy feature try: true, predname, constants = mln.logic.parse_literal(l) except NoSuchPredicateError, e: if ignore_unknown_preds: continue else: raise e except Exception, e: traceback.print_exc() raise MLNParsingError('Error parsing line %d: %s (%s)' % (line + 1, l, e.message))
def parse_db(mln, content, ignore_unknown_preds=False, db=None, dirs=['.'], projectpath=None): ''' Reads one or more databases in a string representation and returns the respective Database objects. :param mln: the MLN object which should be used to load the database. :param content: the string representation of one or multiple ('---'-separated) databases :param ignore_unknown_preds: by default this function raises an Exception when it encounters a predicate in the DB that has not been declared in the associated MLN. ignore_unknown_preds=True simply ignores such predicates. :param db: the Database object that shall receive the facts stored in the new DB. If None, a new `Database` object will be created. ''' log = logging.getLogger('db') content = stripComments(content) allow_multiple = True if db is None: allow_multiple = True db = Database(mln, ignore_unknown_preds=ignore_unknown_preds) dbs = [] # expand domains with dbtext constants and save evidence for line, l in enumerate(content.split("\n")): l = l.strip() if l == '': continue # separator between independent databases elif l == '---' and not db.isempty(): dbs.append(db) db = Database(mln) continue # domain declaration elif "{" in l: domname, constants = db.mln.logic.parse_domain(l) domnames = [domname for _ in constants] # include elif l.startswith('#include'): filename = l[len("#include "):].strip() m = re.match(r'"(?P<filename>.+)"', filename) if m is not None: filename = m.group('filename') # if the path is relative, look for the respective file # relatively to all paths specified. Take the first file matching. if not mlnpath(filename).exists: includefilename = None for d in dirs: mlnp = '/'.join([d, filename]) if mlnpath(mlnp).exists: includefilename = mlnp break if includefilename is None: raise Exception('File not found: %s' % filename) else: includefilename = filename else: m = re.match(r'<(?P<filename>.+)>', filename) if m is not None: filename = m.group('filename') else: raise MLNParsingError('Malformed #include statement: %s' % line) if projectpath is None: raise MLNParsingError('No project specified: Cannot locate import from project: %s' % filename) includefilename = ':'.join([projectpath, filename]) logger.debug('Including file: "%s"' % includefilename) p = mlnpath(includefilename) dbs.extend(parse_db(content=mlnpath(includefilename).content, ignore_unknown_preds=ignore_unknown_preds, dirs=[p.resolve_path()]+dirs, projectpath=ifNone(p.project, projectpath, lambda x: '/'.join(p.path+[x])), mln=mln)) continue # valued evidence elif l[0] in "0123456789": s = l.find(" ") gndatom = l[s + 1:].replace(" ", "") value = float(l[:s]) if value < 0 or value > 1: raise Exception('Valued evidence must be in [0,1]') if gndatom in db.evidence: raise Exception("Duplicate soft evidence for '%s'" % gndatom) try: positive, predname, constants = mln.logic.parse_literal(gndatom) # TODO Should we allow soft evidence on non-atoms here? (This assumes atoms) except NoSuchPredicateError, e: if ignore_unknown_preds: continue else: raise e domnames = mln.predicate(predname).argdoms db << (gndatom, value) # literal else: if l[0] == "?": raise Exception("Unknown literals not supported (%s)" % l) # this is an Alchemy feature try: true, predname, constants = mln.logic.parse_literal(l) except NoSuchPredicateError, e: if ignore_unknown_preds: continue else: raise e except Exception, e: traceback.print_exc() raise MLNParsingError('Error parsing line %d: %s (%s)' % (line+1, l, e.message))
def parse_mln(text, searchpaths=['.'], projectpath=None, logic='FirstOrderLogic', grammar='PRACGrammar', mln=None): ''' Reads an MLN from a stream providing a 'read' method. ''' dirs = [ os.path.abspath(os.path.expandvars(os.path.expanduser(p))) for p in searchpaths ] formulatemplates = [] text = str(text) if text == "": raise MLNParsingError( "No MLN content to construct model from was given; must specify either file/list of files or content string!" ) # replace some meta-directives in comments text = re.compile(r'//\s*<group>\s*$', re.MULTILINE).sub("#group", text) text = re.compile(r'//\s*</group>\s*$', re.MULTILINE).sub("#group.", text) # remove comments text = stripComments(text) if mln is None: mln = MLN(logic, grammar) # read lines mln.hard_formulas = [] templateIdx2GroupIdx = {} inGroup = False idxGroup = -1 fixWeightOfNextFormula = False fuzzy = False pseudofuzzy = False uniquevars = None fixedWeightTemplateIndices = [] lines = text.split("\n") iLine = 0 while iLine < len(lines): line = lines[iLine] iLine += 1 line = line.strip() try: if len(line) == 0: continue # meta directives if line == "#group": idxGroup += 1 inGroup = True continue elif line == "#group.": inGroup = False continue elif line.startswith("#fixweight"): fixWeightOfNextFormula = True continue elif line.startswith('#fuzzy'): if not isinstance(mln.logic, FuzzyLogic): logger.warning( 'Fuzzy declarations are not supported in %s. Treated as a binary predicate.' % mln.logic.__class__.__name__) pseudofuzzy = True else: fuzzy = True continue elif line.startswith("#include"): filename = line[len("#include "):].strip() m = re.match(r'"(?P<filename>.+)"', filename) if m is not None: filename = m.group('filename') # if the path is relative, look for the respective file # relatively to all paths specified. Take the first file matching. if not mlnpath(filename).exists: includefilename = None for d in dirs: mlnp = '/'.join([d, filename]) if mlnpath(mlnp).exists: includefilename = mlnp break if includefilename is None: raise Exception('File not found: %s' % filename) else: includefilename = filename else: m = re.match(r'<(?P<filename>.+)>', filename) if m is not None: filename = m.group('filename') else: raise MLNParsingError( 'Malformed #include statement: %s' % line) if projectpath is None: raise MLNParsingError( 'No project specified: Cannot locate import from project: %s' % filename) includefilename = ':'.join([projectpath, filename]) logger.debug('Including file: "%s"' % includefilename) p = mlnpath(includefilename) parse_mln(text=mlnpath(includefilename).content, searchpaths=[p.resolve_path()] + dirs, projectpath=ifNone(p.project, projectpath, lambda x: '/'.join(p.path + [x])), logic=logic, grammar=grammar, mln=mln) continue elif line.startswith('#unique'): try: uniVars = re.search('#unique{(.+)}', line) uniVars = uniVars.groups()[0] uniVars = map(str.strip, uniVars.split(',')) uniquevars = uniVars except: raise MLNParsingError( 'Malformed #unique expression: "%s"' % line) continue elif line.startswith( "#AdaptiveMLNDependency" ): # declared as "#AdaptiveMLNDependency:pred:domain"; seems to be deprecated depPredicate, domain = line.split(":")[1:3] if hasattr(mln, 'AdaptiveDependencyMap'): if depPredicate in mln.AdaptiveDependencyMap: mln.AdaptiveDependencyMap[depPredicate].add(domain) else: mln.AdaptiveDependencyMap[depPredicate] = set([domain]) else: mln.AdaptiveDependencyMap = {depPredicate: set([domain])} continue # domain decl if '=' in line: # try normal domain definition parse = mln.logic.parse_domain(line) if parse is not None: domName, constants = parse domName = str(domName) constants = map(str, constants) if domName in mln.domains: logger.debug( "Domain redefinition: Domain '%s' is being updated with values %s." % (domName, str(constants))) if domName not in mln.domains: mln.domains[domName] = [] mln.constant(domName, *constants) mln.domain_decls.append(line) continue # prior probability requirement if line.startswith("P("): m = re.match(r"P\((.*?)\)\s*=\s*([\.\de]+)", line) if m is None: raise MLNParsingError( "Prior probability constraint formatted incorrectly: %s" % line) mln.prior(f=mln.logic.parse_formula(m.group(1)), p=float(m.group(2))) continue # posterior probability requirement/soft evidence if line.startswith("R(") or line.startswith("SE("): m = re.match(r"(?:R|SE)\((.*?)\)\s*=\s*([\.\de]+)", line) if m is None: raise MLNParsingError( "Posterior probability constraint formatted incorrectly: %s" % line) mln.posterior(f=mln.logic.parse_formula(m.group(1)), p=float(m.group(2))) continue # variable definition if re.match(r'(\$\w+)\s*=(.+)', line): m = re.match(r'(\$\w+)\s*=(.+)', line) if m is None: raise MLNParsingError("Variable assigment malformed: %s" % line) mln.vars[m.group(1)] = "%s" % m.group(2).strip() continue # predicate decl or formula with weight else: isHard = False isPredDecl = False if line[-1] == '.': # hard (without explicit weight -> determine later) isHard = True formula = line[:-1] else: # with weight # try predicate declaration isPredDecl = True try: pred = mln.logic.parse_predicate(line) except Exception, e: isPredDecl = False if isPredDecl: predname = str(pred[0]) argdoms = map(str, pred[1]) softmutex = False mutex = None for i, dom in enumerate(argdoms): if dom[-1] in ('!', '?'): if mutex is not None: raise Exception( 'More than one arguments are specified as (soft-)functional' ) if fuzzy: raise Exception( '(Soft-)functional predicates must not be fuzzy.' ) mutex = i if dom[-1] == '?': softmutex = True argdoms = map(lambda x: x.strip('!?'), argdoms) pred = None if mutex is not None: if softmutex: pred = SoftFunctionalPredicate( predname, argdoms, mutex) else: pred = FunctionalPredicate(predname, argdoms, mutex) elif fuzzy: pred = FuzzyPredicate(predname, argdoms) fuzzy = False else: pred = Predicate(predname, argdoms) if pseudofuzzy: mln.fuzzypreds.append(predname) pseudofuzzy = False mln.predicate(pred) continue else: # formula (template) with weight or terminated by '.' if not isHard: spacepos = line.find(' ') weight = line[:spacepos] formula = line[spacepos:].strip() try: formula = mln.logic.parse_formula(formula) if isHard: weight = HARD # not set until instantiation when other weights are known idxTemplate = len(formulatemplates) formulatemplates.append(formula) fixweight = False if inGroup: templateIdx2GroupIdx[idxTemplate] = idxGroup if fixWeightOfNextFormula == True: fixWeightOfNextFormula = False fixweight = True fixedWeightTemplateIndices.append(idxTemplate) # expand predicate groups for variant in formula.expandgrouplits(): mln.formula(variant, weight=weight, fixweight=fixweight, unique_templvars=uniquevars) if uniquevars: uniquevars = None except ParseException, e: raise MLNParsingError("Error parsing formula '%s'\n" % formula) if fuzzy and not isPredDecl: raise Exception( '"#fuzzy" decorator not allowed at this place: %s' % line)