Exemplo n.º 1
0
def interval_union_subset(t):
    """Given t of the form I1 Un I2, return a theorem of the form
    I1 Un I2 SUB I.

    """
    assert t.is_comb('union', 2), "interval_union_subset"

    I1, I2 = t.args
    a, b = I1.args
    c, d = I2.args
    if is_closed_interval(I1) and is_closed_interval(I2):
        pt = apply_theorem('closed_interval_union',
                           inst=Inst(a=a, b=b, c=c, d=d))
        return pt.on_prop(
            arg_conv(
                then_conv(arg1_conv(const_min_conv()),
                          arg_conv(const_max_conv()))))
    elif is_open_interval(I1) and is_ropen_interval(I2):
        if eval_hol_expr(c) <= eval_hol_expr(a):
            pt = apply_theorem('open_ropen_interval_union1',
                               auto.auto_solve(real.less_eq(c, a)),
                               inst=Inst(b=b, d=d))
        else:
            pt = apply_theorem('open_ropen_interval_union2',
                               auto.auto_solve(real.less(a, c)),
                               inst=Inst(b=b, d=d))
        return pt.on_prop(arg_conv(arg_conv(const_max_conv())))
    else:
        raise NotImplementedError

    return pt
Exemplo n.º 2
0
 def get_proof_term(self, t):
     if eval_hol_expr(t.arg1) <= eval_hol_expr(t.arg):
         return apply_theorem('real_max_eq_right',
                              auto.auto_solve(real.less_eq(t.arg1, t.arg)))
     else:
         return apply_theorem('real_max_eq_left',
                              auto.auto_solve(real.greater(t.arg1, t.arg)))
Exemplo n.º 3
0
def combine_mem_bounds(pt1, pt2):
    """Given two inequalities of the form x </<= a and b </<= y, where
    a and b are constants, attempt to form the theorem x </<= y.

    """
    assert pt1.prop.is_less_eq() or pt1.prop.is_less(), "combine_mem_bounds"
    assert pt2.prop.is_less_eq() or pt2.prop.is_less(), "combine_mem_bounds"

    x, a = pt1.prop.args
    b, y = pt2.prop.args

    # First obtain the comparison between a and b
    if eval_hol_expr(a) < eval_hol_expr(b):
        pt_ab = ProofTerm('const_inequality', real.less(a, b))
    elif eval_hol_expr(a) <= eval_hol_expr(b):
        pt_ab = ProofTerm('const_inequality', real.less_eq(a, b))
    else:
        raise TacticException

    # Next, successively combine the inequalities
    pt = inequality_trans(inequality_trans(pt1, pt_ab), pt2)
    return pt
Exemplo n.º 4
0
def get_bounds_proof(t, var_range):
    """Given a term t and a mapping from variables to intervals,
    return a theorem for t belonging to an interval.

    t - Term, a HOL expression.
    var_range - dict(str, Thm): mapping from variables x to theorems of
        the form x Mem [a, b] or x Mem (a, b).

    Returns a theorem of the form t Mem [a, b] or t Mem (a, b).

    """
    if t.ty == Term.VAR:
        assert t.name in var_range, "get_bounds_proof: variable %s not found" % t.name
        return var_range[t.name]

    elif t.is_number() or t == real.pi:
        return apply_theorem('const_interval', inst=Inst(x=t))

    elif t.is_plus():
        pt1 = get_bounds_proof(t.arg1, var_range)
        pt2 = get_bounds_proof(t.arg, var_range)
        if is_mem_closed(pt1) and is_mem_closed(pt2):
            pt = apply_theorem('add_interval_closed', pt1, pt2)
        elif is_mem_open(pt1) and is_mem_open(pt2):
            pt = apply_theorem('add_interval_open', pt1, pt2)
        elif is_mem_open(pt1) and is_mem_closed(pt2):
            pt = apply_theorem('add_interval_open_closed', pt1, pt2)
        elif is_mem_closed(pt1) and is_mem_open(pt2):
            pt = apply_theorem('add_interval_closed_open', pt1, pt2)
        elif is_mem_closed(pt1) and is_mem_lopen(pt2):
            pt = apply_theorem('add_interval_closed_lopen', pt1, pt2)
        elif is_mem_closed(pt1) and is_mem_ropen(pt2):
            pt = apply_theorem('add_interval_closed_ropen', pt1, pt2)
        elif is_mem_ropen(pt1) and is_mem_closed(pt2):
            pt = apply_theorem('add_interval_closed_ropen', pt2, pt1)
            pt = pt.on_prop(arg1_conv(rewr_conv('real_add_comm')))
        else:
            raise NotImplementedError('get_bounds: %s, %s' % (pt1, pt2))
        return norm_mem_interval(pt)

    elif t.is_uminus():
        pt = get_bounds_proof(t.arg, var_range)
        if is_mem_closed(pt):
            pt = apply_theorem('neg_interval_closed', pt)
        elif is_mem_open(pt):
            pt = apply_theorem('neg_interval_open', pt)
        else:
            raise NotImplementedError
        return norm_mem_interval(pt)

    elif t.is_minus():
        rewr_t = t.arg1 + (-t.arg)
        pt = get_bounds_proof(rewr_t, var_range)
        return pt.on_prop(arg1_conv(rewr_conv('real_minus_def', sym=True)))

    elif t.is_real_inverse():
        pt = get_bounds_proof(t.arg, var_range)
        a, b = get_mem_bounds(pt)
        if eval_hol_expr(a) > 0 and is_mem_closed(pt):
            pt = apply_theorem('inverse_interval_pos_closed',
                               auto.auto_solve(real_pos(a)), pt)
        else:
            raise NotImplementedError
        return norm_mem_interval(pt)

    elif t.is_times():
        if t.arg1.has_var():
            pt1 = get_bounds_proof(t.arg1, var_range)
            pt2 = get_bounds_proof(t.arg, var_range)
            a, b = get_mem_bounds(pt1)
            c, d = get_mem_bounds(pt2)
            if eval_hol_expr(a) >= 0 and eval_hol_expr(c) >= 0 and is_mem_open(
                    pt1) and is_mem_open(pt2):
                pt = apply_theorem('mult_interval_pos_pos_open',
                                   auto.auto_solve(real_nonneg(a)),
                                   auto.auto_solve(real_nonneg(c)), pt1, pt2)
            elif eval_hol_expr(a) >= 0 and eval_hol_expr(
                    c) >= 0 and is_mem_closed(pt1) and is_mem_closed(pt2):
                pt = apply_theorem('mult_interval_pos_pos_closed',
                                   auto.auto_solve(real_nonneg(a)),
                                   auto.auto_solve(real_nonneg(c)), pt1, pt2)
            elif eval_hol_expr(a) >= 0 and eval_hol_expr(
                    c) >= 0 and is_mem_lopen(pt1) and is_mem_ropen(pt2):
                pt = apply_theorem('mult_interval_pos_pos_lopen_ropen',
                                   auto.auto_solve(real_nonneg(a)),
                                   auto.auto_solve(real_nonneg(c)), pt1, pt2)
            elif eval_hol_expr(b) <= 0 and eval_hol_expr(
                    c) >= 0 and is_mem_open(pt1) and is_mem_open(pt2):
                pt = apply_theorem('mult_interval_neg_pos_open',
                                   auto.auto_solve(real_nonpos(b)),
                                   auto.auto_solve(real_nonneg(c)), pt1, pt2)
            else:
                raise NotImplementedError('get_bounds: %s, %s' % (pt1, pt2))
        else:
            pt = get_bounds_proof(t.arg, var_range)
            a, b = get_mem_bounds(pt)
            c = t.arg1
            nc = eval_hol_expr(c)
            if nc >= 0 and is_mem_closed(pt):
                pt = apply_theorem('mult_interval_pos_closed',
                                   auto.auto_solve(real_nonneg(c)), pt)
            elif nc >= 0 and is_mem_open(pt):
                pt = apply_theorem('mult_interval_pos_open',
                                   auto.auto_solve(real_nonneg(c)), pt)
            elif nc >= 0 and is_mem_lopen(pt):
                pt = apply_theorem('mult_interval_pos_lopen',
                                   auto.auto_solve(real_nonneg(c)), pt)
            elif nc >= 0 and is_mem_ropen(pt):
                pt = apply_theorem('mult_interval_pos_ropen',
                                   auto.auto_solve(real_nonneg(c)), pt)
            elif nc < 0 and is_mem_closed(pt):
                pt = apply_theorem('mult_interval_neg_closed',
                                   auto.auto_solve(real_neg(c)), pt)
            elif nc < 0 and is_mem_open(pt):
                pt = apply_theorem('mult_interval_neg_open',
                                   auto.auto_solve(real_neg(c)), pt)
            elif nc < 0 and is_mem_lopen(pt):
                pt = apply_theorem('mult_interval_neg_lopen',
                                   auto.auto_solve(real_neg(c)), pt)
            elif nc < 0 and is_mem_ropen(pt):
                pt = apply_theorem('mult_interval_neg_ropen',
                                   auto.auto_solve(real_neg(c)), pt)
            else:
                raise NotImplementedError
        return norm_mem_interval(pt)

    elif t.is_divides():
        rewr_t = t.arg1 * (real.inverse(t.arg))
        pt = get_bounds_proof(rewr_t, var_range)
        return pt.on_prop(arg1_conv(rewr_conv('real_divide_def', sym=True)))

    elif t.is_nat_power():
        pt = get_bounds_proof(t.arg1, var_range)
        if not t.arg.is_number():
            raise NotImplementedError
        return get_nat_power_bounds(pt, t.arg)

    elif t.is_real_power():
        pt = get_bounds_proof(t.arg1, var_range)
        a, b = get_mem_bounds(pt)
        if not t.arg.is_number():
            raise NotImplementedError
        p = t.arg.dest_number()
        if p >= 0 and eval_hol_expr(a) >= 0:
            nonneg_p = auto.auto_solve(real_nonneg(t.arg))
            nonneg_a = auto.auto_solve(real_nonneg(a))
            if is_mem_closed(pt):
                pt = apply_theorem('real_power_interval_pos_closed', nonneg_p,
                                   nonneg_a, pt)
            elif is_mem_open(pt):
                pt = apply_theorem('real_power_interval_pos_open', nonneg_p,
                                   nonneg_a, pt)
            else:
                raise NotImplementedError
        elif p < 0:
            neg_p = auto.auto_solve(real_neg(t.arg))
            if is_mem_closed(pt) and eval_hol_expr(a) > 0:
                pos_a = auto.auto_solve(real_pos(a))
                pt = apply_theorem('real_power_interval_neg_closed', neg_p,
                                   pos_a, pt)
            elif is_mem_open(pt):
                nonneg_a = auto.auto_solve(real_nonneg(a))
                pt = apply_theorem('real_power_interval_neg_open', neg_p,
                                   nonneg_a, pt)
            elif is_mem_lopen(pt):
                nonneg_a = auto.auto_solve(real_nonneg(a))
                pt = apply_theorem('real_power_interval_neg_lopen', neg_p,
                                   nonneg_a, pt)
            else:
                print(pt)
                raise NotImplementedError
        else:
            raise NotImplementedError
        return norm_mem_interval(pt)

    elif t.head == real.log:
        pt = get_bounds_proof(t.arg, var_range)
        a, b = get_mem_bounds(pt)
        if eval_hol_expr(a) > 0 and is_mem_closed(pt):
            pt = apply_theorem('log_interval_closed',
                               auto.auto_solve(real_pos(a)), pt)
        elif eval_hol_expr(a) >= 0 and is_mem_open(pt):
            pt = apply_theorem('log_interval_open',
                               auto.auto_solve(real_nonneg(a)), pt)
        else:
            raise NotImplementedError
        return norm_mem_interval(pt)

    elif t.head == real.exp:
        pt = get_bounds_proof(t.arg, var_range)
        if is_mem_closed(pt):
            pt = apply_theorem('exp_interval_closed', pt)
        elif is_mem_open(pt):
            pt = apply_theorem('exp_interval_open', pt)
        else:
            raise NotImplementedError
        return norm_mem_interval(pt)

    elif t.head == real.sin:
        pt = get_bounds_proof(t.arg, var_range)
        a, b = get_mem_bounds(pt)
        if eval_hol_expr(a) >= -math.pi / 2 and eval_hol_expr(
                b) <= math.pi / 2:
            if is_mem_closed(pt):
                pt = apply_theorem(
                    'sin_interval_main_closed',
                    auto.auto_solve(real.greater_eq(a, -real.pi / 2)),
                    auto.auto_solve(real.less_eq(b, real.pi / 2)), pt)
            elif is_mem_open(pt):
                pt = apply_theorem(
                    'sin_interval_main_open',
                    auto.auto_solve(real.greater_eq(a, -real.pi / 2)),
                    auto.auto_solve(real.less_eq(b, real.pi / 2)), pt)
            else:
                raise NotImplementedError
        elif eval_hol_expr(a) >= 0 and eval_hol_expr(b) <= math.pi:
            if is_mem_closed(pt):
                pt = apply_theorem('sin_interval_pos_closed',
                                   auto.auto_solve(real_nonneg(a)),
                                   auto.solve(real.less_eq(b, real.pi)), pt)
            elif is_mem_open(pt):
                pt = apply_theorem('sin_interval_pos_open',
                                   auto.auto_solve(real_nonneg(a)),
                                   auto.solve(real.less_eq(b, real.pi)), pt)
            else:
                raise NotImplementedError
        else:
            raise NotImplementedError
        return norm_mem_interval(pt)

    elif t.head == real.cos:
        pt = get_bounds_proof(t.arg, var_range)
        a, b = get_mem_bounds(pt)
        if eval_hol_expr(a) >= 0 and eval_hol_expr(b) <= math.pi:
            if is_mem_closed(pt):
                pt = apply_theorem('cos_interval_main_closed',
                                   auto.auto_solve(real_nonneg(a)),
                                   auto.auto_solve(real.less_eq(b, real.pi)),
                                   pt)
            elif is_mem_open(pt):
                pt = apply_theorem('cos_interval_main_open',
                                   auto.auto_solve(real_nonneg(a)),
                                   auto.auto_solve(real.less_eq(b, real.pi)),
                                   pt)
            else:
                raise NotImplementedError
        elif eval_hol_expr(a) >= -math.pi / 2 and eval_hol_expr(
                b) <= math.pi / 2:
            if is_mem_closed(pt):
                pt = apply_theorem(
                    'cos_interval_pos_closed',
                    auto.auto_solve(real.greater_eq(a, -real.pi / 2)),
                    auto.auto_solve(real.less_eq(b, real.pi / 2)), pt)
            elif is_mem_open(pt):
                pt = apply_theorem(
                    'cos_interval_pos_open',
                    auto.auto_solve(real.greater_eq(a, -real.pi / 2)),
                    auto.auto_solve(real.less_eq(b, real.pi / 2)), pt)
            else:
                raise NotImplementedError
        else:
            raise NotImplementedError
        return norm_mem_interval(pt)

    elif t.head == real.atn:
        pt = get_bounds_proof(t.arg, var_range)
        if is_mem_closed(pt):
            pt = apply_theorem('atn_interval_closed', pt)
        elif is_mem_open(pt):
            pt = apply_theorem('atn_interval_open', pt)
        else:
            raise NotImplementedError
        return norm_mem_interval(pt)

    else:
        print("Cannot deal with", t)
        raise NotImplementedError
Exemplo n.º 5
0
def get_nat_power_bounds(pt, n):
    """Given theorem of the form t Mem I, obtain a theorem of
    the form t ^ n Mem J.

    """
    a, b = get_mem_bounds(pt)
    if not n.is_number():
        raise NotImplementedError
    if eval_hol_expr(a) >= 0 and is_mem_closed(pt):
        pt = apply_theorem('nat_power_interval_pos_closed',
                           auto.auto_solve(real_nonneg(a)),
                           pt,
                           inst=Inst(n=n))
    elif eval_hol_expr(a) >= 0 and is_mem_open(pt):
        pt = apply_theorem('nat_power_interval_pos_open',
                           auto.auto_solve(real_nonneg(a)),
                           pt,
                           inst=Inst(n=n))
    elif eval_hol_expr(a) >= 0 and is_mem_lopen(pt):
        pt = apply_theorem('nat_power_interval_pos_lopen',
                           auto.auto_solve(real_nonneg(a)),
                           pt,
                           inst=Inst(n=n))
    elif eval_hol_expr(a) >= 0 and is_mem_ropen(pt):
        pt = apply_theorem('nat_power_interval_pos_ropen',
                           auto.auto_solve(real_nonneg(a)),
                           pt,
                           inst=Inst(n=n))
    elif eval_hol_expr(b) <= 0 and is_mem_closed(pt):
        int_n = n.dest_number()
        if int_n % 2 == 0:
            even_pt = nat_as_even(int_n)
            pt = apply_theorem('nat_power_interval_neg_even_closed',
                               auto.auto_solve(real_nonpos(b)), even_pt, pt)
        else:
            odd_pt = nat_as_odd(int_n)
            pt = apply_theorem('nat_power_interval_neg_odd_closed',
                               auto.auto_solve(real_nonpos(b)), odd_pt, pt)
    elif eval_hol_expr(b) <= 0 and is_mem_open(pt):
        int_n = n.dest_number()
        if int_n % 2 == 0:
            even_pt = nat_as_even(int_n)
            pt = apply_theorem('nat_power_interval_neg_even_open',
                               auto.auto_solve(real_nonpos(b)), even_pt, pt)
        else:
            odd_pt = nat_as_odd(int_n)
            pt = apply_theorem('nat_power_interval_neg_odd_open',
                               auto.auto_solve(real_nonpos(b)), odd_pt, pt)
    elif is_mem_closed(pt):
        # Closed interval containing 0
        t = pt.prop.arg1
        assm1 = hol_set.mk_mem(t, real.closed_interval(a, Real(0)))
        assm2 = hol_set.mk_mem(t, real.closed_interval(Real(0), b))
        pt1 = get_nat_power_bounds(ProofTerm.assume(assm1),
                                   n).implies_intr(assm1)
        pt2 = get_nat_power_bounds(ProofTerm.assume(assm2),
                                   n).implies_intr(assm2)
        x = Var('x', RealType)
        pt = apply_theorem('split_interval_closed',
                           auto.auto_solve(real.less_eq(a, Real(0))),
                           auto.auto_solve(real.less_eq(Real(0), b)),
                           pt1,
                           pt2,
                           pt,
                           inst=Inst(x=t, f=Lambda(x, x**n)))
        subset_pt = interval_union_subset(pt.prop.arg)
        pt = apply_theorem('subsetE', subset_pt, pt)
    elif is_mem_open(pt):
        # Open interval containing 0
        t = pt.prop.arg1
        assm1 = hol_set.mk_mem(t, real.open_interval(a, Real(0)))
        assm2 = hol_set.mk_mem(t, real.ropen_interval(Real(0), b))
        pt1 = get_nat_power_bounds(ProofTerm.assume(assm1),
                                   n).implies_intr(assm1)
        pt2 = get_nat_power_bounds(ProofTerm.assume(assm2),
                                   n).implies_intr(assm2)
        x = Var('x', RealType)
        pt = apply_theorem('split_interval_open',
                           auto.auto_solve(real.less_eq(a, Real(0))),
                           auto.auto_solve(real.less_eq(Real(0), b)),
                           pt1,
                           pt2,
                           pt,
                           inst=Inst(x=t, f=Lambda(x, x**n)))
        subset_pt = interval_union_subset(pt.prop.arg)
        pt = apply_theorem('subsetE', subset_pt, pt)
    else:
        raise NotImplementedError
    return norm_mem_interval(pt)
Exemplo n.º 6
0
def real_nonpos(a):
    return real.less_eq(a, Real(0))