/* Librarian or Farmer problem in Picat. From Probabilistic Programming and Bayesian Methods for Hackers, page 7ff """ Consider the following story, inspired by Thinking, Fast and Slow by Daniel Kahneman (2011). Steve is described as a shy individual, very helpful, but he has little interest in other people. He likes things in their proper order, and is very detailed about his work. Do you think Steve is more likely to be a librarian or a farmer? It may seem that Steve is more likely to be a librarian, and most people would agree with this conclusion, but that’s ignoring the background distribution of librarians and farmers: The ratio of male farmers to male librarians is 20:1. Steve is statistically more likely to be a farmer! """ (In the online version of the book, this example seems to have been replaced with a problem of finding bugs in a program.) Cf my Gamble model gamble_librarian_or_farmer.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. main => go. /* var : job Probabilities: farmer: 0.9542000000000000 librarian: 0.0458000000000000 mean = [farmer = 0.9542,librarian = 0.0458] var : job prior Probabilities: farmer: 0.9540999999999999 librarian: 0.0459000000000000 mean = [farmer = 0.9541,librarian = 0.0459] var : librarian desc Probabilities: false: 0.5078000000000000 true: 0.4922000000000000 mean = [false = 0.5078,true = 0.4922] var : steve farmer Probabilities: true: 0.9283000000000000 false: 0.0717000000000000 mean = [true = 0.9283,false = 0.0717] var : steve librarian Probabilities: false: 0.9283000000000000 true: 0.0717000000000000 mean = [false = 0.9283,true = 0.0717] Even though Steve seems like a librarian, him being a farmer is much more likely. */ go ?=> reset_store, run_model(10_000,$model,[show_probs_trunc,mean]), nl, % show_store_lengths, % fail, nl. go => true. model() => % Being a farmer is 20 times more common than being a librarian. Ps = [1,20].simplex, % 1/21 20/21 Vs = [librarian,farmer], JobPrior = categorical(Ps,Vs), Job = categorical(Ps,Vs), % Does Steve matches the description of a librarian LibrarianDesc = flip(0.5), % Is Steve a librarian? SteveLibrarian = cond( (Job == librarian, LibrarianDesc==true), flip(0.95), flip(0.05)), % Is Steve a farmer? The assumption is that there are only % librarians and farmers in this world. SteveFarmer = check(not SteveLibrarian), add("job",Job), add("job prior",JobPrior), add("librarian desc",LibrarianDesc), add("steve librarian",SteveLibrarian), add("steve farmer",SteveFarmer).