Beispiel #1
0
    def test_inversion(self):
        pool = Pool()
        build = Builder(pool)
        build.vars("bool", "a", "b")
        build.vars("int", "x")

        test1 = build.test("a")
        test2 = build.test("b")
        test3 = build.test("x", "<=", 5)

        node3 = build.ite(test3, 1, 0)
        diagram = build.ite(test1, build.ite(test2, node3, 1), node3)

        self.assertTrue(is_ordered(diagram))

        def inversion1(root_id):
            minus_one = pool.terminal("-1")
            return pool.apply(Multiplication, pool.apply(Summation, root_id, minus_one), minus_one)

        def transform(terminal_node, d):
            if terminal_node.expression == 1:
                return d.pool.zero_id
            elif terminal_node.expression == 0:
                return d.pool.one_id
            else:
                raise RuntimeError("Could not invert value {}".format(terminal_node.expression))

        def inversion2(root_id):
            to_invert = pool.diagram(root_id)
            profile = WalkingProfile(diagram)
            return leaf_transform.transform_leaves(transform, to_invert)

        iterations = 1000
        timer = Timer(precision=6)
        timer.start("Legacy inversion")
        for _ in range(iterations):
            inversion1(diagram.root_id)
        time_legacy = timer.stop()

        inverted1 = pool.diagram(inversion1(diagram.root_id))

        timer.start("New inversion")
        for _ in range(iterations):
            inversion2(diagram.root_id)
        time_new = timer.stop()

        inverted2 = pool.diagram(inversion2(diagram.root_id))

        for a in [True, False]:
            for b in [True, False]:
                for x in range(10):
                    assignment = {"a": a, "b": b, "x": x}
                    self.assertNotEqual(diagram.evaluate(assignment), inverted1.evaluate(assignment))
                    self.assertNotEqual(diagram.evaluate(assignment), inverted2.evaluate(assignment))

        self.assertTrue(time_legacy > time_new, "New inversion ({}) not faster than legacy implementation ({})"
                        .format(time_new, time_legacy))
Beispiel #2
0
 def get_looping_diagram():
     pool = Pool()
     pool.int_var("x")
     test = LinearTest("x", "<=", "2")
     zero = pool.terminal(0)
     one = pool.terminal(1)
     node1 = pool.internal(test, one, zero)
     node2 = pool.internal(test, node1, zero)
     diagram = pool.diagram(node2)
     return diagram
Beispiel #3
0
 def get_unordered_diagram():
     pool = Pool()
     pool.int_var("x")
     test1 = LinearTest("x", "<=", "2")
     test2 = LinearTest("x", "<=", "3")
     zero = pool.terminal(0)
     one = pool.terminal(1)
     pool.internal(test1, one, zero)
     pool.internal(test2, one, zero)
     # test2 => test1 => 1
     node1 = pool.internal(test1, one, zero)
     node2 = pool.internal(test2, node1, zero)
     diagram = pool.diagram(node2)
     return diagram
Beispiel #4
0
    def test_inversion(self):
        pool = Pool()
        build = Builder(pool)
        build.vars("bool", "a", "b")
        build.vars("int", "x")

        test1 = build.test("a")
        test2 = build.test("b")
        test3 = build.test("x", "<=", 5)

        node3 = build.ite(test3, 1, 0)
        diagram = build.ite(test1, build.ite(test2, node3, 1), node3)

        self.assertTrue(is_ordered(diagram))

        def inversion1(root_id):
            minus_one = pool.terminal("-1")
            return pool.apply(Multiplication,
                              pool.apply(Summation, root_id, minus_one),
                              minus_one)

        def transform(terminal_node, d):
            if terminal_node.expression == 1:
                return d.pool.zero_id
            elif terminal_node.expression == 0:
                return d.pool.one_id
            else:
                raise RuntimeError("Could not invert value {}".format(
                    terminal_node.expression))

        def inversion2(root_id):
            to_invert = pool.diagram(root_id)
            profile = WalkingProfile(diagram)
            return leaf_transform.transform_leaves(transform, to_invert)

        iterations = 1000
        timer = Timer(precision=6)
        timer.start("Legacy inversion")
        for _ in range(iterations):
            inversion1(diagram.root_id)
        time_legacy = timer.stop()

        inverted1 = pool.diagram(inversion1(diagram.root_id))

        timer.start("New inversion")
        for _ in range(iterations):
            inversion2(diagram.root_id)
        time_new = timer.stop()

        inverted2 = pool.diagram(inversion2(diagram.root_id))

        for a in [True, False]:
            for b in [True, False]:
                for x in range(10):
                    assignment = {"a": a, "b": b, "x": x}
                    self.assertNotEqual(diagram.evaluate(assignment),
                                        inverted1.evaluate(assignment))
                    self.assertNotEqual(diagram.evaluate(assignment),
                                        inverted2.evaluate(assignment))

        self.assertTrue(
            time_legacy > time_new,
            "New inversion ({}) not faster than legacy implementation ({})".
            format(time_new, time_legacy))
Beispiel #5
0
 def test_leaf_transform_simple_test(self):
     pool = Pool()
     pool.int_var("x")
     test1 = pool.bool_test(LinearTest("x", ">="))
     leaf_transform.transform_leaves(lambda t, d: d.pool.terminal(2), pool.diagram(test1))
Beispiel #6
0
 def test_leaf_transform_leaf_node(self):
     pool = Pool()
     diagram = pool.diagram(pool.one_id)
     leaf_transform.transform_leaves(lambda t, d: d.pool.terminal(2), diagram)
Beispiel #7
0
 def test_leaf_walking_leaf_node(self):
     pool = Pool()
     diagram = pool.diagram(pool.one_id)
     walk.walk_leaves(lambda p, n: True, diagram)
Beispiel #8
0
 def test_leaf_transform_simple_test(self):
     pool = Pool()
     pool.int_var("x")
     test1 = pool.bool_test(LinearTest("x", ">="))
     leaf_transform.transform_leaves(lambda t, d: d.pool.terminal(2),
                                     pool.diagram(test1))
Beispiel #9
0
 def test_leaf_transform_leaf_node(self):
     pool = Pool()
     diagram = pool.diagram(pool.one_id)
     leaf_transform.transform_leaves(lambda t, d: d.pool.terminal(2),
                                     diagram)
Beispiel #10
0
 def test_leaf_walking_leaf_node(self):
     pool = Pool()
     diagram = pool.diagram(pool.one_id)
     walk.walk_leaves(lambda p, n: True, diagram)