def testIsPattern(self): test_data = [ (Var('a', Ta), True), (Var('f', TFun(Ta, Tb))(Var('a', Ta)), False), (Const('f', TFun(Ta, Tb))(Var('a', Ta)), True), ] for t, res in test_data: self.assertEqual(matcher.is_pattern(t, []), res)
def get_proof_term(self, goal, *, args=None, prevs=None): if isinstance(args, tuple): th_name, inst = args else: th_name, inst = args, None assert isinstance(th_name, str), "rule: theorem name must be a string" if prevs is None: prevs = [] th = theory.get_theorem(th_name) As, C = th.assums, th.concl # Length of prevs is at most length of As assert len(prevs) <= len(As), "rule: too many previous facts" if inst is None: inst = Inst() # Match the conclusion and assumptions. Either the conclusion # or the list of assumptions must be a first-order pattern. if matcher.is_pattern(C, []): inst = matcher.first_order_match(C, goal.prop, inst) for pat, prev in zip(As, prevs): inst = matcher.first_order_match(pat, prev.prop, inst) else: for pat, prev in zip(As, prevs): inst = matcher.first_order_match(pat, prev.prop, inst) inst = matcher.first_order_match(C, goal.prop, inst) # Check that every variable in the theorem has an instantiation. unmatched_vars = [ v.name for v in term.get_svars(As + [C]) if v.name not in inst ] if unmatched_vars: raise theory.ParameterQueryException( list("param_" + name for name in unmatched_vars)) # Substitute and normalize As, _ = th.prop.subst_norm(inst).strip_implies() goal_Alen = len(goal.assums) if goal_Alen > 0: As = As[:-goal_Alen] pts = prevs + [ ProofTerm.sorry(Thm(goal.hyps, A)) for A in As[len(prevs):] ] # Determine whether it is necessary to provide instantiation # to apply_theorem. if set(term.get_svars(th.assums)) != set(th.prop.get_svars()) or \ set(term.get_stvars(th.assums)) != set(th.prop.get_stvars()) or \ not matcher.is_pattern_list(th.assums, []): return apply_theorem(th_name, *pts, inst=inst) else: return apply_theorem(th_name, *pts)
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 testIsPattern(self): test_data = [ ("?a", True), ("?f ?a", False), ("?m + ?n", True), ("%x. ?P x", True), ("?P (THE x. ?P x)", False), ("(!x. ?P x) & ?P x", True), ("?P x & (!x. ?P x)", True), ("?P ?x & ?x > 0", True), ("?P (?x + 1)", False), ("∀x. ∀s. ?Q s ⟶ ¬x ∈ s ⟶ finite s ⟶ ?Q (insert x s)", True), ] context.set_context('set', svars={ "f": "'a => 'b", "a": "'a", "m": "nat", "n": "nat", "P": "nat => bool", "Q": "nat set => bool", "x": "nat", "s": "nat set"}) for t, res in test_data: t = parser.parse_term(t) self.assertEqual(matcher.is_pattern(t, []), res)
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)