1-- Conditional probability, the law of total probability, and Bayes' theorem2-- Part of Cumulus, the Grace17 mathematics library.3-- Copyright (c) 2026 Grant Passmore.4-- Released under the Apache License 2.0. See LICENSE in the repository root.5-- Authors: Grant Passmore67module Grace.Cumulus.Probability.Conditional8import Space910-- The probability of A given B.11def condProb (P A B : Set) : Set:= call2(realDiv, prob(P, A ∩ B), prob(P, B))1213theorem condProb.value (P A B : Set)14shows condProb(P, A, B) = (prob(P, A ∩ B):R) / (prob(P, B):R)15proof16simp [condProb]1718theorem prob.ne_zero_of_positive (Ω P B : Set)19requires space : ProbabilitySpace(Ω, P)20requires event : B ⊆ Ω21requires positive : (0:R) < (prob(P, B):R)22shows prob(P, B) ≠ (0:R)23proof24have realB := prob.real with space, event25intro zero26rw zero at positive27exact realLess.not_self with positive2829theorem prob.positive_of_ne_zero (Ω P B : Set)30requires space : ProbabilitySpace(Ω, P)31requires event : B ⊆ Ω32requires nonzero : prob(P, B) ≠ (0:R)33shows (0:R) < (prob(P, B):R)34proof35have realB := prob.real with space, event36have nonnegative := prob.nonnegative with space, event37exactReal.positive_of_nonnegative_of_ne_zero with nonnegative, nonzero3839theorem condProb.real (Ω P A B : Set)40requires space : ProbabilitySpace(Ω, P)41requires eventA : A ⊆ Ω42requires eventB : B ⊆ Ω43showsReal(condProb(P, A, B))44proof45have eventMeet : A ∩ B ⊆ Ω bysimp46have realMeet := prob.real with space, eventMeet47have realB := prob.real with space, eventB48rw condProb.value49exact realDiv.real at prob(P, A ∩ B), prob(P, B)5051theorem condProb.nonnegative (Ω P A B : Set)52requires space : ProbabilitySpace(Ω, P)53requires eventA : A ⊆ Ω54requires eventB : B ⊆ Ω55requires positive : (0:R) < (prob(P, B):R)56shows (0:R) ≤ (condProb(P, A, B):R)57proof58have eventMeet : A ∩ B ⊆ Ω bysimp59have realMeet := prob.real with space, eventMeet60have realB := prob.real with space, eventB61have nonnegativeMeet := prob.nonnegative with space, eventMeet62have inversePositive := realInvValue.positive at prob(P, B) with positive63have inverseReal := realInvValue.real at prob(P, B)64have inverseNonnegative : (0:R) ≤ (realInvValue(prob(P, B)):R) bylinarith65have division := realDiv.eq_mul_inv at prob(P, A ∩ B), prob(P, B)66have product := realMulValue.nonnegative at prob(P, A ∩ B),67 realInvValue(prob(P, B)) with68 nonnegativeMeet, inverseNonnegative69rw [condProb.value, division]70exact product7172theorem condProb.le_one (Ω P A B : Set)73requires space : ProbabilitySpace(Ω, P)74requires eventA : A ⊆ Ω75requires eventB : B ⊆ Ω76requires positive : (0:R) < (prob(P, B):R)77shows (condProb(P, A, B):R) ≤ (1:R)78proof79have eventMeet : A ∩ B ⊆ Ω bysimp80have realMeet := prob.real with space, eventMeet81have realB := prob.real with space, eventB82have nonzero := prob.ne_zero_of_positive with space, eventB, positive83have bound := prob.intersection_le_right at Ω, P, A, B with space, eventB84have inversePositive := realInvValue.positive at prob(P, B) with positive85have inverseReal := realInvValue.real at prob(P, B)86have inverseNonnegative : (0:R) ≤ (realInvValue(prob(P, B)):R) bylinarith87have division := realDiv.eq_mul_inv at prob(P, A ∩ B), prob(P, B)88have scaled := realLe.mul_right_of_nonnegative at prob(P, A ∩ B), prob(P, B),89 realInvValue(prob(P, B)) with bound, inverseNonnegative90have inverseLaw := realInvValue.mul_right at prob(P, B) with nonzero91rw [condProb.value, division]92rw inverseLaw at scaled93exact scaled9495theorem condProb.self (Ω P B : Set)96requires space : ProbabilitySpace(Ω, P)97requires eventB : B ⊆ Ω98requires positive : (0:R) < (prob(P, B):R)99shows condProb(P, B, B) = (1:R)100proof101have realB := prob.real with space, eventB102have nonzero := prob.ne_zero_of_positive with space, eventB, positive103have same := intersection.idempotent at B104rw [condProb.value, same]105exact realDiv.self at prob(P, B) with nonzero106107theorem condProb.whole (Ω P B : Set)108requires space : ProbabilitySpace(Ω, P)109requires eventB : B ⊆ Ω110requires positive : (0:R) < (prob(P, B):R)111shows condProb(P, Ω, B) = (1:R)112proof113have realB := prob.real with space, eventB114have nonzero := prob.ne_zero_of_positive with space, eventB, positive115have same := intersection.eq_right_of_subset at Ω, B with eventB116rw [condProb.value, same]117exact realDiv.self at prob(P, B) with nonzero118119theorem condProb.empty (Ω P B : Set)120requires space : ProbabilitySpace(Ω, P)121requires eventB : B ⊆ Ω122shows condProb(P, ∅, B) = (0:R)123proof124have realB := prob.real with space, eventB125have same := intersection.left_empty at B126have empty := prob.empty at P127rw [condProb.value, same, empty]128exact realDiv.zero_left at prob(P, B)129130theorem condProb.of_disjoint (Ω P A B : Set)131requires space : ProbabilitySpace(Ω, P)132requires eventB : B ⊆ Ω133requires disjoint : Disjoint(A, B)134shows condProb(P, A, B) = (0:R)135proof136have realB := prob.real with space, eventB137have same : A ∩ B =∅:= disjoint138have empty := prob.empty at P139rw [condProb.value, same, empty]140exact realDiv.zero_left at prob(P, B)141142-- The multiplication rule.143theorem condProb.multiplication (Ω P A B : Set)144requires space : ProbabilitySpace(Ω, P)145requires eventA : A ⊆ Ω146requires eventB : B ⊆ Ω147requires positive : (0:R) < (prob(P, B):R)148shows prob(P, A ∩ B) = (condProb(P, A, B):R) * (prob(P, B):R)149proof150have eventMeet : A ∩ B ⊆ Ω bysimp151have realMeet := prob.real with space, eventMeet152have realB := prob.real with space, eventB153have nonzero := prob.ne_zero_of_positive with space, eventB, positive154have cancel := realDiv.mul_right at prob(P, A ∩ B), prob(P, B) with nonzero155rw condProb.value156 symm157exact cancel158159theorem condProb.of_subset (Ω P A B : Set)160requires space : ProbabilitySpace(Ω, P)161requires inner : A ⊆ B162shows condProb(P, A, B) = (prob(P, A):R) / (prob(P, B):R)163proof164have same := intersection.eq_left_of_subset at A, B with inner165rw [condProb.value, same]166rfl167168theorem condProb.of_superset (Ω P A B : Set)169requires space : ProbabilitySpace(Ω, P)170requires eventB : B ⊆ Ω171requires inner : B ⊆ A172requires positive : (0:R) < (prob(P, B):R)173shows condProb(P, A, B) = (1:R)174proof175have realB := prob.real with space, eventB176have nonzero := prob.ne_zero_of_positive with space, eventB, positive177have same := intersection.eq_right_of_subset at A, B with inner178rw [condProb.value, same]179exact realDiv.self at prob(P, B) with nonzero180181theorem condProb.monotone (Ω P A C B : Set)182requires space : ProbabilitySpace(Ω, P)183requires eventC : C ⊆ Ω184requires eventB : B ⊆ Ω185requires inner : A ⊆ C186requires positive : (0:R) < (prob(P, B):R)187shows (condProb(P, A, B):R) ≤ (condProb(P, C, B):R)188proof189have eventMeetC : C ∩ B ⊆ Ω bysimp190have innerMeet : A ∩ B ⊆ C ∩ B bysimp191have eventMeetA := Subset.transitive with innerMeet, eventMeetC192have realMeetA := prob.real with space, eventMeetA193have realMeetC := prob.real with space, eventMeetC194have realB := prob.real with space, eventB195have bound := prob.monotone with space, eventMeetC, innerMeet196have inversePositive := realInvValue.positive at prob(P, B) with positive197have inverseReal := realInvValue.real at prob(P, B)198have inverseNonnegative : (0:R) ≤ (realInvValue(prob(P, B)):R) bylinarith199have divisionA := realDiv.eq_mul_inv at prob(P, A ∩ B), prob(P, B)200have divisionC := realDiv.eq_mul_inv at prob(P, C ∩ B), prob(P, B)201have scaled := realLe.mul_right_of_nonnegative at prob(P, A ∩ B), prob(P,202 C ∩ B),203 realInvValue(prob(P, B)) with bound, inverseNonnegative204rw [condProb.value, condProb.value, divisionA, divisionC]205exact scaled206207theorem condProb.union_disjoint (Ω P A C B : Set)208requires space : ProbabilitySpace(Ω, P)209requires eventA : A ⊆ Ω210requires eventC : C ⊆ Ω211requires eventB : B ⊆ Ω212requires disjoint : Disjoint(A, C)213shows condProb(P, A ∪ C, B) = (condProb(P, A, B):R) + (condProb(P, C, B):R)214proof215have eventMeetA : A ∩ B ⊆ Ω bysimp216have eventMeetC : C ∩ B ⊆ Ω bysimp217have realMeetA := prob.real with space, eventMeetA218have realMeetC := prob.real with space, eventMeetC219have realB := prob.real with space, eventB220havesplit : (A ∪ C) ∩ B = (A ∩ B) ∪ (C ∩ B)221ext y222simp223have innerC := intersection.subset_left at C, B224have innerA := intersection.subset_left at A, B225have disjointRight := Disjoint.of_subset_right with disjoint, innerC226have disjointMeet := Disjoint.of_subset_left with disjointRight, innerA227have union := prob.union_disjoint with space, eventMeetA, eventMeetC,228 disjointMeet229have division := realDiv.add_left at prob(P, A ∩ B), prob(P, C ∩ B), prob(P,230 B)231rw [condProb.value, condProb.value, condProb.value, split, union]232exact division233234theorem condProb.complement (Ω P A B : Set)235requires space : ProbabilitySpace(Ω, P)236requires eventA : A ⊆ Ω237requires eventB : B ⊆ Ω238requires positive : (0:R) < (prob(P, B):R)239shows condProb(P, Ω ∖ A, B) = (1:R) - (condProb(P, A, B):R)240proof241have eventMeet : A ∩ B ⊆ Ω bysimp242have eventRest : B ∖ A ⊆ Ω bysimp243have realMeet := prob.real with space, eventMeet244have realRest := prob.real with space, eventRest245have realB := prob.real with space, eventB246have nonzero := prob.ne_zero_of_positive with space, eventB, positive247have same : (Ω ∖ A) ∩ B = B ∖ A248ext y249simp250have commute := intersection.commutative at B, A251havesplit:= prob.difference at Ω, P, B, A with space, eventB252rw commute atsplit253have inverseReal := realInvValue.real at prob(P, B)254have inverseLaw := realInvValue.mul_right at prob(P, B) with nonzero255have divisionRest := realDiv.eq_mul_inv at prob(P, B ∖ A), prob(P, B)256have divisionMeet := realDiv.eq_mul_inv at prob(P, A ∩ B), prob(P, B)257rw [condProb.value, condProb.value, same, divisionRest, divisionMeet, split]258calc259 ((prob(P, B):R) - (prob(P, A ∩ B):R)) * (realInvValue(prob(P, B)):R) =260 (prob(P, B):R) * (realInvValue(prob(P, B)):R) -261 (prob(P, A ∩ B):R) * (realInvValue(prob(P, B)):R) :=byring262 _ = (1:R) - (prob(P, A ∩ B):R) * (realInvValue(prob(P, B)):R) :=bycc263264-- The law of total probability for the partition B, Ω ∖ B.265theorem condProb.total_probability (Ω P A B : Set)266requires space : ProbabilitySpace(Ω, P)267requires eventA : A ⊆ Ω268requires eventB : B ⊆ Ω269requires positive : (0:R) < (prob(P, B):R)270requires positiveRest : (0:R) < (prob(P, Ω ∖ B):R)271shows prob(P, A) = (condProb(P, A, B):R) * (prob(P, B):R) +272 (condProb(P, A, Ω ∖ B):R) * (prob(P, Ω ∖ B):R)273proof274have eventRest : Ω ∖ B ⊆ Ω bysimp275have eventMeet : A ∩ B ⊆ Ω bysimp276have eventMeetRest : A ∩ (Ω ∖ B) ⊆ Ω bysimp277havesplit : (A ∩ B) ∪ (A ∩ (Ω ∖ B)) = A278ext y279simp280have innerB := intersection.subset_right at A, B281have innerRest := intersection.subset_right at A, Ω ∖ B282have disjointRest := Disjoint.difference_right at Ω, B283have disjointRight := Disjoint.of_subset_right with disjointRest, innerRest284have disjointMeet := Disjoint.of_subset_left with disjointRight, innerB285have union := prob.union_disjoint with space, eventMeet, eventMeetRest,286 disjointMeet287have first := condProb.multiplication with space, eventA, eventB, positive288have second := condProb.multiplication with space, eventA, eventRest,289 positiveRest290rwsplitat union291rw [union, first, second]292rfl293294theorem condProb.bayes (Ω P A B : Set)295requires space : ProbabilitySpace(Ω, P)296requires eventA : A ⊆ Ω297requires eventB : B ⊆ Ω298requires positiveA : (0:R) < (prob(P, A):R)299requires positiveB : (0:R) < (prob(P, B):R)300shows condProb(P, A, B) = ((condProb(P, B, A):R) * (prob(P, A):R)) / (prob(P,301 B):R)302proof303have commute := intersection.commutative at A, B304have product := condProb.multiplication with space, eventB, eventA, positiveA305rw condProb.value306rw [commute, product]307rfl308309-- Conditioning on B is again a probability space on Ω: the weight is310-- rescaled on B and vanishes outside it.311def conditionalWeight (Ω P B : Set) : Set:=312 maskedWeight(Ω, B, weightScale(Ω, realInvValue(prob(P, B)), P))313314theorem conditionalWeight.inverse_real (Ω P B : Set)315requires space : ProbabilitySpace(Ω, P)316requires eventB : B ⊆ Ω317showsReal(realInvValue(prob(P, B)))318proof319have realB := prob.real with space, eventB320exact realInvValue.real at prob(P, B)321322theorem conditionalWeight.function (Ω P B : Set)323requires space : ProbabilitySpace(Ω, P)324requires eventB : B ⊆ Ω325shows conditionalWeight(Ω, P, B) : Ω → ℝ326proof327have function := ProbabilitySpace.function with space328have inverseReal := conditionalWeight.inverse_real with space, eventB329have scaled := weightScale.function at Ω, realInvValue(prob(P, B)), P with330 function331unfold conditionalWeight332exact maskedWeight.function at Ω, B, weightScale(Ω, realInvValue(prob(P, B)),333 P) with334 scaled335336theorem conditionalWeight.inside (Ω P B ω : Set)337requires space : ProbabilitySpace(Ω, P)338requires eventB : B ⊆ Ω339requires point : ω ∈ Ω340requires inside : ω ∈ B341shows conditionalWeight(Ω, P, B)(ω) = (realInvValue(prob(P, B)):R) * (P(ω):R)342proof343have function := ProbabilitySpace.function with space344have inverseReal := conditionalWeight.inverse_real with space, eventB345have scaled := weightScale.function at Ω, realInvValue(prob(P, B)), P with346 function347have mask := maskedWeight.inside at Ω, B, weightScale(Ω, realInvValue(prob(P,348 B)), P),349 ω with scaled, point, inside350have value := weightScale.value at Ω, realInvValue(prob(P, B)), P, ω with351 function, point352unfold conditionalWeight353cc354355theorem conditionalWeight.outside (Ω P B ω : Set)356requires space : ProbabilitySpace(Ω, P)357requires eventB : B ⊆ Ω358requires point : ω ∈ Ω359requires outside : ¬(ω ∈ B)360shows conditionalWeight(Ω, P, B)(ω) = (0:R)361proof362have function := ProbabilitySpace.function with space363have inverseReal := conditionalWeight.inverse_real with space, eventB364have scaled := weightScale.function at Ω, realInvValue(prob(P, B)), P with365 function366have mask := maskedWeight.outside at Ω, B, weightScale(Ω,367 realInvValue(prob(P, B)), P),368 ω with scaled, point, outside369unfold conditionalWeight370cc371372theorem conditionalWeight.nonnegative (Ω P B : Set)373requires space : ProbabilitySpace(Ω, P)374requires eventB : B ⊆ Ω375requires positive : (0:R) < (prob(P, B):R)376shows∀ ω ∈ Ω, (0:R) ≤ (conditionalWeight(Ω, P, B)(ω):R)377proof378intros ω point379have realB := prob.real with space, eventB380have inverseReal := conditionalWeight.inverse_real with space, eventB381have inversePositive := realInvValue.positive at prob(P, B) with positive382have inverseNonnegative : (0:R) ≤ (realInvValue(prob(P, B)):R) bylinarith383have alternatives : ω ∈ B ∨¬(ω ∈ B) bytauto384cases alternatives with inside | outside385 . have value := conditionalWeight.inside with space, eventB, point, inside386have pointReal := ProbabilitySpace.point_real with space, point387have pointNonnegative := ProbabilitySpace.point_nonnegative with space,388 point389rw value390exact realMulValue.nonnegative at realInvValue(prob(P, B)), P(ω) with391 inverseNonnegative, pointNonnegative392 . have value := conditionalWeight.outside with space, eventB, point, outside393rw value394exact realLe.reflexive with realZero.real395396-- Under the conditional weight an event A has probability condProb(A, B).397theorem conditionalWeight.prob (Ω P B A : Set)398requires space : ProbabilitySpace(Ω, P)399requires eventB : B ⊆ Ω400requires eventA : A ⊆ Ω401shows prob(conditionalWeight(Ω, P, B), A) = condProb(P, A, B)402proof403have function := ProbabilitySpace.function with space404have finiteA := ProbabilitySpace.event_finite with space, eventA405have inverseReal := conditionalWeight.inverse_real with space, eventB406have scaled := weightScale.function at Ω, realInvValue(prob(P, B)), P with407 function408have eventMeet : A ∩ B ⊆ Ω bysimp409have finiteMeet := ProbabilitySpace.event_finite with space, eventMeet410have realMeet := prob.real with space, eventMeet411have realB := prob.real with space, eventB412have masked := realSetSum.masked_intersection at A, B, Ω,413 weightScale(Ω, realInvValue(prob(P, B)), P) with finiteA, scaled, eventA414have scale := realSetSum.scale at A ∩ B, Ω, P, realInvValue(prob(P, B)) with415 finiteMeet, function, eventMeet416have division := realDiv.eq_mul_inv at prob(P, A ∩ B), prob(P, B)417have commute := realMulValue.commutative at realInvValue(prob(P, B)), prob(P,418 A ∩ B)419have meetValue := prob.value at P, A ∩ B420rw [prob.value, condProb.value, division]421unfold conditionalWeight422cc423424theorem conditionalWeight.total (Ω P B : Set)425requires space : ProbabilitySpace(Ω, P)426requires eventB : B ⊆ Ω427requires positive : (0:R) < (prob(P, B):R)428shows realSetSum(Ω, conditionalWeight(Ω, P, B)) = (1:R)429proof430have whole := Subset.reflexive at Ω431have conditioned := conditionalWeight.prob with space, eventB, whole432have one := condProb.whole with space, eventB, positive433rw prob.value at conditioned434rw conditioned435exact one436437theorem conditionalWeight.space (Ω P B : Set)438requires space : ProbabilitySpace(Ω, P)439requires eventB : B ⊆ Ω440requires positive : (0:R) < (prob(P, B):R)441shows ProbabilitySpace(Ω, conditionalWeight(Ω, P, B))442proof443have finite := ProbabilitySpace.finite with space444have function := conditionalWeight.function with space, eventB445have nonnegative := conditionalWeight.nonnegative with space, eventB, positive446have total := conditionalWeight.total with space, eventB, positive447exact ProbabilitySpace.intro with finite, function, nonnegative, total448