Beispiel #1
0
 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())
Beispiel #2
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
Beispiel #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
Beispiel #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
Beispiel #5
0
    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())
Beispiel #6
0
 def get_proof_term(self, t):
     assert is_interval(t), "numseg_conv"
     mt, nt = t.args
     m, n = mt.dest_number(), nt.dest_number()
     pt = refl(t)
     if n < m:
         less_goal = nat.less(nt, mt)
         less_pt = nat.nat_const_less_macro().get_proof_term(less_goal, [])
         return pt.on_rhs(rewr_conv("natseg_emptyI", conds=[less_pt]))
     else:
         le_goal = nat.less_eq(mt, nt)
         le_pt = nat.nat_const_less_eq_macro().get_proof_term(le_goal, [])
         return pt.on_rhs(rewr_conv("natseg_lrec", conds=[le_pt]),
                          arg_conv(arg1_conv(nat.nat_conv())),
                          arg_conv(self))
Beispiel #7
0
 def get_proof_term(self, t):
     pt = refl(t)
     if t.is_number():
         return pt
     elif t.is_comb('Suc', 1):
         return pt.on_rhs(arg_conv(self), arg_conv(rewr_of_nat_conv()),
                          Suc_conv(), rewr_of_nat_conv(sym=True))
     elif t.is_plus():
         return pt.on_rhs(binop_conv(self), binop_conv(rewr_of_nat_conv()),
                          add_conv(), rewr_of_nat_conv(sym=True))
     elif t.is_times():
         return pt.on_rhs(binop_conv(self), binop_conv(rewr_of_nat_conv()),
                          mult_conv(), rewr_of_nat_conv(sym=True))
     else:
         raise ConvException("nat_conv")
Beispiel #8
0
 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
Beispiel #9
0
 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'))
Beispiel #10
0
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg1.is_disj():
         return pt.on_rhs(rewr_conv('disj_assoc_eq', sym=True),
                          arg_conv(self), norm_disj_atom())
     else:
         return pt.on_rhs(norm_disj_atom())
Beispiel #11
0
 def get_proof_term(self, thy, t):
     if is_conj(t.arg1):
         return then_conv(
             rewr_conv("conj_assoc", sym=True),
             arg_conv(norm_conj_assoc_clauses())).get_proof_term(thy, t)
     else:
         return all_conv().get_proof_term(thy, t)
Beispiel #12
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(), )
Beispiel #13
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)
Beispiel #14
0
 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'))
Beispiel #15
0
 def get_proof_term(self, thy, t):
     if is_plus(t.arg1):
         return every_conv(rewr_conv("add_assoc"),
                           arg_conv(rewr_conv("add_comm")),
                           rewr_conv("add_assoc",
                                     sym=True)).get_proof_term(thy, t)
     else:
         return rewr_conv("add_comm").get_proof_term(thy, t)
Beispiel #16
0
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg1.is_times():
         return pt.on_rhs(rewr_conv("mult_assoc"),
                          arg_conv(rewr_conv("mult_comm")),
                          rewr_conv("mult_assoc", sym=True))
     else:
         return pt.on_rhs(rewr_conv("mult_comm"))
Beispiel #17
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)
Beispiel #18
0
 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())
Beispiel #19
0
def eval_Sem(c, st):
    """Evaluates the effect of program c on state st."""
    T = st.get_type()
    if c.is_const("Skip"):
        return apply_theorem("Sem_Skip", inst=Inst(s=st))
    elif c.is_comb("Assign", 2):
        a, b = c.args
        Ta = a.get_type()
        Tb = b.get_type().range_type()
        pt = apply_theorem("Sem_Assign", inst=Inst(a=a, b=b, s=st))
        return pt.on_arg(arg_conv(norm_cv))
    elif c.is_comb("Seq", 2):
        c1, c2 = c.args
        pt1 = eval_Sem(c1, st)
        pt2 = eval_Sem(c2, pt1.prop.arg)
        pt = apply_theorem("Sem_seq", pt1, pt2)
        return pt.on_arg(function.fun_upd_norm_one_conv())
    elif c.is_comb("Cond", 3):
        b, c1, c2 = c.args
        b_st = beta_norm(b(st))
        b_eval = norm_cond_cv.get_proof_term(b_st)
        if b_eval.prop.arg == true:
            b_res = b_eval.on_prop(rewr_conv("eq_true", sym=True))
            pt1 = eval_Sem(c1, st)
            return apply_theorem("Sem_if1",
                                 b_res,
                                 pt1,
                                 concl=Sem(T)(c, st, pt1.prop.arg))
        else:
            b_res = b_eval.on_prop(rewr_conv("eq_false", sym=True))
            pt2 = eval_Sem(c2, st)
            return apply_theorem("Sem_if2",
                                 b_res,
                                 pt2,
                                 concl=Sem(T)(c, st, pt2.prop.arg))
    elif c.is_comb("While", 3):
        b, inv, body = c.args
        b_st = beta_norm(b(st))
        b_eval = norm_cond_cv.get_proof_term(b_st)
        if b_eval.prop.arg == true:
            b_res = b_eval.on_prop(rewr_conv("eq_true", sym=True))
            pt1 = eval_Sem(body, st)
            pt2 = eval_Sem(c, pt1.prop.arg)
            pt = apply_theorem("Sem_while_loop",
                               b_res,
                               pt1,
                               pt2,
                               concl=Sem(T)(c, st, pt2.prop.arg),
                               inst=Inst(s3=pt1.prop.arg))
            return pt.on_arg(function.fun_upd_norm_one_conv())
        else:
            b_res = b_eval.on_prop(rewr_conv("eq_false", sym=True))
            return apply_theorem("Sem_while_skip",
                                 b_res,
                                 concl=Sem(T)(c, st, st))
    else:
        raise NotImplementedError
Beispiel #20
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
Beispiel #21
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())
Beispiel #22
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()))
Beispiel #23
0
 def get_proof_term(self, t):
     pt = refl(t)
     if t.arg.is_zero():
         return pt.on_rhs(rewr_conv("nat_one_def", sym=True))
     elif t.arg.is_one():
         return pt.on_rhs(rewr_conv("one_Suc"))
     elif is_bit0(t.arg):
         return pt.on_rhs(rewr_conv("bit0_Suc"))
     else:
         return pt.on_rhs(rewr_conv("bit1_Suc"), arg_conv(self))
Beispiel #24
0
 def get_proof_term(self, thy, t):
     n = t.arg  # remove Suc
     if n == zero:
         return all_conv().get_proof_term(thy, t)
     elif n == one:
         return rewr_conv("one_Suc").get_proof_term(thy, t)
     elif n.head == bit0:
         return rewr_conv("bit0_Suc").get_proof_term(thy, t)
     else:
         return then_conv(rewr_conv("bit1_Suc"),
                          arg_conv(self)).get_proof_term(thy, t)
Beispiel #25
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())
Beispiel #26
0
 def testRewrConvWithAssum(self):
     x = Const("x", natT)
     y = Const("y", natT)
     x_eq_y = Term.mk_equals(x, y)
     th = Thm([], Term.mk_implies(x_eq_y, x_eq_y))
     cv = arg_conv(rewr_conv(ProofTerm.atom(0, th)))
     f = Const("f", TFun(natT, natT))
     res = Thm([x_eq_y], Term.mk_equals(f(x), f(y)))
     self.assertEqual(cv.eval(thy, f(x)), res)
     prf = Proof()
     prf.add_item(0, "sorry", th=th)
     cv.get_proof_term(thy, f(x)).export(prf=prf)
     self.assertEqual(thy.check_proof(prf), res)
Beispiel #27
0
 def get_proof_term(self, thy, t):
     pt = refl(t)
     if is_binary(t):
         return pt
     else:
         if t.head == Suc:
             return pt.on_rhs(thy, arg_conv(self), Suc_conv())
         elif t.head == plus:
             return pt.on_rhs(thy, binop_conv(self), add_conv())
         elif t.head == times:
             return pt.on_rhs(thy, binop_conv(self), mult_conv())
         else:
             raise ConvException()
Beispiel #28
0
    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)
Beispiel #29
0
    def get_proof_term(self, t):
        if not (t.is_compares() and t.arg.get_type() == IntType):
            raise ConvException("%s is not an integer comparison." % str(t))
        pt_refl = refl(t)
        if t.is_less():
            pt = pt_refl.on_rhs(rewr_conv('int_zero_less'))
        elif t.is_less_eq():
            pt = pt_refl.on_rhs(rewr_conv('int_zero_less_eq'))
        elif t.is_greater():
            pt = pt_refl.on_rhs(rewr_conv('int_zero_greater'))
        else:
            pt = pt_refl.on_rhs(rewr_conv('int_zero_greater_eq'))

        return pt.on_rhs(arg_conv(omega_simp_full_conv()))
Beispiel #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