示例#1
0
    def testPrintReal(self):
        basic.load_theory('real')

        m = Var("m", RealType)
        test_data = [
            (real.zero, "(0::real)"),
            (real.one, "(1::real)"),
            (Real(2), "(2::real)"),
            (Real(3), "(3::real)"),
            (real.plus(m, real.one), "m + 1"),
            (real.plus(real.one, Real(2)), "(1::real) + 2"),
        ]

        for t, s in test_data:
            self.assertEqual(printer.print_term(t), s)
示例#2
0
文件: real.py 项目: bzhan/holpy
 def get_proof_term(self, t):
     if t.get_type() != RealType:
         return refl(t)
     simp_t = Real(real_eval(t))
     if simp_t == t:
         return refl(t)
     return ProofTerm('real_eval', Eq(t, simp_t))
示例#3
0
文件: real.py 项目: bzhan/holpy
    def handle_leq_stage2(self, pt_upper_bound, pts, delta):
        # get ⊢ x_i ≤ -δ, for i = 1...n
        leq_pt = []
        pt_b = pt_upper_bound

        for i in range(len(pts)):
            if i != len(pts) - 1:
                pt = logic.apply_theorem("both_leq_max", pt_b)
                pt_1, pt_2 = logic.apply_theorem("conjD1",
                                                 pt), logic.apply_theorem(
                                                     "conjD2", pt)
            else:
                pt_2 = pt_b

            ineq = pt_2.prop

            if ineq.arg1.is_minus() and ineq.arg1.arg.is_number():
                num = ineq.arg1.arg
                expr = less_eq(ineq.arg1.arg1, num - delta)

            else:
                expr = less_eq(ineq.arg1, Real(0) - delta)

            pt_eq_comp = ProofTerm("real_eq_comparison", Eq(ineq, expr))
            leq_pt.insert(0, pt_2.on_prop(replace_conv(pt_eq_comp)))
            if i != len(pts) - 1:
                pt_b = pt_1

        return leq_pt
示例#4
0
文件: real.py 项目: bzhan/holpy
    def handle_geq_stage2(self, pt_lower_bound, pts, delta):
        # get ⊢ x_i ≥ δ, i = 1...n
        geq_pt = []
        pt_a = pt_lower_bound
        d = set()

        for i in range(len(pts)):
            if i != len(pts) - 1:
                pt = logic.apply_theorem("both_geq_min", pt_a)
                pt_1, pt_2 = logic.apply_theorem("conjD1",
                                                 pt), logic.apply_theorem(
                                                     "conjD2", pt)
            else:
                pt_2 = pt_a

            ineq = pt_2.prop

            if ineq.arg1.is_minus() and ineq.arg1.arg.is_number():
                # move all constant term from left to right in pt_2's prop
                num = ineq.arg1.arg
                expr = greater_eq(ineq.arg1.arg1, num + delta)

            else:
                expr = greater_eq(ineq.arg1, Real(0) + delta)

            pt_eq_comp = ProofTerm("real_eq_comparison", Eq(ineq, expr))
            geq_pt.insert(0, pt_2.on_prop(replace_conv(pt_eq_comp)))

            if i != len(pts) - 1:
                pt_a = pt_1

        return geq_pt
示例#5
0
文件: real.py 项目: bzhan/holpy
    def get_proof_term(self, t):
        a, p = t.args

        # Exponent is an integer: apply rpow_pow
        if p.is_number() and p.is_comb('of_nat', 1) and p.arg.is_binary():
            return refl(t).on_rhs(
                arg_conv(rewr_conv('real_of_nat_id', sym=True)),
                rewr_conv('rpow_pow'))

        if not (a.is_number() and p.is_number()):
            raise ConvException

        a, p = a.dest_number(), p.dest_number()
        if a <= 0:
            raise ConvException

        # Case 1: base is a composite number
        factors = factorint(a)
        keys = list(factors.keys())
        if len(keys) > 1 or (len(keys) == 1 and keys[0] != a):
            b1 = list(factors.keys())[0]
            b2 = a // b1
            eq_th = refl(Real(b1) * b2).on_rhs(real_eval_conv())
            pt = refl(t).on_rhs(arg1_conv(rewr_conv(eq_th, sym=True)))
            pt = pt.on_rhs(rewr_conv('rpow_mul'))
            return pt

        # Case 2: exponent is not between 0 and 1
        if isinstance(p, Fraction) and p.numerator // p.denominator != 0:
            div, mod = divmod(p.numerator, p.denominator)
            eq_th = refl(Real(div) + Real(mod) / p.denominator).on_rhs(
                real_eval_conv())
            pt = refl(t).on_rhs(arg_conv(rewr_conv(eq_th, sym=True)))
            a_gt_0 = auto.auto_solve(Real(a) > 0)
            pt = pt.on_rhs(rewr_conv('rpow_add', conds=[a_gt_0]))
            return pt

        return refl(t)
示例#6
0
文件: real.py 项目: bzhan/holpy
    def handle_geq_stage1(self, pts):
        if not pts:
            return None, None, None

        # ⊢ min(min(...(min(x_1, x_2), x_3)...), x_n-1), x_n) > 0
        min_pos_pt = functools.reduce(
            lambda pt1, pt2: logic.apply_theorem("min_greater_0", pt1, pt2),
            pts[1:], pts[0])

        # ⊢ 0 < 2
        two_pos_pt = ProofTerm("real_compare", Real(0) < Real(2))

        # ⊢ min(...) / 2 > 0
        min_divides_two_pos = logic.apply_theorem(
            "real_lt_div", min_pos_pt.on_prop(rewr_conv("real_ge_to_le")),
            two_pos_pt).on_prop(rewr_conv("real_ge_to_le", sym=True))

        # ⊢ 2 ≥ 1
        two_larger_one = ProofTerm("real_compare", Real(2) >= Real(1))

        # ⊢ min(...) ≥ min(...) / 2
        larger_half_pt = logic.apply_theorem("real_divides_larger_1",
                                             two_larger_one, min_pos_pt)

        # ⊢ min(...) / 2 = δ_1
        delta_1 = Var("δ_1", RealType)
        pt_delta1_eq = ProofTerm.assume(Eq(larger_half_pt.prop.arg, delta_1))

        # ⊢ min(...) ≥ δ_1
        larger_half_pt_delta = larger_half_pt.on_prop(
            top_conv(replace_conv(pt_delta1_eq)))

        # ⊢ δ_1 > 0
        delta_1_pos = min_divides_two_pos.on_prop(
            arg1_conv(replace_conv(pt_delta1_eq)))

        return larger_half_pt_delta, delta_1_pos, pt_delta1_eq
示例#7
0
文件: real.py 项目: bzhan/holpy
    def handle_leq_stage1(self, pts):
        if not pts:
            return None, None, None
        # ⊢ max(max(...(max(x_1, x_2), x_3)...), x_n-1), x_n) < 0
        max_pos_pt = functools.reduce(
            lambda pt1, pt2: logic.apply_theorem("max_less_0", pt1, pt2),
            pts[1:], pts[0])

        # ⊢ 0 < 2
        two_pos_pt = ProofTerm("real_compare", Real(2) > Real(0))

        # ⊢ max(...) / 2 < 0
        max_divides_two_pos = logic.apply_theorem("real_neg_div_pos",
                                                  max_pos_pt, two_pos_pt)

        # ⊢ 2 ≥ 1
        two_larger_one = ProofTerm("real_compare", Real(2) >= Real(1))

        # ⊢ max(...) ≤ max(...) / 2
        less_half_pt = logic.apply_theorem("real_neg_divides_larger_1",
                                           two_larger_one, max_pos_pt)

        # ⊢ max(...) / 2 = -δ
        delta_2 = Var("δ_2", RealType)
        pt_delta_eq = ProofTerm.assume(Eq(less_half_pt.prop.arg, -delta_2))

        # ⊢ δ > 0
        delta_pos_pt = max_divides_two_pos.on_prop(
            rewr_conv("real_le_gt"), top_conv(replace_conv(pt_delta_eq)),
            auto.auto_conv())

        # max(...) ≤ -δ
        less_half_pt_delta = less_half_pt.on_prop(
            arg_conv(replace_conv(pt_delta_eq)))

        return less_half_pt_delta, delta_pos_pt, pt_delta_eq
示例#8
0
文件: real.py 项目: bzhan/holpy
def from_mono(m):
    """Convert a monomial to a term."""
    assert isinstance(m, poly.Monomial), "from_mono: input is not a monomial"
    factors = []
    for base, power in m.factors:
        assert isinstance(base, Term), "from_mono: base is not a Term"
        baseT = base.get_type()
        if baseT != RealType:
            base = Const('of_nat', TFun(baseT, RealType))(base)
        if power == 1:
            factors.append(base)
        else:
            factors.append(nat_power(base, Nat(power)))
    if m.coeff != 1:
        factors = [Real(m.coeff)] + factors
    return Prod(RealType, factors)
示例#9
0
    def testReal(self):
        basic.load_theory('real')

        x = Var('x', RealType)
        y = Var('y', RealType)
        n = Var('n', NatType)
        test_data = [
            (x + y, "x + y"),
            (x * y, "x * y"),
            (x - y, "x - y"),
            (-x, "-x"),
            (x - (-y), "x - -y"),
            (-(-x), "--x"),
            (-(x - y), "-(x - y)"),
            (-(x**n), "-(x ^ n)"),
            ((-x)**n, "-x ^ n"),
            (x + real.of_nat(Nat(2)), "x + of_nat 2"),
            (x + Real(1) / 0, "x + 1 / 0"),
        ]

        for t, s in test_data:
            self.assertEqual(printer.print_term(t), s)
示例#10
0
文件: inequality.py 项目: bzhan/holpy
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)
示例#11
0
文件: inequality.py 项目: bzhan/holpy
def real_nonpos(a):
    return real.less_eq(a, Real(0))
示例#12
0
文件: inequality.py 项目: bzhan/holpy
def real_neg(a):
    return real.less(a, Real(0))
示例#13
0
文件: inequality.py 项目: bzhan/holpy
def real_nonneg(a):
    return real.greater_eq(a, Real(0))
示例#14
0
文件: inequality.py 项目: bzhan/holpy
def real_pos(a):
    return real.greater(a, Real(0))
示例#15
0
文件: real.py 项目: bzhan/holpy
    def get_proof_term(self, args, prevs=None):
        """
        Let x_i denotes greater comparison, x__i denotes less comparison,
        for the greater comparison, find the smallest number x_min = min(x_1, ..., x_n), since x_min is positive, 
        x_min/2 > 0 ==> x_min >= x_min / 2 ==> x_1, ..., x_n >= x_min / 2 ==> ∃δ. δ > 0 ∧ x_1 >= δ ∧ ... ∧ x_n >= δ.
        for the less comparison, find the largest number x_max = max(x__1, ..., x__n), since x_max is negative, x_max < 
        x_max/2 ==> x__1, ..., x__n <= x_max/2;
        let δ = min(x_min/2, -x_max/2), then all x_i >= δ as well as all x__i <= -δ.
        """
        def need_convert(tm):
            return False if real_eval(tm.arg) != 0 else True

        original_ineq_pts = [ProofTerm.assume(ineq) for ineq in args]

        # record the ineq which rhs is not 0
        need_convert_pt = {arg for arg in args if need_convert(arg)}

        # record the args order
        order_args = {args[i].arg1: i for i in range(len(args))}

        # convert all ineqs to x_i > 0 or x_i < 0
        normal_ineq_pts = [
            pt.on_prop(norm_real_ineq_conv()) if pt.prop.arg != Real(0) else pt
            for pt in original_ineq_pts
        ]

        # dividing less comparison and greater comparison
        greater_ineq_pts = [
            pt for pt in normal_ineq_pts if pt.prop.is_greater()
        ]
        less_ineq_pts = [pt for pt in normal_ineq_pts if pt.prop.is_less()]

        # stage 1: get the max(min) pos bound
        # ⊢ min(...) ≥ δ_1, δ_1 > 0
        # ⊢ max(...) ≤ δ_2, δ_2 < 0
        pt_lower_bound, lower_bound_pos_pt, pt_assert_delta1 = self.handle_geq_stage1(
            greater_ineq_pts)
        pt_upper_bound, upper_bound_neg_pt, pt_assert_delta2 = self.handle_leq_stage1(
            less_ineq_pts)

        delta_1 = Var("δ_1", RealType)
        delta_2 = Var("δ_2", RealType)

        # generate the relaxed inequations
        if pt_lower_bound is None:  # all comparisons are ≤
            pts = self.handle_leq_stage2(pt_upper_bound, less_ineq_pts,
                                         delta_2)
            bound_pt = upper_bound_neg_pt
            delta = delta_2
            pt_asserts = [pt_assert_delta2]
        elif pt_upper_bound is None:  # all comparisons are ≥
            pts = self.handle_geq_stage2(pt_lower_bound, greater_ineq_pts,
                                         delta_1)
            bound_pt = lower_bound_pos_pt
            delta = delta_1
            pt_asserts = [pt_assert_delta1]
        else:  # have both ≥ and ≤
            # ⊢ δ_1 ≥ min(δ_1, δ_2)
            pt_min_lower_bound = logic.apply_theorem("real_greater_min",
                                                     inst=matcher.Inst(
                                                         x=delta_1, y=delta_2))
            # ⊢ -δ_2 ≤ max(-δ_2, -δ_1)
            pt_max_upper_bound = logic.apply_theorem("real_less_max",
                                                     inst=matcher.Inst(
                                                         x=-delta_2,
                                                         y=-delta_1))
            # ⊢ max(-δ_2, -δ_1) = -min(δ_1, δ_2)
            pt_max_min = logic.apply_theorem("max_min",
                                             inst=matcher.Inst(x=delta_1,
                                                               y=delta_2))
            # ⊢ min(...) ≥ min(δ_1, δ_2)
            pt_new_lower_bound = logic.apply_theorem("real_geq_trans",
                                                     pt_lower_bound,
                                                     pt_min_lower_bound)
            # ⊢ -δ_2 ≤ -min(δ_1, δ_2)
            pt_max_upper_bound_1 = pt_max_upper_bound.on_prop(
                arg_conv(replace_conv(pt_max_min)))
            # ⊢ max(...) ≤ -min(δ_1, δ_2)
            pt_new_upper_bound = logic.apply_theorem("real_le_trans",
                                                     pt_upper_bound,
                                                     pt_max_upper_bound_1)
            # ⊢ min(δ_1, δ_2) > 0
            pt_new_lower_bound_pos = logic.apply_theorem(
                "min_pos", lower_bound_pos_pt, upper_bound_neg_pt)
            # ⊢ min(δ_1, δ_2) = δ
            delta = Var("δ", RealType)
            pt_delta_eq = ProofTerm.assume(
                Eq(pt_min_lower_bound.prop.arg, delta))
            pt_asserts = [pt_delta_eq, pt_assert_delta1, pt_assert_delta2]
            # ⊢ min(...) ≥ δ
            pt_new_lower_bound_delta = pt_new_lower_bound.on_prop(
                arg_conv(replace_conv(pt_delta_eq)))
            # ⊢ max(...) ≤ -δ
            pt_new_upper_bound_delta = pt_new_upper_bound.on_prop(
                top_conv(replace_conv(pt_delta_eq)))
            # use new bound
            pts_leq = self.handle_leq_stage2(pt_new_upper_bound_delta,
                                             less_ineq_pts, delta)
            pts_geq = self.handle_geq_stage2(pt_new_lower_bound_delta,
                                             greater_ineq_pts, delta)
            pts = pts_leq + pts_geq
            bound_pt = pt_new_lower_bound_pos.on_prop(
                arg1_conv(replace_conv(pt_delta_eq)))

        # sort_pts = sorted(pts, key=lambda pt: order_args[pt.prop.arg1])

        pt_conj = functools.reduce(
            lambda x, y: logic.apply_theorem("conjI", y, x),
            reversed([bound_pt] + pts))

        # get ⊢∃δ. δ > 0 ∧ x_1 >= δ ∧ ... ∧ x_n >= δ
        th = ProofTerm.theorem("exI")
        inst = matcher.first_order_match(th.prop.arg,
                                         Exists(delta, pt_conj.prop))
        pt_conj_exists = logic.apply_theorem("exI", pt_conj, inst=inst)
        pt_final = pt_conj_exists
        for pt_subst in pt_asserts:
            lhs, rhs = pt_subst.prop.args
            if not rhs.is_uminus():
                pt_final = pt_final.implies_intr(pt_subst.prop).forall_intr(rhs).\
                            forall_elim(lhs).implies_elim(ProofTerm.reflexive(lhs))
            else:
                pt_final = pt_final.implies_intr(pt_subst.prop).forall_intr(rhs.arg).\
                    forall_elim(-lhs).on_prop(top_conv(rewr_conv("real_neg_neg"))).implies_elim(ProofTerm.reflexive(lhs))
        return pt_final