def test_build_basic_network(self):
        bn = NetworkExamples.construct_basic_network()

        assert len(bn.get_nodes()) == 8

        assert len(bn.get_node("Burglary").get_output_nodes()) == 3
        assert len(bn.get_node("Alarm").get_output_nodes()) == 2
        assert len(bn.get_node("Alarm").get_input_nodes()) == 2
        assert len(bn.get_node("Util1").get_input_nodes()) == 2

        assert len(bn.get_node("Burglary").get_values()) == 2
        assert len(bn.get_node("Alarm").get_values()) == 2
        assert len(bn.get_node("MaryCalls").get_values()) == 2

        assert ValueFactory.create(True) in bn.get_node(
            "Burglary").get_values()

        assert bn.get_chance_node("Burglary").get_prob(
            ValueFactory.create(True)) == pytest.approx(0.001, abs=0.0001)
        assert bn.get_chance_node("Alarm").get_prob(
            Assignment(["Burglary", "Earthquake"]),
            ValueFactory.create(True)) == pytest.approx(0.95, abs=0.0001)
        assert bn.get_chance_node("JohnCalls").get_prob(
            Assignment("Alarm"),
            ValueFactory.create(True)) == pytest.approx(0.9, abs=0.0001)

        assert len(bn.get_action_node("Action").get_values()) == 3
        assert bn.get_utility_node("Util2").get_utility(
            Assignment(Assignment("Burglary"), "Action",
                       ValueFactory.create("DoNothing"))) == pytest.approx(
                           -10, abs=0.0001)
    def test_table_expansion(self):
        bn = NetworkExamples.construct_basic_network()

        builder = CategoricalTableBuilder("HouseSize")
        builder.add_row(ValueFactory.create("Small"), 0.7)
        builder.add_row(ValueFactory.create("Big"), 0.2)
        builder.add_row(ValueFactory.create("None"), 0.1)

        node = ChanceNode("HouseSize", builder.build())
        bn.add_node(node)
        bn.get_node("Burglary").add_input_node(node)
        assert bn.get_chance_node("Burglary").get_prob(
            Assignment(["HouseSize", "Small"]),
            ValueFactory.create(True)) == pytest.approx(0.001, abs=0.0001)
        assert bn.get_chance_node("Burglary").get_prob(
            Assignment(["HouseSize", "Big"]),
            ValueFactory.create(True)) == pytest.approx(0.001, abs=0.0001)
        bn.get_node("Alarm").add_input_node(node)
        assert bn.get_chance_node("Alarm").get_prob(
            Assignment(["Burglary", "Earthquake"]),
            ValueFactory.create(True)) == pytest.approx(0.95, abs=0.0001)
        assert bn.get_chance_node("Alarm").get_prob(
            Assignment(Assignment(["Burglary", "Earthquake"]), "HouseSize",
                       ValueFactory.create("None")),
            ValueFactory.create(True)) == pytest.approx(0.95, abs=0.0001)
예제 #3
0
    def test_network1(self):
        bn = NetworkExamples.construct_basic_network()
        full_joint = NaiveInference.get_full_joint(bn, False)

        assert full_joint[Assignment(
            ["JohnCalls", "MaryCalls", "Alarm", "!Burglary",
             "!Earthquake"])] == pytest.approx(0.000628, abs=0.000001)
        assert full_joint.get(
            Assignment([
                "!JohnCalls", "!MaryCalls", "!Alarm", "!Burglary",
                "!Earthquake"
            ])) == pytest.approx(0.9367428, abs=0.000001)

        naive = NaiveInference()
        query = naive.query_prob(bn, ["Burglary"],
                                 Assignment(["JohnCalls", "MaryCalls"]))

        assert query.get_prob(Assignment("Burglary",
                                         False)) == pytest.approx(0.71367,
                                                                  abs=0.0001)
        assert query.get_prob(Assignment("Burglary",
                                         True)) == pytest.approx(0.286323,
                                                                 abs=0.0001)

        query2 = naive.query_prob(bn, ["Alarm", "Burglary"],
                                  Assignment(["Alarm", "MaryCalls"]))

        assert query2.get_prob(Assignment(["Alarm", "!Burglary"
                                           ])) == pytest.approx(0.623974,
                                                                abs=0.001)
예제 #4
0
    def test_network1bis(self):
        bn = NetworkExamples.construct_basic_network2()
        full_joint = NaiveInference.get_full_joint(bn, False)

        assert full_joint.get(
            Assignment([
                "JohnCalls", "MaryCalls", "Alarm", "!Burglary", "!Earthquake"
            ])) == pytest.approx(0.000453599, abs=0.000001)
        assert full_joint.get(
            Assignment([
                "!JohnCalls", "!MaryCalls", "!Alarm", "!Burglary",
                "!Earthquake"
            ])) == pytest.approx(0.6764828, abs=0.000001)

        naive = NaiveInference()
        query = naive.query_prob(bn, ["Burglary"],
                                 Assignment(["JohnCalls", "MaryCalls"]))

        assert query.get_prob(Assignment("Burglary",
                                         False)) == pytest.approx(0.360657,
                                                                  abs=0.0001)
        assert query.get_prob(Assignment("Burglary",
                                         True)) == pytest.approx(0.639343,
                                                                 abs=0.0001)

        query2 = naive.query_prob(bn, ["Alarm", "Burglary"],
                                  Assignment(["Alarm", "MaryCalls"]))

        assert query2.get_prob(Assignment(["Alarm", "!Burglary"
                                           ])) == pytest.approx(0.3577609,
                                                                abs=0.001)
    def test_removal(self):
        bn = NetworkExamples.construct_basic_network()

        bn.remove_node("Earthquake")
        assert len(bn.get_chance_node("Alarm").get_input_nodes()) == 1
        bn.remove_node("Alarm")
        assert len(bn.get_chance_node("MaryCalls").get_input_nodes()) == 0
        assert len(bn.get_chance_node("Burglary").get_output_nodes()) == 2
        assert len(bn.get_nodes()) == 6

        bn = NetworkExamples.construct_basic_network()

        e = bn.get_chance_node("Alarm")
        e.remove_input_node("Earthquake")
        assert len(bn.get_chance_node("Alarm").get_input_nodes()) == 1
        assert len(bn.get_chance_node("Earthquake").get_output_nodes()) == 0
예제 #6
0
    def test_switching(self):
        old_factor = SwitchingAlgorithm.max_branching_factor
        SwitchingAlgorithm.max_branching_factor = 4
        network = NetworkExamples.construct_basic_network2()
        distrib = SwitchingAlgorithm().query_prob(
            network, ["Burglary"], Assignment(["JohnCalls", "MaryCalls"]))

        assert isinstance(distrib, MultivariateTable)

        builder = CategoricalTableBuilder("n1")
        builder.add_row(ValueFactory.create("aha"), 1.0)

        n1 = ChanceNode("n1", builder.build())
        network.add_node(n1)
        builder = CategoricalTableBuilder("n2")
        builder.add_row(ValueFactory.create("oho"), 0.7)

        n2 = ChanceNode("n2", builder.build())
        network.add_node(n2)
        builder = CategoricalTableBuilder("n3")
        builder.add_row(ValueFactory.create("ihi"), 0.7)

        n3 = ChanceNode("n3", builder.build())
        network.add_node(n3)
        network.get_node("Alarm").add_input_node(n1)
        network.get_node("Alarm").add_input_node(n2)
        network.get_node("Alarm").add_input_node(n3)

        distrib = SwitchingAlgorithm().query_prob(
            network, ["Burglary"], Assignment(["JohnCalls", "MaryCalls"]))
        assert distrib.__class__ == EmpiricalDistribution

        network.remove_node(n1.get_id())
        network.remove_node(n2.get_id())

        distrib = SwitchingAlgorithm().query_prob(
            network, ["Burglary"], Assignment(["JohnCalls", "MaryCalls"]))
        assert isinstance(distrib, MultivariateTable)

        n1 = ChanceNode(
            "n1",
            ContinuousDistribution("n1", UniformDensityFunction(-2.0, 2.0)))
        n2 = ChanceNode(
            "n2",
            ContinuousDistribution("n2", GaussianDensityFunction(-1.0, 3.0)))

        network.add_node(n1)
        network.add_node(n2)
        network.get_node("Earthquake").add_input_node(n1)
        network.get_node("Earthquake").add_input_node(n2)

        distrib = SwitchingAlgorithm().query_prob(
            network, ["Burglary"], Assignment(["JohnCalls", "MaryCalls"]))
        assert isinstance(distrib, EmpiricalDistribution)

        SwitchingAlgorithm.max_branching_factor = old_factor
    def test_id_chance(self):
        bn = NetworkExamples.construct_basic_network()

        node = bn.get_node("Alarm")
        node.set_id("Alarm2")
        assert bn.has_node("Alarm2")
        assert not bn.has_node("Alarm")
        assert bn.has_chance_node("Alarm2")
        assert not bn.has_chance_node("Alarm")
        assert "Alarm2" in bn.get_node("Burglary").get_output_node_ids()
        assert "Alarm" not in bn.get_node("Burglary").get_output_node_ids()
        assert "Alarm2" in bn.get_node("MaryCalls").get_input_node_ids()
        assert "Alarm" not in bn.get_node("MaryCalls").get_input_node_ids()
    def test_cliques(self):
        bn = NetworkExamples.construct_basic_network()
        assert len(bn.get_cliques()) == 1
        assert len(bn.get_cliques()[0]) == 8

        bn.get_node("JohnCalls").remove_input_node("Alarm")
        cliques = bn.get_cliques()
        assert len(cliques) == 2
        # 원래 테스트 케이스와 셋에 대한 정렬 순서가 달라 테스트케이스 그대로 활용 불가능.
        # assert len(bn.get_cliques()[1]) == 7
        # assert len(bn.get_cliques()[0]) == 1
        result = dict()
        for clique in cliques:
            if len(clique) not in result:
                result[len(clique)] = 0

            result[len(clique)] += 1

        assert result[7] == 1
        del result[7]
        assert result[1] == 1
        del result[1]

        assert len(result) == 0

        bn.get_node("Alarm").remove_input_node("Burglary")
        bn.get_node("Alarm").remove_input_node("Earthquake")
        cliques = bn.get_cliques()
        assert len(cliques) == 4
        # 원래 테스트 케이스와 셋에 대한 정렬 순서가 달라 테스트케이스 그대로 활용 불가능.
        # assert len(bn.get_cliques()[3]) == 2
        # assert len(bn.get_cliques()[2]) == 4
        # assert len(bn.get_cliques()[1]) == 1
        # assert len(bn.get_cliques()[0]) == 1

        result = dict()
        for clique in cliques:
            if len(clique) not in result:
                result[len(clique)] = 0

            result[len(clique)] += 1

        assert result[1] == 2
        del result[1]
        assert result[2] == 1
        del result[2]
        assert result[4] == 1
        del result[4]

        assert len(result) == 0
    def test_copy_id_change(self):
        bn = NetworkExamples.construct_basic_network()

        bn2 = copy(bn)
        node = bn.get_node("Earthquake")
        node.set_id("Earthquake2")
        assert "Earthquake2" not in bn2.get_node("Alarm").get_input_node_ids()
        assert "Earthquake2" not in bn2.get_node("Alarm").get_input_node_ids()

        node2 = bn.get_node("Alarm")
        node2.set_id("Alarm2")
        assert "Alarm2" not in bn2.get_node("MaryCalls").get_input_node_ids()
        assert "Alarm2" not in bn2.get_node("Burglary").get_output_node_ids()
        assert "Alarm" in bn2.get_node("Burglary").get_output_node_ids()
        assert "Alarm" in bn2.get_node("MaryCalls").get_input_node_ids()
    def test_copy(self):
        bn = NetworkExamples.construct_basic_network()

        bn2 = copy(bn)
        b = bn.get_chance_node("Burglary")

        builder = CategoricalTableBuilder("Burglary")
        builder.add_row(ValueFactory.create(True), 0.2)
        builder.add_row(ValueFactory.create(False), 0.8)
        b.set_distrib(builder.build())

        value = bn.get_utility_node("Util1")
        value.add_utility(
            Assignment(Assignment("Burglary", True), "Action",
                       ValueFactory.create("DoNothing")), -20.0)

        assert len(bn.get_node("Burglary").get_output_nodes()) == 3
        assert len(bn2.get_node("Burglary").get_output_nodes()) == 3

        assert len(bn.get_node("Alarm").get_output_nodes()) == 2
        assert len(bn2.get_node("Alarm").get_output_nodes()) == 2
        assert len(bn.get_node("Alarm").get_input_nodes()) == 2
        assert len(bn2.get_node("Alarm").get_input_nodes()) == 2

        assert len(bn.get_node("Util1").get_input_nodes()) == 2
        assert len(bn2.get_node("Util1").get_input_nodes()) == 2

        assert len(bn2.get_node("Burglary").get_values()) == 2
        assert len(bn2.get_node("Alarm").get_values()) == 2
        assert len(bn2.get_node("MaryCalls").get_values()) == 2

        assert ValueFactory.create(True) in bn2.get_node(
            "Burglary").get_values()

        assert bn2.get_chance_node("Burglary").get_prob(
            ValueFactory.create(True)) == pytest.approx(0.001, abs=0.0001)
        assert bn2.get_chance_node("Alarm").get_prob(
            Assignment(["Burglary", "Earthquake"]),
            ValueFactory.create(True)) == pytest.approx(0.95, abs=0.0001)
        assert bn2.get_chance_node("JohnCalls").get_prob(
            Assignment("Alarm"),
            ValueFactory.create(True)) == pytest.approx(0.9, abs=0.0001)

        assert len(bn2.get_action_node("Action").get_values()) == 3
        assert bn2.get_utility_node("Util2").get_utility(
            Assignment(Assignment("Burglary"), "Action",
                       ValueFactory.create("DoNothing"))) == pytest.approx(
                           -10, abs=0.0001)
    def test_structure(self):
        bn = NetworkExamples.construct_basic_network()

        assert len(bn.get_node("Burglary").get_descendant_ids()) == 5
        assert "Alarm" in bn.get_node("Burglary").get_descendant_ids()
        assert "MaryCalls" in bn.get_node("Burglary").get_descendant_ids()

        assert len(bn.get_node("MaryCalls").get_ancestor_ids()) == 3
        assert "Alarm" in bn.get_node("MaryCalls").get_ancestor_ids()
        assert "Earthquake" in bn.get_node("MaryCalls").get_ancestor_ids()
        assert len(bn.get_node("MaryCalls").get_descendant_ids()) == 0

        assert len(bn.get_node("Util1").get_ancestor_ids()) == 2
        assert "Action" in bn.get_node("Util1").get_ancestor_ids()
        assert len(bn.get_node("Util1").get_descendant_ids()) == 0

        assert len(bn.get_node("Action").get_ancestor_ids()) == 0
        assert "Util1" in bn.get_node("Action").get_descendant_ids()
        assert len(bn.get_node("Action").get_descendant_ids()) == 2
예제 #12
0
    def test_network3bis(self):
        iz = SamplingAlgorithm(5000, 300)
        bn = NetworkExamples.construct_basic_network2()

        query = iz.query_prob(bn, ["Burglary"],
                              Assignment(["JohnCalls", "MaryCalls"]))

        assert query.get_prob(Assignment("Burglary",
                                         False)) == pytest.approx(0.362607,
                                                                  abs=0.06)
        assert query.get_prob(Assignment("Burglary",
                                         True)) == pytest.approx(0.637392,
                                                                 abs=0.06)

        query2 = iz.query_prob(bn, ["Alarm", "Burglary"],
                               Assignment(["Alarm", "MaryCalls"]))

        assert query2.get_prob(Assignment(["Alarm", "!Burglary"
                                           ])) == pytest.approx(0.35970,
                                                                abs=0.05)
예제 #13
0
    def test_network2(self):
        ve = VariableElimination()
        bn = NetworkExamples.construct_basic_network()

        distrib = ve.query_prob(bn, ["Burglary"],
                                Assignment(["JohnCalls", "MaryCalls"]))

        assert distrib.get_prob(Assignment("Burglary",
                                           False)) == pytest.approx(0.713676,
                                                                    abs=0.0001)
        assert distrib.get_prob(Assignment("Burglary",
                                           True)) == pytest.approx(0.286323,
                                                                   abs=0.0001)

        query2 = ve.query_prob(bn, ["Alarm", "Burglary"],
                               Assignment(["Alarm", "MaryCalls"]))

        assert query2.get_prob(Assignment(["Alarm", "!Burglary"
                                           ])) == pytest.approx(0.623974,
                                                                abs=0.001)
예제 #14
0
    def test_network2bis(self):
        ve = VariableElimination()
        bn = NetworkExamples.construct_basic_network2()

        query = ve.query_prob(bn, ["Burglary"],
                              Assignment(["JohnCalls", "MaryCalls"]))

        assert query.get_prob(Assignment("Burglary",
                                         False)) == pytest.approx(0.360657,
                                                                  abs=0.0001)
        assert query.get_prob(Assignment("Burglary",
                                         True)) == pytest.approx(0.63934,
                                                                 abs=0.0001)

        query2 = ve.query_prob(bn, ["Alarm", "Burglary"],
                               Assignment(["Alarm", "MaryCalls"]))

        assert query2.get_prob(Assignment(["Alarm", "!Burglary"
                                           ])) == pytest.approx(0.3577609,
                                                                abs=0.001)
    def test_sorted_nodes(self):
        bn = NetworkExamples.construct_basic_network()
        assert "Action" == bn.get_sorted_nodes()[7].get_id()
        assert "Burglary" == bn.get_sorted_nodes()[6].get_id()
        assert "Earthquake" == bn.get_sorted_nodes()[5].get_id()
        assert "Alarm" == bn.get_sorted_nodes()[4].get_id()
        assert "Util1" == bn.get_sorted_nodes()[3].get_id()
        assert "Util2" == bn.get_sorted_nodes()[2].get_id()
        assert "JohnCalls" == bn.get_sorted_nodes()[1].get_id()
        assert "MaryCalls" == bn.get_sorted_nodes()[0].get_id()

        d1 = ActionNode("a_m'")
        d2 = ActionNode("a_m.obj'")
        d3 = ActionNode("a_m.place'")
        bn2 = BNetwork()
        bn2.add_node(d1)
        bn2.add_node(d2)
        bn2.add_node(d3)
        assert "a_m'" == bn2.get_sorted_nodes()[2].get_id()
        assert "a_m.obj'" == bn2.get_sorted_nodes()[1].get_id()
        assert "a_m.place'" == bn2.get_sorted_nodes()[0].get_id()
    def test_network(self):
        inference = InferenceChecks()
        inference.include_naive(True)

        bn = NetworkExamples.construct_basic_network2()

        query_vars_powerset = self.generate_powerset(bn.get_chance_node_ids())
        evidence_powerset = self.generate_evidence_powerset(bn)

        nb_errors = 0

        for query_vars in query_vars_powerset:
            if len(query_vars) != 0:
                for evidence in evidence_powerset:
                    if Random().random(
                    ) < TestInferenceLargeScale.percent_comparisions / 100.0:
                        try:
                            inference.check_prob(bn, query_vars, evidence)
                        except:
                            nb_errors += 1
                            if nb_errors > 2:
                                assert False, "more than 2 sampling errors"

        inference.show_performance()
예제 #17
0
    def test_network_util(self):
        network = NetworkExamples.construct_basic_network2()
        ve = VariableElimination()
        naive = NaiveInference()
        iz = SamplingAlgorithm(4000, 300)

        assert ve.query_util(
            network, ["Action"],
            Assignment([
                Assignment("JohnCalls"),
                Assignment("MaryCalls")
            ])).get_util(Assignment("Action",
                                    "CallPolice")) == pytest.approx(-0.680,
                                                                    abs=0.001)
        assert naive.query_util(
            network, ["Action"],
            Assignment([
                Assignment("JohnCalls"),
                Assignment("MaryCalls")
            ])).get_util(Assignment("Action",
                                    "CallPolice")) == pytest.approx(-0.680,
                                                                    abs=0.001)
        assert iz.query_util(
            network, ["Action"],
            Assignment([Assignment("JohnCalls"),
                        Assignment("MaryCalls")])).get_util(
                            Assignment("Action",
                                       "CallPolice")) == pytest.approx(-0.680,
                                                                       abs=0.5)
        assert ve.query_util(
            network, ["Action"],
            Assignment([
                Assignment("JohnCalls"),
                Assignment("MaryCalls")
            ])).get_util(Assignment("Action",
                                    "DoNothing")) == pytest.approx(-6.213,
                                                                   abs=0.001)
        assert naive.query_util(
            network, ["Action"],
            Assignment([
                Assignment("JohnCalls"),
                Assignment("MaryCalls")
            ])).get_util(Assignment("Action",
                                    "DoNothing")) == pytest.approx(-6.213,
                                                                   abs=0.001)
        assert iz.query_util(
            network, ["Action"],
            Assignment([Assignment("JohnCalls"),
                        Assignment("MaryCalls")])).get_util(
                            Assignment("Action",
                                       "DoNothing")) == pytest.approx(-6.213,
                                                                      abs=1.5)
        assert ve.query_util(
            network, ["Burglary"],
            Assignment([
                Assignment("JohnCalls"),
                Assignment("MaryCalls")
            ])).get_util(Assignment("!Burglary")) == pytest.approx(-0.1667,
                                                                   abs=0.001)
        assert naive.query_util(
            network, ["Burglary"],
            Assignment([
                Assignment("JohnCalls"),
                Assignment("MaryCalls")
            ])).get_util(Assignment("!Burglary")) == pytest.approx(-0.1667,
                                                                   abs=0.001)
        assert iz.query_util(
            network, ["Burglary"],
            Assignment([Assignment("JohnCalls"),
                        Assignment("MaryCalls")])).get_util(
                            Assignment("!Burglary")) == pytest.approx(-0.25,
                                                                      abs=0.5)
        assert ve.query_util(
            network, ["Burglary"],
            Assignment([Assignment("JohnCalls"),
                        Assignment("MaryCalls")])).get_util(
                            Assignment("Burglary")) == pytest.approx(-3.5,
                                                                     abs=0.001)
        assert naive.query_util(
            network, ["Burglary"],
            Assignment([Assignment("JohnCalls"),
                        Assignment("MaryCalls")])).get_util(
                            Assignment("Burglary")) == pytest.approx(-3.5,
                                                                     abs=0.001)
        assert iz.query_util(
            network, ["Burglary"],
            Assignment([Assignment("JohnCalls"),
                        Assignment("MaryCalls")])).get_util(
                            Assignment("Burglary")) == pytest.approx(-3.5,
                                                                     abs=1.0)
class TestNetworkReduction:
    network = NetworkExamples.construct_basic_network2()
    ve = VariableElimination()

    # change the variable name 'is' -> 'iz'
    iz = SamplingAlgorithm(3000, 500)
    naive = NaiveInference()
    sw = SwitchingAlgorithm()

    def test1(self):
        reduced_net = TestNetworkReduction.ve.reduce(
            TestNetworkReduction.network,
            ["Burglary", "Earthquake", "MaryCalls"])
        reduced_net2 = TestNetworkReduction.naive.reduce(
            TestNetworkReduction.network,
            ["Burglary", "Earthquake", "MaryCalls"])
        reduced_net3 = TestNetworkReduction.iz.reduce(
            TestNetworkReduction.network,
            ["Burglary", "Earthquake", "MaryCalls"])
        reduced_net4 = TestNetworkReduction.sw.reduce(
            TestNetworkReduction.network,
            ["Burglary", "Earthquake", "MaryCalls"])

        assert len(reduced_net.get_nodes()) == 3
        assert len(reduced_net2.get_nodes()) == 3
        assert len(reduced_net3.get_nodes()) == 3
        assert len(reduced_net4.get_nodes()) == 3
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network,
            ["MaryCalls"], Assignment("Burglary")).get_prob(
                Assignment("MaryCalls")) == pytest.approx(
                    TestNetworkReduction.ve.query_prob(
                        reduced_net, ["MaryCalls"],
                        Assignment("Burglary")).get_prob(
                            Assignment("MaryCalls")),
                    abs=0.0001)
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network,
            ["MaryCalls"], Assignment("Burglary")).get_prob(
                Assignment("MaryCalls")) == pytest.approx(
                    TestNetworkReduction.ve.query_prob(
                        reduced_net2, ["MaryCalls"],
                        Assignment("Burglary")).get_prob(
                            Assignment("MaryCalls")),
                    abs=0.0001)
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network,
            ["MaryCalls"], Assignment("Burglary")).get_prob(
                Assignment("MaryCalls")) == pytest.approx(
                    TestNetworkReduction.iz.query_prob(
                        reduced_net3, ["MaryCalls"],
                        Assignment("Burglary")).get_prob(
                            Assignment("MaryCalls")),
                    abs=0.15)
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network,
            ["MaryCalls"], Assignment("Burglary")).get_prob(
                Assignment("MaryCalls")) == pytest.approx(
                    TestNetworkReduction.iz.query_prob(
                        reduced_net4, ["MaryCalls"],
                        Assignment("Burglary")).get_prob(
                            Assignment("MaryCalls")),
                    abs=0.15)
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network, ["Earthquake"],
            Assignment("!MaryCalls")).get_prob(
                Assignment("Earthquake")) == pytest.approx(
                    TestNetworkReduction.ve.query_prob(
                        reduced_net, ["Earthquake"],
                        Assignment("!MaryCalls")).get_prob(
                            Assignment("Earthquake")),
                    abs=0.0001)
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network, ["Earthquake"],
            Assignment("!MaryCalls")).get_prob(
                Assignment("Earthquake")) == pytest.approx(
                    TestNetworkReduction.ve.query_prob(
                        reduced_net2, ["Earthquake"],
                        Assignment("!MaryCalls")).get_prob(
                            Assignment("Earthquake")),
                    abs=0.0001)
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network, ["Earthquake"],
            Assignment("!MaryCalls")).get_prob(
                Assignment("Earthquake")) == pytest.approx(
                    TestNetworkReduction.iz.query_prob(
                        reduced_net3, ["Earthquake"],
                        Assignment("!MaryCalls")).get_prob(
                            Assignment("Earthquake")),
                    abs=0.05)
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network, ["Earthquake"],
            Assignment("!MaryCalls")).get_prob(
                Assignment("Earthquake")) == pytest.approx(
                    TestNetworkReduction.iz.query_prob(
                        reduced_net4, ["Earthquake"],
                        Assignment("!MaryCalls")).get_prob(
                            Assignment("Earthquake")),
                    abs=0.05)

    def test2(self):
        reduced_net = TestNetworkReduction.ve.reduce(
            TestNetworkReduction.network, ["Burglary", "MaryCalls"],
            Assignment("!Earthquake"))
        reduced_net2 = TestNetworkReduction.naive.reduce(
            TestNetworkReduction.network, ["Burglary", "MaryCalls"],
            Assignment("!Earthquake"))
        reduced_net3 = TestNetworkReduction.iz.reduce(
            TestNetworkReduction.network, ["Burglary", "MaryCalls"],
            Assignment("!Earthquake"))
        reduced_net4 = TestNetworkReduction.sw.reduce(
            TestNetworkReduction.network, ["Burglary", "MaryCalls"],
            Assignment("!Earthquake"))

        assert len(reduced_net.get_nodes()) == 2
        assert len(reduced_net2.get_nodes()) == 2
        assert len(reduced_net3.get_nodes()) == 2
        assert len(reduced_net4.get_nodes()) == 2
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network, ["MaryCalls"],
            Assignment("!Earthquake")).get_prob(
                Assignment("MaryCalls")) == pytest.approx(
                    TestNetworkReduction.ve.query_prob(
                        reduced_net,
                        ["MaryCalls"]).get_prob(Assignment("MaryCalls")),
                    abs=0.0001)
        assert TestNetworkReduction.ve.query_prob(
            reduced_net,
            ["MaryCalls"]).get_prob(Assignment("MaryCalls")) == pytest.approx(
                TestNetworkReduction.naive.query_prob(
                    reduced_net2,
                    ["MaryCalls"]).get_prob(Assignment("MaryCalls")),
                abs=0.0001)
        assert TestNetworkReduction.ve.query_prob(
            reduced_net,
            ["MaryCalls"]).get_prob(Assignment("MaryCalls")) == pytest.approx(
                TestNetworkReduction.iz.query_prob(
                    reduced_net3,
                    ["MaryCalls"]).get_prob(Assignment("MaryCalls")),
                abs=0.05)
        assert TestNetworkReduction.ve.query_prob(
            reduced_net,
            ["MaryCalls"]).get_prob(Assignment("MaryCalls")) == pytest.approx(
                TestNetworkReduction.iz.query_prob(
                    reduced_net4,
                    ["MaryCalls"]).get_prob(Assignment("MaryCalls")),
                abs=0.05)
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network, ["Burglary"],
            Assignment(["!MaryCalls", "!Earthquake"
                        ])).get_prob(Assignment("Burglary")) == pytest.approx(
                            TestNetworkReduction.ve.query_prob(
                                reduced_net, ["Burglary"],
                                Assignment("!MaryCalls")).get_prob(
                                    Assignment("Burglary")),
                            abs=0.0001)
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network, ["Burglary"],
            Assignment(["!MaryCalls", "!Earthquake"
                        ])).get_prob(Assignment("Burglary")) == pytest.approx(
                            TestNetworkReduction.naive.query_prob(
                                reduced_net2, ["Burglary"],
                                Assignment("!MaryCalls")).get_prob(
                                    Assignment("Burglary")),
                            abs=0.0001)
        assert TestNetworkReduction.ve.query_prob(
            reduced_net, ["Burglary"], Assignment("!MaryCalls")).get_prob(
                Assignment("Burglary")) == pytest.approx(
                    TestNetworkReduction.iz.query_prob(
                        reduced_net3, ["Burglary"],
                        Assignment("!MaryCalls")).get_prob(
                            Assignment("Burglary")),
                    abs=0.05)
        assert TestNetworkReduction.ve.query_prob(
            reduced_net, ["Burglary"], Assignment("!MaryCalls")).get_prob(
                Assignment("Burglary")) == pytest.approx(
                    TestNetworkReduction.iz.query_prob(
                        reduced_net4, ["Burglary"],
                        Assignment("!MaryCalls")).get_prob(
                            Assignment("Burglary")),
                    abs=0.05)

    def test3(self):
        reduced_net = TestNetworkReduction.ve.reduce(
            TestNetworkReduction.network, ["Burglary", "Earthquake"],
            Assignment("JohnCalls"))
        reduced_net2 = TestNetworkReduction.naive.reduce(
            TestNetworkReduction.network, ["Burglary", "Earthquake"],
            Assignment("JohnCalls"))
        reduced_net3 = TestNetworkReduction.iz.reduce(
            TestNetworkReduction.network, ["Burglary", "Earthquake"],
            Assignment("JohnCalls"))
        reduced_net4 = TestNetworkReduction.sw.reduce(
            TestNetworkReduction.network, ["Burglary", "Earthquake"],
            Assignment("JohnCalls"))

        assert len(reduced_net.get_nodes()) == 2
        assert len(reduced_net2.get_nodes()) == 2
        assert len(reduced_net3.get_nodes()) == 2
        assert len(reduced_net4.get_nodes()) == 2
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network,
            ["Burglary"], Assignment("JohnCalls")).get_prob(
                Assignment("Burglary")) == pytest.approx(
                    TestNetworkReduction.iz.query_prob(
                        reduced_net,
                        ["Burglary"]).get_prob(Assignment("Burglary")),
                    abs=0.1)
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network,
            ["Burglary"], Assignment("JohnCalls")).get_prob(
                Assignment("Burglary")) == pytest.approx(
                    TestNetworkReduction.naive.query_prob(
                        reduced_net2,
                        ["Burglary"]).get_prob(Assignment("Burglary")),
                    abs=0.0001)
        assert TestNetworkReduction.ve.query_prob(
            reduced_net,
            ["Burglary"]).get_prob(Assignment("Burglary")) == pytest.approx(
                TestNetworkReduction.naive.query_prob(
                    reduced_net3,
                    ["Burglary"]).get_prob(Assignment("Burglary")),
                abs=0.08)
        assert TestNetworkReduction.ve.query_prob(
            reduced_net2,
            ["Burglary"]).get_prob(Assignment("Burglary")) == pytest.approx(
                TestNetworkReduction.naive.query_prob(
                    reduced_net4,
                    ["Burglary"]).get_prob(Assignment("Burglary")),
                abs=0.05)
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network, ["Earthquake"],
            Assignment("JohnCalls")).get_prob(
                Assignment("Earthquake")) == pytest.approx(
                    TestNetworkReduction.ve.query_prob(
                        reduced_net,
                        ["Earthquake"]).get_prob(Assignment("Earthquake")),
                    abs=0.0001)
        assert TestNetworkReduction.ve.query_prob(
            reduced_net, ["Earthquake"]).get_prob(
                Assignment("Earthquake")) == pytest.approx(
                    TestNetworkReduction.iz.query_prob(
                        reduced_net2,
                        ["Earthquake"]).get_prob(Assignment("Earthquake")),
                    abs=0.07)
        assert TestNetworkReduction.ve.query_prob(
            TestNetworkReduction.network, ["Earthquake"],
            Assignment("JohnCalls")).get_prob(
                Assignment("Earthquake")) == pytest.approx(
                    TestNetworkReduction.naive.query_prob(
                        reduced_net3,
                        ["Earthquake"]).get_prob(Assignment("Earthquake")),
                    abs=0.07)
        assert TestNetworkReduction.ve.query_prob(
            reduced_net, ["Earthquake"]).get_prob(
                Assignment("Earthquake")) == pytest.approx(
                    TestNetworkReduction.naive.query_prob(
                        reduced_net4,
                        ["Earthquake"]).get_prob(Assignment("Earthquake")),
                    abs=0.07)

    def test5(self):
        reduced_net = TestNetworkReduction.ve.reduce(
            TestNetworkReduction.network, ["Burglary"],
            Assignment(["JohnCalls", "MaryCalls"]))

        reduced_net2 = TestNetworkReduction.iz.reduce(
            TestNetworkReduction.network, ["Burglary"],
            Assignment(["JohnCalls", "MaryCalls"]))

        reduced_net.add_node(
            copy(TestNetworkReduction.network.get_node("Action")))
        reduced_net.add_node(
            copy(TestNetworkReduction.network.get_node("Util1")))
        reduced_net.add_node(
            copy(TestNetworkReduction.network.get_node("Util2")))
        reduced_net.get_node("Util1").add_input_node(
            reduced_net.get_node("Burglary"))
        reduced_net.get_node("Util1").add_input_node(
            reduced_net.get_node("Action"))
        reduced_net.get_node("Util2").add_input_node(
            reduced_net.get_node("Burglary"))
        reduced_net.get_node("Util2").add_input_node(
            reduced_net.get_node("Action"))

        table1 = TestNetworkReduction.ve.query_util(reduced_net, "Action")
        table2 = TestNetworkReduction.ve.query_util(
            TestNetworkReduction.network, ["Action"],
            Assignment(["JohnCalls", "MaryCalls"]))

        for a in table1.get_table().keys():
            assert table1.get_util(a) == pytest.approx(table2.get_util(a),
                                                       abs=0.01)

        reduced_net2.add_node(
            copy(TestNetworkReduction.network.get_node("Action")))
        reduced_net2.add_node(
            copy(TestNetworkReduction.network.get_node("Util1")))
        reduced_net2.add_node(
            copy(TestNetworkReduction.network.get_node("Util2")))
        reduced_net2.get_node("Util1").add_input_node(
            reduced_net2.get_node("Burglary"))
        reduced_net2.get_node("Util1").add_input_node(
            reduced_net2.get_node("Action"))
        reduced_net2.get_node("Util2").add_input_node(
            reduced_net2.get_node("Burglary"))
        reduced_net2.get_node("Util2").add_input_node(
            reduced_net2.get_node("Action"))

        table3 = TestNetworkReduction.ve.query_util(reduced_net2, ["Action"])

        for a in table1.get_table().keys():
            assert table1.get_util(a) == pytest.approx(table3.get_util(a),
                                                       abs=0.8)

    def test6(self):
        old = copy(TestNetworkReduction.network)

        TestNetworkReduction.network.get_node("Alarm").remove_input_node(
            "Earthquake")
        TestNetworkReduction.network.get_node("Alarm").remove_input_node(
            "Burglary")
        TestNetworkReduction.network.get_chance_node("Alarm").set_distrib(
            SingleValueDistribution("Alarm", "False"))

        self.test1()
        self.test2()
        self.test3()

        TestNetworkReduction.network = old