def try_assumptions(self, pot, decompose_variant):
        self.assumptions += decompose_variant.assumptions
        self.assumptions = dedup(self.assumptions)

        symbol_intervals = deepcopy( pot.symbol_intervals )

        for assumption in self.assumptions:
            assumption_deps = assumption.depends()
            deps_len = len(assumption_deps)
            if deps_len == 0:
                if assumption.test() == result.not_possible: return False
                continue

            if deps_len == 1:
                symbol = assumption_deps[0]
                if symbol not in symbol_intervals:
                    symbol_intervals[symbol] = intervals()
                lim = decompose(assumption)
                if not lim:
                    print("[warn] decompose failed:", assumption)
                    return False

                res = symbol_intervals[symbol]
                res *= lim
                if res.is_zero(): return False
                symbol_intervals[symbol] = res
                continue

        for symbol_assumption in decompose_variant.symbol_assumptions:
            self._add_symbol_assumption(symbol_assumption)

        self._update_symbol_assumptions()
        if not self._test_symbol_assumptions(): return False
        return self.test_by_symbol_intervals(symbol_intervals)
Exemple #2
0
def get_linear_data_intervals(sym_lims, exp):
    ret = intervals(interval(0, True, 0, True))
    expcd = exp.as_coefficients_dict()
    for mn in expcd:
        k = expcd[mn]
        one = intervals(interval(k, False, k, False))
        c, mns = mn.as_coeff_mul()
        for omns in mns:
            pomns = omns.as_powers_dict()
            for s in pomns:
                p = pomns[s]
                if s in sym_lims:
                    one = one.get_mult_intervals(sym_lims[s].get_intervals_by_pow(p))
                else:
                    one = one.get_mult_intervals(intervals(interval(float('-inf'), True, float('inf'), True)))
        ret = ret.get_add_intervals(one)
    return ret
Exemple #3
0
def test_linear_assumption(sym_lims, a):
    a_interval = get_linear_data_intervals(sym_lims, a.exp)
    if a.sign == '>=': need = intervals(interval(0, False, float('inf'), True))
    elif a.sign == '>': need = intervals(interval(0, True, float('inf'), True))
    elif a.sign == '<': need = intervals(interval(float('-inf'), True, 0, True))
    elif a.sign == '<=': need = intervals(interval(float('-inf'), True, 0, False))
    elif a.sign == '==': need = intervals(interval(0, False, 0, False))
    elif a.sign == '!=': need = intervals(interval(float('-inf'), True, 0, True)) + interval(0, True, float('inf'), True)
    else: raise Exception('unknown sign: ', a.sign)
    result = a_interval * need
    return not result.is_zero()
Exemple #4
0
def get_poly_interval(a, n, sign, roots):
    roots = sorted(roots)
    i = intervals(interval(0, True, 0, True))

    if sign == "==":
        for x in roots:
            i += interval(x, False, x, False)
        return i
    if sign == "!=":
        r = float("-inf")
        for x in roots:
            l, r = r, x
            i += interval(l, True, r, True)
        l, r = r, float("inf")
        i += interval(l, True, r, True)
        return i

    need_neg = False
    strong = True
    if sign == ">=":
        strong = False
    if sign == "<" or sign == "<=":
        need_neg = True
        if sign == "<=":
            strong = False

    f = get_fx(a, n)
    neg = False
    if f(float("-inf")) < 0:
        neg = True

    r = float("-inf")
    for x in roots:
        l, r = r, x
        if not neg ^ need_neg:
            i += interval(l, strong, r, strong)
        neg = not neg

    l, r = r, float("inf")
    if not neg ^ need_neg:
        i += interval(l, strong, r, strong)

    return i
Exemple #5
0
def get_intervals(poly, sign, roots, minimum):
    i = intervals(interval(0, True, 0, True))

    if sign == "==":
        for x in roots:
            i += interval(x, False, x, False)
        return i
    if sign == "!=":
        r = float("-inf")
        for x in roots:
            l, r = r, x
            i += interval(l, True, r, True)
        l, r = r, float("inf")
        i += interval(l, True, r, True)
        return i

    need_neg = False
    strong = True
    if sign == ">=":
        strong = False
    if sign == "<" or sign == "<=":
        need_neg = True
        if sign == "<=":
            strong = False

    neg = False
    if poly(minimum - Number(100)).is_negative:
        neg = True

    r = float("-inf")
    for x in roots:
        l, r = r, x
        if not neg ^ need_neg:
            i += interval(l, strong, r, strong)
        neg = not neg

    l, r = r, float("inf")
    if not neg ^ need_neg:
        i += interval(l, strong, r, strong)

    return i
Exemple #6
0
def get_linear(res, sign):
    a_, b_, p = res
    if len(a_) == 1 and len(b_) <= 1 and p > 0:
        a, mn_a = a_[0]
        if len(b_) == 1:
            b, mn_b = b_[0]
        else:
            b, mn_b = 0.0, []
        if len(mn_a) == 0 and len(mn_b) == 0:
            c = -b / a
            if a < 0:
                if sign == ">":
                    sign = "<"
                elif sign == ">=":
                    sign = "<="
            if p % 2 == 0:
                if c <= 0:
                    if sign == ">":
                        return intervals(interval(0, True, float("inf"), True))
                    elif sign == ">=":
                        return intervals(interval(0, False, float("inf"), True))
                    elif sign == "==":
                        if c == 0:
                            return intervals(interval(0, False, 0, False))
                        else:
                            intervals(interval(0, True, 0, True))
                    elif sign == "!=":
                        if c == 0:
                            return intervals(interval(0, True, float("inf"), True))
                        else:
                            return intervals(interval(0, False, float("inf"), True))
                    else:
                        if sign == "<=" and c == 0:
                            return intervals(interval(0, False, 0, False))
                        return intervals(interval(0, True, 0, True))
                d = math.pow(c, 1 / p)
                if sign == ">":
                    return intervals(interval(float("-inf"), True, -d, True)) + interval(d, True, float("inf"), True)
                elif sign == ">=":
                    return intervals(interval(float("-inf"), True, -d, False)) + interval(d, False, float("inf"), True)
                elif sign == "<":
                    return intervals(interval(-d, True, d, True))
                elif sign == "<=":
                    return intervals(interval(-d, False, d, False))
                elif sign == "==":
                    return intervals(interval(d, False, d, False)) + interval(-d, False, -d, False)
                elif sign == "!=":
                    return (
                        intervals(interval(float("-inf"), True, -d, True))
                        + interval(-d, True, d, True)
                        + interval(d, True, float("inf"), True)
                    )
                else:
                    raise Exception("unknown sign: " + sign)
            if c < 0:
                d = -math.pow(-c, 1 / p)
            else:
                d = math.pow(c, 1 / p)
            if sign == ">":
                return intervals(interval(d, True, float("inf"), True))
            elif sign == ">=":
                return intervals(interval(d, False, float("inf"), True))
            elif sign == "<":
                return intervals(interval(float("-inf"), True, d, True))
            elif sign == "<=":
                return intervals(interval(float("-inf"), True, d, False))
            elif sign == "==":
                return intervals(interval(d, False, d, False))
            elif sign == "!=":
                return intervals(interval(float("-inf"), True, d, True)) + interval(d, True, float("inf"), True)
            else:
                raise Exception("unknown sign: " + sign)
    return None
Exemple #7
0
                    one = one.get_mult_intervals(intervals(interval(float('-inf'), True, float('inf'), True)))
        ret = ret.get_add_intervals(one)
    return ret

def test_linear_assumption(sym_lims, a):
    a_interval = get_linear_data_intervals(sym_lims, a.exp)
    if a.sign == '>=': need = intervals(interval(0, False, float('inf'), True))
    elif a.sign == '>': need = intervals(interval(0, True, float('inf'), True))
    elif a.sign == '<': need = intervals(interval(float('-inf'), True, 0, True))
    elif a.sign == '<=': need = intervals(interval(float('-inf'), True, 0, False))
    elif a.sign == '==': need = intervals(interval(0, False, 0, False))
    elif a.sign == '!=': need = intervals(interval(float('-inf'), True, 0, True)) + interval(0, True, float('inf'), True)
    else: raise Exception('unknown sign: ', a.sign)
    result = a_interval * need
    return not result.is_zero()

def get_ration_data_intervals(sym_lims, exp):
    num, denom = exp.as_numer_denom()
    denom_intervals = get_linear_data_intervals(sym_lims, denom)
    num_intervals = get_linear_data_intervals(sym_lims, num)
    denom_intervals = denom_intervals.get_dived_intervals()
    return num_intervals.get_mult_intervals(denom_intervals)


if __name__ == "__main__":
    from sympy import Symbol
    from sympy.parsing.sympy_parser import parse_expr

    print(get_linear_data_intervals(dict(), parse_expr('4')))
    print(get_linear_data_intervals({Symbol('a'): intervals(interval(float(1), True, float('+inf'), True)) }, parse_expr('4*a')))
    print(get_linear_data_intervals({Symbol('a'): intervals(interval(float(1), False, float('+inf'), True)) }, parse_expr('4*a')))