def get_proof_term(self, thy, goal, pts): f, (P, c, Q) = goal.strip_comb() T = Q.get_type().domain_type() pt = vcg(thy, T, goal) for A in reversed(pt.hyps): pt = ProofTerm.implies_intr(A, pt) return pt.on_assums(thy, rewr_conv("Entail_def"), top_conv(beta_conv()), top_conv(function.fun_upd_eval_conv()))
def encode(t): """Given a propositional formula t, compute its Tseitin encoding. The theorem is structured as follows: Each of the assumptions, except the last, is an equality, where the right side is either an atom or a logical operation between atoms. We call these assumptions As. The last assumption is the original formula. We call it F. The conclusion is in CNF. Each clause except the last is an expansion of one of As. The last clause is obtained by performing substitutions of As on F. """ # Mapping from subterms to newly introduced variables subterm_dict = dict() for i, subt in enumerate(logic_subterms(t)): subterm_dict[subt] = Var('x' + str(i + 1), BoolType) # Collect list of equations eqs = [] for subt in subterm_dict: r = subterm_dict[subt] if not is_logical(subt): eqs.append(Eq(r, subt)) elif subt.is_not(): r1 = subterm_dict[subt.arg] eqs.append(Eq(r, Not(r1))) else: r1 = subterm_dict[subt.arg1] r2 = subterm_dict[subt.arg] eqs.append(Eq(r, subt.head(r1, r2))) # Form the proof term eq_pts = [ProofTerm.assume(eq) for eq in eqs] encode_pt = ProofTerm.assume(t) for eq_pt in eq_pts: encode_pt = encode_pt.on_prop(top_conv(rewr_conv(eq_pt, sym=True))) for eq_pt in eq_pts: if is_logical(eq_pt.rhs): encode_pt = logic.apply_theorem('conjI', eq_pt, encode_pt) # Rewrite using Tseitin rules encode_thms = [ 'encode_conj', 'encode_disj', 'encode_imp', 'encode_eq', 'encode_not' ] for th in encode_thms: encode_pt = encode_pt.on_prop(top_conv(rewr_conv(th))) # Normalize the conjuncts return encode_pt.on_prop(logic.conj_norm())
def real_solver(self, args): refl_pt = conv.refl(args).on_rhs( conv.top_conv(conv.rewr_conv("real_ge_le_same_num")), conv.top_conv(conv.rewr_conv("de_morgan_thm1")), conv.top_conv(real.norm_neg_real_ineq_conv()), conv.top_conv(real.real_simplex_form()), conv.top_conv(real.real_const_compares()), proplogic.norm_full()) if refl_pt.rhs == true: return refl_pt.on_prop(conv.rewr_conv("eq_true", sym=True)) pt_result = real_th_lemma([refl_pt.rhs]) return refl_pt.symmetric().equal_elim(pt_result)
def int_solver(self, args): refl_pt = conv.refl(args).on_rhs( conv.top_conv(conv.rewr_conv("int_eq_leq_geq")), conv.top_conv(conv.rewr_conv("de_morgan_thm1")), conv.top_conv(integer.int_norm_neg_compares()), conv.top_conv(integer.omega_form_conv()), conv.top_conv(integer.int_const_compares()), proplogic.norm_full()) if refl_pt.rhs == true: return refl_pt.on_prop(conv.rewr_conv("eq_true", sym=True)) try: pt_result = int_th_lemma_1_simplex(refl_pt.rhs) except: pt_result = int_th_lemma_1_omega(refl_pt.rhs) return refl_pt.symmetric().equal_elim(pt_result)
def norm(t, pts=None): """The main normalization function. The function should always succeed. It returns an equality whose left side is t. If no normalization is available, it returns t = t. """ if debug_auto: print("Norm:", t, [str(pt.prop) for pt in pts]) # Do not normalize variables and abstractions if t.is_var() or t.is_abs(): return refl(t) # No further work for numbers if t.is_number(): return refl(t) # Record if not pts and t in norm_record: return norm_record[t] eq_pt = refl(t.head) # First normalize each argument for arg in t.args: eq_pt = eq_pt.combination(norm(arg, pts)) # Next, apply each normalization rule if t.head in global_autos_norm: ori_rhs = eq_pt.rhs for f in global_autos_norm[t.head]: try: if isinstance(f, Conv): eq_pt = eq_pt.on_rhs(f) else: eq_pt = eq_pt.transitive(f(eq_pt.rhs, pts)) except ConvException: continue if eq_pt.rhs.head != t.head: # Head changed, should try something else break if eq_pt.rhs == ori_rhs: # Unchanged, normalization stops here res_pt = eq_pt else: # Head changed, continue apply norm eq_pt2 = norm(eq_pt.rhs, pts) if eq_pt2.lhs != eq_pt.rhs: eq_pt2 = eq_pt2.on_lhs(top_conv(eta_conv())) res_pt = eq_pt.transitive(eq_pt2) else: # No normalization rule available for this head res_pt = eq_pt if not pts: norm_record[t] = res_pt return res_pt
def search(self, state, id, prevs): cur_th = state.get_proof_item(id).th if cur_th.prop.is_all(): return [] thy = state.thy results = [] for th_name, th in thy.get_data("theorems").items(): if 'hint_rewrite' not in thy.get_attributes(th_name): continue cv = top_conv(rewr_conv(th_name)) th = cv.eval(thy, cur_th.prop) new_goal = th.prop.rhs new_As = list(th.hyps) if cur_th.prop != new_goal: if Term.is_equals(new_goal) and new_goal.lhs == new_goal.rhs: results.append({"theorem": th_name, "_goal": new_As}) else: results.append({ "theorem": th_name, "_goal": [new_goal] + new_As }) return sorted(results, key=lambda d: d['theorem'])
def get_proof_term(self, thy, goal, *, args=None, prevs=None): assert isinstance(prevs, list) and len(prevs) == 1, "rewrite_goal_with_prev" pt = prevs[0] init_As = goal.hyps C = goal.prop cv = then_conv(top_sweep_conv(rewr_conv(pt, match_vars=False)), top_conv(beta_conv())) eq_th = cv.eval(thy, C) new_goal = eq_th.prop.rhs new_As = list(set(eq_th.hyps) - set(init_As)) new_As_pts = [ProofTerm.sorry(Thm(init_As, A)) for A in new_As] if Term.is_equals(new_goal) and new_goal.lhs == new_goal.rhs: return ProofTermDeriv('rewrite_goal_with_prev', thy, args=C, prevs=[pt] + new_As_pts) else: new_goal_pts = ProofTerm.sorry(Thm(init_As, new_goal)) return ProofTermDeriv('rewrite_goal_with_prev', thy, args=C, prevs=[pt, new_goal_pts] + new_As_pts)
def get_proof_term(self, thy, args, pts): assert len(pts) == 1 and isinstance( args, str), "rewrite_fact_macro: signature" th_name = args eq_pt = ProofTerm.theorem(thy, th_name) cv = then_conv(top_sweep_conv(rewr_conv(eq_pt)), top_conv(beta_conv())) return pts[0].on_prop(thy, cv)
def testTopBetaConv(self): cv = top_conv(beta_conv()) t = lf(lf(x)) res = f(f(x, x), f(x, x)) res_th = eq(t, res) self.assertEqual(cv.eval(thy, t), res_th) prf = cv.get_proof_term(thy, t).export() self.assertEqual(len(prf.items), 5) self.assertEqual(thy.check_proof(prf), res_th)
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
def get_proof_term(self, thy, args, pts): assert isinstance(args, tuple) and len(args) == 2 and \ isinstance(args[0], str) and isinstance(args[1], Term), "rewrite_goal_macro: signature" name, goal = args eq_pt = ProofTerm.theorem(thy, name) if self.backward: eq_pt = ProofTerm.symmetric(eq_pt) cv = then_conv(top_conv(rewr_conv(eq_pt)), top_conv(beta_conv())) pt = cv.get_proof_term(thy, goal) # goal = th.prop pt = ProofTerm.symmetric(pt) # th.prop = goal if Term.is_equals(pt.prop.lhs) and pt.prop.lhs.lhs == pt.prop.lhs.rhs: pt = ProofTerm.equal_elim(pt, ProofTerm.reflexive(pt.prop.lhs.lhs)) else: pt = ProofTerm.equal_elim(pt, pts[0]) # goal pts = pts[1:] for A in pts: pt = ProofTerm.implies_elim(ProofTerm.implies_intr(A.prop, pt), A) 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 __init__(self, pt): self.pt = pt self.pt = self.pt.on_prop( top_conv(rewr_conv('disj_conv_imp', sym=True))) new_names = logic.get_forall_names(pt.prop) new_vars, _, _ = logic.strip_all_implies(pt.prop, new_names) for new_var in new_vars: self.pt = self.pt.forall_elim(new_var) self.prop = self.pt.prop self.disjuncts = self.prop.strip_disj()
def testTopBetaConvAbs(self): cv = top_conv(beta_conv()) # %x. (%a. f a) x reduces to %x. f x. a = Var("a", Ta) t = abs(x, abs(a, f(a))(x)) res = abs(x, f(x)) prf = cv.get_proof_term(thy, t).export() self.assertEqual(cv.eval(thy, t), eq(t, res)) self.assertEqual(len(prf.items), 2) self.assertEqual(thy.check_proof(prf), eq(t, res))
def testTopBetaConvLarge(self): """Stress test for beta conversion in the top-down order.""" cv = top_conv(beta_conv()) t = x res = x for i in range(8): t = lf(t) res = f(res, res) prf = cv.get_proof_term(thy, t).export() self.assertEqual(cv.eval(thy, t), eq(t, res)) self.assertEqual(len(prf.items), 29) self.assertEqual(thy.check_proof(prf), eq(t, res))
def get_encode_proof(th): """Given resulting theorem for an encoding, obtain the proof of the theorem. The theorem is structured as follows: Each of the assumptions, except the last, is an equality, where the right side is either an atom or a logical operation between atoms. We call these assumptions As. The last assumption is the original formula. We call it F. The conclusion is in CNF. Each clause except the last is an expansion of one of As. The last clause is obtained by performing substitutions of As on F. """ As, F = th.hyps[:-1], th.hyps[-1] # Obtain the assumptions ptAs = [ProofTerm.assume(A) for A in As] ptF = ProofTerm.assume(F) # Obtain the expansion of each As to a non-atomic term. pts = [] for ptA in ptAs: rhs = ptA.prop.rhs if logic.is_conj(rhs): pts.append(ptA.on_prop(thy, rewr_conv("encode_conj"))) elif logic.is_disj(rhs): pts.append(ptA.on_prop(thy, rewr_conv("encode_disj"))) elif rhs.is_implies(): pts.append(ptA.on_prop(thy, rewr_conv("encode_imp"))) elif rhs.is_equals(): pts.append(ptA.on_prop(thy, rewr_conv("encode_eq"))) elif logic.is_neg(rhs): pts.append(ptA.on_prop(thy, rewr_conv("encode_not"))) # Obtain the rewrite of the original formula. cvs = [ top_conv(rewr_conv(ProofTerm.symmetric(ptA), match_vars=False)) for ptA in ptAs ] cv = every_conv(*cvs) pts.append(ptF.on_prop(thy, cv)) pt = pts[0] for pt2 in pts[1:]: pt = logic_macro.apply_theorem(thy, 'conjI', pt, pt2) return pt.on_prop(thy, logic.norm_conj_assoc())
def get_proof_term(self, t): if not (t.is_compares() or t.is_equals()) or not t.arg1.get_type() == IntType: raise ConvException(str(t)) pt = refl(t) if t.is_equals(): pt1 = pt.on_rhs(rewr_conv("real_of_int_eq", sym=True)) elif t.is_greater_eq(): pt1 = pt.on_rhs(rewr_conv("real_of_int_geq", sym=True)) elif t.is_greater(): pt1 = pt.on_rhs(rewr_conv("real_of_int_gt", sym=True)) elif t.is_less_eq(): pt1 = pt.on_rhs(rewr_conv("real_of_int_leq", sym=True)) elif t.is_less(): pt1 = pt.on_rhs(rewr_conv("real_of_int_lt", sym=True)) else: raise NotImplementedError return pt1.on_rhs( top_conv(rewr_conv('real_of_int_add', sym=True)), top_conv(rewr_conv('real_of_int_mul', sym=True)), )
def get_proof_term(self, thy, goal, args=None, prevs=None): th_name = args init_As = goal.hyps C = goal.prop cv = then_conv(top_conv(rewr_conv(th_name)), top_conv(beta_conv())) eq_th = cv.eval(thy, C) new_goal = eq_th.prop.rhs new_As = list(eq_th.hyps) new_As_pts = [ProofTerm.sorry(Thm(init_As, A)) for A in new_As] if Term.is_equals(new_goal) and new_goal.lhs == new_goal.rhs: return ProofTermDeriv('rewrite_goal', thy, args=(th_name, C), prevs=new_As_pts) else: new_goal_pts = ProofTerm.sorry(Thm(init_As, new_goal)) return ProofTermDeriv('rewrite_goal', thy, args=(th_name, C), prevs=[new_goal_pts] + new_As_pts)
def get_proof_term(self, args, pts): # First, find the pair i, j such that B_j = ~A_i or A_i = ~B_j, the # variable side records the side of the positive literal. pt1, pt2 = pts disj1 = strip_num(pt1.prop, args[0]) disj2 = strip_num(pt2.prop, args[1]) side = None for i, t1 in enumerate(disj1): for j, t2 in enumerate(disj2): if t2 == Not(t1): side = 'left' break elif t1 == Not(t2): side = 'right' break if side is not None: break assert side is not None, "resolution: literal not found" # If side is wrong, just swap: if side == 'right': return self.get_proof_term([args[1], args[0]], [pt2, pt1]) # Move items i and j to the front disj1 = [disj1[i]] + disj1[:i] + disj1[i + 1:] disj2 = [disj2[j]] + disj2[:j] + disj2[j + 1:] eq_pt1 = logic.imp_disj_iff(Eq(pt1.prop, Or(*disj1))) eq_pt2 = logic.imp_disj_iff(Eq(pt2.prop, Or(*disj2))) pt1 = eq_pt1.equal_elim(pt1) pt2 = eq_pt2.equal_elim(pt2) if len(disj1) > 1 and len(disj2) > 1: pt = logic.apply_theorem('resolution', pt1, pt2) elif len(disj1) > 1 and len(disj2) == 1: pt = logic.apply_theorem('resolution_left', pt1, pt2) elif len(disj1) == 1 and len(disj2) > 1: pt = logic.apply_theorem('resolution_right', pt1, pt2) else: pt = logic.apply_theorem('negE', pt2, pt1) # return pt.on_prop(disj_norm()) disj_new = set(disj1[1:] + disj2[1:]) # eq_pt_norm = logic.imp_disj_iff(Eq(pt.prop, Or(*disj_new))) implies_pt_norm = ProofTerm("imp_disj", Implies(pt.prop, Or(*disj_new))) pt_final = implies_pt_norm.implies_elim(pt) self.arity = len(disj_new) return pt_final.on_prop(conv.top_conv(conv.rewr_conv("double_neg")))
def vcg_norm(T, goal): """Compute vcg, then normalize the result into the form A_1 --> A_2 --> ... --> A_n --> Valid P c Q, where A_i are the normalized verification conditions. """ pt = vcg(T, goal) for A in reversed(pt.hyps): pt = pt.implies_intr(A) # Normalize each of the assumptions return pt.on_prop(assums_conv(rewr_conv("Entail_def")), assums_conv(beta_norm_conv()), assums_conv(top_conv(function.fun_upd_eval_conv())))
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 solve(self): res, value = solve_matrix(self.factoids) if res == "SAT": return value elif res == "UNSAT": pt_unsat = self.handle_unsat_result(value) # for the reason that the comparisons in hypothesis may have term like: # 0 <= Σ ai * xi + 0, but we don't want to keep the zero, so we need to # postprocess to normalize each comparisons again. hyps = pt_unsat.hyps pt_norm = pt_unsat for h in hyps: pt_norm = pt_norm.implies_intr(h) pt_norm = pt_norm.on_prop(conv.top_conv(integer.omega_form_conv())) premises, _ = pt_norm.prop.strip_implies() for p in premises: pt_norm = pt_norm.implies_elim(proofterm.ProofTerm.assume(p)) return pt_norm
def get_proof_term(self, thy, args, pts): assert isinstance(args, Term), "rewrite_goal_macro: signature" goal = args eq_pt = pts[0] pts = pts[1:] if self.backward: eq_pt = ProofTerm.symmetric(eq_pt) cv = then_conv(top_sweep_conv(rewr_conv(eq_pt, match_vars=False)), top_conv(beta_conv())) pt = cv.get_proof_term(thy, goal) # goal = th.prop pt = ProofTerm.symmetric(pt) # th.prop = goal if Term.is_equals(pt.prop.lhs) and pt.prop.lhs.lhs == pt.prop.lhs.rhs: pt = ProofTerm.equal_elim(pt, ProofTerm.reflexive(pt.prop.lhs.rhs)) else: pt = ProofTerm.equal_elim(pt, pts[0]) pts = pts[1:] for A in pts: pt = ProofTerm.implies_elim(ProofTerm.implies_intr(A.prop, pt), A) return pt
def testLargeSum(self): f = Const("f", TFun(natT, natT)) g = Const("g", TFun(natT, natT)) x = Var("x", natT) th0, th1 = eq(one, zero), eq(f(x), g(x)) cv = top_conv( else_conv(rewr_conv(ProofTerm.atom(0, th0)), rewr_conv(ProofTerm.atom(1, th1)))) f1 = f(one) g0 = g(zero) t = plus(*([f1] * 50)) res = plus(*([g0] * 50)) self.assertEqual(cv.eval(thy, t), eq(t, res)) prf = Proof() prf.add_item(0, "sorry", th=th0) prf.add_item(1, "sorry", th=th1) cv.get_proof_term(thy, t).export(prf=prf) self.assertEqual(thy.check_proof(prf, check_level=1), eq(t, res))
def handle_geq_stage1(self, pts): if not pts: return None, None, None # ⊢ min(min(...(min(x_1, x_2), x_3)...), x_n-1), x_n) > 0 min_pos_pt = functools.reduce( lambda pt1, pt2: logic.apply_theorem("min_greater_0", pt1, pt2), pts[1:], pts[0]) # ⊢ 0 < 2 two_pos_pt = ProofTerm("real_compare", Real(0) < Real(2)) # ⊢ min(...) / 2 > 0 min_divides_two_pos = logic.apply_theorem( "real_lt_div", min_pos_pt.on_prop(rewr_conv("real_ge_to_le")), two_pos_pt).on_prop(rewr_conv("real_ge_to_le", sym=True)) # ⊢ 2 ≥ 1 two_larger_one = ProofTerm("real_compare", Real(2) >= Real(1)) # ⊢ min(...) ≥ min(...) / 2 larger_half_pt = logic.apply_theorem("real_divides_larger_1", two_larger_one, min_pos_pt) # ⊢ min(...) / 2 = δ_1 delta_1 = Var("δ_1", RealType) pt_delta1_eq = ProofTerm.assume(Eq(larger_half_pt.prop.arg, delta_1)) # ⊢ min(...) ≥ δ_1 larger_half_pt_delta = larger_half_pt.on_prop( top_conv(replace_conv(pt_delta1_eq))) # ⊢ δ_1 > 0 delta_1_pos = min_divides_two_pos.on_prop( arg1_conv(replace_conv(pt_delta1_eq))) return larger_half_pt_delta, delta_1_pos, pt_delta1_eq
def search(self, state, id, prevs): if len(prevs) != 1: return [] prev_th = state.get_proof_item(prevs[0]).th cur_th = state.get_proof_item(id).th if not prev_th.prop.is_equals(): return [] pt = ProofTermAtom(prevs[0], prev_th) cv = then_conv(top_sweep_conv(rewr_conv(pt, match_vars=False)), top_conv(beta_conv())) eq_th = cv.eval(state.thy, cur_th.prop) new_goal = eq_th.prop.rhs new_As = list(set(eq_th.hyps) - set(cur_th.hyps)) if cur_th.prop != new_goal: if Term.is_equals(new_goal) and new_goal.lhs == new_goal.rhs: return [{"_goal": new_As}] else: return [{"_goal": [new_goal] + new_As}] else: return []
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
def get_proof_term(self, thy, args, pts): tyinst, inst = dict(), dict() if self.with_inst: name, tyinst, inst = args else: name = args th = thy.get_theorem(name) if not self.with_inst: As = th.assums for idx, pt in enumerate(pts): matcher.first_order_match_incr(As[idx], pt.prop, (tyinst, inst)) pt = ProofTerm.substitution( inst, ProofTerm.subst_type(tyinst, ProofTerm.theorem(thy, name))) if pt.prop.beta_norm() == pt.prop: pt2 = pt else: pt2 = top_conv(beta_conv()).apply_to_pt(thy, pt) for pt in pts: pt2 = ProofTerm.implies_elim(pt2, pt) return pt2
def get_proof_term(self, t): return refl(t).on_rhs(simp_full(), top_conv(rewr_conv('int_mul_1_l')), top_conv(rewr_conv('int_pow_1_r')))
def get_proof_term(self, t): return refl(t).on_rhs(simp_full(), top_conv(rewr_conv('int_pow_1_r')), omega_norm_add_num())