fixes #7899
Revert back Mul._eval_is_imaginary helper, as per 293606b
Fix tests (0 is NOT an imaginary!)
Adopt re/im/abs to work around (real*I).is_real is None
Adopt RoundFunction class to work around (real*I).is_real is None
minor tweaks
do not dispatch to re/im when all factors are already known
fix is_zero detection on Mul._eval_is_* tests

Once a None is obtained for is_zero, it should no longer be updated.
The return value must consider the value of is_zero. This can
change if S.Zero.is_imaginary = S.Zero.is_real = True is ever true.

The routines were shortened a bit, too.
keep floor(i) unchanged if i is imaginary symbol
watch for pairs of imaginaries that control Mul sign
only process imaginaries in is_negative
only process literal imaginary in abs
quicker exit for Pow is_imaginary handlers
add some numerical handling to Pow imaginary/real/complex handlers

I do not know how to add the same thing to the new assumptions
since arg must be computed and whether it comes back evaluated
or not depends on arg's use of the old assumptions. So

var('x');ask(Q.real((x - I*x)**2), Q.positive(x))

will not evaluate properly unless one *also* does var('x', positive=1).