def _(expr, assumptions): """ * Unbounded ** NonZero -> Unbounded * Bounded ** Bounded -> Bounded * Abs()<=1 ** Positive -> Bounded * Abs()>=1 ** Negative -> Bounded * Otherwise unknown """ if expr.base == E: return ask(Q.finite(expr.exp), assumptions) base_bounded = ask(Q.finite(expr.base), assumptions) exp_bounded = ask(Q.finite(expr.exp), assumptions) if base_bounded is None and exp_bounded is None: # Common Case return None if base_bounded is False and ask(Q.extended_nonzero(expr.exp), assumptions): return False if base_bounded and exp_bounded: return True if (abs(expr.base) <= 1) == True and ask(Q.extended_positive(expr.exp), assumptions): return True if (abs(expr.base) >= 1) == True and ask(Q.extended_negative(expr.exp), assumptions): return True if (abs(expr.base) >= 1) == True and exp_bounded is False: return False return None
def _(expr, assumptions): """ Return True if expr is bounded, False if not and None if unknown. Truth Table: +---+---+---+--------+ | | | | | | | B | U | ? | | | | | | +---+---+---+---+----+ | | | | | | | | | | s | /s | | | | | | | +---+---+---+---+----+ | | | | | | B | B | U | ? | | | | | | +---+---+---+---+----+ | | | | | | | U | | U | U | ? | | | | | | | +---+---+---+---+----+ | | | | | | ? | | | ? | | | | | | +---+---+---+---+----+ * B = Bounded * U = Unbounded * ? = unknown boundedness * s = signed (hence nonzero) * /s = not signed """ result = True for arg in expr.args: _bounded = ask(Q.finite(arg), assumptions) if _bounded: continue elif _bounded is None: if result is None: return None if ask(Q.extended_nonzero(arg), assumptions) is None: return None if result is not False: result = None else: result = False return result