Example #1
0
    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'])
Example #2
0
    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
Example #3
0
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])
Example #4
0
    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)
Example #5
0
    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
Example #6
0
    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'])
Example #7
0
    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)