Ejemplo n.º 1
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))
Ejemplo n.º 2
0
from pracmln.logic.fol import FirstOrderLogic
from pracmln.praclog import logging
from multiprocessing import Pool
from pracmln.utils.multicore import with_tracing
from pracmln.mln.mrfvars import FuzzyVariable
from pracmln.mln.constants import auto, HARD
from pracmln.mln.errors import SatisfiabilityException
from pracmln.mln.grounding.fastconj import FastConjunctionGrounding
from pracmln.mln.util import Interval, ProgressBar, colorize
from numpy.ma.core import exp
from pracmln.mln.inference.infer import Inference
from pracmln.logic.common import Logic


logger = logging.getLogger(__name__)

# this readonly global is for multiprocessing to exploit copy-on-write
# on linux systems
global_enumAsk = None


def eval_queries(world):
    """
    Evaluates the queries given a possible world.
    """
    numerators = [0] * len(global_enumAsk.queries)
    denominator = 0
    expsum = 0
    for gf in global_enumAsk.grounder.itergroundings():
        if global_enumAsk.soft_evidence_formula(gf):
Ejemplo n.º 3
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))