Exemplo n.º 1
0
        public Proposition GetProposition(object owner, IContextLookup globalVars, IDictionary <string, RandomVariable> randomVariables)
        {
            switch (PropositionType)
            {
            case PropositionType.RandomVariable:
            case PropositionType.Assignment:
                RandomVariable randomVar;
                if (!randomVariables.TryGetValue(RandomVariable, out randomVar))
                {
                    throw new ApplicationException("Missing variable " + RandomVariable);
                }
                switch (PropositionType)
                {
                case PropositionType.RandomVariable:
                    return((Proposition)randomVar);

                case PropositionType.Assignment:
                    var objValue = Value.EvaluateTyped(owner, globalVars);
                    return(new AssignmentProposition(randomVar, objValue));

                default:
                    throw new ArgumentOutOfRangeException();
                }

            case PropositionType.Dysjunctive:
            case PropositionType.Conjunctive:
                if (Children.Count > 0)
                {
                    Proposition newPropositionInfo = null;
                    foreach (PropositionInfo assignmentPropositionInfo in Children)
                    {
                        var objAssignment = assignmentPropositionInfo.GetProposition(owner, globalVars, randomVariables);
                        if (newPropositionInfo == null)
                        {
                            newPropositionInfo = objAssignment;
                        }
                        else
                        {
                            if (PropositionType == PropositionType.Conjunctive)
                            {
                                newPropositionInfo = new ConjunctiveProposition(newPropositionInfo, objAssignment);
                            }
                            else
                            {
                                newPropositionInfo = new DisjunctiveProposition(newPropositionInfo, objAssignment);
                            }
                        }
                    }
                    return(newPropositionInfo);
                }
                else
                {
                    throw new ArgumentOutOfRangeException();
                }

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemplo n.º 2
0
        public virtual double posterior(IProposition phi, params IProposition[] evidence)
        {
            IProposition conjEvidence = ProbUtil.constructConjunction(evidence);

            // P(A | B) = P(A AND B)/P(B) - (13.3 AIMA3e)
            IProposition aAndB = new ConjunctiveProposition(phi, conjEvidence);
            double       probabilityOfEvidence = prior(conjEvidence);

            if (0 != probabilityOfEvidence)
            {
                return(prior(aAndB) / probabilityOfEvidence);
            }

            return(0);
        }
        //
        // PROTECTED METHODS
        //
        protected void test_RollingPairFairDiceModel(IProbabilityModel 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);
        }
        // AIMA3e pg. 488, 494
        protected void test_ToothacheCavityCatchWeatherModel(IProbabilityModel model)
        {
            // Should be able to run all the same queries for this independent
            // sub model.
            test_ToothacheCavityCatchModel(model);

            // AIMA3e pg. 486
            AssignmentProposition asunny = new AssignmentProposition(
                ExampleRV.WEATHER_RV, "sunny");
            AssignmentProposition arain = new AssignmentProposition(
                ExampleRV.WEATHER_RV, "rain");
            AssignmentProposition acloudy = new AssignmentProposition(
                ExampleRV.WEATHER_RV, "cloudy");
            AssignmentProposition asnow = new AssignmentProposition(
                ExampleRV.WEATHER_RV, "snow");

            Assert.AreEqual(0.6, model.prior(asunny), DELTA_THRESHOLD);
            Assert.AreEqual(0.1, model.prior(arain), DELTA_THRESHOLD);
            Assert.AreEqual(0.29, model.prior(acloudy), DELTA_THRESHOLD);
            Assert.AreEqual(0.01, model.prior(asnow), DELTA_THRESHOLD);

            // AIMA3e pg. 488
            // P(sunny, cavity)
            // P(sunny AND cavity)
            AssignmentProposition atoothache = new AssignmentProposition(
                ExampleRV.TOOTHACHE_RV, true);
            AssignmentProposition acatch = new AssignmentProposition(
                ExampleRV.CATCH_RV, true);
            AssignmentProposition acavity = new AssignmentProposition(
                ExampleRV.CAVITY_RV, true);
            ConjunctiveProposition sunnyAndCavity = new ConjunctiveProposition(
                asunny, acavity);

            // 0.6 (sunny) * 0.2 (cavity) = 0.12
            Assert.AreEqual(0.12, model.prior(asunny, acavity), DELTA_THRESHOLD);
            Assert.AreEqual(0.12, model.prior(sunnyAndCavity), DELTA_THRESHOLD);

            // AIMA3e pg. 494
            // P(toothache, catch, cavity, cloudy) =
            // P(cloudy | toothache, catch, cavity)P(toothache, catch, cavity)
            Assert.AreEqual(
                model.prior(atoothache, acatch, acavity, acloudy),
                model.posterior(acloudy, atoothache, acatch, acavity)
                * model.prior(atoothache, acatch, acavity),
                DELTA_THRESHOLD);
            ConjunctiveProposition toothacheAndCatchAndCavityAndCloudy = new ConjunctiveProposition(
                new ConjunctiveProposition(atoothache, acatch),
                new ConjunctiveProposition(acavity, acloudy));
            ConjunctiveProposition toothacheAndCatchAndCavity = new ConjunctiveProposition(
                new ConjunctiveProposition(atoothache, acatch), acavity);

            Assert.AreEqual(
                model.prior(toothacheAndCatchAndCavityAndCloudy),
                model.posterior(acloudy, atoothache, acatch, acavity)
                * model.prior(toothacheAndCatchAndCavity),
                DELTA_THRESHOLD);

            // P(cloudy | toothache, catch, cavity) = P(cloudy)
            // (13.10)
            Assert.AreEqual(
                model.posterior(acloudy, atoothache, acatch, acavity),
                model.prior(acloudy), DELTA_THRESHOLD);

            // P(toothache, catch, cavity, cloudy) =
            // P(cloudy)P(tootache, catch, cavity)
            Assert.AreEqual(
                model.prior(atoothache, acatch, acavity, acloudy),
                model.prior(acloudy) * model.prior(atoothache, acatch, acavity),
                DELTA_THRESHOLD);

            // P(a | b) = P(a)
            Assert.AreEqual(model.posterior(acavity, acloudy),
                            model.prior(acavity), DELTA_THRESHOLD);
            // P(b | a) = P(b)
            Assert.AreEqual(model.posterior(acloudy, acavity),
                            model.prior(acloudy), DELTA_THRESHOLD);
            // P(a AND b) = P(a)P(b)
            Assert.AreEqual(model.prior(acavity, acloudy), model.prior(acavity)
                            * model.prior(acloudy), DELTA_THRESHOLD);
            ConjunctiveProposition acavityAndacloudy = new ConjunctiveProposition(
                acavity, acloudy);

            Assert.AreEqual(model.prior(acavityAndacloudy),
                            model.prior(acavity) * model.prior(acloudy), DELTA_THRESHOLD);
        }
        protected void test_ToothacheCavityCatchModel(IProbabilityModel model)
        {
            Assert.IsTrue(model.isValid());

            AssignmentProposition atoothache = new AssignmentProposition(
                ExampleRV.TOOTHACHE_RV, true);
            AssignmentProposition anottoothache = new AssignmentProposition(
                ExampleRV.TOOTHACHE_RV, false);
            AssignmentProposition acavity = new AssignmentProposition(
                ExampleRV.CAVITY_RV, true);
            AssignmentProposition anotcavity = new AssignmentProposition(
                ExampleRV.CAVITY_RV, false);
            AssignmentProposition acatch = new AssignmentProposition(
                ExampleRV.CATCH_RV, true);
            AssignmentProposition anotcatch = new AssignmentProposition(
                ExampleRV.CATCH_RV, 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);
        }
Exemplo n.º 6
0
        protected void test_ToothacheCavityCatchModel_Distributions(IFiniteProbabilityModel model)
        {
            AssignmentProposition atoothache    = new AssignmentProposition(ExampleRV.TOOTHACHE_RV, true);
            AssignmentProposition anottoothache = new AssignmentProposition(ExampleRV.TOOTHACHE_RV, false);
            AssignmentProposition acatch        = new AssignmentProposition(ExampleRV.CATCH_RV, true);
            AssignmentProposition anotcatch     = new AssignmentProposition(ExampleRV.CATCH_RV, false);

            // AIMA3e pg. 493
            // P<>(Cavity | toothache) = <0.6, 0.4>
            assertArrayEquals(new double[] { 0.6, 0.4 }, model
                              .posteriorDistribution(ExampleRV.CAVITY_RV, atoothache)
                              .getValues(), DELTA_THRESHOLD);

            // AIMA3e pg. 497
            // P<>(Cavity | toothache AND catch) = <0.871, 0.129>
            assertArrayEquals(new double[] { 0.8709677419354839, 0.12903225806451615 },
                              model.posteriorDistribution(ExampleRV.CAVITY_RV, atoothache,
                                                          acatch).getValues(), DELTA_THRESHOLD);

            // AIMA3e pg. 498
            // (13.17)
            // P<>(toothache AND catch | Cavity)
            // = P<>(toothache | Cavity)P<>(catch | Cavity)
            ConjunctiveProposition toothacheAndCatch = new ConjunctiveProposition(atoothache, acatch);

            assertArrayEquals(model.posteriorDistribution(toothacheAndCatch,
                                                          ExampleRV.CAVITY_RV).getValues(),
                              model.posteriorDistribution(atoothache, ExampleRV.CAVITY_RV)
                              .multiplyBy(
                                  model.posteriorDistribution(acatch,
                                                              ExampleRV.CAVITY_RV)).getValues(),
                              DELTA_THRESHOLD);

            // (13.18)
            // P<>(Cavity | toothache AND catch)
            // = &alpha;P<>(toothache | Cavity)P<>(catch | Cavity)P(Cavity)
            assertArrayEquals(model.posteriorDistribution(ExampleRV.CAVITY_RV,
                                                          toothacheAndCatch).getValues(),
                              model.posteriorDistribution(atoothache, ExampleRV.CAVITY_RV)
                              .multiplyBy(
                                  model.posteriorDistribution(acatch,
                                                              ExampleRV.CAVITY_RV))
                              .multiplyBy(
                                  model.priorDistribution(ExampleRV.CAVITY_RV))
                              .normalize().getValues(), DELTA_THRESHOLD);

            // (13.19)
            // P<>(Toothache, Catch | Cavity)
            // = P<>(Toothache | Cavity)P<>(Catch | Cavity)
            ConjunctiveProposition toothacheAndCatchRV = new ConjunctiveProposition(ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV);

            assertArrayEquals(model.posteriorDistribution(toothacheAndCatchRV,
                                                          ExampleRV.CAVITY_RV).getValues(),
                              model.posteriorDistribution(ExampleRV.TOOTHACHE_RV,
                                                          ExampleRV.CAVITY_RV)
                              .multiplyByPOS(
                                  model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                              ExampleRV.CAVITY_RV),
                                  ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV,
                                  ExampleRV.CAVITY_RV).getValues(),
                              DELTA_THRESHOLD);

            // (product rule)
            // P<>(Toothache, Catch, Cavity)
            // = P<>(Toothache, Catch | Cavity)P<>(Cavity)
            assertArrayEquals(model.priorDistribution(ExampleRV.TOOTHACHE_RV,
                                                      ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV).getValues(),
                              model.posteriorDistribution(toothacheAndCatchRV,
                                                          ExampleRV.CAVITY_RV)
                              .multiplyBy(
                                  model.priorDistribution(ExampleRV.CAVITY_RV))
                              .getValues(), DELTA_THRESHOLD);

            // (using 13.19)
            // P<>(Toothache, Catch | Cavity)P<>(Cavity)
            // = P<>(Toothache | Cavity)P<>(Catch | Cavity)P<>(Cavity)
            assertArrayEquals(model.posteriorDistribution(toothacheAndCatchRV,
                                                          ExampleRV.CAVITY_RV)
                              .multiplyBy(
                                  model.priorDistribution(ExampleRV.CAVITY_RV))
                              .getValues(),
                              model.posteriorDistribution(ExampleRV.TOOTHACHE_RV,
                                                          ExampleRV.CAVITY_RV)
                              .multiplyByPOS(
                                  model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                              ExampleRV.CAVITY_RV)
                                  .multiplyBy(
                                      model.priorDistribution(ExampleRV.CAVITY_RV)),
                                  ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV,
                                  ExampleRV.CAVITY_RV).getValues(),
                              DELTA_THRESHOLD);
            //
            // P<>(Toothache, Catch, Cavity)
            // = P<>(Toothache | Cavity)P<>(Catch | Cavity)P<>(Cavity)
            assertArrayEquals(model.priorDistribution(ExampleRV.TOOTHACHE_RV,
                                                      ExampleRV.CATCH_RV, ExampleRV.CAVITY_RV).getValues(),
                              model.posteriorDistribution(ExampleRV.TOOTHACHE_RV,
                                                          ExampleRV.CAVITY_RV)
                              .multiplyByPOS(
                                  model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                              ExampleRV.CAVITY_RV),
                                  ExampleRV.TOOTHACHE_RV, ExampleRV.CATCH_RV,
                                  ExampleRV.CAVITY_RV)
                              .multiplyBy(
                                  model.priorDistribution(ExampleRV.CAVITY_RV))
                              .getValues(), DELTA_THRESHOLD);

            // AIMA3e pg. 496
            // General case of Bayes' Rule
            // P<>(Y | X) = P<>(X | Y)P<>(Y)/P<>(X)
            // Note: Performing in this order -
            // P<>(Y | X) = (P<>(Y)P<>(X | Y))/P<>(X)
            // as default multiplication of distributions are not commutative (could
            // also use pointwiseProductPOS() to specify the order).
            assertArrayEquals(model.posteriorDistribution(ExampleRV.CAVITY_RV,
                                                          ExampleRV.TOOTHACHE_RV).getValues(),
                              model.priorDistribution(ExampleRV.CAVITY_RV)
                              .multiplyBy(
                                  model.posteriorDistribution(
                                      ExampleRV.TOOTHACHE_RV,
                                      ExampleRV.CAVITY_RV))
                              .divideBy(
                                  model.priorDistribution(ExampleRV.TOOTHACHE_RV))
                              .getValues(), DELTA_THRESHOLD);

            assertArrayEquals(
                model.posteriorDistribution(ExampleRV.CAVITY_RV,
                                            ExampleRV.CATCH_RV).getValues(),
                model.priorDistribution(ExampleRV.CAVITY_RV)
                .multiplyBy(
                    model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                ExampleRV.CAVITY_RV))
                .divideBy(model.priorDistribution(ExampleRV.CATCH_RV))
                .getValues(), DELTA_THRESHOLD);

            // General Bayes' Rule conditionalized on background evidence e (13.3)
            // P<>(Y | X, e) = P<>(X | Y, e)P<>(Y|e)/P<>(X | e)
            // Note: Performing in this order -
            // P<>(Y | X, e) = (P<>(Y|e)P<>(X | Y, e)))/P<>(X | e)
            // as default multiplication of distributions are not commutative (could
            // also use pointwiseProductPOS() to specify the order).
            assertArrayEquals(
                model.posteriorDistribution(ExampleRV.CAVITY_RV,
                                            ExampleRV.TOOTHACHE_RV, acatch).getValues(),
                model.posteriorDistribution(ExampleRV.CAVITY_RV, acatch)
                .multiplyBy(
                    model.posteriorDistribution(
                        ExampleRV.TOOTHACHE_RV,
                        ExampleRV.CAVITY_RV, acatch))
                .divideBy(
                    model.posteriorDistribution(
                        ExampleRV.TOOTHACHE_RV, acatch))
                .getValues(), DELTA_THRESHOLD);
            //
            assertArrayEquals(
                model.posteriorDistribution(ExampleRV.CAVITY_RV,
                                            ExampleRV.TOOTHACHE_RV, anotcatch).getValues(),
                model.posteriorDistribution(ExampleRV.CAVITY_RV, anotcatch)
                .multiplyBy(
                    model.posteriorDistribution(
                        ExampleRV.TOOTHACHE_RV,
                        ExampleRV.CAVITY_RV, anotcatch))
                .divideBy(
                    model.posteriorDistribution(
                        ExampleRV.TOOTHACHE_RV, anotcatch))
                .getValues(), DELTA_THRESHOLD);
            //
            assertArrayEquals(
                model.posteriorDistribution(ExampleRV.CAVITY_RV,
                                            ExampleRV.CATCH_RV, atoothache).getValues(),
                model.posteriorDistribution(ExampleRV.CAVITY_RV, atoothache)
                .multiplyBy(
                    model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                ExampleRV.CAVITY_RV, atoothache))
                .divideBy(
                    model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                atoothache)).getValues(),
                DELTA_THRESHOLD);

            assertArrayEquals(
                model.posteriorDistribution(ExampleRV.CAVITY_RV,
                                            ExampleRV.CATCH_RV, anottoothache).getValues(),
                model.posteriorDistribution(ExampleRV.CAVITY_RV, anottoothache)
                .multiplyBy(
                    model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                ExampleRV.CAVITY_RV, anottoothache))
                .divideBy(
                    model.posteriorDistribution(ExampleRV.CATCH_RV,
                                                anottoothache)).getValues(),
                DELTA_THRESHOLD);
        }