/* Orchs problem in Picat. From https://cbmm.mit.edu/sites/default/files/documents/CBMM_Church_Notes.html Here are some of The Battle of the Two Towers Church models (a few of them just uses variant Church method which is not supported by Picat PPL and are thus ignored). Cf - ppl_orchs.pi - my Gamble model gamble_orchs_church.rkt This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import ppl_distributions, ppl_utils. import util. % import ordset. main => go. /* * Problem 1 """ You are studying the historical Battle of the Two Towers. Suppose a-priori you assume Legolas, Gimli and Eowyn each took out somewhere between 0 and 19 orcs. How many orcs did Gimli take out? """ var : gimli Probabilities: 19: 0.0537000000000000 2: 0.0529000000000000 17: 0.0528000000000000 4: 0.0528000000000000 12: 0.0526000000000000 18: 0.0522000000000000 6: 0.0518000000000000 0: 0.0505000000000000 1: 0.0502000000000000 10: 0.0498000000000000 13: 0.0496000000000000 3: 0.0493000000000000 11: 0.0488000000000000 5: 0.0486000000000000 9: 0.0484000000000000 14: 0.0480000000000000 15: 0.0476000000000000 16: 0.0474000000000000 8: 0.0465000000000000 7: 0.0465000000000000 mean = 9.5147 * Problem 2 """ Someone tells you that together, they took out at least 45 orcs. What is your belief about how many orcs Gimli took out? """ var : gimli Probabilities: 19: 0.1980000000000000 18: 0.1660000000000000 17: 0.1590000000000000 16: 0.1130000000000000 15: 0.1080000000000000 14: 0.0740000000000000 13: 0.0570000000000000 12: 0.0440000000000000 11: 0.0370000000000000 9: 0.0220000000000000 10: 0.0170000000000000 8: 0.0030000000000000 7: 0.0020000000000000 mean = 15.999 * Problem 3 """ ... This allows us to do inference even when the conditional is rare – for instance if the team took out at least 55 orcs. """ Note: In Picat PPL, the min_accepted_samples is used to ensure a certain number of accepted samples. Here we ensure 1000 accepted samples var : gimli Probabilities: 19: 0.6020000000000000 18: 0.2850000000000000 17: 0.1130000000000000 mean = 18.489 */ go ?=> member(Problem,1..3), println(problem=Problem), reset_store, Parameters = cond(Problem == 1,[show_probs,mean], [show_probs,mean, min_accepted_samples=1000 % ,show_accepted_samples=true ]), run_model(10_000,$model(Problem),Parameters), nl, % show_store_lengths,nl, fail, nl. go => true. model(Problem) => Legolas = discrete_uniform_dist(0,19), Gimli = discrete_uniform_dist(0,19), Eowyn = discrete_uniform_dist(0,19), TotalOrchs = Legolas + Gimli + Eowyn, if Problem == 2 then observe(TotalOrchs >= 45) end, if Problem == 3 then observe(TotalOrchs >= 55) end, if Problem == 1 ; observed_ok then add("gimli",Gimli), % add("total orchs",TotalOrchs), end.