def search(self, state, id, prevs): prev_ths = [state.get_proof_item(prev).th for prev in prevs] thy = state.thy if len(prevs) == 0: return [] results = [] for name, th in thy.get_data("theorems").items(): if 'hint_forward' not in thy.get_attributes(name): continue instsp = (dict(), dict()) As, C = th.prop.strip_implies() if len(prevs) != len(As): continue if set(term.get_vars(As)) != set(term.get_vars(As + [C])): continue if not term.get_consts(As): continue try: for pat, prev in zip(As, prev_ths): matcher.first_order_match_incr(pat, prev.concl, instsp) except matcher.MatchException: continue # All matches succeed t = logic.subst_norm(th.prop, instsp) _, new_fact = t.strip_implies() results.append({"theorem": name, "_fact": [new_fact]}) return sorted(results, key=lambda d: d['theorem'])
def get_proof_term(self, thy, t): if isinstance(self.pt, str): self.pt = ProofTerm.theorem(thy, self.pt) if self.sym: self.pt = ProofTerm.symmetric(self.pt) # Deconstruct th into assumptions and conclusion As, C = self.pt.assums, self.pt.concl assert Term.is_equals(C), "rewr_conv: theorem is not an equality." tyinst, inst = dict(), dict() if self.match_vars: try: matcher.first_order_match_incr(C.lhs, t, (tyinst, inst)) except matcher.MatchException: raise ConvException() elif C.lhs != t: raise ConvException() pt = ProofTerm.substitution(inst, ProofTerm.subst_type(tyinst, self.pt)) if self.conds is not None: pt = ProofTerm.implies_elim(pt, *self.conds) As = pt.assums for A in As: pt = ProofTerm.implies_elim(pt, ProofTerm.assume(A)) return pt
def apply_theorem(thy, th_name, *pts, concl=None, tyinst=None, inst=None): """Wrapper for apply_theorem and apply_theorem_for macros. The function takes optional arguments concl, tyinst, and inst. Matching always starts with tyinst and inst. If conclusion is specified, it is matched next. Finally, the assumptions are matched. """ if concl is None and tyinst is None and inst is None: # Normal case, can use apply_theorem return ProofTermDeriv("apply_theorem", thy, th_name, pts) else: pt = ProofTerm.theorem(thy, th_name) if tyinst is None: tyinst = dict() if inst is None: inst = dict() if concl is not None: matcher.first_order_match_incr(pt.concl, concl, (tyinst, inst)) pt = ProofTermDeriv("apply_theorem_for", thy, (th_name, tyinst, inst), pts) if pt.prop.beta_norm() == pt.prop: return pt else: return ProofTermDeriv("beta_norm", thy, None, [pt])
def eval(self, thy, args, prevs): 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 assert len(prevs) <= len( As), "apply_theorem_macro: too many prevs." for idx, prev_th in enumerate(prevs): matcher.first_order_match_incr(As[idx], prev_th.prop, (tyinst, inst)) As, C = logic.subst_norm(th.prop, (tyinst, inst)).strip_implies() new_prop = Term.mk_implies(*(As[len(prevs):] + [C])) prev_hyps = sum([prev.hyps for prev in prevs], ()) return Thm(th.hyps + prev_hyps, new_prop)
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 search(self, state, id, prevs): goal_th = state.get_proof_item(id).th prev_ths = [state.get_proof_item(prev).th for prev in prevs] thy = state.thy results = [] for name, th in thy.get_data("theorems").items(): if 'hint_backward' not in thy.get_attributes(name): continue instsp = (dict(), dict()) As, C = th.assums, th.concl # Only process those theorems where C and the matched As # contain all of the variables. if set(term.get_vars(As[:len(prevs)] + [C])) != set( term.get_vars(As + [C])): continue # When there is no assumptions to match, only process those # theorems where C contains at least a constant (skip falseE, # induction theorems, etc). if len(prevs) == 0 and term.get_consts(C) == []: continue try: if matcher.is_pattern(C, []): matcher.first_order_match_incr(C, goal_th.prop, instsp) for pat, prev in zip(As, prev_ths): matcher.first_order_match_incr(pat, prev.prop, instsp) else: for pat, prev in zip(As, prev_ths): matcher.first_order_match_incr(pat, prev.prop, instsp) matcher.first_order_match_incr(C, goal_th.prop, instsp) except matcher.MatchException: continue # All matches succeed t = logic.subst_norm(th.prop, instsp) As, C = t.strip_implies() results.append({"theorem": name, "_goal": As[len(prevs):]}) return sorted(results, key=lambda d: d['theorem'])
def get_proof_term(self, thy, goal, *, args=None, prevs=None): if isinstance(args, tuple): th_name, instsp = args else: th_name = args instsp = None assert isinstance(th_name, str), "rule: theorem name must be a string" if prevs is None: prevs = [] th = thy.get_theorem(th_name) As, C = th.assums, th.concl if instsp is None: instsp = (dict(), dict()) if matcher.is_pattern(C, []): matcher.first_order_match_incr(C, goal.prop, instsp) for pat, prev in zip(As, prevs): matcher.first_order_match_incr(pat, prev.prop, instsp) else: for pat, prev in zip(As, prevs): matcher.first_order_match_incr(pat, prev.prop, instsp) matcher.first_order_match_incr(C, goal.prop, instsp) As, _ = logic.subst_norm(th.prop, instsp).strip_implies() pts = prevs + [ ProofTerm.sorry(Thm(goal.hyps, A)) for A in As[len(prevs):] ] if set(term.get_vars(th.assums)) != set(term.get_vars(th.prop)) or \ not matcher.is_pattern_list(th.assums, []): tyinst, inst = instsp return apply_theorem(thy, th_name, *pts, tyinst=tyinst, inst=inst) else: return apply_theorem(thy, th_name, *pts)