Picat PPL - Probabilistic Programming Light

31 views
Skip to first unread message

Hakan Kjellerstrand

unread,
Nov 27, 2025, 3:27:33 AMNov 27
to Picat
Picat PPL - Probabilistic Programming Light is is a lightweight probabilistic programming framework implemented entirely in Picat. It is designed for exploring uncertainty, solving probability puzzles, and experimenting with small-scale probabilistic models - rather than performing heavy Bayesian data analysis. 

It has two features:
- support for doing probabilistic programming modelling using a fairly high level syntax (such as Gamble and WebPPL)
- support of over 40 different probability distributions (or about 80 depending how one count) with exact calculations, upto Picat's precision of about 1.0e-15.

The dedicated page for Picat PPL is https://hakank.org/picat/ppl .

Also, the published files can be downloaded from the Zip file: https://www.hakank.org/picat/ppl/all_public.zip . This file will be updated when changes are done.

The Picat PPL page includes documentation of the features of Picat PPL as well as over 550 probabilistic programming models.  (In total, it's now over 115 000 lines, including comments and output of the model.)

To run a model, three modules must be downloaded:

Then run the model as usual, say with the Monty Hall problem: https://www.hakank.org/picat/ppl/ppl_monty_hall.pi
"""
model() =>
  Doors = [d1,d2,d3],
  
  % The prize can be behind any door 1..3.
  Prize = uniform_draw(Doors),

   % Which door will Monty open?
   % Assumption (WLOG): We always select door 1.
   % If the prize is behind door 1 (our selected door),
   % then Monty picks some of the other doors by random.
   % Note: Monty knows where the prize is and never opens
   % the door of the prize.
   MontyOpen = cond(Prize == d1,
                    uniform_draw([d2,d3]),  % Monty must pick D2 or D3 randomly
                    cond(Prize==d2,d3,d2)), % Monty must open D2
   
   % We see that Monty opens door 2
   % What are the probabilities that the price is behind
   % - door D1 (the one we selected, i.e don't switch)
   % - or door D3 (i.e. switch door)
   observe(MontyOpen == d2),

   if observed_ok then     
     add("prize",Prize)
   end.
"""

$ picat monty_hall.pi

The output is something like:
"""
var : prize
Probabilities:
d3: 0.66149440596696851 (9933 / 15016)
d1: 0.33850559403303143 (5083 / 15016)
"""

Note that Picat PPL does not calculate exact probabilities. Instead it uses a rather simple rejection sampler for inference.

Besides supporting probabilistic programming, Picat PPL also supports over 40 (or 80) different probability distributions, which calculates exact probability (upto Picat's precision of about 1.0e-15). All these have a generator function which can be used in Picat PPL modeling. See the full list of the supported distributions at the Picat PPL page.

Full disclosure: For some of the more advanced number crunching methods in https://hakank.org/picat/ppl/ppl_distributions.pi, ChatGPT-5 was of some help. 

Most of the Picat PPL models - as well as the supported functions - have been ported from my Gamble and WebPPL models as well from some other probabilistic programming systems. Here are my pages for these PPL systems:
- Racket/Gamble page: https://www.hakank.org/racket/ (search for Gamble)
 
/Hakan
--

C. G.

unread,
Nov 30, 2025, 7:59:23 PM (12 days ago) Nov 30
to Picat
Hello Hakan,

Very interesting, also a well chosen example! Next you should maybe show how do you model the sleeping beauty problem in it, if at all possible.

best regards,
Cristian

Hakan Kjellerstrand

unread,
Dec 1, 2025, 5:13:03 AM (12 days ago) Dec 1
to C. G., Picat
Thanks, Cristian.

That's a great suggestion. I'll see what I can do.

Best,

Hakan

--
You received this message because you are subscribed to the Google Groups "Picat" group.
To unsubscribe from this group and stop receiving emails from it, send an email to picat-lang+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/picat-lang/1ebf7729-346f-4486-aac8-a2f39557ae7cn%40googlegroups.com.

Hakan Kjellerstrand

unread,
Dec 1, 2025, 1:04:21 PM (11 days ago) Dec 1
to C. G., Picat
Hi, Cristian.

Here's is a simple model showing two different approaches for getting the two different solution (1/2 and 1/3): https://www.hakank.org/picat/ppl/ppl_sleeping_beauty_problem.pi


Here's the model part:
"""
model() =>
  Coin = categorical([1/2,1/2],[heads,tails]), 
  SB = new_list(2), % The Sleeping Beauty

  if Coin = heads then
    SB[1] := wake_up,
    add("sleeping beauty wakeups",heads), % 1/3 solution
  else
    SB[1] := wake_up_and_sleep,
    SB[2] := wake_up,
    add("sleeping beauty wakeups",tails),
    add("sleeping beauty wakeups",tails),
  end,
  
  % 1/2 solution:
  % I.e. monday was a wake up but tuesday was not
  P = check( (SB[1] == wake_up ; SB[2] != wake_up)),

  add("p",P).
"""

Output from one run:
"""
var : sleeping beauty wakeups
Probabilities:
tails: 0.6663110162710056
heads: 0.3336889837289944

var : p
Probabilities:
true: 0.5004000000000000
false: 0.4996000000000000
mean = 0.5004
"""

(Again, Picat PPL models do not calculate exact probabilities.)

Please ask if you have any questions or comments on this. 

Best,

Hakan
Reply all
Reply to author
Forward
0 new messages