Sleeping Julia: Empirical support for thirder argument in the Sleeping Beauty Problem

I’ve created an emulation of the Sleeping Beauty Problem in the Julia programming language which supports the thirder solution.

For those unfamiliar with the problem, I recommend this explanation by Julia Galef: https://​​www.youtube.com/​​watch?v=zL52lG6aNIY

In this explanation, I’ll briefly explain the current situation with regard to this problem’s status in academia, how the emulation works, and how we can formalize the intuitions gleaned from this experiment. Let’s start with the code.

Originally I wrote this in Julia (hence the name), and that code can be found on GitHub: https://​​github.com/​​seisvelas/​​SleepingJulia/​​blob/​​main/​​sleeping.jl.ipynb

Here I’ll do the same thing, but in Python, as that language is likely grokked by a broader audience of LessWrong readers. First, I create a class to run the experiment and track the state of various sleeping beauty experiments:

import random

class SleepingBeautyExperiment:
  def __init__(self):
    self.wakeups = 0
    self.bets = {
      'heads' : { 'win' : 0, 'loss' : 0},
      'tails' : { 'win' : 0, 'loss' : 0},
    }
  
  def run(self, bet):
    coin = ('heads', 'tails')
    coin_toss = random.choice(coin)
    win_or_loss = 'win' if coin_toss == bet else 'loss'
    self.bets[bet][win_or_loss] += 1

    # Tuesday, in case of tails
    if coin_toss == 'tails':
      self.bets[bet][win_or_loss] += 1

  def repeat(self, bet, times):
    for i in range(times):
      self.run(bet)

  def reset(self):
    self.__init__()

I apologize for the lack of code highlighting. I tried to write code that self-documents as much as possible, but if I failed, just leave a comment and I’ll clarify to the best of my ability. The key observation is that in the case of tails, we wake SB twice. Ie, for every 100 experiments, there will be 150 wakeups. We don’t care how many whole experiments SB summarily wins (if we did, though, the halfer interpretation would be the correct one!).

Let’s see the code in action:

>>> heads_wins = Sb.bets['heads']['win']
>>> heads_losses = Sb.bets['heads']['loss']
>>> heads_wins / (heads_wins + heads_losses)
0.33378682085242317
>>> # As percent rounded to two decimal places:
>>> int(heads_wins / (heads_wins + heads_losses) * 10000) / 100
33.37

There ya go, a nice right dose of thirderism. In the lay rationality community the SB problem is often treated as an open debate, with larger and smaller menshevik and bolshevik factions, but this has not been the case for some time. I made these emulations originally to prove halferism before reading up on academic work from decision theorists such as Silvia Milano’s wonderful Bayesian Beauty paper. In academia, SB problem is resoundingly considered solved.

For a lay level overview of the situation, we can do some Bayesian mini-algebra to simply summarize what halfers get wrong.

A = heads
B = SB awoken

Halfers believe these priors:

P(B | A) = 1
P(A ) = 12
P(B) = 1

Therefore, following Bayes’ theorem:

P(A | B) = (P(B | A) * P(A)) /​ P(B) = (1 * 12) /​ 1 = 12

But for every tails flip, SB is awoken twice (once on Monday then again on Tuesday), so the probable number of wakeups per experiment is 1.5, therefore P(B) = 1.5. If we run the math again with this new prior:

P(A | B) = (P(B | A) * P(A)) /​ P(B) = (1 * 12) /​ 1.5 = .5 /​ 1.5 = 13
QED

Readers learning about this problem from the rationality community or Wikipedia are given an outdated sense of the problem’s openness. Perhaps some enterprising spirit would like to review the academic literature and give Wikipedia’s article a makeover. I’ll do it one day, if no one else beats me to it.