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 norm_term(t):
    # Collect list of theorems that can be used.
    cvs = []
    for th_name in norm_thms:
        if isinstance(th_name, str) and theory.thy.has_theorem(th_name):
            cvs.append(conv.try_conv(conv.rewr_conv(th_name)))
        elif theory.thy.has_theorem(th_name[0]):
            cvs.append(conv.try_conv(conv.rewr_conv(th_name[0], sym=True)))
    cvs.append(conv.try_conv(conv.beta_conv()))
    cv = conv.top_conv(conv.every_conv(*cvs))
    while True:
        rhs = cv.eval(t).rhs
        if rhs == t:
            break
        else:
            t = rhs
    return fologic.simplify(t)
Beispiel #3
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 #4
0
    def get_proof_term(self, prevs, goal_lit):
        disj, *lit_pts = prevs
        pt_conj = lit_pts[0]

        for i in range(len(lit_pts)):
            pt = lit_pts[i]
            if not pt.prop.is_not():
                lit_pts[i] = pt.on_prop(rewr_conv('double_neg', sym=True))

        def conj_right_assoc(pts):
            """
            Give a sequence of proof terms: ⊢ A, ⊢ B, ⊢ C,
            return ⊢ A ∧ (B ∧ C)
            """
            if len(pts) == 1:
                return pts[0]
            else:
                return apply_theorem('conjI', pts[0],
                                     conj_right_assoc(pts[1:]))

        # get a /\ b /\ c
        pt_conj = conj_right_assoc(lit_pts)

        other_lits = [
            l.prop.arg if l.prop.is_not() else Not(l.prop) for l in lit_pts
        ]

        # use de Morgan
        pt_conj1 = pt_conj.on_prop(
            bottom_conv(rewr_conv('de_morgan_thm2', sym=True)))

        # if len(other_lits) == 1 and other_lits[0].is_not():
        #     pt_conj1 = pt_conj.on_prop(rewr_conv('double_neg', sym=True))

        # Equality for two disjunctions which literals are the same, but order is different.
        eq_pt = imp_disj_iff(Eq(disj.prop, Or(goal_lit, *other_lits)))
        new_disj_pt = disj.on_prop(top_conv(replace_conv(eq_pt)))

        # A \/ B --> ~B --> A
        pt = ProofTerm.theorem('force_disj_true1')
        A, B = pt.prop.strip_implies()[0]
        C = pt.prop.strip_implies()[1]

        inst1 = matcher.first_order_match(C, goal_lit)
        inst2 = matcher.first_order_match(A,
                                          Or(goal_lit, *other_lits),
                                          inst=inst1)
        inst3 = matcher.first_order_match(B, pt_conj1.prop, inst=inst2)
        pt_implies = apply_theorem('force_disj_true1',
                                   new_disj_pt,
                                   pt_conj1,
                                   inst=inst3)

        return pt_implies.on_prop(try_conv(rewr_conv('double_neg')))
Beispiel #5
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
Beispiel #6
0
 def testTryConv(self):
     cv = try_conv(beta_conv())
     t = lf(x)
     self.assertEqual(cv.eval(thy, t), Thm.beta_conv(t))
     self.assertEqual(cv.eval(thy, x), Thm.reflexive(x))