1

Does anybody know where to find a Prolog algorithm for computing the probability of a disjunction for N dependent events? For N = 2 i know that P(E1 OR E2) = P(E1) + P(E2) - P(E1) * P(E2), so one could do:

prob_disjunct(E1, E2, P):- P is E1 + E2 - E1 * E2

But how can this predicate be generalised to N events when the input is a list? Maybe there is a package which does this?

Kinds regards/JCR

  • 1
    Saw [cplint on SWISH](http://cplint.ml.unife.it/) via this [answer](https://swi-prolog.discourse.group/t/probabilistic-logic-programming/506/2). When at the SWISH site click the `about` link at the top for more info. – Guy Coder Apr 09 '19 at 10:48
  • Yes, thanks, but i needed my own recipe. –  Apr 10 '19 at 04:08

3 Answers3

1

I don't know anything about Prolog, but anyway it's convenient to write the probability of a disjunction of a number of independent items p_m = Pr(S_1 or S_2 or S_3 or ... or S_m) recursively as

p_m = Pr(S_m) + p_{m - 1} (1 - P(S_m))

You can prove this by just peeling off the last item -- look at Pr((S_1 or ... or S_{m - 1}) or S_m) and just write that in terms of the usual formula, writing Pr(A or B) = Pr(A) + Pr(B) - Pr(A) Pr(B) = Pr(B) + Pr(A) (1 - Pr(B)), for A and B independent.

The formula above is item C.3.10 in my dissertation: http://riso.sourceforge.net/docs/dodier-dissertation.pdf It is a simple result, and I suppose it must be an exercise in some textbooks, although I don't remember seeing it.

Robert Dodier
  • 16,905
  • 2
  • 31
  • 48
1

The recursive formula from Robert Dodier's answer directly translates to

p_or([], 0).
p_or([P|Ps], Or) :-
    p_or(Ps, Or1),
    Or is P + Or1*(1-P).

Although this works fine, e.g.

?- p_or([0.5,0.3,0.7,0.1],P).
P = 0.9055

hardcore Prolog programmers can't help noticing that the definition isn't . This would really only be a problem when you are processing very long lists, but since the order of list elements doesn't matter, it is easy to turn things around. This is a standard technique, using an auxiliary predicate and an "accumulator pair" of arguments:

p_or(Ps, Or) :-
    p_or(Ps, 0, Or).

p_or([], Or, Or).
p_or([P|Ps], Or0, Or) :-
    Or1 is P + Or0*(1-P),
    p_or(Ps, Or1, Or).       % tail-recursive call
jschimpf
  • 4,904
  • 11
  • 24
1

For any event E I'll write E' for the complementary event (ie E' occurs iff E doesn't). Then we have:

P(E') = 1 - P(E)
(A union B)' = A' inter B'
A and B are independent iff A' and B' are independent

so for independent E1..En

P( E1 union .. union En ) = 1 - P( E1' inter .. inter En')
= 1 - product{ i<=i<=n | 1 - P(E[i])}
dmuir
  • 4,211
  • 2
  • 14
  • 12