예제 #1
0
파일: real.py 프로젝트: bzhan/holpy
 def get_proof_term(self, t):
     pt = refl(t)
     is_l_atom = (dest_monomial(t.arg1) == t.arg1)
     is_r_atom = (dest_monomial(t.arg) == t.arg)
     if is_l_atom and is_r_atom:
         return pt.on_rhs(norm_mult_monomial(self.conds))
     elif is_l_atom and not is_r_atom:
         if t.arg.is_number():
             return pt.on_rhs(rewr_conv('real_mult_comm'),
                              try_conv(rewr_conv('real_mul_rid')),
                              try_conv(rewr_conv('real_mul_lzero')))
         else:
             return pt.on_rhs(arg_conv(rewr_conv('real_mult_comm')),
                              rewr_conv('real_mult_assoc'),
                              rewr_conv('real_mult_comm'),
                              arg_conv(norm_mult_monomial(self.conds)))
     elif not is_l_atom and is_r_atom:
         if t.arg1.is_number():
             return pt.on_rhs(try_conv(rewr_conv('real_mul_rid')),
                              try_conv(rewr_conv('real_mul_lzero')))
         else:
             return pt.on_rhs(rewr_conv('real_mult_assoc', sym=True),
                              arg_conv(norm_mult_monomial(self.conds)))
     else:
         return pt.on_rhs(
             binop_conv(to_coeff_form()),  # (c_1 * m_1) * (c_2 * m_2)
             rewr_conv('real_mult_assoc'),  # (c_1 * m_1 * c_2) * m_2
             arg1_conv(swap_mult_r()),  # (c_1 * c_2 * m_1) * m_2
             arg1_conv(arg1_conv(real_eval_conv())),  # (c_1c_2 * m_1) * m_2
             rewr_conv('real_mult_assoc', sym=True),  # c_1c_2 * (m_1 * m_2)
             arg_conv(norm_mult_monomial(self.conds)),
             from_coeff_form())
예제 #2
0
 def get_proof_term(self, t):
     pt = refl(t)
     if t.is_plus():
         if t.arg1.is_zero():
             return pt.on_rhs(rewr_conv('int_add_0_left'))
         elif t.arg.is_zero():
             return pt.on_rhs(rewr_conv('int_add_0_right'))
         elif t.arg.is_plus():  # t is of form a + (b + c)
             return pt.on_rhs(
                 rewr_conv('int_add_assoc'),  # (a + b) + c
                 arg1_conv(self),  # merge terms in b into a
                 norm_add_monomial())  # merge c into a + b
         elif t.arg.is_minus():  # t is of form a + (b - c)
             return pt.on_rhs(
                 arg_conv(norm_add_monomial()),  # a + b + (-1) * c
                 arg1_conv(self),
                 norm_add_polynomial())
         else:
             return pt.on_rhs(norm_add_monomial())
     elif t.is_minus():
         if t.arg.is_plus():  # t is of form a - (b + c)
             return pt.on_rhs(
                 rewr_conv('int_sub_add_distr'),  # a - b - c
                 arg1_conv(self),  # merge terms in b into a
                 norm_add_monomial()  # merge c into a - b
             )
         elif t.arg.is_minus():  # t is of form a - (b - c)
             return pt.on_rhs(
                 rewr_conv('int_sub_sub_distr'),  # a - b + c
                 arg1_conv(self),  # merge terms in b into c
                 norm_add_monomial()  # merge c into a - b
             )
         else:
             return pt.on_rhs(norm_add_monomial(), )
예제 #3
0
 def get_proof_term(self, t):
     if not t.is_compares() or not t.arg1.get_type() == IntType:
         raise ConvException(str(t))
     pt = refl(t)
     # first move all terms in rhs to lhs and normalize lhs
     if t.is_greater():
         pt1 = pt.on_rhs(rewr_conv('int_gt_to_geq'), rewr_conv('int_geq'),
                         arg1_conv(omega_simp_full_conv()))
     elif t.is_greater_eq():
         pt1 = pt.on_rhs(rewr_conv('int_geq'),
                         arg1_conv(omega_simp_full_conv()))
     elif t.is_less():
         pt1 = pt.on_rhs(rewr_conv('int_less_to_leq'), rewr_conv('int_leq'),
                         arg1_conv(omega_simp_full_conv()))
     elif t.is_less_eq():
         pt1 = pt.on_rhs(rewr_conv('int_leq'),
                         arg1_conv(omega_simp_full_conv()))
     else:
         raise NotImplementedError
     # move all constant term on lhs to rhs
     lhs = pt1.rhs.arg1
     if lhs.is_number() or lhs.is_times() or lhs.arg.is_times():
         return pt1
     elif pt1.rhs.is_greater_eq() and lhs.arg.is_number():
         return pt1.on_rhs(rewr_conv('int_geq_shift'),
                           arg_conv(int_eval_conv()))
     elif pt1.rhs.is_less_eq() and lhs.arg.is_number():
         return pt1.on_rhs(rewr_conv('int_leq_shift'),
                           arg_conv(int_eval_conv()))
     else:
         raise NotImplementedError
예제 #4
0
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg1.is_times():  # t is of form (a * b) * c
         cp = compare_atom(t.arg1.arg,
                           t.arg)  # compare b with c by their base
         if cp > 0:  # if b > c, need to swap b with c
             return pt.on_rhs(
                 swap_mult_r(),  # (a * c) * b
                 arg1_conv(self))  # possibly move c further inside a
         elif cp == 0:  # if b and c have the same base, combine the exponents
             return pt.on_rhs(
                 rewr_conv('int_mult_assoc', sym=True),  # a * (b^e1 * b^e2)
                 arg_conv(rewr_conv('int_power_add',
                                    sym=True)),  # a * (b^(e1 + e2))
                 arg_conv(arg_conv(int_eval_conv())))  # evaluate e1 + e2
         else:  # if b < c, atoms already ordered since we assume b is ordered.
             return pt
     else:  # t is of the form a * b
         cp = compare_atom(t.arg1, t.arg)  # compare a with b by their base
         if cp > 0:  # if a > b, need to swap a and b
             return pt.on_rhs(rewr_conv('int_mult_comm'))
         elif cp == 0:  # if a and b have the same base, combine the exponents
             return pt.on_rhs(rewr_conv('int_power_add', sym=True),
                              arg_conv(int_eval_conv()))
         else:
             return pt
예제 #5
0
파일: real.py 프로젝트: bzhan/holpy
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg.is_times():
         return pt.on_rhs(rewr_conv('real_mult_assoc'), arg1_conv(self),
                          norm_mult_atom(self.conds))
     else:
         return pt.on_rhs(norm_mult_atom(self.conds))
예제 #6
0
파일: real.py 프로젝트: bzhan/holpy
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg1.is_one():
         return pt.on_rhs(rewr_conv('real_mul_lid'))
     elif t.arg.is_one():
         return pt.on_rhs(rewr_conv('real_mul_rid'))
     elif t.arg1.is_times():
         # Left side has more than one atom. Compare last atom with b
         m1, m2 = dest_atom(t.arg1.arg), dest_atom(t.arg)
         if m1 == m2:
             pt = pt.on_rhs(rewr_conv('real_mult_assoc', sym=True),
                            arg_conv(combine_atom(self.conds)))
             if pt.rhs.arg.is_one():
                 pt = pt.on_rhs(rewr_conv('real_mul_rid'))
             return pt
         elif atom_less(m1, m2):
             return pt
         else:
             pt = pt.on_rhs(swap_mult_r(), arg1_conv(self))
             if pt.rhs.arg1.is_one():
                 pt = pt.on_rhs(rewr_conv('real_mul_lid'))
             return pt
     else:
         # Left side is an atom. Compare two sides
         m1, m2 = dest_atom(t.arg1), dest_atom(t.arg)
         if m1 == m2:
             return pt.on_rhs(combine_atom(self.conds))
         elif atom_less(m1, m2):
             return pt
         else:
             return pt.on_rhs(rewr_conv('real_mult_comm'))
예제 #7
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())
예제 #8
0
파일: real.py 프로젝트: bzhan/holpy
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg.is_plus():
         return pt.on_rhs(rewr_conv('real_add_assoc'), arg1_conv(self),
                          norm_add_monomial())
     else:
         return pt.on_rhs(norm_add_monomial())
예제 #9
0
파일: real.py 프로젝트: bzhan/holpy
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg1.is_zero():
         return pt.on_rhs(rewr_conv("real_add_lid"))
     elif t.arg.is_zero():
         return pt.on_rhs(rewr_conv("real_add_rid"))
     elif t.arg1.is_plus():
         # Left side has more than one term. Compare last term with a
         m1, m2 = dest_monomial(t.arg1.arg), dest_monomial(t.arg)
         if m1 == m2:
             pt = pt.on_rhs(rewr_conv('real_add_assoc', sym=True),
                            arg_conv(combine_monomial()))
             if pt.rhs.arg.is_zero():
                 pt = pt.on_rhs(rewr_conv('real_add_rid'))
             return pt
         elif atom_less(m1, m2):
             return pt
         else:
             pt = pt.on_rhs(swap_add_r(), arg1_conv(self))
             if pt.rhs.arg1.is_zero():
                 pt = pt.on_rhs(rewr_conv('real_add_lid'))
             return pt
     else:
         # Left side is an atom. Compare two sides
         m1, m2 = dest_monomial(t.arg1), dest_monomial(t.arg)
         if m1 == m2:
             return pt.on_rhs(combine_monomial())
         elif atom_less(m1, m2):
             return pt
         else:
             return pt.on_rhs(rewr_conv('real_add_comm'))
예제 #10
0
파일: nat.py 프로젝트: bzhan/holpy
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg.is_times():
         return pt.on_rhs(rewr_conv("mult_assoc", sym=True),
                          arg1_conv(norm_mult_monomial()), norm_mult_atom())
     else:
         return pt.on_rhs(norm_mult_atom())
예제 #11
0
파일: nat.py 프로젝트: bzhan/holpy
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg1.is_zero():
         return pt.on_rhs(rewr_conv("nat_times_def_1"))
     elif t.arg.is_zero():
         return pt.on_rhs(rewr_conv("mult_0_right"))
     elif t.arg1.is_one():
         return pt.on_rhs(rewr_conv("mult_1_left"))
     elif t.arg.is_one():
         return pt.on_rhs(rewr_conv("mult_1_right"))
     elif t.arg1.is_times():
         cp = compare_atom(t.arg1.arg, t.arg)
         if cp > 0:
             return pt.on_rhs(swap_times_r(), arg1_conv(norm_mult_atom()))
         elif cp == 0:
             if t.arg.is_number() and has_binary_thms():
                 return pt.on_rhs(rewr_conv("mult_assoc"),
                                  arg_conv(nat_conv()))
             else:
                 return pt
         else:
             return pt
     else:
         cp = compare_atom(t.arg1, t.arg)
         if cp > 0:
             return pt.on_rhs(rewr_conv("mult_comm"))
         elif cp == 0:
             if t.arg.is_number() and has_binary_thms():
                 return pt.on_rhs(nat_conv())
             else:
                 return pt
         else:
             return pt
예제 #12
0
파일: nat.py 프로젝트: bzhan/holpy
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg.is_plus():
         return pt.on_rhs(rewr_conv("add_assoc", sym=True),
                          arg1_conv(norm_add_1()), norm_add_atom_1())
     else:
         return pt.on_rhs(norm_add_atom_1())
예제 #13
0
 def get_proof_term(self, thy, t):
     if is_plus(t.arg):
         return every_conv(rewr_conv("add_assoc", sym=True),
                           arg1_conv(norm_add_polynomial()),
                           norm_add_monomial()).get_proof_term(thy, t)
     else:
         return norm_add_monomial().get_proof_term(thy, t)
예제 #14
0
 def get_proof_term(self, thy, t):
     if is_times(t.arg):
         return every_conv(rewr_conv("mult_assoc", sym=True),
                           arg1_conv(norm_mult_monomial()),
                           norm_mult_atom()).get_proof_term(thy, t)
     else:
         return norm_mult_atom().get_proof_term(thy, t)
예제 #15
0
파일: inequality.py 프로젝트: bzhan/holpy
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
예제 #16
0
    def get_proof_term(self, thy, t):
        if t.arg1 == zero:
            cv = rewr_conv("times_def_1")
        elif t.arg == zero:
            cv = rewr_conv("mult_0_right")
        elif t.arg1 == one:
            cv = rewr_conv("mult_1_left")
        elif t.arg == one:
            cv = rewr_conv("mult_1_right")
        elif is_times(t.arg1):
            cmp = compare_atom(t.arg1.arg, t.arg)
            if cmp == term_ord.GREATER:
                cv = then_conv(swap_times_r(), arg1_conv(norm_mult_atom()))
            elif cmp == term_ord.EQUAL:
                if is_binary(t.arg):
                    cv = then_conv(rewr_conv("mult_assoc"),
                                   arg_conv(nat_conv()))
                else:
                    cv = all_conv()
            else:
                cv = all_conv()
        else:
            cmp = compare_atom(t.arg1, t.arg)
            if cmp == term_ord.GREATER:
                cv = rewr_conv("mult_comm")
            elif cmp == term_ord.EQUAL:
                if is_binary(t.arg):
                    cv = nat_conv()
                else:
                    cv = all_conv()
            else:
                cv = all_conv()

        return cv.get_proof_term(thy, t)
예제 #17
0
    def get_proof_term(self, t):
        if not t.is_compares():
            raise ConvException('%s is not a comparison.' % str(t))

        pt = refl(t)
        pt_norm_form = pt.on_rhs(norm_eq(), arg1_conv(omega_simp_full_conv()))
        summands = strip_plus(pt_norm_form.rhs.arg1)
        coeffs = [
            int_eval(s.arg1) if not s.is_number() else int_eval(s)
            for s in summands
        ]
        g = functools.reduce(gcd, coeffs)
        if g <= 1:
            return pt

        vars = [s.arg for s in summands if not s.is_number()]
        elim_gcd_coeffs = [int(i / g) for i in coeffs]
        if len(vars) < len(coeffs):
            simp_t = sum([
                coeff * v for coeff, v in zip(elim_gcd_coeffs[1:-1], vars[1:])
            ], elim_gcd_coeffs[0] * vars[0]) + Int(elim_gcd_coeffs[-1])
        else:
            simp_t = sum(
                [coeff * v for coeff, v in zip(elim_gcd_coeffs[1:], vars[1:])],
                elim_gcd_coeffs[0] * vars[0])

        simp_t_times_gcd = Int(g) * simp_t
        pt_simp_t_times_gcd = refl(simp_t_times_gcd).on_rhs(
            omega_simp_full_conv()).symmetric()
        pt_c = ProofTerm('int_const_ineq', greater(IntType)(Int(g), Int(0)))
        if t.is_less():
            gcd_pt = ProofTerm.theorem('int_simp_less')
        elif t.is_less_eq():
            gcd_pt = ProofTerm.theorem('int_simp_leq')
        elif t.is_greater():
            gcd_pt = ProofTerm.theorem('int_simp_gt')
        elif t.is_greater_eq():
            gcd_pt = ProofTerm.theorem('int_simp_geq')

        inst1 = matcher.first_order_match(gcd_pt.prop.arg1, pt_c.prop)
        inst2 = matcher.first_order_match(gcd_pt.prop.arg.rhs.arg1,
                                          simp_t,
                                          inst=inst1)

        pt_simp = gcd_pt.substitution(inst2).implies_elim(pt_c).on_lhs(
            arg1_conv(omega_simp_full_conv()))
        return pt_norm_form.transitive(pt_simp).on_rhs(omega_form_conv())
예제 #18
0
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg.is_conj():
         return pt.on_rhs(rewr_conv('conj_assoc'),
                          arg1_conv(rewr_conv('conj_comm')),
                          rewr_conv('conj_assoc', sym=True))
     else:
         return pt.on_rhs(rewr_conv('conj_comm'))
예제 #19
0
 def get_proof_term(self, thy, t):
     if is_plus(t.arg):
         return every_conv(rewr_conv("distrib_l"),
                           arg1_conv(norm_mult_polynomial()),
                           arg_conv(norm_mult_poly_monomial()),
                           norm_add_polynomial()).get_proof_term(thy, t)
     else:
         return norm_mult_poly_monomial().get_proof_term(thy, t)
예제 #20
0
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg.is_times():  # t is of form a * (b * c)
         return pt.on_rhs(
             rewr_conv('int_mult_assoc'),  # (a * b) * c
             arg1_conv(self),  # merge terms in b into a
             norm_mult_atom())  # merge c into a * b
     else:
         return pt.on_rhs(norm_mult_atom())
예제 #21
0
 def get_proof_term(self, t):
     if not t.is_equals():
         raise ConvException("%s must be an equality." % str(t))
     pt = refl(t)
     pt1 = pt.on_rhs(rewr_conv('int_sub_move_0_r', sym=True),
                     arg1_conv(simp_full()),
                     top_conv(rewr_conv('int_pow_1_r')))
     summands = strip_plus(pt1.rhs.arg1)
     if summands[0].is_number():
         first_coeff = summands[0]
     else:
         first_coeff = summands[0].arg1
     if int_eval(first_coeff) < 0:
         return pt1.on_rhs(rewr_conv('int_pos_neg_eq_0'),
                           arg1_conv(simp_full()),
                           top_conv(rewr_conv('int_pow_1_r')))
     else:
         return pt1
예제 #22
0
파일: nat.py 프로젝트: bzhan/holpy
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg.is_plus():
         return pt.on_rhs(rewr_conv("distrib_l"),
                          arg1_conv(norm_mult_polynomial()),
                          arg_conv(norm_mult_poly_monomial()),
                          norm_add_polynomial())
     else:
         return pt.on_rhs(norm_mult_poly_monomial())
예제 #23
0
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg1.is_number() and t.arg.is_number():  # c * d
         return pt.on_rhs(int_eval_conv())
     elif t.arg1.is_number() and not t.arg.is_number():  # c * (d * body)
         return pt.on_rhs(
             rewr_conv('int_mult_assoc'),  # (c * d) * body
             arg1_conv(int_eval_conv()))  # evaluate c * d
     elif not t.arg1.is_number() and t.arg.is_number():  # (c * body) * d
         return pt.on_rhs(rewr_conv('int_mult_comm'),
                          self)  # d * (c * body)
     else:  # (c * body1) * (d * body2)
         return pt.on_rhs(
             rewr_conv('int_mult_assoc'),  # ((c * body1) * d) * body2
             arg1_conv(swap_mult_r()),  # ((c * d) * body1) * body2
             arg1_conv(arg1_conv(int_eval_conv())),  # evaluate c * d
             rewr_conv('int_mult_assoc', sym=True),  # cd * (body1 * body2)
             arg_conv(norm_mult_monomial_wo_coeff()))
예제 #24
0
    def get_proof_term(self, t):
        pt = refl(t)
        if t.is_minus():  # a - c
            return pt.on_rhs(
                rewr_conv('int_poly_neg2'),  # a + (-k) * body
                arg_conv(norm_mult_monomial()),
                norm_add_monomial())
        elif t.arg1.is_plus():  # (a + b) + c
            cp = compare_monomial(t.arg1.arg, t.arg)  # compare b with c
            if cp > 0:  # if b > c, need to swap b with c
                return pt.on_rhs(
                    swap_add_r(),  # (a + c) + b
                    arg1_conv(self),  # possibly move c further into a
                    try_conv(rewr_conv('int_add_0_left')))  # 0 +b = 0
            elif cp == 0:  # if b and c have the same body, combine coefficients
                return pt.on_rhs(
                    rewr_conv('int_add_assoc',
                              sym=True),  # a + (c1 * b + c2 * b)
                    arg_conv(rewr_conv('int_mul_add_distr_r',
                                       sym=True)),  # a + (c1 + c2) * b
                    arg_conv(arg1_conv(int_eval_conv())),  # evaluate c1 + c2
                    try_conv(arg_conv(rewr_conv('int_mul_0_l'))),
                    try_conv(rewr_conv('int_add_0_right')))
            else:  # if b < c, monomials are already sorted
                return pt

        else:  # a + b
            if t.arg.is_zero():
                return pt.on_rhs(rewr_conv('int_add_0_right'))
            if t.arg1.is_zero():
                return pt.on_rhs(rewr_conv('int_add_0_left'))
            cp = compare_monomial(t.arg1, t.arg)  # compare a with b
            if cp > 0:  # if a > b, need to swap a with b
                return pt.on_rhs(rewr_conv('int_add_comm'))
            elif cp == 0:  # if b and c have the same body, combine coefficients
                if t.arg.is_number():
                    return pt.on_rhs(int_eval_conv())
                else:
                    return pt.on_rhs(
                        rewr_conv('int_mul_add_distr_r', sym=True),
                        arg1_conv(int_eval_conv()),
                        try_conv(rewr_conv('int_mul_0_l')))
            else:
                return pt
예제 #25
0
    def get_proof_term(self, t):
        if not t.is_disj():
            return refl(t)

        nnf_pt = nnf_conv().get_proof_term(Not(t))
        norm_neg_disj_pt = sort_conj().get_proof_term(nnf_pt.rhs)
        nnf_pt_norm = nnf_pt.transitive(norm_neg_disj_pt)
        return nnf_pt_norm.on_prop(rewr_conv('neg_iff_both_sides'),
                                   arg1_conv(rewr_conv('double_neg')),
                                   arg_conv(nnf_conv()))
예제 #26
0
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg1.is_plus():  # (a + b) * c
         return pt.on_rhs(
             rewr_conv('int_mul_add_distr_r'),  # a * c + b * c
             arg1_conv(self),  # process a * c
             arg_conv(norm_mult_monomial()),  # process b * c
             norm_add_polynomial())  # add the results
     else:
         return pt.on_rhs(norm_mult_monomial())
예제 #27
0
파일: inequality.py 프로젝트: bzhan/holpy
    def get_proof_term(self, goal, pts):
        assert len(pts) == 1 and hol_set.is_mem(pts[0].prop) and pts[0].prop.arg1.is_var(), \
            "interval_inequality"
        var_name = pts[0].prop.arg1.name
        var_range = {var_name: pts[0]}

        if goal.is_not() and goal.arg.is_equals():
            if expr.is_polynomial(expr.holpy_to_expr(goal.arg.arg1)):
                factored = expr.expr_to_holpy(
                    expr.factor_polynomial(expr.holpy_to_expr(goal.arg.arg1)))
                if factored.is_times() and factored != goal.arg.arg1:
                    eq_pt = auto.auto_solve(Eq(factored, goal.arg.arg1))
                    pt1 = get_bounds_proof(factored, var_range).on_prop(
                        arg1_conv(rewr_conv(eq_pt)))
                else:
                    pt1 = get_bounds_proof(goal.arg.arg1, var_range)
            else:
                pt1 = get_bounds_proof(goal.arg.arg1, var_range)
            pt2 = get_bounds_proof(goal.arg.arg, var_range)
            try:
                pt = combine_interval_bounds(pt1, pt2)
                if pt.prop.is_less_eq():
                    raise TacticException
                pt = apply_theorem('real_lt_neq', pt)
            except TacticException:
                pt = combine_interval_bounds(pt2, pt1)
                if pt.prop.is_less_eq():
                    raise TacticException
                pt = apply_theorem('real_gt_neq', reverse_inequality(pt))
            return pt
        else:
            pt1 = get_bounds_proof(goal.arg1, var_range)
            pt2 = get_bounds_proof(goal.arg, var_range)
            if goal.is_less_eq():
                pt = combine_interval_bounds(pt1, pt2)
                if pt.prop.is_less():
                    pt = apply_theorem('real_lt_imp_le', pt)
                return pt
            elif goal.is_less():
                pt = combine_interval_bounds(pt1, pt2)
                if pt.prop.is_less_eq():
                    raise TacticException
                return pt
            elif goal.is_greater_eq():
                pt = combine_interval_bounds(pt2, pt1)
                if pt.prop.is_less():
                    pt = apply_theorem('real_lt_imp_le', pt)
                return reverse_inequality(pt)
            elif goal.is_greater():
                pt = combine_interval_bounds(pt2, pt1)
                if pt.prop.is_less_eq():
                    raise TacticException
                return reverse_inequality(pt)
            else:
                raise AssertionError('interval_inequality')
예제 #28
0
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg1.is_zero():
         return pt.on_rhs(rewr_conv('int_mul_0_l'))
     elif t.arg.is_zero():
         return pt.on_rhs(rewr_conv('int_mul_0_r'))
     elif t.arg.is_plus():  # a * (b + c)
         return pt.on_rhs(
             rewr_conv('int_mul_add_distr_l'),  # a * b + a * c
             arg1_conv(self),  # process a * b
             arg_conv(norm_mult_poly_monomial()),  # process a * c
             norm_add_polynomial())
     elif t.arg.is_minus():
         return pt.on_rhs(arg_conv(norm_add_polynomial()),
                          norm_mult_polynomials())
     elif t.arg1.is_minus():
         return pt.on_rhs(arg1_conv(norm_add_polynomial()),
                          norm_mult_polynomials())
     else:
         return pt.on_rhs(norm_mult_poly_monomial())
예제 #29
0
    def get_proof_term(self, t):
        pt = refl(t)
        if t.arg1 == true:
            return pt.on_rhs(rewr_conv('conj_true_left'))
        elif t.arg == true:
            return pt.on_rhs(rewr_conv('conj_true_right'))
        elif t.arg1 == false:
            return pt.on_rhs(rewr_conv('conj_false_right'))
        elif t.arg == false:
            return pt.on_rhs(rewr_conv('conj_false_left'))
        elif t.arg.is_conj():
            if t.arg1 == Not(t.arg.arg1):  # A /\ (A_1 /\ ... /\ A_n)
                return pt.on_rhs(rewr_conv('conj_assoc'),
                                 arg1_conv(rewr_conv('conj_neg_pos')),
                                 rewr_conv('conj_false_right'))
            elif Not(t.arg1) == t.arg.arg1:
                return pt.on_rhs(rewr_conv('conj_assoc'),
                                 arg1_conv(rewr_conv('conj_pos_neg')),
                                 rewr_conv('conj_false_right'))

            cp = term_ord.fast_compare(t.arg1, t.arg.arg1)
            if cp > 0:
                return pt.on_rhs(swap_conj_r(), arg_conv(self), try_conv(self))
            elif cp == 0:
                return pt.on_rhs(rewr_conv('conj_assoc'),
                                 arg1_conv(rewr_conv('conj_same_atom')))
            else:
                return pt
        else:
            if t.arg == Not(t.arg1):
                return pt.on_rhs(rewr_conv('conj_pos_neg'))
            elif t.arg1 == Not(t.arg):
                return pt.on_rhs(rewr_conv('conj_neg_pos'))
            cp = term_ord.fast_compare(t.arg1, t.arg)
            if cp > 0:
                return pt.on_rhs(swap_conj_r())
            elif cp == 0:
                return pt.on_rhs(rewr_conv('conj_same_atom'))
            else:
                return pt
예제 #30
0
 def get_proof_term(self, t):
     pt = refl(t)
     if t.is_not():
         if t.arg == true:
             return pt.on_rhs(rewr_conv('not_true'))
         elif t.arg == false:
             return pt.on_rhs(rewr_conv('not_false'))
         elif t.arg.is_not():
             return pt.on_rhs(rewr_conv('double_neg'), self)
         elif t.arg.is_conj():
             return pt.on_rhs(rewr_conv('de_morgan_thm1'), arg1_conv(self),
                              arg_conv(self))
         elif t.arg.is_disj():
             return pt.on_rhs(rewr_conv('de_morgan_thm2'), arg1_conv(self),
                              arg_conv(self))
         elif t.arg.is_equals() and t.arg.lhs.get_type() == BoolType:
             return pt.on_rhs(rewr_conv('neg_iff'), binop_conv(self))
         else:
             return pt
     elif t.is_disj() or t.is_conj() or t.is_equals():
         return pt.on_rhs(arg1_conv(self), arg_conv(self))
     else:
         return pt