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())
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)
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
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')))
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
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))