Where do Mathematica's probability functions draw a line in the sand for predicates?

Thinking about a recent question mis-posted here (belonged on math), I noted the following.

A contrived example - probability that a or b are 1:

Probability[ a == 1 || b == 1, {a \[Distributed] DiscreteUniformDistribution[{0, 1}],
b \[Distributed] DiscreteUniformDistribution[{0, 1}]}]


outputs as expected 3/4. Now if one had a more complicated predicate, say ten variates involved, it would be a messy predicate to do manually. Of course, one could use various facilities to build it auto-magically, or just use something like (keeping it simple as above, but one can see how this makes extension to many variates simple):

Probability[Total[Unitize[{a, b}]] > 0, {a \[Distributed] DiscreteUniformDistribution[{0, 1}],
b \[Distributed] DiscreteUniformDistribution[{0, 1}]}]


which returns the expected result.

However, something that intuitively seems it should work, like:

Probability[
Count[{a, b}, 0] != 2, {a \[Distributed] DiscreteUniformDistribution[{0, 1}],
b \[Distributed] DiscreteUniformDistribution[{0, 1}]}]


does not, and somewhat worryingly returns a result (invalid) of 1 rather than an error or warning for an unusable predicate.

The same results occur with NProbability.

(1) Is there any rhyme or reason around what works and what doesn't?

(2) Is there any method to get Mathematica to use such a construct directly, or at least spit back a "no can do"?

-

In this particular case there's an easy explanation:

Count[{a, b}, 0] immediately evaluates to 0, so we end up with Probability[ 0 != 2, ...], then Probability[True, ...], which is 1.

To be able to give a warning, Probability would need to be HoldAll and check the arguments before they're evaluated.

I do think that this is a somewhat tricky point, but the problem runs deeper than Probability and has to do with how the language is designed. A less rigid language structure gives more room for making uncatchable mistakes.

The following does seems to work:

f[a_?NumericQ, b_?NumericQ] := Count[{a, b}, 0] != 2

Probability[
f[a, b], {a \[Distributed] DiscreteUniformDistribution[{0, 1}], b \[Distributed] DiscreteUniformDistribution[{0, 1}]}]


Actually I'm a bit surprised to find that blackbox functions do work with Probability. It probably builds a complete probability table to be able to do this.

-
... where ?NumericQ is the secret sauce! –  Stephen Luttrell Mar 4 at 19:43
+1 well done, I'd tried that but without the "secret sauce". N.B.: It appears it is sufficient to just have that on any one of the arguments. –  rasher Mar 5 at 0:07