(expr, assumptions)
Even * Integer    -> Even
        Even * Odd        -> Even
        Integer * Odd     -> ?
        Odd * Odd         -> Odd
        Even * Even       -> Even
        Integer * Integer -> Even if Integer + Integer = Odd
                          -> ? otherwise
Even * Integer    -> Even
        Even * Odd        -> Even
        Integer * Odd     -> ?
        Odd * Odd         -> Odd
        Even * Even       -> Even
        Integer * Integer -> Even if Integer + Integer = Odd
                          -> ? otherwise
Even * Integer - > Even Even * Odd - > Even Integer * Odd - > ? Odd * Odd - > Odd Even * Even - > Even Integer * Integer - > Even if Integer + Integer = Odd - > ? otherwise
def Mul(expr, assumptions):
        """
        Even * Integer    -> Even
        Even * Odd        -> Even
        Integer * Odd     -> ?
        Odd * Odd         -> Odd
        Even * Even       -> Even
        Integer * Integer -> Even if Integer + Integer = Odd
                          -> ? otherwise
        """
        if expr.is_number:
            return AskEvenHandler._number(expr, assumptions)
        even, odd, irrational, acc = False, 0, False, 1
        for arg in expr.args:
            # check for all integers and at least one even
            if ask(Q.integer(arg), assumptions):
                if ask(Q.even(arg), assumptions):
                    even = True
                elif ask(Q.odd(arg), assumptions):
                    odd += 1
                elif not even and acc != 1:
                    if ask(Q.odd(acc + arg), assumptions):
                        even = True
            elif ask(Q.irrational(arg), assumptions):
                # one irrational makes the result False
                # two makes it undefined
                if irrational:
                    break
                irrational = True
            else:
                break
            acc = arg
        else:
            if irrational:
                return False
            if even:
                return True
            if odd == len(expr.args):
                return False
def Mul ( expr , assumptions ) : if expr . is_number : return AskEvenHandler . _number ( expr , assumptions ) even , odd , irrational , acc = False , 0 , False , 1 for arg in expr . args : # check for all integers and at least one even if ask ( Q . integer ( arg ) , assumptions ) : if ask ( Q . even ( arg ) , assumptions ) : even = True elif ask ( Q . odd ( arg ) , assumptions ) : odd += 1 elif not even and acc != 1 : if ask ( Q . odd ( acc + arg ) , assumptions ) : even = True elif ask ( Q . irrational ( arg ) , assumptions ) : # one irrational makes the result False # two makes it undefined if irrational : break irrational = True else : break acc = arg else : if irrational : return False if even : return True if odd == len ( expr . args ) : return False