fix Mul._eval_is_zero trap; check bounded for zero in _eval_is_real

Some important reminders:

If the order of args matters then it is not enough to use evaluate=False
to create the object with args in a new order since the sorted args are
used for the cache. Use Dummy to create the args (or else Symbol with
new names for the arguments). I prefer Dummy because then you don't have
to worry about a name and there will be no accidental duplication of symbols.

When checking for multiple args, it is not enough to use a symbol twice
in a Mul since this will create a single Pow (e.g. c, c -> c**2). Again,
using Dummy is a good idea.