コード例 #1
0
    def testNormAbsoluteValue(self):
        test_data = [
            ("abs x", ["x >= 0"], "x"),
            ("abs x", ["x Mem real_closed_interval 0 1"], "x"),
            ("abs x", ["x Mem real_closed_interval (-1) 0"], "-1 * x"),
            ("abs (sin x)", ["x Mem real_closed_interval 0 (pi / 2)"],
             "sin x"),
            ("abs (sin x)", ["x Mem real_closed_interval (-pi / 2) 0"],
             "-1 * sin x"),
            ("abs (log x)", ["x Mem real_open_interval (exp (-1)) 1"],
             "-1 * log x"),
        ]

        vars = {'x': 'real'}
        context.set_context('interval_arith', vars=vars)
        for t, conds, res in test_data:
            conds_pt = [
                ProofTerm.assume(parser.parse_term(cond)) for cond in conds
            ]
            cv = auto.auto_conv(conds_pt)
            test_conv(self,
                      'interval_arith',
                      cv,
                      vars=vars,
                      t=t,
                      t_res=res,
                      assms=conds)
コード例 #2
0
    def testNormPoly(self):
        test_data = [
            ("x + x", "2 * x"),
            ("x + 2 * x", "3 * x"),
            ("(1 / 2) * x + (1 / 3) * x", "5 / 6 * x"),
            ("x + y + x", "2 * x + y"),
            ("x + (-1) * x", "(0::real)"),
            ("x + (-1) * y + y", "x"),
            ("x + y + (-1) * x", "y"),
            ("(x + y) * (x + y)", "2 * (x * y) + x ^ (2::nat) + y ^ (2::nat)"),
            ("(x + y) * (x - y)", "x ^ (2::nat) + -1 *  y ^ (2::nat)"),
            ("x ^ (3::real)", "x ^ (3::nat)"),
            ("(2::real) ^ (3::nat)", "(8::real)"),
            ("(2::real) ^ (-(1::real))", "1 / 2"),
            ("(9::real) ^ (1 / 2)", "(3::real)"),
            ("(9::real) ^ (1 / 3)", "(3::real) ^ (2 / 3)"),
            ("(3::real) ^ (4 / 3)", "3 * (3::real) ^ (1 / 3)"),
            ("(2::real) ^ -(1 / 2)", "1 / 2 * 2 ^ (1 / 2)"),
            ("(1 / 4) ^ (1 / 2)", "1 / 2"),
            ("((3::real) ^ (1 / 2) * 3 ^ (1 / 2))", "(3::real)"),
            ("(2::real) * (-((1/2) * -(3 ^ (1/2))) + 1)", "2 + (3::real) ^ (1 / 2)"),
            ("(0::real) ^ (6::nat)", "(0::real)"),
        ]

        vars = {'x': 'real', 'y': 'real'}
        for expr, res in test_data:
            test_conv(self, 'transcendentals', auto.auto_conv(), vars=vars, t=expr, t_res=res)
コード例 #3
0
ファイル: real.py プロジェクト: bzhan/holpy
    def get_proof_term(self, t):
        if not is_real_ineq(t):
            return refl(t)

        pt_refl = refl(t).on_rhs(real_norm_comparison())
        left_expr = pt_refl.rhs.arg1
        summands = integer.strip_plus(left_expr)
        first = summands[0]

        if not left_expr.is_plus() or not first.is_constant():
            return pt_refl
        first_value = real_eval(first)
        if pt_refl.rhs.is_greater_eq():
            pt_th = ProofTerm.theorem("real_sub_both_sides_geq")
        elif pt_refl.rhs.is_greater():
            pt_th = ProofTerm.theorem("real_sub_both_sides_gt")
        elif pt_refl.rhs.is_less_eq():
            pt_th = ProofTerm.theorem("real_sub_both_sides_leq")
        elif pt_refl.rhs.is_less():
            pt_th = ProofTerm.theorem("real_sub_both_sides_le")
        else:
            raise NotImplementedError(str(t))

        inst = matcher.first_order_match(pt_th.lhs,
                                         pt_refl.rhs,
                                         inst=matcher.Inst(c=first))
        return pt_refl.transitive(pt_th.substitution(inst=inst)).on_rhs(
            auto.auto_conv())
コード例 #4
0
ファイル: real.py プロジェクト: bzhan/holpy
    def get_proof_term(self, t):
        pt = refl(t).on_rhs(binop_conv(to_exponent_form()))
        if pt.rhs.arg1.is_comb('exp', 1) and pt.rhs.arg.is_comb('exp', 1):
            # Both sides are exponentials
            return pt.on_rhs(rewr_conv('real_exp_add', sym=True),
                             arg_conv(auto.auto_conv(self.conds)))
        elif pt.rhs.arg1.is_nat_power() and pt.rhs.arg.is_nat_power():
            # Both sides are natural number powers, simply add
            return pt.on_rhs(rewr_conv('real_pow_add', sym=True),
                             arg_conv(nat.nat_conv()))
        else:
            # First check that x > 0 can be proved. If not, just return
            # without change.
            x = pt.rhs.arg1.arg1
            try:
                x_gt_0 = auto.solve(x > 0, self.conds)
            except TacticException:
                return refl(t)

            # Convert both sides to real powers
            if pt.rhs.arg1.is_nat_power():
                pt = pt.on_rhs(arg1_conv(rewr_conv('rpow_pow', sym=True)))
            if pt.rhs.arg.is_nat_power():
                pt = pt.on_rhs(arg_conv(rewr_conv('rpow_pow', sym=True)))
            pt = pt.on_rhs(rewr_conv('rpow_add', sym=True, conds=[x_gt_0]),
                           arg_conv(real_eval_conv()))

            # Simplify back to nat if possible
            if pt.rhs.arg.is_comb('of_nat', 1):
                pt = pt.on_rhs(rewr_conv('rpow_pow'),
                               arg_conv(rewr_conv('nat_of_nat_def', sym=True)))

            return pt.on_rhs(from_exponent_form())
コード例 #5
0
    def testNormRealDerivative(self):
        test_data = [
            # Differentiable everywhere
            ("real_derivative (%x. x) x", [], "(1::real)"),
            ("real_derivative (%x. 3) x", [], "(0::real)"),
            ("real_derivative (%x. 3 * x) x", [], "(3::real)"),
            ("real_derivative (%x. x ^ (2::nat)) x", [], "2 * x"),
            ("real_derivative (%x. x ^ (3::nat)) x", [], "3 * x ^ (2::nat)"),
            ("real_derivative (%x. (x + 1) ^ (3::nat)) x", [],
             "3 + 6 * x + 3 * x ^ (2::nat)"),
            ("real_derivative (%x. exp x) x", [], "exp x"),
            ("real_derivative (%x. exp (x ^ (2::nat))) x", [],
             "2 * (exp (x ^ (2::nat)) * x)"),
            # ("real_derivative (%x. exp (exp x)) x", [], "exp (x + exp x)"),
            ("real_derivative (%x. sin x) x", [], "cos x"),
            ("real_derivative (%x. cos x) x", [], "-1 * sin x"),
            ("real_derivative (%x. sin x * cos x) x", [],
             "(cos x) ^ (2::nat) + -1 * (sin x) ^ (2::nat)"),

            # Differentiable with conditions
            ("real_derivative (%x. 1 / x) x", ["x Mem real_open_interval 0 1"],
             "-1 * x ^ -(2::real)"),
            ("real_derivative (%x. 1 / (x ^ (2::nat) + 1)) x",
             ["x Mem real_open_interval (-1) 1"],
             "-2 * (x * (1 + 2 * x ^ (2::nat) + x ^ (4::nat)) ^ -(1::real))"),
            ("real_derivative (%x. log x) x", ["x Mem real_open_interval 0 1"],
             "x ^ -(1::real)"),
            ("real_derivative (%x. log (sin x)) x",
             ["x Mem real_open_interval 0 1"], "cos x * (sin x) ^ -(1::real)"),
            ("real_derivative (%x. sqrt x) x",
             ["x Mem real_open_interval 0 1"], "1 / 2 * x ^ -(1 / 2)"),
            ("real_derivative (%x. sqrt (x ^ (2::nat) + 1)) x",
             ["x Mem real_open_interval (-1) 1"
              ], "x * (1 + x ^ (2::nat)) ^ -(1 / 2)"),

            # Real power
            ("real_derivative (%x. x ^ (1 / 3)) x",
             ["x Mem real_open_interval 0 1"], "1 / 3 * x ^ -(2 / 3)"),
            ("real_derivative (%x. 2 ^ x) x",
             ["x Mem real_open_interval (-1) 1"], "log 2 * 2 ^ x"),
        ]

        vars = {'x': 'real'}
        context.set_context('interval_arith', vars=vars)
        for t, conds, res in test_data:
            conds_pt = [
                ProofTerm.assume(parser.parse_term(cond)) for cond in conds
            ]
            cv = auto.auto_conv(conds_pt)
            test_conv(self,
                      'interval_arith',
                      cv,
                      vars=vars,
                      t=t,
                      t_res=res,
                      assms=conds)
コード例 #6
0
ファイル: real.py プロジェクト: bzhan/holpy
    def get_proof_term(self, t):
        if not t.is_equals() and not t.is_compares() or t.arg1.get_type(
        ) != RealType:
            return refl(t)
        pt = refl(t)
        if t.is_equals():
            pt1 = pt.on_rhs(rewr_conv('real_sub_0', sym=True),
                            auto.auto_conv())
        elif t.is_greater_eq():
            pt1 = pt.on_rhs(rewr_conv('real_geq_sub'), auto.auto_conv())
        elif t.is_greater():
            pt1 = pt.on_rhs(rewr_conv('real_gt_sub'), auto.auto_conv())
        elif t.is_less_eq():
            pt1 = pt.on_rhs(rewr_conv('real_leq_sub'), auto.auto_conv())
        elif t.is_less():
            pt1 = pt.on_rhs(rewr_conv('real_le_sub'), auto.auto_conv())
        else:
            raise ConvException(str(t))

        summands = integer.strip_plus(pt1.rhs.arg1)
        first = summands[0]
        if first.is_var():
            return pt1
        elif first.is_number() and real_eval(first) > 0:
            return pt1
        elif first.is_times() and real_eval(first.arg1) > 0:
            return pt1

        lhs = pt1.rhs
        if lhs.is_equals():
            return pt1.on_rhs(rewr_conv('real_eq_neg2', sym=True),
                              auto.auto_conv())
        elif lhs.is_greater_eq():
            return pt1.on_rhs(rewr_conv('real_geq_leq'), auto.auto_conv())
        elif lhs.is_greater():
            return pt1.on_rhs(rewr_conv('real_gt_le'), auto.auto_conv())
        elif lhs.is_less_eq():
            return pt1.on_rhs(rewr_conv('real_leq_geq'), auto.auto_conv())
        elif lhs.is_less():
            return pt1.on_rhs(rewr_conv('real_le_gt'), auto.auto_conv())
コード例 #7
0
    def testNormTranscendental(self):
        test_data = [
            ("sin 0", "(0::real)"),
            ("sin (1 / 6 * pi)", "1 / 2"),
            ("cos 0", "(1::real)"),
            ("cos (1 / 6 * pi)", "1 / 2 * 3 ^ (1 / 2)"),
            ("exp 0", "(1::real)"),
            ("cos (pi / 4)", "1 / 2 * 2 ^ (1 / 2)"),
            ("sin (13 / 6 * pi)", "1 / 2"),
            ("sin (7 / 6 * pi)", "-(1 / 2)"),
            ("sin (5 / 6 * pi)", "1 / 2"),
            ("cos (7 / 6 * pi)", "-(1 / 2) * 3 ^ (1 / 2)"),
            ("cos (-pi / 2)", "(0::real)"),
            ("log 1", "(0::real)"),
            ("log (exp 2)", "(2::real)"),
            ("log 9", "2 * log 3"),
            ("log (9 / 10)", "-1 * log 2 + 2 * log 3 + -1 * log 5"),
            ("log (1 / 2)", "-1 * log(2)"),
            ("(0::real) ^ (6::nat)", "(0::real)"),
        ]

        for t, res in test_data:
            test_conv(self, 'interval_arith', auto.auto_conv(), t=t, t_res=res)
コード例 #8
0
    def testNormRealIntegral(self):
        test_data = [
            # Linearity and common integrals
            ("real_integral (real_closed_interval 0 1) (%x. 1)", "(1::real)"),
            ("real_integral (real_closed_interval 0 1) (%x. 2 * x)",
             "(1::real)"),
            ("real_integral (real_closed_interval 0 1) (%x. x + 1)", "3 / 2"),
            ("real_integral (real_closed_interval 0 1) (%x. x ^ (2::nat))",
             "1 / 3"),
            ("real_integral (real_closed_interval 0 1) (%x. exp x)",
             "-1 + exp 1"),
            ("real_integral (real_closed_interval 0 1) (%x. sin x)",
             "1 + -1 * cos 1"),
            ("real_integral (real_closed_interval 0 1) (%x. cos x)", "sin 1"),
            ("1/2 * (-2 * real_integral (real_closed_interval 0 (1/2)) (%x. exp x))",
             "1 + -1 * exp (1 / 2)"),

            # Normalize body
            ("real_integral (real_closed_interval 0 1) (%x. x ^ (2::nat) * x)",
             "1 / 4"),
            ("real_integral (real_closed_interval 0 1) (%x. x ^ (1 / 3) * (x ^ (1 / 2) + 1))",
             "57 / 44"),
            ("real_integral (real_closed_interval (exp (-1)) 1) (%x. abs (log x))",
             "-1 * real_integral (real_closed_interval (exp (-1)) 1) (%x. log x)"
             ),
            ("real_integral (real_closed_interval 0 (1 / 2 * pi)) (%x. 2 ^ (1 / 2) * cos x * (2 + -2 * sin x ^ (2::nat)) ^ (1 / 2))",
             "2 ^ (1 / 2) * real_integral (real_closed_interval 0 (1 / 2 * pi)) (%x. cos x * (2 + -2 * sin x ^ (2::nat)) ^ (1 / 2))"
             )
        ]

        for expr, res in test_data:
            test_conv(self,
                      'interval_arith',
                      auto.auto_conv(),
                      t=expr,
                      t_res=res)
コード例 #9
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
コード例 #10
0
ファイル: inequality.py プロジェクト: bzhan/holpy
def norm_mem_interval(pt):
    """Normalize membership in interval."""
    return pt.on_prop(arg_conv(binop_conv(auto.auto_conv())))