Skip to content
The Lumenary
Grades 6–8Ages 11–14 55 min

Probability

Chance as a number from 00 to 11 — counting equally likely outcomes, checking against experiment, and the famous puzzles that got it wrong.

Formally verified · 20 LeanComputationally tested · 2 PythonAI-drafted · awaiting human reviewMathematically reviewed: Awaiting human review

Your guides: Chloe, Margaret, Gideon

MotivationH

A puzzle from seventeenth-century Italy

Gamblers in Galileo's time played a game with three dice and bet on the total. Experienced players had noticed that a total of 10 turns up a little more often than a total of 9. That seemed strange, because each total can be made in six ways:

  • 9=1+2+6=1+3+5=1+4+4=2+2+5=2+3+4=3+3+39 = 1 + 2 + 6 = 1 + 3 + 5 = 1 + 4 + 4 = 2 + 2 + 5 = 2 + 3 + 4 = 3 + 3 + 3;
  • 10=1+3+6=1+4+5=2+2+6=2+3+5=2+4+4=3+3+410 = 1 + 3 + 6 = 1 + 4 + 5 = 2 + 2 + 6 = 2 + 3 + 5 = 2 + 4 + 4 = 3 + 3 + 4.

Were the players imagining it? Galileo explained the answer around 1620, and by the end of this lesson you will be able to explain it too — and even to check it with a computer and with Lean.

Probability is the mathematics of uncertainty. It helps a weather service say “70% chance of rain”, a doctor judge a test result, and an engineer design a network that rarely fails. It begins with a simple idea: count the equally likely possibilities.

IntuitionH

Chance as a number

We measure chance on a scale from 00 to 11:

  • 00 means impossible (rolling a 77 on an ordinary die);
  • 11 means certain (rolling a number less than 77);
  • 12\tfrac12 means as likely as not (a fair coin landing heads).

When an experiment has a few outcomes that are all equally likely, the probability of an event is the fraction of outcomes that make it happen. A fair die has six equally likely faces, and three are even, so the probability of an even number is 36=12\tfrac36 = \tfrac12.

But “equally likely” is an assumption that must be checked. The spinner below has three outcomes — but they are not equally likely.

Spinner

Three outcomes, but not equally likely. Spin 60 times: how close does each fraction of spins come to the sector's share?

RedBlueGreen

No spins yet.

PartSpinsSpins compared with the spinner
Red0
–
1/2 50%
Blue0
–
1/3 33.3%
Green0
–
1/6 16.7%

fraction of spins fraction of the spinner

More spins usually bring the fraction of spins closer to the fraction of the spinner — usually, not always. This is a simulation with a seeded random number generator: evidence, not proof.

“Start again” replays the same spins; “New run” makes new ones.
DefinitionsH

Definitions

Definition— sample space, outcome, event

An experiment is something with an uncertain result, like rolling a die. Each possible result is an outcome. The sample space SS is the set of all outcomes. An event is a subset A⊆SA \subseteq S: the outcomes for which “it happens”.

For one die, S={1,2,3,4,5,6}S = \{1, 2, 3, 4, 5, 6\}, and “an even number” is the event A={2,4,6}A = \{2, 4, 6\}.

Definition— probability with equally likely outcomes

If all outcomes in a finite sample space SS are equally likely, the probability of an event AA is

P(A)=∣A∣∣S∣=number of outcomes in Anumber of outcomes in S.P(A) = \frac{|A|}{|S|} = \frac{\text{number of outcomes in } A}{\text{number of outcomes in } S}.

Here ∣A∣|A| is the number of elements of AA, as in the lesson on sets. The event “not AA”, written AcA^c (the complement), is the set of outcomes of SS that are not in AA.

Definition— relative frequency

If an experiment is repeated nn times and an event happens mm times, its relative frequency is mn\dfrac{m}{n}.

Probability is a statement about the experiment; relative frequency is a record of what happened. The two are linked, but they are not the same thing.

Worked examplesH

Worked examples

Example— Two coins: a tree diagram

Toss a coin twice. The first toss is H or T; for each, the second toss is H or T. A tree diagram lists the four equally likely outcomes.

HT1/21/21/21/21/21/2HH 1/4HT 1/4TH 1/4TT 1/4
The tree for two coin tosses. Each path is one outcome; each of the four has probability $\tfrac12 \times \tfrac12 = \tfrac14$.

“At least one head” is {HH,HT,TH}\{HH, HT, TH\}, so its probability is 34\tfrac34. “Exactly one head” is {HT,TH}\{HT, TH\}, with probability 24=12\tfrac24 = \tfrac12.

Example— Two dice: a table

Roll a red die and a blue die. Each of the 6×6=366 \times 6 = 36 ordered pairs is equally likely. The table shows the sum for each pair.

red \ blue123456
1234567
2345678
3456789
45678910
567891011
6789101112
  • P(sum=7)=636=16P(\text{sum} = 7) = \tfrac{6}{36} = \tfrac16: the diagonal of 77s has six cells.
  • P(sum=2)=136P(\text{sum} = 2) = \tfrac{1}{36}: only (1,1)(1, 1).
  • P(doubles)=636=16P(\text{doubles}) = \tfrac{6}{36} = \tfrac16.
  • P(sum≥10)=3+2+136=16P(\text{sum} \ge 10) = \tfrac{3 + 2 + 1}{36} = \tfrac16.

There are 1111 possible sums, but they are not equally likely: 77 is six times as likely as 22.

Example— Galileo's answer

With three dice there are 6×6×6=2166 \times 6 \times 6 = 216 equally likely ordered outcomes. The six ways of writing 99 are not equally likely: 1+2+61 + 2 + 6 can come up in 66 orders (126, 162, 216, 261, 612, 621), 1+4+41 + 4 + 4 in only 33 orders, and 3+3+33 + 3 + 3 in just 11. Counting orders, a total of 99 has 2525 outcomes and a total of 1010 has 2727. So

P(9)=25216≈0.116,P(10)=27216=0.125.P(9) = \tfrac{25}{216} \approx 0.116, \qquad P(10) = \tfrac{27}{216} = 0.125.

The gamblers were right. The difference is small — they must have played a great many games to notice it.

Example— A non-example

“Tomorrow it will either rain or not, so the probability of rain is 12\tfrac12.” This is wrong: the two outcomes are not equally likely. In the Atacama Desert rain is rare; in a Mumbai monsoon it is common. Forecasters estimate such probabilities from data and models, not by counting outcomes.

ProofH

The rules of probability, with proofs

Throughout, SS is a finite, non-empty sample space of equally likely outcomes.

Theorem— Theorem 1 (basic properties)

For every event AA: 0≤P(A)≤10 \le P(A) \le 1. Also P(S)=1P(S) = 1, P(∅)=0P(\varnothing) = 0, and

P(Ac)=1−P(A).P(A^c) = 1 - P(A).

Proof

Since A⊆SA \subseteq S, we have 0≤∣A∣≤∣S∣0 \le |A| \le |S|; dividing by ∣S∣|S| gives 0≤P(A)≤10 \le P(A) \le 1. P(S)=∣S∣∣S∣=1P(S) = \tfrac{|S|}{|S|} = 1 and P(∅)=0∣S∣=0P(\varnothing) = \tfrac{0}{|S|} = 0. Every outcome lies in exactly one of AA and AcA^c, so ∣A∣+∣Ac∣=∣S∣|A| + |A^c| = |S|. Dividing by ∣S∣|S|: P(A)+P(Ac)=1P(A) + P(A^c) = 1.

∎

The complement rule is often the easy way in. The probability of at least one six in four rolls of a die is 1−P(no six)=1−5464=1−6251296=6711296≈0.5181 - P(\text{no six}) = 1 - \tfrac{5^4}{6^4} = 1 - \tfrac{625}{1296} = \tfrac{671}{1296} \approx 0.518.

Theorem— Theorem 2 (addition rule)

For events AA and BB:

P(A or B)=P(A)+P(B)−P(A and B).P(A \text{ or } B) = P(A) + P(B) - P(A \text{ and } B).

In particular, if AA and BB cannot both happen, P(A or B)=P(A)+P(B)P(A \text{ or } B) = P(A) + P(B).

Proof

“AA or BB” is the union A∪BA \cup B, and “AA and BB” is the intersection A∩BA \cap B. Adding ∣A∣+∣B∣|A| + |B| counts every outcome of A∪BA \cup B once, except those in A∩BA \cap B, which are counted twice. So ∣A∪B∣=∣A∣+∣B∣−∣A∩B∣|A \cup B| = |A| + |B| - |A \cap B|. Divide by ∣S∣|S|.

∎

For one die, P(even or more than 4)=36+26−16=46P(\text{even or more than } 4) = \tfrac36 + \tfrac26 - \tfrac16 = \tfrac46: the outcome 66 is both even and more than 44, and must not be counted twice.

Theorem— Theorem 3 (product rule for independent stages)

Suppose an experiment has two stages: the first has a sample space SS and the second a sample space TT, each of equally likely outcomes, and the second stage does not depend on the first. If AA is an event of the first stage and BB an event of the second, then

P(A at stage 1 and B at stage 2)=P(A)⋅P(B).P(A \text{ at stage 1 and } B \text{ at stage 2}) = P(A) \cdot P(B).

Proof

The outcomes of the whole experiment are the ordered pairs (s,t)(s, t) with s∈Ss \in S, t∈Tt \in T: the Cartesian product S×TS \times T, with ∣S∣⋅∣T∣|S| \cdot |T| equally likely elements. The favourable pairs form A×BA \times B, with ∣A∣⋅∣B∣|A| \cdot |B| elements. So the probability is ∣A∣⋅∣B∣∣S∣⋅∣T∣=∣A∣∣S∣⋅∣B∣∣T∣=P(A) P(B)\dfrac{|A| \cdot |B|}{|S| \cdot |T|} = \dfrac{|A|}{|S|} \cdot \dfrac{|B|}{|T|} = P(A)\,P(B).

∎

This is why we multiply along the branches of a tree diagram. For a double six, P=16×16=136P = \tfrac16 \times \tfrac16 = \tfrac1{36}. (When the second stage does depend on the first — drawing two cards without putting the first back — the rule needs changing; that is the subject of conditional probability.)

Theorem— Law of large numbers (stated informally, without proof)

If an experiment is repeated independently many times, the relative frequency of an event tends to settle near its probability: with more and more trials, large deviations become less and less likely.

We do not prove this here; a precise version was first proved by Jacob Bernoulli (published 1713), and you will meet proofs in probability theory. Notice what it does not say: it does not say the relative frequency ever equals the probability exactly, and it does not say that the coin “corrects” a run of tails. Earlier results are not undone; they are swamped by the many trials that follow.

Formal mathematicsF

Probability in Lean

In Lean, a finite sample space of equally likely outcomes is a list S, and an event is a test A that answers true or false for each outcome. The probability is computed exactly as a rational number.

countLean 4Formally verified
/-- The number of outcomes in the list `S` that belong to the event `A`. -/
def count (S : List α) (A : α → Bool) : Nat := (S.filter A).length
Axioms used: No axiomsformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
probLean 4Formally verified
/-- **Probability with equally likely outcomes:** `P(A) = |A| / |S|`, the number of favourable
outcomes divided by the number of possible outcomes. -/
def prob (S : List α) (A : α → Bool) : Rat := (count S A : Rat) / (S.length : Rat)
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor

Theorem 1. The proofs of count_compl and count_union_inter go through the list one outcome at a time (induction): each outcome is counted on both sides of the equation in the same way.

prob_nonnegLean 4Proved here from basic factsFormally verified
/-- Probabilities are never negative: a count divided by a count. -/
theorem prob_nonneg (S : List α) (A : α → Bool) : 0 ≤ prob S A := by
  unfold prob
  rw [Rat.div_def]
  apply Rat.mul_nonneg (Rat.natCast_nonneg)
  by_cases h : (S.length : Rat) = 0
  · rw [h, Rat.inv_zero]
    exact Rat.le_refl
  · have hpos : (0 : Rat) < S.length := Rat.lt_of_le_of_ne Rat.natCast_nonneg (Ne.symm h)
    exact Rat.le_of_lt (Rat.inv_pos.mpr hpos)
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
prob_le_oneLean 4Proved here from basic factsFormally verified
/-- Probabilities are at most `1`: the event has at most as many outcomes as `S`. -/
theorem prob_le_one (S : List α) (A : α → Bool) : prob S A ≤ 1 := by
  unfold prob
  have hle : (count S A : Rat) ≤ S.length := Rat.natCast_le_natCast.mpr (count_le_length S A)
  by_cases h : S.length = 0
  · rw [h]
    simp [Rat.div_def]
    decide
  · have hpos : (0 : Rat) < S.length := Rat.natCast_pos.mpr (Nat.pos_of_ne_zero h)
    -- `c / n ≤ 1` means "not `1 < c / n`", i.e. not `1 · n < c`.
    rw [← Rat.not_lt, Rat.lt_div_iff hpos]
    grind
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
prob_certainLean 4Proved here from basic factsFormally verified
/-- The certain event (every outcome) has probability `1`, when there is at least one outcome. -/
theorem prob_certain (S : List α) (hS : S ≠ []) : prob S (fun _ => true) = 1 := by
  unfold prob count
  simp only [List.filter_eq_self.mpr (fun _ _ => rfl)]
  have hpos : (S.length : Rat) ≠ 0 := by
    have : S.length ≠ 0 := by
      intro h0
      exact hS (List.eq_nil_of_length_eq_zero h0)
    simpa using this
  rw [Rat.div_def]
  exact Rat.mul_inv_cancel _ hpos
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
count_complLean 4Proved here from basic factsFormally verified
/-- Every outcome is either in `A` or in "not `A`", never both:
`|A| + |not A| = |S|`. Proof by induction on the list of outcomes. -/
theorem count_compl (S : List α) (A : α → Bool) :
    count S A + count S (fun x => !A x) = S.length := by
  induction S with
  | nil => rfl
  | cons a S ih =>
    unfold count at ih ⊢
    cases h : A a <;> simp [h] <;> omega
Axioms used: propext, Quot.soundformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
prob_complLean 4Proved here from basic factsFormally verified
/-- **The complement rule:** `P(not A) = 1 - P(A)` (for a non-empty sample space).
Divide `|A| + |not A| = |S|` by `|S|`. -/
theorem prob_compl (S : List α) (hS : S ≠ []) (A : α → Bool) :
    prob S (fun x => !A x) = 1 - prob S A := by
  have hlen : S.length ≠ 0 := by
    intro h0
    exact hS (List.eq_nil_of_length_eq_zero h0)
  have hne : (S.length : Rat) ≠ 0 := by simpa using hlen
  have hsum : (count S A : Rat) + (count S (fun x => !A x) : Rat) = S.length := by
    have := count_compl S A
    have hc := congrArg (fun n : Nat => (n : Rat)) this
    simpa using hc
  unfold prob
  grind
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor

Theorem 2, the addition rule:

count_union_interLean 4Proved here from basic factsFormally verified
/-- **Counting a union.** Outcomes in `A` or `B`, plus outcomes in both, equals outcomes in `A`
plus outcomes in `B`: `|A ∪ B| + |A ∩ B| = |A| + |B|`. Induction on the list, checking the
four cases for whether the first outcome is in `A` and in `B`. -/
theorem count_union_inter (S : List α) (A B : α → Bool) :
    count S (fun x => A x || B x) + count S (fun x => A x && B x) = count S A + count S B := by
  induction S with
  | nil => rfl
  | cons a S ih =>
    unfold count at ih ⊢
    cases hA : A a <;> cases hB : B a <;> simp [hA, hB] <;> omega
Axioms used: propext, Quot.soundformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
prob_unionLean 4Proved here from basic factsFormally verified
/-- **The addition rule:** `P(A or B) = P(A) + P(B) - P(A and B)`. Divide `count_union_inter`
by `|S|`. When `A` and `B` cannot happen together, this is `P(A) + P(B)`. -/
theorem prob_union (S : List α) (A B : α → Bool) :
    prob S (fun x => A x || B x) = prob S A + prob S B - prob S (fun x => A x && B x) := by
  have h := congrArg (fun n : Nat => (n : Rat)) (count_union_inter S A B)
  push_cast at h
  unfold prob
  rw [Rat.div_def, Rat.div_def, Rat.div_def, Rat.div_def]
  grind
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor

Theorem 3, the product rule. The sample space of two stages is the list of all pairs.

pairsLean 4Formally verified
/-- All ordered pairs `(a, b)` with `a` from `S` and `b` from `T`: the sample space of a
two-stage experiment, as in a table or a tree diagram. -/
def pairs (S : List α) (T : List β) : List (α × β) := S.flatMap (fun a => T.map (fun b => (a, b)))
Axioms used: No axiomsformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
length_pairsLean 4Proved here from basic factsFormally verified
/-- A two-stage experiment with `|S|` and `|T|` outcomes has `|S| · |T|` outcomes. -/
theorem length_pairs (S : List α) (T : List β) : (pairs S T).length = S.length * T.length := by
  induction S with
  | nil => simp [pairs]
  | cons a S ih =>
    simp only [pairs, List.flatMap_cons, List.length_append, List.length_map] at ih ⊢
    rw [ih, List.length_cons, Nat.succ_mul, Nat.add_comm]
Axioms used: propextformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
count_pairsLean 4Proved here from basic factsFormally verified
/-- The pairs with first outcome in `A` and second outcome in `B` number `|A| · |B|`. -/
theorem count_pairs (S : List α) (T : List β) (A : α → Bool) (B : β → Bool) :
    count (pairs S T) (fun p => A p.1 && B p.2) = count S A * count T B := by
  induction S with
  | nil => simp [pairs, count]
  | cons a S ih =>
    unfold count pairs at ih ⊢
    simp only [List.flatMap_cons, List.filter_append, List.length_append] at ih ⊢
    rw [ih]
    cases hA : A a
    · simp [hA, List.filter_map, Function.comp_def]
    · simp [hA, List.filter_map, Function.comp_def]
      rw [Nat.succ_mul, Nat.add_comm]
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
prob_pairsLean 4Proved here from basic factsFormally verified
/-- **The product rule for independent stages:** if the second stage does not depend on the
first, then `P(A at stage 1 and B at stage 2) = P(A) · P(B)` — multiply along the branches of
the tree. -/
theorem prob_pairs (S : List α) (T : List β) (A : α → Bool) (B : β → Bool) :
    prob (pairs S T) (fun p => A p.1 && B p.2) = prob S A * prob T B := by
  unfold prob
  rw [count_pairs, length_pairs]
  push_cast
  by_cases hS : (S.length : Rat) = 0
  · rw [hS]
    simp [Rat.div_def]
  · by_cases hT : (T.length : Rat) = 0
    · rw [hT]
      simp [Rat.div_def]
    · grind
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor

Finally, Lean computes the dice examples and Galileo's counts by checking all the outcomes:

dieLean 4Formally verified
/-- The six equally likely outcomes of a fair die. -/
def die : List Nat := [1, 2, 3, 4, 5, 6]
Axioms used: No axiomsformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
twoDiceLean 4Formally verified
/-- The 36 equally likely outcomes of rolling two dice (a red one and a blue one). -/
def twoDice : List (Nat × Nat) := pairs die die
Axioms used: No axiomsformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
prob_sum_sevenLean 4Proved here from basic factsFormally verified
/-- With two dice, a sum of `7` has probability `6/36 = 1/6`. Computed by Lean. -/
theorem prob_sum_seven : prob twoDice (fun p => p.1 + p.2 == 7) = 1 / 6 := by
  decide +kernel
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
sums_not_equally_likelyLean 4Proved here from basic factsFormally verified
/-- The eleven possible sums are **not** equally likely: a sum of `2` has probability `1/36`,
but a sum of `7` has probability `1/6`. -/
theorem sums_not_equally_likely :
    prob twoDice (fun p => p.1 + p.2 == 2) = 1 / 36 ∧
    prob twoDice (fun p => p.1 + p.2 == 2) ≠ prob twoDice (fun p => p.1 + p.2 == 7) := by
  decide +kernel
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
threeDiceLean 4Formally verified
/-- The 216 equally likely outcomes of rolling three dice. -/
def threeDice : List (Nat × Nat × Nat) := pairs die (pairs die die)
Axioms used: No axiomsformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
galileoLean 4Proved here from basic factsFormally verified
/-- **Galileo's dice problem.** With three dice, a sum of `10` can be made in `27` ways but a
sum of `9` in only `25`, although each sum has six partitions into three numbers from 1 to 6.
Counted by Lean over all 216 outcomes. -/
theorem galileo :
    count threeDice (fun t => t.1 + t.2.1 + t.2.2 == 9) = 25 ∧
    count threeDice (fun t => t.1 + t.2.1 + t.2.2 == 10) = 27 := by
  decide
Axioms used: No axiomsformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor
at_least_one_headLean 4Proved here from basic factsFormally verified
/-- **d'Alembert's question.** Toss two coins (`true` = heads). The outcomes HH, HT, TH, TT
are equally likely, so "at least one head" has probability `3/4`, not `2/3`. -/
theorem at_least_one_head : prob (pairs [true, false] [true, false]) (fun p => p.1 || p.2) = 3 / 4 := by
  decide +kernel
Axioms used: propext, Classical.choice, Quot.soundformal/Lumenary/ProbabilityIntro.leanTry it in the Lean web editor

What is not formalised: the law of large numbers, and the modelling assumption that real dice are fair. Lean proves facts about the mathematical model; whether a real die fits the model is a question for experiment.

ComputationC

Counting and simulating

Galileo, d'Alembert and de Mere: dice questions settled by countingPythonExact computationExhaustive finite checkComputationally tested
"""Famous dice and coin questions, settled by listing every outcome.

When all outcomes are equally likely, P(A) = |A| / |S|. This experiment
lists sample spaces with itertools.product and counts exactly with Fraction:
the sums of two dice; Galileo's question about three dice (why does 10 come
up more often than 9?); d'Alembert's mistake about two coins; and the
Chevalier de Mere's two bets. Where listing is impossible (36**24 outcomes)
it uses the complement rule P(not A) = 1 - P(A) instead, and says so.
"""

from collections import Counter
from fractions import Fraction
from itertools import product

DIE = range(1, 7)

def sum_counts(dice):
    """Counter: sum -> number of ordered outcomes, for `dice` fair dice."""
    return Counter(sum(roll) for roll in product(DIE, repeat=dice))

def partitions(total, parts=3):
    """Unordered ways to write total as a sum of `parts` numbers from 1-6."""
    return sorted({tuple(sorted(roll)) for roll in product(DIE, repeat=parts)
                   if sum(roll) == total})

def probability(event, outcomes):
    """Exact P(event) when every outcome in the list is equally likely."""
    outcomes = list(outcomes)
    return Fraction(sum(1 for o in outcomes if event(o)), len(outcomes))

def at_least_one_six(rolls):
    """P(at least one 6 in `rolls` rolls), by listing all 6**rolls outcomes."""
    return probability(lambda r: 6 in r, product(DIE, repeat=rolls))

def at_least_one_double_six(throws):
    """P(at least one double six in `throws` throws of two dice).

    Uses the complement rule: no double six in one throw has probability
    35/36, and independent throws multiply.
    """
    return 1 - Fraction(35, 36) ** throws

def main():
    two = sum_counts(2)
    print("Two dice: ordered outcomes giving each sum (out of 36)")
    print("  sum: " + " ".join(f"{s:2d}" for s in range(2, 13)))
    print("  ways:" + " ".join(f"{two[s]:2d}" for s in range(2, 13)))
    print()
    three = sum_counts(3)
    print("Galileo: three dice, 216 equally likely ordered outcomes")
    for total in (9, 10):
        p = Fraction(three[total], 216)
        print(f"  sum {total:2d}: {len(partitions(total))} partitions, "
              f"{three[total]} outcomes, P = {p} = {float(p):.4f}")
    print()
    coins = list(product("HT", repeat=2))
    p = probability(lambda c: "H" in c, coins)
    print("d'Alembert: two coins, outcomes " + " ".join("".join(c)
                                                       for c in coins))
    print(f"  P(at least one head) = {p}, not 2/3: of his three cases")
    print("  H, TH, TT, the first (H) covers two outcomes, HH and HT.")
    print()
    four = at_least_one_six(4)
    print("de Mere's bets:")
    print(f"  at least one 6 in 4 rolls: listing 1296 outcomes gives {four}"
          f" = {float(four):.4f}")
    print(f"  complement rule 1 - (5/6)^4 = {1 - Fraction(5, 6) ** 4}"
          " (the same)")
    p24 = at_least_one_double_six(24)
    print(f"  at least one double 6 in 24 throws: 1 - (35/36)^24 = "
          f"{float(p24):.4f}")
    print("  (36^24 outcomes are far too many to list: complement rule only)")
    print()
    print("Epistemic status: exact counts over complete lists of outcomes,")
    print("assuming fair dice and coins with independent throws. Whether real")
    print("dice behave like this is a question about the world, tested by")
    print("experiment (see the simulation), not settled by counting.")

if __name__ == "__main__":
    main()
Runs entirely in your browser, in an isolated worker. Nothing is sent to a server.

The Chevalier de Méré, a French gambler, is said to have asked Blaise Pascal about these two bets in 1654: the first wins slightly more than half the time, the second slightly less.

Relative frequency versus probability: simulated dice and coinsPythonStatistical evidenceExact computationComputationally tested
"""Simulated dice and coins against exact probabilities.

A seeded pseudo-random generator rolls two dice thousands of times. The
relative frequency of each sum is compared with its exact probability
(ways / 36). Repeating with more and more rolls shows the frequencies
settling down - the law of large numbers - with typical errors shrinking
roughly like 1/sqrt(n). Two misconceptions are then tested: that a coin is
"due" heads after three tails (the gambler's fallacy), and that a
probability of 1/6 means exactly one six in every six rolls.
"""

import math
import random
from collections import Counter

EXACT = {s: (6 - abs(s - 7)) / 36 for s in range(2, 13)}

def roll_two_dice(rng, n):
    """Counter of sums for n rolls of two dice."""
    return Counter(rng.randint(1, 6) + rng.randint(1, 6) for _ in range(n))

def largest_error(counts, n):
    """Largest |relative frequency - exact probability| over all sums."""
    return max(abs(counts[s] / n - EXACT[s]) for s in range(2, 13))

def heads_after_tails(flips, run):
    """Among flips that follow `run` tails in a row, the fraction of heads.

    Returns (fraction, number of such flips). Flips are 'H' or 'T'.
    """
    after = [flips[i] for i in range(run, len(flips))
             if all(f == "T" for f in flips[i - run:i])]
    if not after:
        return None, 0
    return after.count("H") / len(after), len(after)

def exactly_one_six_rate(rng, blocks):
    """Fraction of blocks of six rolls that contain exactly one six."""
    hits = 0
    for _ in range(blocks):
        sixes = sum(1 for _ in range(6) if rng.randint(1, 6) == 6)
        hits += sixes == 1
    return hits / blocks

def main():
    rng = random.Random(2024)
    counts = roll_two_dice(rng, 3600)
    print("3,600 rolls of two dice: relative frequency vs exact probability")
    print("  sum   count   frequency   exact (ways/36)")
    for s in range(2, 13):
        print(f"  {s:3d}   {counts[s]:5d}   {counts[s] / 3600:9.4f}   "
              f"{EXACT[s]:.4f}")
    print()
    print("More rolls, smaller errors (largest error over the 11 sums):")
    for n in (60, 600, 6000, 60000):
        err = largest_error(roll_two_dice(rng, n), n)
        print(f"  n = {n:6d}: largest error {err:.4f}   1/sqrt(n) = "
              f"{1 / math.sqrt(n):.4f}")
    print()
    flips = ["H" if rng.random() < 0.5 else "T" for _ in range(100000)]
    frac, cases = heads_after_tails(flips, 3)
    print(f"Coin: after three tails in a row ({cases} times in 100,000 "
          f"flips),")
    print(f"  the next flip was heads {frac:.3f} of the time. Not 'due'.")
    rate = exactly_one_six_rate(rng, 20000)
    print(f"Blocks of six rolls with exactly one six: {rate:.3f} "
          f"(exact (5/6)^5 = {(5 / 6) ** 5:.3f})")
    print()
    print("Epistemic status: statistical evidence from one seeded run of a")
    print("pseudo-random generator, compared with exact values. Frequencies")
    print("vary from run to run; the law of large numbers (a theorem) says")
    print("they settle near the probabilities as n grows, not that they hit")
    print("them exactly.")

if __name__ == "__main__":
    main()
Runs entirely in your browser, in an isolated worker. Nothing is sent to a server.

The simulated frequencies are close to the exact probabilities but never exactly equal, and the largest error shrinks as nn grows — roughly in step with 1n\tfrac{1}{\sqrt n}, so a hundred times as many rolls makes the error about ten times smaller. This is statistical evidence: another run would give slightly different numbers. The exact counts are a different kind of knowledge, true for the model of fair dice.

Explore

Explore: relative frequency settles down

Experiment versus theory

Roll two dice and add them: sums near 7 come up most often, just as counting the 36 outcomes predicts.

0%10%20%23456789101112sum of the two dice1629525064727565352616
  • simulated frequency
  • exact (ways out of 36)

Sum 7

Simulated14.4%

Exact6/36 ≈ 16.7%

Sum 12

Simulated3.2%

Exact1/36 ≈ 2.8%

Simulation of 500 rolls of two dice: a sum of 7 came up 14.4% of the time. The exact probability is 6/36, about 16.7%.

Evidence, not proofThis is a simulation of 500 rolls of two dice (run 1) using a seeded random number generator. It is evidence, not proof: the exact values come from mathematics, and a new run gives slightly different numbers.

There are 6 ways to make 7 (1+6, 2+5, 3+4, 4+3, 5+2, 6+1) but only one way to make 12 (6+6).

On the two-dice tab, compare the histogram with the exact triangle of ways out of 3636. Increase the number of rolls: the bars hug the triangle more closely, but never perfectly. On the coin tab, watch the running proportion of heads wander and then settle near 12\tfrac12, mostly inside the band 12±1n\tfrac12 \pm \tfrac{1}{\sqrt n}. Press “New run” several times: every run is different, and every run settles.

Exercises

Exercises

1. Probability

Warm-upHuman

A coin is tossed and a die is rolled. How many outcomes are in the sample space? (For example, (H, 3) is one outcome.)

2. Probability

Warm-upHuman

Two fair dice are rolled. What is the probability that the sum is 88?

Choose one

3. Probability

CoreHuman

A die is rolled three times. What is the probability of getting at least one six?

Choose one

4. Probability

CoreHuman

A number is chosen at random from 1,2,…,201, 2, \ldots, 20 (all equally likely). What is the probability that it is a multiple of 22 or a multiple of 55?

Choose one

5. Probability

Warm-upHuman

A fair coin has landed tails 66 times in a row. What is the probability that the next toss is heads?

Choose one

6. Probability

CoreHuman

In 1754 d'Alembert argued: “Toss a coin up to twice, stopping when heads appears. The possible results are H, TH and TT; two of the three give a head, so the probability of getting a head is 23\tfrac23.” What is wrong?

Choose one

7. Probability

CoreHuman

Neema rolls a fair die 6060 times and gets 1414 sixes. Which statements are true? (Choose all that apply.)

Choose all that apply

8. Probability

StretchHuman

Three dice are rolled. In how many of the 216216 ordered outcomes is the sum equal to 1010?

9. Probability

CoreFormal

In the Lean file, prob S A is the probability of the event A in the list of outcomes S. Which statement is the complement rule, correctly stated?

Choose one

10. Probability

StretchComputational

Write prob_sum(dice, total) that returns the exact probability (as a Fraction) that dice fair dice add up to total. List every ordered outcome with itertools.product(range(1, 7), repeat=dice) and count. Then check Galileo: is a total of 1010 more likely than 99 with three dice?

Runs entirely in your browser, in an isolated worker. Nothing is sent to a server.
Common misconceptionsH

Common misconceptions

Misconception

The gambler's fallacy. “The coin has landed tails five times, so heads is due.” A fair coin has no memory: the next toss is heads with probability 12\tfrac12, whatever happened before. The simulation confirms it — after three tails in a row, heads came up about half the time.

Misconception

Assuming all outcomes are equally likely. The sums 2,3,…,122, 3, \ldots, 12 of two dice are not equally likely, and neither are Galileo's six ways of making 99. Equally likely outcomes are the ordered ones: (1,6)(1, 6) and (6,1)(6, 1) are different outcomes.

Misconception

“A probability of 16\tfrac16 means exactly one six in every six rolls.” It describes the long run, not each block of rolls. In six rolls, the chance of exactly one six is only (56)5≈0.40\left(\tfrac56\right)^5 \approx 0.40.

Misconception

“Two outcomes means a probability of one half.” Rain or no rain, winning or losing the lottery: having two possibilities says nothing about how likely each one is.

Misconception

“Unlikely means it won't happen.” An event with probability 11000\tfrac1{1000} is unlikely on one try, but over 10 00010\,000 tries we expect it about 1010 times. Rare events happen all the time somewhere.

ViewpointsH

Other ways of seeing

Geometry— Probability as area

Choose a point at random in a 1×11 \times 1 square. The probability that it lands in a region is the region's area. For example, the quarter-disc of radius 11 around one corner has area π4≈0.785\tfrac{\pi}{4} \approx 0.785: about 78.5%78.5\% of random points land in it, so throwing random points can even estimate π\pi. Buffon's needle (try it in the Chance Lab) is a famous version of this idea. When the sample space is infinite, “counting outcomes” becomes “measuring areas” — and Andrey Kolmogorov's 1933 foundations of probability make exactly this step, treating probability as a kind of area or volume; see measure-theoretic probability.

Combinatorics— Probability is counting, divided

With equally likely outcomes, every probability question is two counting questions: count the favourable outcomes, count all the outcomes, divide. The tools of counting principles — the multiplication principle, arrangements, complements — become tools of probability. For example, a randomly guessed 4-digit PIN is right with probability 1104=110 000\tfrac{1}{10^4} = \tfrac{1}{10\,000}.

Set-theoretic connectionH

Set-theoretic connection

Probability speaks the language of sets. Outcomes are elements, the sample space is the universe, and events are subsets. “Or” is union, “and” is intersection, “not” is complement — so a Venn diagram is a picture of events. The addition rule is the counting formula ∣A∪B∣=∣A∣+∣B∣−∣A∩B∣|A \cup B| = |A| + |B| - |A \cap B|, and the product rule is ∣A×B∣=∣A∣⋅∣B∣|A \times B| = |A| \cdot |B|, both from the sets lesson.

Wonder Trails

Wonder Trails

History & global context

History and global context

  • India. In the Mahābhārata, King Ṛtuparṇa estimates the number of leaves and fruits on a whole tree by counting those on one branch, and connects this skill with knowledge of dice. The philosopher Ian Hacking has pointed to this story as an early link between sampling and chance.
  • The Islamic world. In the 9th century, al-Kindī described how to break secret codes by comparing the relative frequencies of letters in a message with their frequencies in ordinary Arabic text.
  • Italy. Gerolamo Cardano's Book on Games of Chance (written in the 16th century, published in 1663) compared the number of favourable outcomes with the number of all equally likely outcomes. Galileo's short note on three dice (around 1620) explained the 9 versus 10 puzzle by counting ordered outcomes.
  • France and the Netherlands. In 1654 Blaise Pascal and Pierre de Fermat exchanged letters on how to divide the stakes of an unfinished game, often seen as the start of mathematical probability. Christiaan Huygens wrote the first printed textbook on probability (1657). In 1754 Jean le Rond d'Alembert argued that the chance of at least one head in two tosses is 23\tfrac23 — a famous mistake.
  • Switzerland and Russia. Jacob Bernoulli's Ars Conjectandi (1713) proved the first law of large numbers. Andrey Kolmogorov's book of 1933 gave probability the axioms used today.
Further reading

Further reading

  • Ian Hacking, An Introduction to Probability and Inductive Logic (2001).
  • Charles M. Grinstead and J. Laurie Snell, Introduction to Probability (1997), with many simulations.
  • William Feller, An Introduction to Probability Theory and Its Applications, volume 1 (1950) — a classic, for later.
  • Ian Hacking, The Emergence of Probability (1975), on the history of the subject.