// AIMA3e pg. 512
        protected void test_BurglaryAlarmModel(ProbabilityModel model)
        {
            Assert.IsTrue(model.isValid());

            AssignmentProposition aburglary = new AssignmentProposition(
                ExampleRV.BURGLARY_RV, Boolean.TRUE);
            AssignmentProposition anotburglary = new AssignmentProposition(
                ExampleRV.BURGLARY_RV, Boolean.FALSE);
            AssignmentProposition anotearthquake = new AssignmentProposition(
                ExampleRV.EARTHQUAKE_RV, Boolean.FALSE);
            AssignmentProposition aalarm = new AssignmentProposition(
                ExampleRV.ALARM_RV, Boolean.TRUE);
            AssignmentProposition anotalarm = new AssignmentProposition(
                ExampleRV.ALARM_RV, Boolean.FALSE);
            AssignmentProposition ajohnCalls = new AssignmentProposition(
                ExampleRV.JOHN_CALLS_RV, Boolean.TRUE);
            AssignmentProposition amaryCalls = new AssignmentProposition(
                ExampleRV.MARY_CALLS_RV, Boolean.TRUE);

            // AIMA3e pg. 514
            Assert.AreEqual(0.00062811126, model.prior(ajohnCalls, amaryCalls,
                                                       aalarm, anotburglary, anotearthquake), DELTA_THRESHOLD);
            Assert.AreEqual(0.00049800249, model.prior(ajohnCalls, amaryCalls,
                                                       anotalarm, anotburglary, anotearthquake), DELTA_THRESHOLD);

            // AIMA3e pg. 524
            // P(Burglary = true | JohnCalls = true, MaryCalls = true) = 0.00059224
            Assert.AreEqual(0.00059224,
                            model.prior(aburglary, ajohnCalls, amaryCalls), DELTA_THRESHOLD);
            // P(Burglary = false | JohnCalls = true, MaryCalls = true) = 0.0014919
            Assert.AreEqual(0.00149185764899,
                            model.prior(anotburglary, ajohnCalls, amaryCalls),
                            DELTA_THRESHOLD);
        }
        // AIMA3e pg. 496
        protected void test_MeningitisStiffNeckModel(ProbabilityModel model)
        {
            Assert.IsTrue(model.isValid());

            AssignmentProposition ameningitis = new AssignmentProposition(
                ExampleRV.MENINGITIS_RV, true);
            AssignmentProposition anotmeningitis = new AssignmentProposition(
                ExampleRV.MENINGITIS_RV, false);
            AssignmentProposition astiffNeck = new AssignmentProposition(
                ExampleRV.STIFF_NECK_RV, true);
            AssignmentProposition anotstiffNeck = new AssignmentProposition(
                ExampleRV.STIFF_NECK_RV, false);

            // P(stiffNeck | meningitis) = 0.7
            Assert.AreEqual(0.7, model.posterior(astiffNeck, ameningitis),
                            DELTA_THRESHOLD);
            // P(meningitis) = 1/50000
            Assert.AreEqual(0.00002, model.prior(ameningitis), DELTA_THRESHOLD);
            // P(~meningitis) = 1-1/50000
            Assert.AreEqual(0.99998, model.prior(anotmeningitis),
                            DELTA_THRESHOLD);
            // P(stiffNeck) = 0.01
            Assert.AreEqual(0.01, model.prior(astiffNeck), DELTA_THRESHOLD);
            // P(~stiffNeck) = 0.99
            Assert.AreEqual(0.99, model.prior(anotstiffNeck), DELTA_THRESHOLD);
            // P(meningitis | stiffneck)
            // = P(stiffneck | meningitis)P(meningitis)/P(stiffneck)
            // = (0.7 * 0.00002)/0.01
            // = 0.0014 (13.4)
            Assert.AreEqual(0.0014, model.posterior(ameningitis, astiffNeck),
                            DELTA_THRESHOLD);

            // Assuming P(~stiffneck | meningitis) = 0.3 (pg. 497), i.e. CPT (row
            // must = 1)
            //
            // P(meningitis | ~stiffneck)
            // = P(~stiffneck | meningitis)P(meningitis)/P(~stiffneck)
            // = (0.3 * 0.00002)/0.99
            // = 0.000006060606
            Assert.AreEqual(0.000006060606,
                            model.posterior(ameningitis, anotstiffNeck), DELTA_THRESHOLD);
        }
        public void test_RollingPairFairDiceModel(ProbabilityModel model)
        {
            Assert.IsTrue(model.isValid());

            // Ensure each dice has 1/6 probability
            for (int d = 1; d <= 6; d++)
            {
                AssignmentProposition ad1 = new AssignmentProposition(
                    ExampleRV.DICE_1_RV, d);
                AssignmentProposition ad2 = new AssignmentProposition(
                    ExampleRV.DICE_2_RV, d);

                Assert.AreEqual(1.0 / 6.0, model.prior(ad1), DELTA_THRESHOLD);
                Assert.AreEqual(1.0 / 6.0, model.prior(ad2), DELTA_THRESHOLD);
            }

            // Ensure each combination is 1/36
            for (int d1 = 1; d1 <= 6; d1++)
            {
                for (int d2 = 1; d2 <= 6; d2++)
                {
                    AssignmentProposition ad1 = new AssignmentProposition(
                        ExampleRV.DICE_1_RV, d1);
                    AssignmentProposition ad2 = new AssignmentProposition(
                        ExampleRV.DICE_2_RV, d2);
                    ConjunctiveProposition d1AndD2 = new ConjunctiveProposition(
                        ad1, ad2);

                    Assert.AreEqual(1.0 / 6.0, model.prior(ad1),
                                    DELTA_THRESHOLD);
                    Assert.AreEqual(1.0 / 6.0, model.prior(ad2),
                                    DELTA_THRESHOLD);

                    // pg. 485 AIMA3e
                    Assert.AreEqual(1.0 / 36.0, model.prior(ad1, ad2),
                                    DELTA_THRESHOLD);
                    Assert.AreEqual(1.0 / 36.0, model.prior(d1AndD2),
                                    DELTA_THRESHOLD);

                    Assert.AreEqual(1.0 / 6.0, model.posterior(ad1, ad2),
                                    DELTA_THRESHOLD);
                    Assert.AreEqual(1.0 / 6.0, model.posterior(ad2, ad1),
                                    DELTA_THRESHOLD);
                }
            }

            // Test Sets of events defined via constraint propositions
            IntegerSumProposition total11 = new IntegerSumProposition("Total11",
                                                                      new FiniteIntegerDomain(11), ExampleRV.DICE_1_RV,
                                                                      ExampleRV.DICE_2_RV);

            Assert.AreEqual(2.0 / 36.0, model.prior(total11), DELTA_THRESHOLD);
            EquivalentProposition doubles = new EquivalentProposition("Doubles",
                                                                      ExampleRV.DICE_1_RV, ExampleRV.DICE_2_RV);

            Assert.AreEqual(1.0 / 6.0, model.prior(doubles), DELTA_THRESHOLD);
            SubsetProposition evenDice1 = new SubsetProposition("EvenDice1",
                                                                new FiniteIntegerDomain(2, 4, 6), ExampleRV.DICE_1_RV);

            Assert.AreEqual(0.5, model.prior(evenDice1), DELTA_THRESHOLD);
            SubsetProposition oddDice2 = new SubsetProposition("OddDice2",
                                                               new FiniteIntegerDomain(1, 3, 5), ExampleRV.DICE_2_RV);

            Assert.AreEqual(0.5, model.prior(oddDice2), DELTA_THRESHOLD);

            // pg. 485 AIMA3e
            AssignmentProposition dice1Is5 = new AssignmentProposition(
                ExampleRV.DICE_1_RV, 5);

            Assert.AreEqual(1.0 / 6.0, model.posterior(doubles, dice1Is5),
                            DELTA_THRESHOLD);

            Assert.AreEqual(1.0, model.prior(ExampleRV.DICE_1_RV),
                            DELTA_THRESHOLD);
            Assert.AreEqual(1.0, model.prior(ExampleRV.DICE_2_RV),
                            DELTA_THRESHOLD);
            Assert.AreEqual(1.0,
                            model.posterior(ExampleRV.DICE_1_RV, ExampleRV.DICE_2_RV),
                            DELTA_THRESHOLD);
            Assert.AreEqual(1.0,
                            model.posterior(ExampleRV.DICE_2_RV, ExampleRV.DICE_1_RV),
                            DELTA_THRESHOLD);

            // Test a disjunctive proposition pg.489
            // P(a OR b) = P(a) + P(b) - P(a AND b)
            // = 1/6 + 1/6 - 1/36
            AssignmentProposition dice2Is5 = new AssignmentProposition(
                ExampleRV.DICE_2_RV, 5);
            DisjunctiveProposition dice1Is5OrDice2Is5 = new DisjunctiveProposition(
                dice1Is5, dice2Is5);

            Assert.AreEqual(1.0 / 6.0 + 1.0 / 6.0 - 1.0 / 36.0,
                            model.prior(dice1Is5OrDice2Is5), DELTA_THRESHOLD);
        }
        protected void test_ToothacheCavityCatchModel(ProbabilityModel model)
        {
            Assert.IsTrue(model.isValid());

            AssignmentProposition atoothache = new AssignmentProposition(
                ExampleRV.TOOTHACHE_RV, Boolean.TRUE);
            AssignmentProposition anottoothache = new AssignmentProposition(
                ExampleRV.TOOTHACHE_RV, Boolean.FALSE);
            AssignmentProposition acavity = new AssignmentProposition(
                ExampleRV.CAVITY_RV, Boolean.TRUE);
            AssignmentProposition anotcavity = new AssignmentProposition(
                ExampleRV.CAVITY_RV, Boolean.FALSE);
            AssignmentProposition acatch = new AssignmentProposition(
                ExampleRV.CATCH_RV, Boolean.TRUE);
            AssignmentProposition anotcatch = new AssignmentProposition(
                ExampleRV.CATCH_RV, Boolean.FALSE);

            // AIMA3e pg. 485
            Assert.AreEqual(0.2, model.prior(acavity), DELTA_THRESHOLD);
            Assert.AreEqual(0.6, model.posterior(acavity, atoothache),
                            DELTA_THRESHOLD);
            ConjunctiveProposition toothacheAndNotCavity = new ConjunctiveProposition(
                atoothache, anotcavity);

            Assert.AreEqual(0.0,
                            model.posterior(acavity, toothacheAndNotCavity),
                            DELTA_THRESHOLD);
            Assert.AreEqual(0.0,
                            model.posterior(acavity, atoothache, anotcavity),
                            DELTA_THRESHOLD);

            // AIMA3e pg. 492
            DisjunctiveProposition cavityOrToothache = new DisjunctiveProposition(
                acavity, atoothache);

            Assert.AreEqual(0.28, model.prior(cavityOrToothache),
                            DELTA_THRESHOLD);

            // AIMA3e pg. 493
            Assert.AreEqual(0.4, model.posterior(anotcavity, atoothache),
                            DELTA_THRESHOLD);

            Assert.AreEqual(1.0, model.prior(ExampleRV.TOOTHACHE_RV),
                            DELTA_THRESHOLD);
            Assert.AreEqual(1.0, model.prior(ExampleRV.CAVITY_RV),
                            DELTA_THRESHOLD);
            Assert.AreEqual(1.0, model.prior(ExampleRV.CATCH_RV),
                            DELTA_THRESHOLD);
            Assert.AreEqual(1.0,
                            model.posterior(ExampleRV.TOOTHACHE_RV, ExampleRV.CAVITY_RV),
                            DELTA_THRESHOLD);
            Assert.AreEqual(1.0,
                            model.posterior(ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV),
                            DELTA_THRESHOLD);
            Assert.AreEqual(1.0, model.posterior(ExampleRV.TOOTHACHE_RV,
                                                 ExampleRV.CAVITY_RV, ExampleRV.CATCH_RV), DELTA_THRESHOLD);
            Assert.AreEqual(1.0,
                            model.posterior(ExampleRV.CAVITY_RV, ExampleRV.TOOTHACHE_RV),
                            DELTA_THRESHOLD);
            Assert.AreEqual(1.0,
                            model.posterior(ExampleRV.CAVITY_RV, ExampleRV.CATCH_RV),
                            DELTA_THRESHOLD);
            Assert.AreEqual(1.0, model.posterior(ExampleRV.CAVITY_RV,
                                                 ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV), DELTA_THRESHOLD);
            Assert.AreEqual(1.0,
                            model.posterior(ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV),
                            DELTA_THRESHOLD);
            Assert.AreEqual(1.0,
                            model.posterior(ExampleRV.CATCH_RV, ExampleRV.TOOTHACHE_RV),
                            DELTA_THRESHOLD);
            Assert.AreEqual(1.0, model.posterior(ExampleRV.CATCH_RV,
                                                 ExampleRV.CAVITY_RV, ExampleRV.TOOTHACHE_RV), DELTA_THRESHOLD);

            // AIMA3e pg. 495 - Bayes' Rule
            // P(b|a) = P(a|b)P(b)/P(a)
            Assert.AreEqual(model.posterior(acavity, atoothache),
                            (model.posterior(atoothache, acavity) * model.prior(acavity))
                            / model.prior(atoothache), DELTA_THRESHOLD);
            Assert.AreEqual(
                model.posterior(acavity, anottoothache),
                (model.posterior(anottoothache, acavity) * model.prior(acavity))
                / model.prior(anottoothache), DELTA_THRESHOLD);
            Assert.AreEqual(
                model.posterior(anotcavity, atoothache),
                (model.posterior(atoothache, anotcavity) * model
                 .prior(anotcavity)) / model.prior(atoothache),
                DELTA_THRESHOLD);
            Assert.AreEqual(
                model.posterior(anotcavity, anottoothache),
                (model.posterior(anottoothache, anotcavity) * model
                 .prior(anotcavity)) / model.prior(anottoothache),
                DELTA_THRESHOLD);
            //
            Assert.AreEqual(model.posterior(acavity, acatch),
                            (model.posterior(acatch, acavity) * model.prior(acavity))
                            / model.prior(acatch), DELTA_THRESHOLD);
            Assert.AreEqual(model.posterior(acavity, anotcatch),
                            (model.posterior(anotcatch, acavity) * model.prior(acavity))
                            / model.prior(anotcatch), DELTA_THRESHOLD);
            Assert.AreEqual(model.posterior(anotcavity, acatch),
                            (model.posterior(acatch, anotcavity) * model.prior(anotcavity))
                            / model.prior(acatch), DELTA_THRESHOLD);
            Assert.AreEqual(
                model.posterior(anotcavity, anotcatch),
                (model.posterior(anotcatch, anotcavity) * model
                 .prior(anotcavity)) / model.prior(anotcatch),
                DELTA_THRESHOLD);
        }