Exemplo n.º 1
0
    def setUp(self):
        #
        # db, store
        #

        db_url = 'sqlite:///foo.db'

        # setup compiler + environment

        self.db = LogicDB(db_url)
        self.parser = PrologParser(self.db)
        self.rt = PrologRuntime(self.db)

        self.db.clear_module(UNITTEST_MODULE)
Exemplo n.º 2
0
class TestEmbeddings (unittest.TestCase):

    def setUp(self):

        #
        # db, store
        #

        db_url = 'sqlite:///foo.db'

        # setup compiler + environment

        self.db     = LogicDB(db_url, echo=False)
        self.parser = PrologParser(self.db)
        self.rt     = PrologRuntime(self.db)

        # self.rt.set_trace(True)

        self.db.clear_module(UNITTEST_MODULE)

    def tearDown(self):
        self.db.close()

    #@unittest.skip("temporarily disabled")
    def test_custom_builtins(self):

        global recorded_moves

        self.parser.compile_file('samples/hanoi2.pl', UNITTEST_MODULE)

        clause = self.parser.parse_line_clause_body('move(3,left,right,center)')
        logging.debug('clause: %s' % clause)

        # register our custom builtin
        recorded_moves = []
        self.rt.register_builtin('record_move', record_move)

        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual (len(solutions), 1)

        self.assertEqual (len(recorded_moves), 7)

    #@unittest.skip("temporarily disabled")
    def test_custom_builtin_multiple_bindings(self):

        self.rt.register_builtin('multi_binder', multi_binder)

        clause = self.parser.parse_line_clause_body('multi_binder(X,Y)')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual (len(solutions), 4)

    def _custom_directive(self, db, module_name, clause, user_data):
        # logging.debug('custom_directive has been run')
        self.assertEqual (len(clause.head.args), 3)
        self.assertEqual (unicode(clause.head.args[0]), u'abc')
        self.assertEqual (clause.head.args[1].f, 42)
        self.assertEqual (clause.head.args[2].s, u'foo')

        self.directive_mark = True

    #@unittest.skip("temporarily disabled")
    def test_custom_directives(self):

        self.parser.register_directive('custom_directive', self._custom_directive, None)
        self.directive_mark = False

        # self.parser.compile_file('samples/dir.pl', UNITTEST_MODULE)
        clauses = self.parser.parse_line_clauses('custom_directive(abc, 42, \'foo\').')

        self.assertEqual (self.directive_mark, True)
Exemplo n.º 3
0
class TestZamiaProlog(unittest.TestCase):
    def setUp(self):

        #
        # db, store
        #

        db_url = 'sqlite:///foo.db'

        # setup compiler + environment

        self.db = LogicDB(db_url)
        self.parser = PrologParser(self.db)
        self.rt = PrologRuntime(self.db)

        self.db.clear_module(UNITTEST_MODULE)

    def tearDown(self):
        self.db.close()

    # @unittest.skip("temporarily disabled")
    def test_parser(self):

        error_catched = False

        try:

            clause = self.parser.parse_line_clause_body(
                'say_eoa(en, "Kids are the best')
            logging.debug('clause: %s' % clause)
        except PrologError as e:
            error_catched = True

        self.assertEqual(error_catched, True)

    # @unittest.skip("temporarily disabled")
    def test_parse_line_clauses(self):

        line = 'time_span(TE) :- date_time_stamp(+(D, 1.0)).'

        tree = self.parser.parse_line_clauses(line)
        logging.debug(unicode(tree[0].body))
        self.assertEqual(tree[0].body.name, 'date_time_stamp')
        self.assertEqual(tree[0].head.name, 'time_span')

        line = 'time_span(tomorrow, TS, TE) :- context(currentTime, T), stamp_date_time(T, date(Y, M, D, H, Mn, S, "local")), date_time_stamp(date(Y, M, +(D, 1.0), 0.0, 0.0, 0.0, "local"), TS), date_time_stamp(date(Y, M, +(D, 1.0), 23.0, 59.0, 59.0, "local"), TE).'

        tree = self.parser.parse_line_clauses(line)
        logging.debug(unicode(tree[0].body))
        self.assertEqual(tree[0].head.name, 'time_span')
        self.assertEqual(tree[0].body.name, 'and')
        self.assertEqual(len(tree[0].body.args), 4)

    # @unittest.skip("temporarily disabled")
    def test_kb1(self):

        self.assertEqual(len(self.db.lookup('party', 0)), 0)

        self.parser.compile_file('samples/kb1.pl', UNITTEST_MODULE)

        self.assertEqual(len(self.db.lookup('party', 0)), 1)

        clause = self.parser.parse_line_clause_body('woman(X)')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 3)

        clause = self.parser.parse_line_clause_body('party')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)

        clause = self.parser.parse_line_clause_body('woman(fred)')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 0)

    # @unittest.skip("temporarily disabled")
    def test_parse_to_string(self):

        line = u'time_span(c, X, Y) :- p1(c), p2(X, Y); p3(c); p4.'

        line2 = u'time_span(c, X, Y) :- or(and(p1(c), p2(X, Y)), p3(c), p4).'

        tree = self.parser.parse_line_clauses(line)
        logging.debug(unicode(tree[0].body))
        self.assertEqual(unicode(tree[0]), line2)

    # @unittest.skip("temporarily disabled")
    def test_or(self):

        self.parser.compile_file('samples/or_test.pl', UNITTEST_MODULE)

        # self.rt.set_trace(True)

        solutions = self.rt.search_predicate('woman', ['X'])
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 3)

        solutions = self.rt.search_predicate('human', ['X'])
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 8)

    def test_or_toplevel(self):

        self.parser.compile_file('samples/or_test.pl', UNITTEST_MODULE)

        clause = self.parser.parse_line_clause_body(
            u'woman(mary); woman(jody)')
        logging.debug(u'clause: %s' % clause)
        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)

    def test_or_bindings(self):

        clause = self.parser.parse_line_clause_body(
            u'S is "a", or(str_append(S, "b"), str_append(S, "c"))')
        logging.debug(u'clause: %s' % clause)
        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 2)
        self.assertEqual(solutions[0]['S'].s, "ab")
        self.assertEqual(solutions[1]['S'].s, "ac")

        clause = self.parser.parse_line_clause_body(u'X is 42; X is 23')
        logging.debug(u'clause: %s' % clause)
        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 2)

    def test_var_access(self):

        # set var X from python:

        clause = self.parser.parse_line_clause_body('Y is X*X')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause, {'X': NumberLiteral(3)})
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)

        # access prolog result Y from python:

        self.assertEqual(solutions[0]['Y'].f, 9)

    def test_list_equality(self):

        clause = self.parser.parse_line_clause_body('[] is []')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause, {})
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)

        clause = self.parser.parse_line_clause_body('[1] is []')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause, {})
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 0)

        clause = self.parser.parse_line_clause_body('909442800.0 is []')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause, {})
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 0)

        clause = self.parser.parse_line_clause_body('[1,2,3] = [1,2,3]')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause, {})
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)

        clause = self.parser.parse_line_clause_body('[1,2,3] \\= [1,2,3,4,5]')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause, {})
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)

    def test_is(self):

        clause = self.parser.parse_line_clause_body(
            'GENDER is "blubber", GENDER is wde:Male')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause, {})
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 0)

    # @unittest.skip("temporarily disabled")
    def test_list_eval(self):

        clause = self.parser.parse_line_clause_body(
            'X is 23, Z is 42, Y is [X, U, Z].')
        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)
        self.assertEqual(len(solutions[0]['Y'].l), 3)
        self.assertEqual(solutions[0]['Y'].l[0].f, 23.0)
        self.assertTrue(isinstance(solutions[0]['Y'].l[1], Variable))
        self.assertEqual(solutions[0]['Y'].l[2].f, 42.0)

    def test_clauses_location(self):

        # this will trigger a runtime error since a(Y) is a predicate,
        # but format_str requires a literal arg
        clause = self.parser.parse_line_clause_body(
            'X is format_str("%s", a(Y))')
        logging.debug('clause: %s' % clause)
        try:
            solutions = self.rt.search(clause, {})
            self.fail("we should have seen a runtime error here")
        except PrologRuntimeError as e:
            self.assertEqual(e.location.line, 1)
            self.assertEqual(e.location.col, 29)

    def test_cut(self):

        self.parser.compile_file('samples/cut_test.pl', UNITTEST_MODULE)

        # self.rt.set_trace(True)

        clause = self.parser.parse_line_clause_body(u'bar(R, X)')
        logging.debug(u'clause: %s' % clause)
        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 4)
        self.assertEqual(solutions[0]['R'].s, "one")
        self.assertEqual(solutions[1]['R'].s, "two")
        self.assertEqual(solutions[2]['R'].s, "many")
        self.assertEqual(solutions[3]['R'].s, "many")

    # @unittest.skip("temporarily disabled")
    def test_anon_var(self):

        clause = self.parser.parse_line_clause_body('_ is 23, _ is 42.')
        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)

    def test_nonvar(self):

        clause = self.parser.parse_line_clause_body(u'S is "a", nonvar(S)')
        logging.debug(u'clause: %s' % clause)
        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)

        clause = self.parser.parse_line_clause_body(u'nonvar(S)')
        logging.debug(u'clause: %s' % clause)
        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 0)

    def test_unify_pseudo(self):

        clause = self.parser.parse_line_clause_body(
            u'C is foo, assertz(mem(foo, bar)), if var(C:mem|bar) then C:mem|bar := 23 endif, X := C:mem|bar'
        )
        logging.debug(u'clause: %s' % clause)
        # self.rt.set_trace(True)
        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)
        self.assertEqual(solutions[0]['X'].f, 23.0)
Exemplo n.º 4
0
 def __init__(self, kernal):
     self.kernal = kernal
     self.rt = PrologRuntime(kernal.db)
     super(AIPrologParser, self).__init__(kernal.db)
Exemplo n.º 5
0
class AIPrologParser(PrologParser):
    def __init__(self, kernal):
        self.kernal = kernal
        self.rt = PrologRuntime(kernal.db)
        super(AIPrologParser, self).__init__(kernal.db)

    def compile_file(self, filename, module_name, clear_module=False):

        # quick source line count for progress output below

        self.linecnt = 1
        with codecs.open(filename, encoding='utf-8', errors='ignore',
                         mode='r') as f:
            while f.readline():
                self.linecnt += 1
        logging.info("%s: %d lines." % (filename, self.linecnt))

        # remove old predicates of this module from db
        if clear_module:
            self.clear_module(module_name, db)

        # (re-) init

        self.ds = []
        self.ts = []
        self.ner = {}
        self.named_macros = {}
        self.lang = 'en'
        self.train_prio = 0
        self.train_prefixes = []

        # actual parsing starts here

        with codecs.open(filename, encoding='utf-8', errors='ignore',
                         mode='r') as f:
            self.start(f,
                       filename,
                       module_name=module_name,
                       linecnt=self.linecnt)

            while self.cur_sym != SYM_EOF:
                clauses = self.clause()

                for clause in clauses:
                    logging.debug(u"%7d / %7d (%3d%%) > %s" %
                                  (self.cur_line, self.linecnt, self.cur_line *
                                   100 / self.linecnt, unicode(clause)))

                    if clause.head.name == 'train':
                        self.extract_training_data(clause)
                    elif clause.head.name == 'train_priority':
                        self.extract_training_priority(clause)
                    elif clause.head.name == 'train_prefix':
                        self.extract_training_prefixes(clause)
                    elif clause.head.name == 'test':
                        self.extract_test_data(clause)
                    elif clause.head.name == 'train_ner':
                        self.extract_ner_training(clause)

                    else:
                        self.db.store(module_name, clause)

                if self.comment_pred:

                    self.db.store_doc(module_name, self.comment_pred,
                                      self.comment)

                    self.comment_pred = None
                    self.comment = ''

        self.db.commit()

        logging.info("Compilation succeeded.")

        return self.ds, self.ts, self.ner

    ###############################################
    #
    # training data extraction
    #
    ###############################################

    def fetch_named_macro(self, lang, name):

        # if name == 'firstname':
        #     import pdb; pdb.set_trace()

        if not lang in self.named_macros:
            self.named_macros[lang] = {}

        if name in self.named_macros[lang]:
            return self.named_macros[lang][name]

        # extract variable binding from prolog macro, if any

        macros = self.db.lookup('macro', arity=-1)

        for macro in macros:
            if len(macro.head.args) < 2:
                continue
            if not isinstance(macro.head.args[0],
                              Predicate) or macro.head.args[0].name != lang:
                continue
            if not isinstance(macro.head.args[1],
                              Predicate) or macro.head.args[1].name != name:
                continue

            args = [lang, name]
            for a in macro.head.args[2:]:
                if not isinstance(a, Variable):
                    self.report_error(u'invalid macro %s encountered.' %
                                      unicode(macro))
                args.append(a.name)

            solutions = self.rt.search_predicate('macro', args)

            if solutions:
                self.named_macros[lang][name] = solutions
                return solutions

            break

        return None

    def _expand_macros(self, txt):

        logging.debug(u"expand macros  : %s" % txt)

        implicit_macros = {}

        txt2 = ''

        i = 0
        while i < len(txt):

            if txt[i] == '(':

                j = txt[i + 1:].find(')')
                if j < 0:
                    self.report_error(') missing')
                j += i

                # extract macro

                macro_s = txt[i + 1:j + 1]

                # print "macro_s: %s" % macro_s

                macro_name = 'MACRO_%d' % len(implicit_macros)

                implicit_macros[macro_name] = []
                for s in macro_s.split('|'):
                    sub_parts = tokenize(s,
                                         lang=self.lang,
                                         keep_punctuation=False)
                    implicit_macros[macro_name].append({'W': sub_parts})

                txt2 += '{' + macro_name + ':W}'

                i = j + 2
            else:

                txt2 += txt[i]
                i += 1

        logging.debug("implicit macros: %s" % repr(implicit_macros))
        logging.debug("txt2           : %s" % txt2)

        parts = []
        for p1 in txt2.split('{'):
            for p2 in p1.split('}'):
                parts.append(p2)

        done = []

        todo = [(parts, 0, [], {}, {})]

        while len(todo) > 0:

            parts1, cnt, r, mpos, macro_rs = todo.pop()

            if cnt >= len(parts1):
                done.append((r, mpos))
                continue

            p1 = parts1[cnt]

            if cnt % 2 == 1:

                sub_parts = p1.split(':')

                if len(sub_parts) != 2:
                    self.report_error('syntax error in macro call %s' %
                                      repr(p1))

                name = sub_parts[0]

                if name == 'empty':
                    todo.append(
                        (parts, cnt + 1, copy(r), mpos, copy(macro_rs)))
                else:

                    vn = sub_parts[1]

                    if name in macro_rs:
                        macro = [macro_rs[name]]
                    else:
                        macro = self.fetch_named_macro(self.lang, name)
                        if not macro:
                            macro = implicit_macros.get(name, None)
                        if not macro:
                            self.report_error('unknown macro "%s"[%s] called' %
                                              (name, self.lang))

                    for r3 in macro:
                        r1 = copy(r)
                        mpos1 = copy(mpos)
                        macro_rs1 = copy(macro_rs)

                        macro_rs1[name] = r3

                        # take care of multiple invocactions of the same macro

                        mpnn = 0
                        while True:
                            mpn = '%s_%d_start' % (name, mpnn)
                            if not mpn in mpos1:
                                break
                            mpnn += 1

                        mpos1['%s_%d_start' % (name, mpnn)] = len(r1)
                        s3 = r3[vn]
                        if isinstance(s3, StringLiteral):
                            s3 = tokenize(s3.s, lang=self.lang)
                            r3[vn] = s3
                        r1.extend(r3[vn])
                        mpos1['%s_%d_end' % (name, mpnn)] = len(r1)

                        for vn3 in r3:
                            mpos1['%s_%d_%s' %
                                  (name, mpnn, vn3.lower())] = r3[vn3]

                        todo.append((parts, cnt + 1, r1, mpos1, macro_rs1))

                        # if name == 'home_locations':
                        #     import pdb; pdb.set_trace()

            else:

                sub_parts = tokenize(p1,
                                     lang=self.lang,
                                     keep_punctuation=False)

                r = copy(r)
                r.extend(sub_parts)

                todo.append((parts, cnt + 1, r, mpos, macro_rs))

        return done

    def _token_positions(self, a, mpos):

        if isinstance(a, Predicate):

            if a.name == 'tstart':

                if len(a.args) == 1:
                    occ = 0
                    tname = a.args[0]
                elif len(a.args) == 2:
                    occ = int(a.args[1].f)
                    tname = a.args[0]
                else:
                    self.report_error(
                        'tstart: one or two args expected, found "%s" instead'
                        % unicode(a))

                k = '%s_%d_start' % (tname, occ)
                if not k in mpos:
                    self.report_error('tstart: could not determine "%s"' %
                                      unicode(a))

                return NumberLiteral(mpos[k])

            elif a.name == 'tend':

                if len(a.args) == 1:
                    occ = 0
                    tname = a.args[0]
                elif len(a.args) == 2:
                    occ = int(a.args[1].f)
                    tname = a.args[0]
                else:
                    self.report_error(
                        'tend: one or two args expected, found "%s" instead' %
                        unicode(a))

                k = '%s_%d_end' % (tname, occ)
                if not k in mpos:
                    self.report_error('tend: could not determine "%s"' %
                                      unicode(a))

                return NumberLiteral(mpos[k])

            elif a.name == 'mvar':

                # import pdb; pdb.set_trace()
                if len(a.args) == 2:
                    tname = a.args[0]
                    vname = a.args[1]
                    occ = 0
                elif len(a.args) == 3:
                    tname = a.args[0]
                    vname = a.args[1]
                    occ = int(a.args[2].f)
                else:
                    self.report_error(
                        'mvar: one or two args expected, found "%s" instead' %
                        unicode(a))

                k = '%s_%d_%s' % (tname, occ, vname)
                if not k in mpos:
                    self.report_error('mvar: could not determine "%s"' %
                                      unicode(a))

                return mpos[k]

            else:

                margs = []
                for a2 in a.args:
                    margs.append(self._token_positions(a2, mpos))

                return Predicate(a.name, margs)

        elif isinstance(a, ListLiteral):

            l2 = []
            for a2 in a.l:
                l2.append(self._token_positions(a2, mpos))

            return ListLiteral(l2)

        return a

    def _generate_training_code(self, and_args, mpos, and_mode=True):

        # import pdb; pdb.set_trace()

        code = []

        for a in and_args:

            if isinstance(a, StringLiteral):

                # code.append(Predicate('r_bor', [ Variable('C') ]))
                # code.append(u'r_bor(C)')

                parts = []
                for p1 in a.s.split('{'):
                    for p2 in p1.split('}'):
                        parts.append(p2)

                if not and_mode:
                    code.append(u'and(')

                cnt = 0
                for part in parts:

                    if cnt % 2 == 1:

                        subparts = part.split(',')

                        if len(subparts) != 2:
                            self.report_error(
                                'variable string "%s" not recognized .' %
                                repr(part))

                        var_s = subparts[0]
                        fmt_s = subparts[1]

                        code.append(
                            unicode(
                                Predicate('r_sayv', [
                                    Variable('C'),
                                    Variable(var_s),
                                    Predicate(fmt_s)
                                ])))

                    else:

                        for t in tokenize(part,
                                          lang=self.lang,
                                          keep_punctuation=True):
                            code.append(
                                unicode(
                                    Predicate(
                                        'r_say',
                                        [Variable('C'),
                                         StringLiteral(t)])))
                    cnt += 1

                if not and_mode:
                    code.append(u')')

            elif isinstance(a, Predicate):

                if a.name == 'or':

                    code.append(u'or(')

                    code.extend(
                        self._generate_training_code(a.args,
                                                     mpos,
                                                     and_mode=False))

                    code.append(u')')

                elif a.name == 'and':

                    code.append(u'and(')

                    code.extend(self._generate_training_code(a.args, mpos))

                    code.append(u')')

                else:

                    code.append(unicode(self._token_positions(a, mpos)))

            else:
                code.append(unicode(self._token_positions(a, mpos)))

        return code

    def _extract_context(self, a):
        if len(a.args) != 2:
            self.report_error('context: 2 args expected.')

        a0 = a.args[0]
        if isinstance(a0, StringLiteral):
            a0 = a0.s
        elif isinstance(a0, Predicate):
            a0 = a0.name
        else:
            self.report_error(
                'context: string or constant expected, %s found instead.' %
                repr(a0))
        a1 = a.args[1]
        if isinstance(a1, StringLiteral):
            a1 = a1.s
        elif isinstance(a1, Predicate):
            a1 = a1.name
        else:
            self.report_error(
                'context: string or constant expected, %s found instead.' %
                repr(a1))

        return [a0, a1]

    def extract_training_data(self, clause):

        if len(clause.head.args) != 1:
            self.report_error('train: single language argument expected')
        self.lang = clause.head.args[0].name

        if not clause.body or clause.body.name != 'and':
            self.report_error('train: flat (and) body expected')

        # filter out contexts, input line

        context_sets = []
        inps = []
        code = []
        for a in clause.body.args:

            if not inps:
                if isinstance(a, StringLiteral):
                    inps.append(a.s)
                    continue

                if not isinstance(a, Predicate):
                    self.report_error(
                        'input string(s) or context specifier expected.')
                    continue

                if a.name == 'context':
                    if len(context_sets) > 1:
                        self.report_error(
                            'more than one context specifier found.')
                    elif not context_sets:
                        context_sets.append([])

                    context_sets[0].append(self._extract_context(a))

                elif a.name == 'or':
                    if isinstance(a.args[0], StringLiteral):
                        for a1 in a.args:
                            if not isinstance(a1, StringLiteral):
                                self.report_error('input string(s) expected.')
                            inps.append(a1.s)

                    elif isinstance(a.args[0], Predicate):
                        for a1 in a.args:
                            if not isinstance(a1, Predicate):
                                self.report_error(
                                    'context specifier expected.')

                            if a1.name == 'context':
                                context_sets.append(
                                    [self._extract_context(a1)])
                            elif a1.name == 'and':
                                context_sets.append([])
                                for a2 in a1.args:
                                    if not isinstance(
                                            a2,
                                            Predicate) or a2.name != 'context':
                                        self.report_error(
                                            'context specifier expected.')
                                    context_sets[len(context_sets) - 1].append(
                                        self._extract_context(a2))
                            elif a1.name == 'true':
                                context_sets.append([])
                            else:
                                self.report_error(
                                    'context specifier expected.')
                    else:
                        self.report_error(
                            'input string(s) or context specifier expected.')

                else:
                    self.report_error(
                        'input string(s) or context specifier expected.')

                continue

            code.append(a)

        if not inps:
            self.report_error('train: no input string(s).')

        if not context_sets:
            context_sets.append([])

        if len(code) == 0:
            self.report_error('train: no code.')

        prefixes = self.train_prefixes if self.train_prefixes else [u'']

        # import pdb; pdb.set_trace()
        for prefix in prefixes:

            for inp in inps:

                pinp = prefix + inp

                for d, mpos in self._expand_macros(pinp):

                    r = self._generate_training_code(code, mpos)

                    logging.debug('%s -> %s' % (repr(d), repr(r)))

                    for contexts in context_sets:

                        self.ds.append(
                            (self.lang, contexts, d, r, clause.location.fn,
                             clause.location.line, clause.location.col,
                             self.train_prio))

                        if len(self.ds) % 100 == 0:
                            logging.info(
                                '%6d training samples extracted so far...' %
                                len(self.ds))

    def extract_training_priority(self, clause):

        # import pdb; pdb.set_trace()

        if len(clause.head.args) != 1:
            self.report_error(
                'train_priority: single priority argument expected')

        self.train_prio = self.rt.prolog_get_int(clause.head.args[0], {},
                                                 clause.location)

    def extract_training_prefixes(self, clause):

        if len(clause.head.args) != 1:
            self.report_error(
                'train_prefixes: single prefix argument expected')

        if not clause.body:
            prefix = self.rt.prolog_get_string(clause.head.args[0], {},
                                               clause.location)
            self.train_prefixes.append(prefix)
            return

        # import pdb; pdb.set_trace()

        v = self.rt.prolog_get_variable(clause.head.args[0], {},
                                        clause.location)

        solutions = self.rt.search(clause, env={})
        for s in solutions:
            prefix = s[v].s
            self.train_prefixes.append(prefix)

    def extract_test_data(self, clause):

        if len(clause.head.args) != 2:
            self.report_error('test: 2 arguments (lang, test_name) expected')

        self.lang = clause.head.args[0].name
        test_name = clause.head.args[1].name

        if not clause.body or clause.body.name != 'and':
            self.report_error('test: flat (and) body expected')

        prep = []
        rounds = []

        inp = None
        resp = None
        actions = []
        cnt = 0

        for a in clause.body.args:

            # import pdb; pdb.set_trace()
            if isinstance(a, StringLiteral):

                if cnt % 2 == 0:
                    if inp:
                        rounds.append((inp, resp, actions))
                    inp = tokenize(a.s, lang=self.lang, keep_punctuation=False)
                    resp = None
                    actions = []

                else:
                    resp = tokenize(a.s,
                                    lang=self.lang,
                                    keep_punctuation=False)

                cnt += 1
            else:

                if not inp:
                    prep.append(a)
                else:
                    if not isinstance(a, Predicate) or a.name != 'action':
                        self.report_error(
                            'only action predicates allowed here.')
                    actions.append(list(map(lambda x: unicode(x), a.args)))

        if inp:
            rounds.append((inp, resp, actions))

        self.ts.append((test_name, self.lang, prep, rounds, clause.location.fn,
                        clause.location.line, clause.location.col))

    def extract_ner_training(self, clause):

        if len(clause.head.args) != 4:
            self.report_error(
                'train_ner: 4 arguments (+Lang, +Class, -Entity, -Label) expected'
            )

        arg_Lang = clause.head.args[0].name
        arg_Cls = clause.head.args[1].name
        arg_Entity = clause.head.args[2].name
        arg_Label = clause.head.args[3].name

        logging.info('computing NER training data for %s [%s] ...' %
                     (arg_Cls, arg_Lang))

        # cProfile.run('self.rt.search(clause)', 'mestats')
        # self.rt.set_trace(True)
        solutions = self.rt.search(clause)

        if not arg_Lang in self.ner:
            self.ner[arg_Lang] = {}

        if not arg_Cls in self.ner[arg_Lang]:
            self.ner[arg_Lang][arg_Cls] = {}

        ner = self.ner[arg_Lang][arg_Cls]

        cnt = 0
        for s in solutions:
            entity = s[arg_Entity].name
            label = s[arg_Label].s

            ner[entity] = label
            cnt += 1

        logging.info(
            'computing NER training data for %s [%s] ... done. %d entries processed.'
            % (arg_Cls, arg_Lang, cnt))
Exemplo n.º 6
0
 def __init__(self, db):
     self.rt = PrologRuntime(db)
     super(AIPrologParser, self).__init__(db)
Exemplo n.º 7
0
class TestBuiltins(unittest.TestCase):
    def setUp(self):
        #
        # db, store
        #

        db_url = 'sqlite:///foo.db'

        # setup compiler + environment

        self.db = LogicDB(db_url)
        self.parser = PrologParser(self.db)
        self.rt = PrologRuntime(self.db)

        self.db.clear_module(UNITTEST_MODULE)

    def tearDown(self):
        self.db.close()

    # @unittest.skip("temporarily disabled")
    def test_hanoi1(self):

        self.parser.compile_file('samples/hanoi1.pl', UNITTEST_MODULE)

        clause = self.parser.parse_line_clause_body(
            'move(3,left,right,center)')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause)
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)

    # @unittest.skip("temporarily disabled")
    def test_lists(self):

        clause = self.parser.parse_line_clause_body('X is []')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions[0]['X'].l), 0)

        clause = self.parser.parse_line_clause_body(
            'L is [1,2,3,4], X is list_sum(L), Y is list_max(L), Z is list_min(L), W is list_avg(L), V is list_len(L)'
        )
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions[0]['L'].l), 4)
        self.assertEqual(solutions[0]['L'].l[3].f, 4.0)

        self.assertEqual(solutions[0]['X'].f, 10.0)
        self.assertEqual(solutions[0]['Y'].f, 4.0)
        self.assertEqual(solutions[0]['Z'].f, 1.0)
        self.assertEqual(solutions[0]['W'].f, 2.5)
        self.assertEqual(solutions[0]['V'].f, 4.0)

        clause = self.parser.parse_line_clause_body(
            'L is [1,2,3,4], list_contains(L, 2).')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 1)

        clause = self.parser.parse_line_clause_body(
            'L is [1,2,3,4], list_contains(L, 23).')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 0)

        clause = self.parser.parse_line_clause_body(
            'X is [1,2,3,4], list_nth(1, X, E).')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['E'].f, 2)

        clause = self.parser.parse_line_clause_body(
            'X is [1,2,3,4], length(X, L).')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['L'].f, 4)

        clause = self.parser.parse_line_clause_body(
            'X is [1,2,3,4], list_slice(1, 3, X, E).')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions[0]['E'].l), 2)
        self.assertEqual(solutions[0]['E'].l[0].f, 2.0)
        self.assertEqual(solutions[0]['E'].l[1].f, 3.0)

        clause = self.parser.parse_line_clause_body(
            'X is [1,2,3,4], E is list_slice(1, 3, X).')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions[0]['E'].l), 2)
        self.assertEqual(solutions[0]['E'].l[0].f, 2.0)
        self.assertEqual(solutions[0]['E'].l[1].f, 3.0)

        clause = self.parser.parse_line_clause_body(
            'X is [1,2,3,4], list_append(X, 5).')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions[0]['X'].l), 5)
        self.assertEqual(solutions[0]['X'].l[4].f, 5.0)

        clause = self.parser.parse_line_clause_body(
            'X is ["1","2","3","4"], list_str_join("@", X, Y).')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['Y'].s, "1@2@3@4")

        clause = self.parser.parse_line_clause_body(
            'X is ["1","2","3","4"], Y is list_join("@", X).')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['Y'].s, "1@2@3@4")

    # @unittest.skip("temporarily disabled")
    def test_list_findall(self):

        self.parser.compile_file('samples/kb1.pl', UNITTEST_MODULE)

        clause = self.parser.parse_line_clause_body(
            'list_findall(X, woman(X), L)')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions[0]), 1)
        self.assertEqual(len(solutions[0]['L'].l), 3)

    # @unittest.skip("temporarily disabled")
    def test_strings(self):

        clause = self.parser.parse_line_clause_body(
            'X is \'bar\', S is format_str(\'test %d %s foo\', 42, X)')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['S'].s, 'test 42 bar foo')

        clause = self.parser.parse_line_clause_body(
            'X is \'foobar\', sub_string(X, 0, 2, _, Y)')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['Y'].s, 'fo')

        clause = self.parser.parse_line_clause_body(
            'atom_chars(foo, X), atom_chars(Y, "bar").')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['X'].s, 'foo')
        self.assertEqual(solutions[0]['Y'].name, 'bar')

    # @unittest.skip("temporarily disabled")
    def test_date_time(self):

        clause = self.parser.parse_line_clause_body('get_time(T)')
        solutions = self.rt.search(clause)
        self.assertGreater(solutions[0]['T'].s, '2017-04-30T23:39:29.092271')

        clause = self.parser.parse_line_clause_body(
            'date_time_stamp(date(2017,2,14,1,2,3,\'local\'), TS), stamp_date_time(TS, date(Y,M,D,H,Mn,S,\'local\'))'
        )
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['Y'].f, 2017)
        self.assertEqual(solutions[0]['M'].f, 2)
        self.assertEqual(solutions[0]['D'].f, 14)
        self.assertEqual(solutions[0]['H'].f, 1)
        self.assertEqual(solutions[0]['Mn'].f, 2)
        self.assertEqual(solutions[0]['S'].f, 3)

        clause = self.parser.parse_line_clause_body(
            'date_time_stamp(date(2017,2,14,1,2,3,\'Europe/Berlin\'), TS), day_of_the_week(TS, WD)'
        )
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['TS'].s, '2017-02-14T01:02:03+01:00')
        self.assertEqual(solutions[0]['WD'].f, 2)

    # @unittest.skip("temporarily disabled")
    def test_arith(self):
        clause = self.parser.parse_line_clause_body('X is -23')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['X'].f, -23)

        clause = self.parser.parse_line_clause_body('X is +42')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['X'].f, 42)

        clause = self.parser.parse_line_clause_body('X is 19 + 23')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['X'].f, 42)

        clause = self.parser.parse_line_clause_body('X is 61 - 19')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['X'].f, 42)

        clause = self.parser.parse_line_clause_body('X is 6*7')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['X'].f, 42)

        clause = self.parser.parse_line_clause_body('X is 1764 / 42')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['X'].f, 42)

        clause = self.parser.parse_line_clause_body('X is 85 mod 43')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['X'].f, 42)

        clause = self.parser.parse_line_clause_body(
            'X is 23, increment(X, 19)')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['X'].f, 42)

        clause = self.parser.parse_line_clause_body(
            'X is 42, decrement(X, 19)')
        solutions = self.rt.search(clause)
        self.assertEqual(solutions[0]['X'].f, 23)

    # @unittest.skip("temporarily disabled")
    def test_comp(self):

        clause = self.parser.parse_line_clause_body('3>1')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 1)
        clause = self.parser.parse_line_clause_body('1>1')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 0)

        clause = self.parser.parse_line_clause_body('3<1')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 0)
        clause = self.parser.parse_line_clause_body('1<1')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 0)

        clause = self.parser.parse_line_clause_body('3=<1')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 0)
        clause = self.parser.parse_line_clause_body('1=<1')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 1)

        clause = self.parser.parse_line_clause_body('3>=1')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 1)
        clause = self.parser.parse_line_clause_body('1>=1')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 1)

        clause = self.parser.parse_line_clause_body('3\\=1')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 1)
        clause = self.parser.parse_line_clause_body('1\\=1')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 0)

        clause = self.parser.parse_line_clause_body('3=1')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 0)
        clause = self.parser.parse_line_clause_body('1=1')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 1)

    # @unittest.skip("temporarily disabled")
    def test_between(self):
        clause = self.parser.parse_line_clause_body('between(1,100,42)')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 1)

        clause = self.parser.parse_line_clause_body('between(1,100,X)')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 100)

    # @unittest.skip("temporarily disabled")
    def test_dicts(self):

        clause = self.parser.parse_line_clause_body(
            'dict_put(U, foo, 42), X is U, dict_put(X, bar, 23), dict_get(X, Y, Z), dict_get(X, foo, V)'
        )
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions[0]['U'].d), 1)
        self.assertEqual(len(solutions[0]['X'].d), 2)
        self.assertEqual(solutions[0]['Z'].f, 42)
        self.assertEqual(solutions[0]['V'].f, 42)
        self.assertEqual(solutions[1]['Z'].f, 23)
        self.assertEqual(solutions[1]['V'].f, 42)

        logging.debug(repr(solutions))

    # @unittest.skip("temporarily disabled")
    def test_assertz(self):

        clause = self.parser.parse_line_clause_body(
            'I is ias00001, assertz(frame (I, qIsFamiliar)), frame (ias00001, X)'
        )
        solutions = self.rt.search(clause)
        logging.debug(repr(solutions))
        self.assertEqual(len(solutions), 1)
        self.assertEqual(solutions[0]['X'].name, 'qIsFamiliar')

    # @unittest.skip("temporarily disabled")
    def test_retract(self):

        clause = self.parser.parse_line_clause_body(
            'I is ias1, assertz(frame (I, a, x)), retract(frame (I, _, _)), assertz(frame (I, a, y)), frame(ias1, a, X)'
        )
        solutions = self.rt.search(clause)
        logging.debug(repr(solutions))
        self.assertEqual(len(solutions), 1)
        self.assertEqual(solutions[0]['X'].name, 'y')

    # @unittest.skip("temporarily disabled")
    def test_retract_db(self):

        clause = self.parser.parse_line_clause_body(
            'I is ias1, assertz(frame (I, a, x))')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions), 1)

        clause = self.parser.parse_line_clause_body('frame(ias1, a, X)')
        s2s = self.rt.search(clause)
        self.assertEqual(len(s2s), 0)

        self.rt.apply_overlay(UNITTEST_MODULE, solutions[0])

        clause = self.parser.parse_line_clause_body('frame(ias1, a, X)')
        s2s = self.rt.search(clause)
        self.assertEqual(len(s2s), 1)
        self.assertEqual(s2s[0]['X'].name, 'x')

        clause = self.parser.parse_line_clause_body(
            'retract(frame (ias1, _, _)), frame(ias1, a, X)')
        s2s = self.rt.search(clause)
        self.assertEqual(len(s2s), 0)

        clause = self.parser.parse_line_clause_body(
            'retract(frame (ias1, _, _))')
        solutions = self.rt.search(clause)

        self.rt.apply_overlay(UNITTEST_MODULE, solutions[0])

        clause = self.parser.parse_line_clause_body('frame(ias1, a, X)')
        s2s = self.rt.search(clause)
        self.assertEqual(len(s2s), 0)

    # @unittest.skip("temporarily disabled")
    def test_setz(self):

        clause = self.parser.parse_line_clause_body(
            'assertz(frame (ias1, a, x)), assertz(frame (ias1, a, y)), setz(frame (ias1, a, _), z), frame (ias1, a, X)'
        )
        solutions = self.rt.search(clause)
        logging.debug(repr(solutions))
        self.assertEqual(len(solutions), 1)
        self.assertEqual(solutions[0]['X'].name, 'z')

    # @unittest.skip("temporarily disabled")
    def test_setz_multi(self):

        # self.rt.set_trace(True)

        clause = self.parser.parse_line_clause_body(
            'I is ias2, setz(ias (I, a, _), a), setz(ias (I, b, _), b), setz(ias (I, c, _), c), ias(I, X, Y). '
        )
        solutions = self.rt.search(clause)
        logging.debug(repr(solutions))
        self.assertEqual(len(solutions), 3)
        self.assertEqual(solutions[0]['X'].name, 'a')
        self.assertEqual(solutions[0]['Y'].name, 'a')
        self.assertEqual(solutions[1]['X'].name, 'b')
        self.assertEqual(solutions[1]['Y'].name, 'b')
        self.assertEqual(solutions[2]['X'].name, 'c')
        self.assertEqual(solutions[2]['Y'].name, 'c')

    # @unittest.skip("temporarily disabled")
    def test_gensym(self):

        logging.debug('test_gensym...')

        clause = self.parser.parse_line_clause_body(
            'gensym(foo, I), gensym(foo, J)')
        solutions = self.rt.search(clause)
        logging.debug(repr(solutions))
        self.assertEqual(len(solutions), 1)
        self.assertNotEqual(solutions[0]['I'].name, solutions[0]['J'].name)

        logging.debug('test_gensym... done.')

    # @unittest.skip("temporarily disabled")
    def test_sets(self):

        clause = self.parser.parse_line_clause_body(
            'set_add(S, 42), set_add(S, 23), set_add(S, 23), set_get(S, V)')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions[0]), 2)
        self.assertEqual(len(solutions[0]['S'].s), 2)

        logging.debug(repr(solutions))

    # @unittest.skip("temporarily disabled")
    def test_set_findall(self):

        self.parser.compile_file('samples/kb1.pl', UNITTEST_MODULE)

        clause = self.parser.parse_line_clause_body(
            'set_findall(X, woman(X), S)')
        solutions = self.rt.search(clause)
        self.assertEqual(len(solutions[0]), 1)
        self.assertEqual(len(solutions[0]['S'].s), 3)

    # @unittest.skip("temporarily disabled")
    def test_eval_functions(self):

        clause = self.parser.parse_line_clause_body(
            'X is [23, 42], Y is [list_avg(X), list_sum(Z)]')
        solutions = self.rt.search(clause)
        logging.debug(repr(solutions))
        self.assertEqual(len(solutions), 1)
        self.assertEqual(len(solutions[0]['Y'].l), 2)

    # @unittest.skip("temporarily disabled")
    def test_set(self):

        clause = self.parser.parse_line_clause_body(
            'set(X, 23), set(X, 42), set(Y, 23), Z := Y * 2')
        solutions = self.rt.search(clause)
        logging.debug(repr(solutions))
        self.assertEqual(len(solutions), 1)
        self.assertEqual(solutions[0]['X'].f, 42)
        self.assertEqual(solutions[0]['Y'].f, 23)
        self.assertEqual(solutions[0]['Z'].f, 46)

    # @unittest.skip("temporarily disabled")
    def test_set_pseudo(self):

        clause = self.parser.parse_line_clause_body(
            'assertz(foo(bar, 23)), set(bar:foo, 42), foo(bar, X), Z := bar:foo'
        )
        # self.rt.set_trace(True)
        solutions = self.rt.search(clause)
        logging.debug(repr(solutions))
        self.assertEqual(len(solutions), 1)
        self.assertEqual(solutions[0]['X'].f, 42)
Exemplo n.º 8
0
class TestNegation(unittest.TestCase):
    def setUp(self):

        #
        # db, store
        #

        db_url = 'sqlite:///foo.db'

        # setup compiler + environment

        self.db = LogicDB(db_url)
        self.parser = PrologParser(self.db)
        self.rt = PrologRuntime(self.db)

        self.db.clear_module(UNITTEST_MODULE)

        self.rt.set_trace(True)

    def tearDown(self):
        self.db.close()

    # @unittest.skip("temporarily disabled")
    def test_not_succ(self):

        clause = self.parser.parse_line_clause_body(
            'X is 1, Y is 2, not(X is Y).')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause, {})
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)

    # @unittest.skip("temporarily disabled")
    def test_not_fail(self):
        clause = self.parser.parse_line_clause_body(
            'X is 2, Y is 2, not(X is Y).')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause, {})
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 0)

    # @unittest.skip("temporarily disabled")
    def test_chancellors(self):

        self.parser.compile_file('samples/not_test.pl', UNITTEST_MODULE)

        clause = self.parser.parse_line_clause_body(
            'was_chancellor(helmut_kohl).')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause, {})
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)

    # @unittest.skip("temporarily disabled")
    def test_double_negation(self):

        self.parser.compile_file('samples/not_test.pl', UNITTEST_MODULE)

        clause = self.parser.parse_line_clause_body(
            'not(not(chancellor(helmut_kohl))).')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause, {})
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)

        clause = self.parser.parse_line_clause_body(
            'not(not(chancellor(angela_merkel))).')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause, {})
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)

        clause = self.parser.parse_line_clause_body('not(not(chancellor(X))).')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause, {})
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 2)

    # @unittest.skip("temporarily disabled")
    def test_assertz_negation(self):

        clause = self.parser.parse_line_clause_body(
            'assertz(foobar(a)), foobar(a), (not(foobar(b))).')
        logging.debug('clause: %s' % clause)
        solutions = self.rt.search(clause, {})
        logging.debug('solutions: %s' % repr(solutions))
        self.assertEqual(len(solutions), 1)
Exemplo n.º 9
0
    # default history len is -1 (infinite), which may grow unruly
    readline.set_history_length(1000)
except IOError:
    pass
atexit.register(readline.write_history_file, histfile)

#
# main
#

db_url = config.get('db', 'url')
# db_url = 'sqlite:///tmp/foo.db'

db = LogicDB(db_url)
parser = PrologParser()
rt = PrologRuntime(db)

while True:

    line = raw_input('?- ')

    if line == 'quit' or line == 'exit':
        break

    try:
        c = parser.parse_line_clause_body(line)
        logging.debug("Parse result: %s" % c)

        logging.debug("Searching for c:", c)

        solutions = rt.search(c)