Рекурсивная формула из ответа Роберта Додье напрямую переводит на
p_or([], 0).
p_or([P|Ps], Or) :-
p_or(Ps, Or1),
Or is P + Or1*(1-P).
Хотя это работает отлично, например,
?- p_or([0.5,0.3,0.7,0.1],P).
P = 0.9055
хардкорные программисты Prolog не могут не заметить, что определение не является 't хвостовая рекурсия .Это действительно будет проблемой, только когда вы обрабатываете очень длинные списки, но поскольку порядок элементов списка не имеет значения, все легко изменить.Это стандартная техника, использующая вспомогательный предикат и «пару аккумуляторов» аргументов:
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