Exemple #1
0
 def test_select(self, mock_get_answer):
     (context, t1) = self.init_one_theory('l(1,2). l(3,4).')
     expr = self.mk_z3_result(context)
     mock_get_answer.return_value = expr
     query = ast.parse('l(x,y)')[0]
     result = context.select(t1, query, True)
     self.assertEqual(ast.parse('l(1,2). l(3,4).'), result)
 def check_equal(self, actual_code, correct_code, msg=None, equal=None):
     def minus(iter1, iter2, invert=False):
         extra = []
         for i1 in iter1:
             found = False
             for i2 in iter2:
                 # for asymmetric equality checks
                 if invert:
                     test_result = equal(i2, i1)
                 else:
                     test_result = equal(i1, i2)
                 if test_result:
                     found = True
                     break
             if not found:
                 extra.append(i1)
         return extra
     if equal is None:
         equal = lambda x, y: x == y
     LOG.debug("** Checking equality: %s **", msg)
     actual = compile.parse(actual_code)
     correct = compile.parse(correct_code)
     extra = minus(actual, correct)
     # in case EQUAL is asymmetric, always supply actual as the first arg
     missing = minus(correct, actual, invert=True)
     self.output_diffs(extra, missing, msg)
     LOG.debug("** Finished equality: %s **", msg)
Exemple #3
0
    def test_event_facts(self):
        # insert
        event = compile.parse('insert[p(1) :- true]')
        self.assertEqual(len(event), 1)
        event = event[0]
        fact = compile.parse1('p(1) :- true')
        self.assertEqual(event.formula, fact)
        self.assertEqual(event.insert, True)
        self.assertIsNone(event.target)

        # delete
        event = compile.parse('delete[p(1) :- true]')
        self.assertEqual(len(event), 1)
        event = event[0]
        fact = compile.parse1('p(1) :- true')
        self.assertEqual(event.formula, fact)
        self.assertEqual(event.insert, False)
        self.assertIsNone(event.target)

        # insert with policy
        event = compile.parse('insert[p(1) :- true; "policy"]')
        self.assertEqual(len(event), 1)
        event = event[0]
        fact = compile.parse1('p(1) :- true')
        self.assertEqual(event.formula, fact)
        self.assertEqual(event.insert, True)
        self.assertEqual(event.target, "policy")
Exemple #4
0
 def test_select(self, mock_get_answer):
     (context, t1) = self.init_one_theory('l(1,2). l(3,4).')
     expr = self.mk_z3_result(context)
     mock_get_answer.return_value = expr
     query = ast.parse('l(x,y)')[0]
     result = context.select(t1, query, True)
     self.assertEqual(ast.parse('l(1,2). l(3,4).'), result)
 def check_equal(self, actual_code, correct_code, msg=None, equal=None):
     def minus(iter1, iter2, invert=False):
         extra = []
         for i1 in iter1:
             found = False
             for i2 in iter2:
                 # for asymmetric equality checks
                 if invert:
                     test_result = equal(i2, i1)
                 else:
                     test_result = equal(i1, i2)
                 if test_result:
                     found = True
                     break
             if not found:
                 extra.append(i1)
         return extra
     if equal is None:
         equal = lambda x, y: x == y
     LOG.debug("** Checking equality: %s **", msg)
     actual = compile.parse(actual_code)
     correct = compile.parse(correct_code)
     extra = minus(actual, correct)
     # in case EQUAL is asymmetric, always supply actual as the first arg
     missing = minus(correct, actual, invert=True)
     self.output_diffs(extra, missing, msg)
     LOG.debug("** Finished equality: %s **", msg)
    def test_event_facts(self):
        # insert
        event = compile.parse('insert[p(1) :- true]')
        self.assertEqual(len(event), 1)
        event = event[0]
        fact = compile.parse1('p(1) :- true')
        self.assertEqual(event.formula, fact)
        self.assertEqual(event.insert, True)
        self.assertIsNone(event.target)

        # delete
        event = compile.parse('delete[p(1) :- true]')
        self.assertEqual(len(event), 1)
        event = event[0]
        fact = compile.parse1('p(1) :- true')
        self.assertEqual(event.formula, fact)
        self.assertEqual(event.insert, False)
        self.assertIsNone(event.target)

        # insert with policy
        event = compile.parse('insert[p(1) :- true; "policy"]')
        self.assertEqual(len(event), 1)
        event = event[0]
        fact = compile.parse1('p(1) :- true')
        self.assertEqual(event.formula, fact)
        self.assertEqual(event.insert, True)
        self.assertEqual(event.target, "policy")
 def check_err(code, errmsg, msg):
     try:
         compile.parse(code)
         self.fail("Error should have been thrown but was not: " + msg)
     except exception.PolicyException as e:
         emsg = "Err message '{}' should include '{}'".format(
             str(e), errmsg)
         self.assertTrue(errmsg in str(e), msg + ": " + emsg)
Exemple #8
0
 def check_err(code, errmsg, msg):
     try:
         compile.parse(code)
         self.fail("Error should have been thrown but was not: " + msg)
     except exception.PolicyException as e:
         emsg = "Err message '{}' should include '{}'".format(
             str(e), errmsg)
         self.assertTrue(errmsg in str(e), msg + ": " + emsg)
Exemple #9
0
    def create_unify(self,
                     atom_string1,
                     atom_string2,
                     msg,
                     change_num,
                     unifier1=None,
                     unifier2=None,
                     recursive_str=False):
        """Create unification and check basic results."""
        def str_uni(u):
            if recursive_str:
                return u.recur_str()
            else:
                return str(u)

        def print_unifiers(changes=None):
            LOG.debug("unifier1: %s", str_uni(unifier1))
            LOG.debug("unifier2: %s", str_uni(unifier2))
            if changes is not None:
                LOG.debug("changes: %s", ";".join([str(x) for x in changes]))

        if msg is not None:
            self.open(msg)
        if unifier1 is None:
            # LOG.debug("Generating new unifier1")
            unifier1 = topdown.TopDownTheory.new_bi_unifier()
        if unifier2 is None:
            # LOG.debug("Generating new unifier2")
            unifier2 = topdown.TopDownTheory.new_bi_unifier()
        p1 = compile.parse(atom_string1)[0]
        p2 = compile.parse(atom_string2)[0]
        changes = unify.bi_unify_atoms(p1, unifier1, p2, unifier2)
        self.assertIsNotNone(changes)
        print_unifiers(changes)
        p1p = p1.plug(unifier1)
        p2p = p2.plug(unifier2)
        print_unifiers(changes)
        if not p1p == p2p:
            LOG.debug("Failure: bi-unify(%s, %s) produced %s and %s", p1, p2,
                      str_uni(unifier1), str_uni(unifier2))
            LOG.debug("plug(%s, %s) = %s", p1, str_uni(unifier1), p1p)
            LOG.debug("plug(%s, %s) = %s", p2, str_uni(unifier2), p2p)
            self.fail()
        if change_num is not None and len(changes) != change_num:
            LOG.debug("Failure: bi-unify(%s, %s) produced %s and %s", p1, p2,
                      str_uni(unifier1), str_uni(unifier2))
            LOG.debug("plug(%s, %s) = %s", p1, str_uni(unifier1), p1p)
            LOG.debug("plug(%s, %s) = %s", p2, str_uni(unifier2), p2p)
            LOG.debug("Expected %s changes; computed %s changes", change_num,
                      len(changes))
            self.fail()
        LOG.debug("unifier1: %s", str_uni(unifier1))
        LOG.debug("unifier2: %s", str_uni(unifier2))
        if msg is not None:
            self.open(msg)
        return (p1, unifier1, p2, unifier2, changes)
Exemple #10
0
    def create_unify(self, atom_string1, atom_string2, msg, change_num,
                     unifier1=None, unifier2=None, recursive_str=False):
        """Create unification and check basic results."""
        def str_uni(u):
            if recursive_str:
                return u.recur_str()
            else:
                return str(u)

        def print_unifiers(changes=None):
            LOG.debug("unifier1: %s", str_uni(unifier1))
            LOG.debug("unifier2: %s", str_uni(unifier2))
            if changes is not None:
                LOG.debug("changes: %s",
                          ";".join([str(x) for x in changes]))

        if msg is not None:
            self.open(msg)
        if unifier1 is None:
            # LOG.debug("Generating new unifier1")
            unifier1 = TopDownTheory.new_bi_unifier()
        if unifier2 is None:
            # LOG.debug("Generating new unifier2")
            unifier2 = TopDownTheory.new_bi_unifier()
        p1 = compile.parse(atom_string1)[0]
        p2 = compile.parse(atom_string2)[0]
        changes = unify.bi_unify_atoms(p1, unifier1, p2, unifier2)
        self.assertTrue(changes is not None)
        print_unifiers(changes)
        p1p = p1.plug(unifier1)
        p2p = p2.plug(unifier2)
        print_unifiers(changes)
        if not p1p == p2p:
            LOG.debug("Failure: bi-unify(%s, %s) produced %s and %s",
                      p1, p2, str_uni(unifier1), str_uni(unifier2))
            LOG.debug("plug(%s, %s) = %s", p1, str_uni(unifier1), p1p)
            LOG.debug("plug(%s, %s) = %s", p2, str_uni(unifier2), p2p)
            self.fail()
        if change_num is not None and len(changes) != change_num:
            LOG.debug("Failure: bi-unify(%s, %s) produced %s and %s",
                      p1, p2, str_uni(unifier1), str_uni(unifier2))
            LOG.debug("plug(%s, %s) = %s", p1, str_uni(unifier1), p1p)
            LOG.debug("plug(%s, %s) = %s", p2, str_uni(unifier2), p2p)
            LOG.debug("Expected %s changes; computed %s changes",
                      change_num, len(changes))
            self.fail()
        LOG.debug("unifier1: %s", str_uni(unifier1))
        LOG.debug("unifier2: %s", str_uni(unifier2))
        if msg is not None:
            self.open(msg)
        return (p1, unifier1, p2, unifier2, changes)
 def test_old_new_correctness(self):
     obj = self.MyObject()
     run = agnostic.Runtime()
     run.create_policy('test')
     run.insert('p(x) :- q(x)')
     run.insert('q(x) :- r(x), not s(x)')
     run.insert('r(1) r(2) r(3)')
     run.insert('s(2)')
     oldp = set(compile.parse('p(1) p(3)'))
     newp = set(compile.parse('p(1) p(2)'))
     run.register_trigger('p',
                          lambda old, new: obj.equal(oldp, newp, old, new))
     run.update([compile.Event(compile.parse1('s(3)')),
                 compile.Event(compile.parse1('s(2)'), insert=False)])
     self.assertEqual(obj.equals, True)
Exemple #12
0
 def check_unify_fail(self, atom_string1, atom_string2, msg):
     """Check that the bi-unification fails."""
     self.open(msg)
     unifier1 = topdown.TopDownTheory.new_bi_unifier()
     unifier2 = topdown.TopDownTheory.new_bi_unifier()
     p1 = compile.parse(atom_string1)[0]
     p2 = compile.parse(atom_string2)[0]
     changes = unify.bi_unify_atoms(p1, unifier1, p2, unifier2)
     if changes is not None:
         LOG.debug("Failure failure: bi-unify(%s, %s) produced %s and %s",
                   p1, p2, unifier1, unifier2)
         LOG.debug("plug(%s, %s) = %s", p1, unifier1, p1.plug(unifier1))
         LOG.debug("plug(%s, %s) = %s", p2, unifier2, p2.plug(unifier2))
         self.fail()
     self.close(msg)
Exemple #13
0
    def test_rule_recursion(self):
        rules = compile.parse('p(x) :- q(x), r(x)  q(x) :- r(x) r(x) :- t(x)')
        self.assertFalse(compile.is_recursive(rules))

        rules = compile.parse('p(x) :- p(x)')
        self.assertTrue(compile.is_recursive(rules))

        rules = compile.parse('p(x) :- q(x)  q(x) :- r(x)  r(x) :- p(x)')
        self.assertTrue(compile.is_recursive(rules))

        rules = compile.parse('p(x) :- q(x)  q(x) :- not p(x)')
        self.assertTrue(compile.is_recursive(rules))

        rules = compile.parse('p(x) :- q(x), s(x)  q(x) :- t(x)  s(x) :- p(x)')
        self.assertTrue(compile.is_recursive(rules))
Exemple #14
0
    def test_rule_recursion(self):
        rules = compile.parse('p(x) :- q(x), r(x)  q(x) :- r(x) r(x) :- t(x)')
        self.assertFalse(compile.is_recursive(rules))

        rules = compile.parse('p(x) :- p(x)')
        self.assertTrue(compile.is_recursive(rules))

        rules = compile.parse('p(x) :- q(x)  q(x) :- r(x)  r(x) :- p(x)')
        self.assertTrue(compile.is_recursive(rules))

        rules = compile.parse('p(x) :- q(x)  q(x) :- not p(x)')
        self.assertTrue(compile.is_recursive(rules))

        rules = compile.parse('p(x) :- q(x), s(x)  q(x) :- t(x)  s(x) :- p(x)')
        self.assertTrue(compile.is_recursive(rules))
Exemple #15
0
 def check_unify_fail(self, atom_string1, atom_string2, msg):
     """Check that the bi-unification fails."""
     self.open(msg)
     unifier1 = TopDownTheory.new_bi_unifier()
     unifier2 = TopDownTheory.new_bi_unifier()
     p1 = compile.parse(atom_string1)[0]
     p2 = compile.parse(atom_string2)[0]
     changes = unify.bi_unify_atoms(p1, unifier1, p2, unifier2)
     if changes is not None:
         LOG.debug("Failure failure: bi-unify(%s, %s) produced %s and %s",
                   p1, p2, unifier1, unifier2)
         LOG.debug("plug(%s, %s) = %s", p1, unifier1, p1.plug(unifier1))
         LOG.debug("plug(%s, %s) = %s", p2, unifier2, p2.plug(unifier2))
         self.fail()
     self.close(msg)
Exemple #16
0
 def test_inject(self):
     theory = mock.MagicMock(spec=topdown.TopDownTheory)
     world = {'t': theory}
     theory.name = 't'
     theory.schema = ast.Schema()
     theory.schema.map['l'] = [mkc('Int'), mkc('Int')]
     theory.select.return_value = ast.parse('l(1,2). l(3,4). l(5,6)')
     context = z3theory.Z3Context()
     # An external theory world
     context.theories = world
     # inject the declaration of external relation without rules
     param_types = [
         context.type_registry.get_type(typ)
         for typ in ['Int', 'Int', 'Bool']
     ]
     relation = z3.Function('t:l', *param_types)
     context.context.register_relation(relation)
     context.relations['t:l'] = relation
     # the test
     context.inject('t', 'l')
     rules = context.context._rules  # pylint: disable=E1101
     self.assertIs(True, all(r.decl().name() == 't:l' for r in rules))
     self.assertEqual([[1, 2], [3, 4], [5, 6]],
                      sorted([[c.as_long() for c in r.children()]
                              for r in rules]))
Exemple #17
0
def datalog_equal(actual_code,
                  correct_code,
                  msg=None,
                  equal=None,
                  theories=None,
                  output_diff=True):
    """Check equality.

    Check if the strings given by actual_code
    and CORRECT_CODE represent the same datalog.
    """
    def minus(iter1, iter2, invert=False):
        extra = []
        for i1 in iter1:
            found = False
            for i2 in iter2:
                # for asymmetric equality checks
                if invert:
                    test_result = equal(i2, i1)
                else:
                    test_result = equal(i1, i2)
                if test_result:
                    found = True
                    break
            if not found:
                extra.append(i1)
        return extra

    if equal is None:
        equal = lambda x, y: x == y

    LOG.debug("** Checking equality: %s **", msg)
    actual = compile.parse(actual_code, theories=theories)
    correct = compile.parse(correct_code, theories=theories)
    extra = minus(actual, correct)
    # in case EQUAL is asymmetric, always supply actual as the first arg
    #   and set INVERT to true
    missing = minus(correct, actual, invert=True)
    if output_diff:
        output_diffs(extra, missing, msg)
    LOG.debug("** Finished equality: %s **", msg)
    is_equal = len(extra) == 0 and len(missing) == 0
    if not is_equal:
        LOG.debug('datalog_equal failed, extras: %s, missing: %s', extra,
                  missing)
    return is_equal
Exemple #18
0
 def setUp(self):
     self.world = {}
     t1 = MinTheory('t1', self.world)
     t2 = MinTheory('t2', self.world)
     self.world['t1'] = t1
     self.world['t2'] = t2
     self.rules = ast.parse(
         'l(2). l(3). p(x) :- l(x). q(x,x) :- m(x). '
         'm("a"). k(x) :- t2:f(x). r(y) :- q(x,y). '
         's(x) :- l(y),builtin:plus(y, 2, x).')
     for rule in self.rules:
         t1.insert(rule)
     for rule in ast.parse("f(3)."):
         t2.insert(rule)
     self.t1 = t1
     self.t2 = t2
     super(TestTypeChecker, self).setUp()
Exemple #19
0
 def test_old_new_correctness(self):
     obj = self.MyObject()
     run = agnostic.Runtime()
     run.create_policy('test')
     run.insert('p(x) :- q(x)')
     run.insert('q(x) :- r(x), not s(x)')
     run.insert('r(1) r(2) r(3)')
     run.insert('s(2)')
     oldp = set(compile.parse('p(1) p(3)'))
     newp = set(compile.parse('p(1) p(2)'))
     run.register_trigger('p',
                          lambda old, new: obj.equal(oldp, newp, old, new))
     run.update([
         compile.Event(compile.parse1('s(3)')),
         compile.Event(compile.parse1('s(2)'), insert=False)
     ])
     self.assertEqual(obj.equals, True)
Exemple #20
0
    def test_modal_execute(self):
        # modal rule
        rule = compile.parse('execute[p(x)] :- q(x)')
        self.assertEqual(len(rule), 1)
        rule = rule[0]
        self.assertEqual(rule.head.table.modal, 'execute')

        # modal rule with namespace
        rule = compile.parse('execute[nova:disconnectNetwork(x)] :- q(x)')
        self.assertEqual(len(rule), 1)
        rule = rule[0]
        self.assertEqual(rule.head.table.modal, 'execute')

        # modal query
        rule = compile.parse('execute[p(x)]')
        self.assertEqual(len(rule), 1)
        rule = rule[0]
        self.assertEqual(rule.table.modal, 'execute')
Exemple #21
0
 def init_one_theory(self, prog):
     context = z3theory.Z3Context()
     world = {}
     t1 = z3theory.Z3Theory('t1', theories=world)
     world['t1'] = t1
     context.register(t1)
     for rule in ast.parse(prog):
         t1.insert(rule)
     return (context, t1)
Exemple #22
0
 def test_eval(self, mock_get_answer):
     (context, t1) = self.init_one_theory('l(1,2). l(3,4).')
     expr = self.mk_z3_result(context)
     mock_get_answer.return_value = expr
     query = ast.parse('l(x,y)')[0]
     result = context.eval(t1, query)
     self.assertEqual(2, len(result[1]))
     self.assertEqual(2, len(result[2]))
     self.assertIs(True, all(len(row) == 2 for row in result[0]))
Exemple #23
0
 def init_one_theory(self, prog):
     context = z3theory.Z3Context()
     world = {}
     t1 = z3theory.Z3Theory('t1', theories=world)
     world['t1'] = t1
     context.register(t1)
     for rule in ast.parse(prog):
         t1.insert(rule)
     return (context, t1)
Exemple #24
0
 def test_eval(self, mock_get_answer):
     (context, t1) = self.init_one_theory('l(1,2). l(3,4).')
     expr = self.mk_z3_result(context)
     mock_get_answer.return_value = expr
     query = ast.parse('l(x,y)')[0]
     result = context.eval(t1, query)
     self.assertEqual(2, len(result[1]))
     self.assertEqual(2, len(result[2]))
     self.assertIs(True, all(len(row) == 2 for row in result[0]))
Exemple #25
0
    def test_modal_execute(self):
        # modal rule
        rule = compile.parse('execute[p(x)] :- q(x)')
        self.assertEqual(len(rule), 1)
        rule = rule[0]
        self.assertEqual(rule.head.table.modal, 'execute')

        # modal rule with namespace
        rule = compile.parse('execute[nova:disconnectNetwork(x)] :- q(x)')
        self.assertEqual(len(rule), 1)
        rule = rule[0]
        self.assertEqual(rule.head.table.modal, 'execute')

        # modal query
        rule = compile.parse('execute[p(x)]')
        self.assertEqual(len(rule), 1)
        rule = rule[0]
        self.assertEqual(rule.table.modal, 'execute')
Exemple #26
0
 def init_one_builtin(self, body, typ, arity):
     context = z3theory.Z3Context()
     world = {}
     t1 = z3theory.Z3Theory('t1', theories=world)
     world['t1'] = t1
     context.register(t1)
     rule = ast.parse('p(x) :- ' + body + '.')[0]
     t1.schema.map['p'] = [mkc(typ)]
     context.declare_tables()
     return (context, t1, rule, {0: [mkc(typ)] * arity})
Exemple #27
0
 def init_one_builtin(self, body, typ, arity):
     context = z3theory.Z3Context()
     world = {}
     t1 = z3theory.Z3Theory('t1', theories=world)
     world['t1'] = t1
     context.register(t1)
     rule = ast.parse('p(x) :- ' + body + '.')[0]
     t1.schema.map['p'] = [mkc(typ)]
     context.declare_tables()
     return (context, t1, rule, {0: [mkc(typ)] * arity})
Exemple #28
0
def datalog_equal(actual_code, correct_code,
                  msg=None, equal=None, theories=None,
                  output_diff=True):
    """Check equality.

    Check if the strings given by actual_code
    and CORRECT_CODE represent the same datalog.
    """
    def minus(iter1, iter2, invert=False):
        extra = []
        for i1 in iter1:
            found = False
            for i2 in iter2:
                # for asymmetric equality checks
                if invert:
                    test_result = equal(i2, i1)
                else:
                    test_result = equal(i1, i2)
                if test_result:
                    found = True
                    break
            if not found:
                extra.append(i1)
        return extra
    if equal is None:
        equal = lambda x, y: x == y

    LOG.debug("** Checking equality: %s **", msg)
    actual = compile.parse(actual_code, theories=theories)
    correct = compile.parse(correct_code, theories=theories)
    extra = minus(actual, correct)
    # in case EQUAL is asymmetric, always supply actual as the first arg
    #   and set INVERT to true
    missing = minus(correct, actual, invert=True)
    if output_diff:
        output_diffs(extra, missing, msg)
    LOG.debug("** Finished equality: %s **", msg)
    is_equal = len(extra) == 0 and len(missing) == 0
    if not is_equal:
        LOG.debug('datalog_equal failed, extras: %s, missing: %s', extra,
                  missing)
    return is_equal
Exemple #29
0
 def init_one_rule(self):
     context = z3theory.Z3Context()
     world = {}
     t1 = z3theory.Z3Theory('t1', theories=world)
     world['t1'] = t1
     context.register(t1)
     rule = ast.parse('p(x) :- l(x,y), l(3,x).')[0]
     t1.schema.map['l'] = [mkc('Int'), mkc('Int')]
     t1.schema.map['p'] = [mkc('Int')]
     context.declare_tables()
     return (context, t1, rule)
Exemple #30
0
 def init_one_rule(self):
     context = z3theory.Z3Context()
     world = {}
     t1 = z3theory.Z3Theory('t1', theories=world)
     world['t1'] = t1
     context.register(t1)
     rule = ast.parse('p(x) :- l(x,y), l(3,x).')[0]
     t1.schema.map['l'] = [mkc('Int'), mkc('Int')]
     t1.schema.map['p'] = [mkc('Int')]
     context.declare_tables()
     return (context, t1, rule)
Exemple #31
0
 def init_three_theories(self):
     context = z3theory.Z3Context()
     world = {}
     for name in ['t1', 't2', 't3']:
         world[name] = z3theory.Z3Theory(name, theories=world)
     t1, t2, t3 = world['t1'], world['t2'], world['t3']
     context.register(t1)
     context.register(t2)
     # t3 is kept external
     # Declare rules
     for rule in ast.parse('p(x) :- t2:r(x), t3:s(x). q(x) :- p(x). p(4).'):
         t1.insert(rule)
     for rule in ast.parse('r(x) :- t1:p(x).'):
         t2.insert(rule)
     # typechecker
     t1.schema.map['p'] = [mkc('Int')]
     t1.schema.map['q'] = [mkc('Int')]
     t2.schema.map['r'] = [mkc('Int')]
     t3.schema.map['s'] = [mkc('Int')]
     t3.schema.map['t'] = [mkc('Int')]
     return context
Exemple #32
0
    def check(self, rule, data, correct, possibilities=None):
        rule = compile.parse1(rule, use_modules=False)
        data = compile.parse(data, use_modules=False)
        possibilities = possibilities or ''
        possibilities = compile.parse(possibilities, use_modules=False)
        possibilities = [compile.Rule(x, []) for x in possibilities]
        poss = {}
        for rule_lit in possibilities:
            if rule_lit.head.tablename() not in poss:
                poss[rule_lit.head.tablename()] = set([rule_lit])
            else:
                poss[rule_lit.head.tablename()].add(rule_lit)

        th = MultiModuleNonrecursiveRuleTheory()
        th.debug_mode()
        for lit in data:
            th.insert(lit)
        result = th.instances(rule, poss)
        actual = " ".join(str(x) for x in result)
        e = helper.datalog_equal(actual, correct)
        self.assertTrue(e)
Exemple #33
0
    def check(self, rule, data, correct, possibilities=None):
        rule = compile.parse1(rule, use_modules=False)
        data = compile.parse(data, use_modules=False)
        possibilities = possibilities or ''
        possibilities = compile.parse(possibilities, use_modules=False)
        possibilities = [compile.Rule(x, []) for x in possibilities]
        poss = {}
        for rule_lit in possibilities:
            if rule_lit.head.tablename() not in poss:
                poss[rule_lit.head.tablename()] = set([rule_lit])
            else:
                poss[rule_lit.head.tablename()].add(rule_lit)

        th = nonrecursive.MultiModuleNonrecursiveRuleTheory()
        th.debug_mode()
        for lit in data:
            th.insert(lit)
        result = th.instances(rule, poss)
        actual = " ".join(str(x) for x in result)
        e = helper.datalog_equal(actual, correct)
        self.assertTrue(e)
Exemple #34
0
 def init_three_theories(self):
     context = z3theory.Z3Context()
     world = {}
     for name in ['t1', 't2', 't3']:
         world[name] = z3theory.Z3Theory(name, theories=world)
     t1, t2, t3 = world['t1'], world['t2'], world['t3']
     context.register(t1)
     context.register(t2)
     # t3 is kept external
     # Declare rules
     for rule in ast.parse('p(x) :- t2:r(x), t3:s(x). q(x) :- p(x). p(4).'):
         t1.insert(rule)
     for rule in ast.parse('r(x) :- t1:p(x).'):
         t2.insert(rule)
     # typechecker
     t1.schema.map['p'] = [mkc('Int')]
     t1.schema.map['q'] = [mkc('Int')]
     t2.schema.map['r'] = [mkc('Int')]
     t3.schema.map['s'] = [mkc('Int')]
     t3.schema.map['t'] = [mkc('Int')]
     return context
Exemple #35
0
    def test_event_rules(self):
        """Test modal operators."""
        # a rule we use a few times
        pqrule = compile.parse1('p(x) :- q(x)')

        # rule-level modal (with insert)
        event = compile.parse('insert[p(x) :- q(x)]')
        self.assertEqual(len(event), 1)
        event = event[0]
        self.assertEqual(event.formula, pqrule)
        self.assertEqual(event.insert, True)
        self.assertIsNone(event.target)

        # rule-level modal with delete
        event = compile.parse('delete[p(x) :- q(x)]')
        self.assertEqual(len(event), 1)
        event = event[0]
        self.assertEqual(event.formula, pqrule)
        self.assertEqual(event.insert, False)
        self.assertIsNone(event.target)

        # embedded modals
        event = compile.parse('insert[execute[p(x)] :- q(x)]')
        self.assertEqual(len(event), 1)
        event = event[0]
        rule = compile.parse1('execute[p(x)] :- q(x)')
        self.assertEqual(event.formula, rule)
        self.assertEqual(event.insert, True)
        self.assertIsNone(event.target)

        # rule-level modal with policy name
        event = compile.parse('insert[p(x) :- q(x); "policy"]')
        self.assertEqual(len(event), 1)
        event = event[0]
        self.assertEqual(event.formula, pqrule)
        self.assertEqual(event.insert, True)
        self.assertEqual(event.target, "policy")
Exemple #36
0
    def test_event_rules(self):
        """Test modal operators."""
        # a rule we use a few times
        pqrule = compile.parse1('p(x) :- q(x)')

        # rule-level modal (with insert)
        event = compile.parse('insert[p(x) :- q(x)]')
        self.assertEqual(len(event), 1)
        event = event[0]
        self.assertEqual(event.formula, pqrule)
        self.assertEqual(event.insert, True)
        self.assertIsNone(event.target)

        # rule-level modal with delete
        event = compile.parse('delete[p(x) :- q(x)]')
        self.assertEqual(len(event), 1)
        event = event[0]
        self.assertEqual(event.formula, pqrule)
        self.assertEqual(event.insert, False)
        self.assertIsNone(event.target)

        # embedded modals
        event = compile.parse('insert[execute[p(x)] :- q(x)]')
        self.assertEqual(len(event), 1)
        event = event[0]
        rule = compile.parse1('execute[p(x)] :- q(x)')
        self.assertEqual(event.formula, rule)
        self.assertEqual(event.insert, True)
        self.assertIsNone(event.target)

        # rule-level modal with policy name
        event = compile.parse('insert[p(x) :- q(x); "policy"]')
        self.assertEqual(len(event), 1)
        event = event[0]
        self.assertEqual(event.formula, pqrule)
        self.assertEqual(event.insert, True)
        self.assertEqual(event.target, "policy")
Exemple #37
0
 def init_two_theories(prog):
     context = z3theory.Z3Context()
     world = {}
     for name in ['t1', 't2']:
         world[name] = z3theory.Z3Theory(name, theories=world)
     t1, t2 = world['t1'], world['t2']
     context.register(t1)
     # t2 is kept external
     # Declare rules
     for rule in ast.parse(prog):
         t1.insert(rule)
     # typechecker
     t2.schema.map['p'] = [mkc('Small')]
     t2.schema.map['q'] = [mkc('Str')]
     return context
Exemple #38
0
 def init_two_theories(prog):
     context = z3theory.Z3Context()
     world = {}
     for name in ['t1', 't2']:
         world[name] = z3theory.Z3Theory(name, theories=world)
     t1, t2 = world['t1'], world['t2']
     context.register(t1)
     # t2 is kept external
     # Declare rules
     for rule in ast.parse(prog):
         t1.insert(rule)
     # typechecker
     t2.schema.map['p'] = [mkc('Small')]
     t2.schema.map['q'] = [mkc('Str')]
     return context
Exemple #39
0
 def test_compile_facts(self):
     context = z3theory.Z3Context()
     world = {}
     t1 = z3theory.Z3Theory('t1', theories=world)
     world['t1'] = t1
     context.register(t1)
     for rule in ast.parse('l(1,2). l(3,4). l(5,6).'):
         t1.insert(rule)
     t1.schema.map['l'] = [mkc('Int'), mkc('Int')]
     context.declare_tables()
     context.compile_facts(t1)
     rules = context.context.get_rules()
     self.assertEqual(3, len(rules))
     self.assertIs(True, all(r.decl().name() == 't1:l' for r in rules))
     self.assertEqual([[1, 2], [3, 4], [5, 6]],
                      [[c.as_long() for c in r.children()] for r in rules])
Exemple #40
0
 def test_compile_facts(self):
     context = z3theory.Z3Context()
     world = {}
     t1 = z3theory.Z3Theory('t1', theories=world)
     world['t1'] = t1
     context.register(t1)
     for rule in ast.parse('l(1,2). l(3,4). l(5,6).'):
         t1.insert(rule)
     t1.schema.map['l'] = [mkc('Int'), mkc('Int')]
     context.declare_tables()
     context.compile_facts(t1)
     rules = context.context.get_rules()
     self.assertEqual(3, len(rules))
     self.assertIs(True, all(r.decl().name() == 't1:l' for r in rules))
     self.assertEqual(
         [[1, 2], [3, 4], [5, 6]],
         [[c.as_long() for c in r.children()] for r in rules])
Exemple #41
0
 def test_inject(self):
     theory = mock.MagicMock(spec=topdown.TopDownTheory)
     world = {'t': theory}
     theory.name = 't'
     theory.schema = ast.Schema()
     theory.schema.map['l'] = [mkc('Int'), mkc('Int')]
     theory.select.return_value = ast.parse('l(1,2). l(3,4). l(5,6)')
     context = z3theory.Z3Context()
     # An external theory world
     context.theories = world
     # inject the declaration of external relation without rules
     param_types = [
         context.type_registry.get_type(typ)
         for typ in ['Int', 'Int', 'Bool']]
     relation = z3.Function('t:l', *param_types)
     context.context.register_relation(relation)
     context.relations['t:l'] = relation
     # the test
     context.inject('t', 'l')
     rules = context.context._rules  # pylint: disable=E1101
     self.assertIs(True, all(r.decl().name() == 't:l' for r in rules))
     self.assertEqual(
         [[1, 2], [3, 4], [5, 6]],
         sorted([[c.as_long() for c in r.children()] for r in rules]))
Exemple #42
0
def str2pol(policy_string, theories=None):
    return compile.parse(policy_string, theories=theories)
Exemple #43
0
    def test_rule_stratification(self):
        rules = compile.parse('p(x) :- not q(x)')
        self.assertTrue(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- p(x)')
        self.assertTrue(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- q(x)  q(x) :- p(x)')
        self.assertTrue(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- q(x)  q(x) :- not r(x)')
        self.assertTrue(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- not q(x)  q(x) :- not r(x)')
        self.assertTrue(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- not q(x)  '
                              'q(x) :- not r(x)  '
                              'r(x) :- not s(x)')
        self.assertTrue(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- q(x), r(x) '
                              'q(x) :- not t(x) '
                              'r(x) :- not s(x)')
        self.assertTrue(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- not p(x)')
        self.assertFalse(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- q(x)  q(x) :- not p(x)')
        self.assertFalse(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- q(x),r(x)  r(x) :- not p(x)')
        self.assertFalse(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- q(x), r(x) '
                              'q(x) :- not t(x) '
                              'r(x) :- not s(x) '
                              't(x) :- p(x)')
        self.assertFalse(compile.is_stratified(rules))
Exemple #44
0
def str2pol(policy_string, theories=None):
    return compile.parse(policy_string, theories=theories)
Exemple #45
0
 def parse(self, policy):
     return compile.parse(policy, use_modules=False)
def str2pol(policy_string):
    return compile.parse(policy_string)
Exemple #47
0
    def test_rule_stratification(self):
        rules = compile.parse('p(x) :- not q(x)')
        self.assertTrue(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- p(x)')
        self.assertTrue(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- q(x)  q(x) :- p(x)')
        self.assertTrue(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- q(x)  q(x) :- not r(x)')
        self.assertTrue(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- not q(x)  q(x) :- not r(x)')
        self.assertTrue(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- not q(x)  '
                              'q(x) :- not r(x)  '
                              'r(x) :- not s(x)')
        self.assertTrue(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- q(x), r(x) '
                              'q(x) :- not t(x) '
                              'r(x) :- not s(x)')
        self.assertTrue(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- not p(x)')
        self.assertFalse(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- q(x)  q(x) :- not p(x)')
        self.assertFalse(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- q(x),r(x)  r(x) :- not p(x)')
        self.assertFalse(compile.is_stratified(rules))

        rules = compile.parse('p(x) :- q(x), r(x) '
                              'q(x) :- not t(x) '
                              'r(x) :- not s(x) '
                              't(x) :- p(x)')
        self.assertFalse(compile.is_stratified(rules))
Exemple #48
0
 def parse(self, policy):
     return compile.parse(policy, use_modules=False)
Exemple #49
0
def str2pol(policy_string):
    return compile.parse(policy_string)