Beispiel #1
0
    def get_proof_term(self, goal, *, args=None, prevs=None):
        assert isinstance(prevs,
                          list) and len(prevs) == 1, "rewrite_goal_with_prev"
        pt = prevs[0]
        C = goal.prop

        # In general, we assume pt.th has forall quantification.
        # First, obtain the patterns
        new_names = logic.get_forall_names(pt.prop)
        new_vars, prev_As, prev_C = logic.strip_all_implies(pt.prop, new_names)

        # Fact used must be an equality
        assert len(
            prev_As) == 0 and prev_C.is_equals(), "rewrite_goal_with_prev"

        for new_var in new_vars:
            pt = pt.forall_elim(new_var)

        # Check whether rewriting using the theorem has an effect
        assert has_rewrite(pt.th, C), "rewrite_goal_with_prev"

        cv = then_conv(top_sweep_conv(rewr_conv(pt)), beta_norm_conv())
        eq_th = cv.eval(C)
        new_goal = eq_th.prop.rhs

        prevs = list(prevs)
        if not new_goal.is_reflexive():
            prevs.append(ProofTerm.sorry(Thm(goal.hyps, new_goal)))
        return ProofTerm('rewrite_goal_with_prev', args=C, prevs=prevs)
Beispiel #2
0
    def direct_contr_pt(self, lower, upper):
        """When lower and upper's comparisons don't contain constant, we need to treat them carefully.
        """
        def norm_pt(pt):
            """If comparison in pt's prop does not contain constant, add a zero on the tail."""
            tm = factoid_to_term(self.vars,
                                 term_to_factoid(self.vars, pt.prop))
            pt1 = integer.omega_form_conv().get_proof_term(tm).symmetric()
            return pt.on_prop(conv.top_sweep_conv(conv.rewr_conv(pt1)))

        if lower.prop.arg.is_times():
            lower = norm_pt(lower)
        if upper.prop.arg.is_times():
            upper = norm_pt(upper)
        pos, neg = lower.prop.arg.arg1, upper.prop.arg.arg1
        pt_eq = integer.omega_simp_full_conv().get_proof_term(neg).\
            transitive(integer.omega_simp_full_conv().get_proof_term(term.Int(-1) * pos).symmetric())
        pt1 = lower
        pt2 = upper.on_prop(conv.top_sweep_conv(conv.rewr_conv(pt_eq)))
        lower_bound, upper_bound = -term.Int(
            integer.int_eval(lower.prop.arg.arg)), term.Int(
                integer.int_eval(upper.prop.arg.arg))
        pt3 = proofterm.ProofTerm(
            'int_const_ineq',
            term.greater(term.IntType)(lower_bound, upper_bound))
        return logic.apply_theorem('int_comp_contr', pt1, pt2, pt3)
Beispiel #3
0
    def get_proof_term(self, args, pts):
        assert isinstance(args, Term), "rewrite_goal_macro: signature"

        goal = args
        eq_pt = pts[0]

        new_names = get_forall_names(eq_pt.prop)
        new_vars, _, _ = strip_all_implies(eq_pt.prop, new_names)

        for new_var in new_vars:
            eq_pt = eq_pt.forall_elim(new_var)

        pts = pts[1:]

        cv = then_conv(top_sweep_conv(rewr_conv(eq_pt, sym=self.sym)),
                       beta_norm_conv())
        pt = cv.get_proof_term(goal)  # goal = th.prop
        pt = pt.symmetric()           # th.prop = goal
        if pt.prop.lhs.is_reflexive():
            pt = pt.equal_elim(refl(pt.prop.lhs.rhs))
        else:
            pt = pt.equal_elim(pts[0])
            pts = pts[1:]

        for A in pts:
            pt = pt.implies_intr(A.prop).implies_elim(A)
        return pt
Beispiel #4
0
    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)
Beispiel #5
0
    def get_proof_term(self, goal, *, args=None, prevs=None):
        th_name = args
        C = goal.prop

        # Check whether rewriting using the theorem has an effect
        assert has_rewrite(th_name, C, sym=self.sym, conds=prevs), \
            "rewrite: unable to apply theorem."

        cv = then_conv(
            top_sweep_conv(rewr_conv(th_name, sym=self.sym, conds=prevs)),
            beta_norm_conv())
        eq_th = cv.eval(C)
        new_goal = eq_th.prop.rhs

        if self.sym:
            macro_name = 'rewrite_goal_sym'
        else:
            macro_name = 'rewrite_goal'
        if new_goal.is_equals() and new_goal.lhs == new_goal.rhs:
            return ProofTerm(macro_name, args=(th_name, C), prevs=prevs)
        else:
            new_goal = ProofTerm.sorry(Thm(goal.hyps, new_goal))
            assert new_goal.prop != goal.prop, "rewrite: unable to apply theorem"
            return ProofTerm(macro_name,
                             args=(th_name, C),
                             prevs=[new_goal] + prevs)
Beispiel #6
0
    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)
Beispiel #7
0
    def testTopSweepConv(self):
        f = Const("f", TFun(natT, natT))
        x = Var("x", natT)

        th0 = eq(x, f(x))
        cv = top_sweep_conv(rewr_conv(ProofTerm.atom(0, th0),
                                      match_vars=False))

        prf = Proof()
        prf.add_item(0, "sorry", th=th0)
        cv.get_proof_term(thy, f(x)).export(prf=prf)
        self.assertEqual(thy.check_proof(prf), eq(f(x), f(f(x))))
Beispiel #8
0
    def search(self, state, id, prevs):
        if len(prevs) != 2:
            return []

        eq_th, prev_th = [state.get_proof_item(prev).th for prev in prevs]
        if not eq_th.prop.is_equals():
            return []

        cv = top_sweep_conv(
            rewr_conv(ProofTermAtom(prevs[0], eq_th), match_vars=False))
        th = cv.eval(state.thy, prev_th.prop)
        new_fact = th.prop.rhs
        if prev_th.prop != new_fact:
            return [{}]
        else:
            return []
Beispiel #9
0
    def search(self, state, id, prevs):
        if len(prevs) != 1:
            return []

        prev_th = state.get_proof_item(prevs[0]).th
        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_sweep_conv(rewr_conv(th_name))
            th = cv.eval(thy, prev_th.prop)
            new_fact = th.prop.rhs
            if prev_th.prop != new_fact:
                results.append({"theorem": th_name, "_fact": [new_fact]})

        return sorted(results, key=lambda d: d['theorem'])
Beispiel #10
0
    def get_proof_term(self, args, pts):
        assert isinstance(args, str), "rewrite_fact_macro: signature"

        th_name = args
        eq_pt = ProofTerm.theorem(th_name)

        assert len(pts) == len(eq_pt.assums) + 1, "rewrite_fact_macro: signature"

        # Check rewriting using the theorem has an effect
        if not has_rewrite(th_name, pts[0].prop, sym=self.sym, conds=pts[1:]):
            raise InvalidDerivationException("rewrite_fact using %s" % th_name)

        cv = then_conv(top_sweep_conv(rewr_conv(eq_pt, sym=self.sym, conds=pts[1:])),
                       beta_norm_conv())
        res = pts[0].on_prop(cv)
        if res == pts[0]:
            raise InvalidDerivationException("rewrite_fact using %s" % th_name)
        return res
Beispiel #11
0
    def gcd_pt(self, vars, pt):
        fact = term_to_factoid(vars, pt.prop)
        g = functools.reduce(gcd, fact[:-1])
        assert g > 1
        pt1 = proofterm.ProofTerm('int_const_ineq', term.Int(g) > term.Int(0))
        pt2 = pt
        elim_gcd_fact = [floor(i / g) for i in fact]
        if int(fact[-1] / g) != fact[-1] / g:
            elim_gcd_no_constant = sum(
                [c * v for c, v in zip(elim_gcd_fact[1:-1], vars[1:])],
                elim_gcd_fact[0] * vars[0])
            original_no_constant = sum(
                [c * v for c, v in zip(fact[1:-1], vars[1:])],
                fact[0] * vars[0])

            elim_gcd_no_constant = integer.int_norm_conv().get_proof_term(
                elim_gcd_no_constant).rhs
            original_no_constant = integer.int_norm_conv().get_proof_term(
                original_no_constant).rhs

            pt3 = integer.int_norm_conv().get_proof_term(
                g * elim_gcd_no_constant).transitive(
                    integer.int_norm_conv().get_proof_term(
                        original_no_constant).symmetric())
            n = floor(-fact[-1] / g)
            pt4 = proofterm.ProofTerm('int_const_ineq',
                                      term.Int(g) * term.Int(n) + fact[-1] < 0)
            pt5 = proofterm.ProofTerm(
                'int_const_ineq',
                term.Int(g) * (term.Int(n) + term.Int(1)) + fact[-1] > 0)
            pt6 = integer.int_eval_conv().get_proof_term(-(term.Int(n) +
                                                           term.Int(1)))
            return logic.apply_theorem(
                'int_gcd', pt1, pt2, pt3, pt4,
                pt5).on_prop(conv.top_sweep_conv(conv.rewr_conv(pt6)),
                             conv.arg_conv(integer.omega_simp_full_conv()))
        else:
            elim_gcd_term = factoid_to_term(vars, elim_gcd_fact)
            pt3 = integer.omega_simp_full_conv().get_proof_term(pt.prop.arg).transitive(\
                    integer.omega_simp_full_conv().get_proof_term(term.Int(g) * elim_gcd_term.arg).symmetric())
            return logic.apply_theorem('int_gcd_1', pt1, pt2, pt3)
Beispiel #12
0
    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
Beispiel #13
0
    def get_proof_term(self, args, pts):
        assert isinstance(args, tuple) and len(args) == 2 and \
               isinstance(args[0], str) and isinstance(args[1], Term), "rewrite_goal: signature"

        name, goal = args
        eq_pt = ProofTerm.theorem(name)

        if len(pts) == len(eq_pt.assums):
            rewr_cv = rewr_conv(eq_pt, sym=self.sym, conds=pts)
        else:
            assert len(pts) == len(eq_pt.assums) + 1, "rewrite_goal: wrong number of prevs"
            rewr_cv = rewr_conv(eq_pt, sym=self.sym, conds=pts[1:])

        cv = then_conv(top_sweep_conv(rewr_cv), beta_norm_conv())
        pt = cv.get_proof_term(goal)  # goal = th.prop
        pt = pt.symmetric()           # th.prop = goal
        if pt.prop.lhs.is_equals() and pt.prop.lhs.lhs == pt.prop.lhs.rhs:
            pt = pt.equal_elim(refl(pt.prop.lhs.lhs))
        else:
            pt = pt.equal_elim(pts[0])  # goal

        return pt
Beispiel #14
0
    def get_proof_term(self, args, pts):
        assert len(pts) == 2, "rewrite_fact_with_prev"

        eq_pt, pt = pts

        # In general, we assume eq_pt has forall quantification
        # First, obtain the patterns
        new_names = get_forall_names(eq_pt.prop)
        new_vars, eq_As, eq_C = strip_all_implies(eq_pt.prop, new_names)

        # First fact must be an equality
        assert len(eq_As) == 0 and eq_C.is_equals(), "rewrite_fact_with_prev"

        for new_var in new_vars:
            eq_pt = eq_pt.forall_elim(new_var)

        # Check rewriting using eq_pt has an effect
        cv1 = top_sweep_conv(rewr_conv(eq_pt))
        assert not cv1.eval(pt.prop).is_reflexive(), "rewrite_fact_with_prev"

        cv = then_conv(cv1, beta_norm_conv())
        return pt.on_prop(cv)
Beispiel #15
0
    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 []
Beispiel #16
0
 def get_proof_term(self, thy, args, pts):
     eq_pt, pt = pts
     cv = then_conv(top_sweep_conv(rewr_conv(eq_pt, match_vars=False)),
                    top_conv(beta_conv()))
     return pt.on_prop(thy, cv)
Beispiel #17
0
 def norm_pt(pt):
     """If comparison in pt's prop does not contain constant, add a zero on the tail."""
     tm = factoid_to_term(self.vars,
                          term_to_factoid(self.vars, pt.prop))
     pt1 = integer.omega_form_conv().get_proof_term(tm).symmetric()
     return pt.on_prop(conv.top_sweep_conv(conv.rewr_conv(pt1)))
Beispiel #18
0
    def get_proof_term(self, t):

        if not t.is_conj():
            return refl(t)

        d_pos = dict()
        d_neg = dict()
        qu = deque([ProofTerm.assume(t)])
        # collect each conjunct's proof term in conjuntion
        while qu:
            pt = qu.popleft()
            if pt.prop.is_conj():
                conj1, conj2 = pt.prop.arg1, pt.prop.arg
                pt_conj1, pt_conj2 = apply_theorem('conjD1',
                                                   pt), apply_theorem(
                                                       'conjD2', pt)
                if conj1 == false:
                    th = ProofTerm.theorem("falseE")
                    inst = matcher.first_order_match(th.prop.arg, t)
                    pt_false_implies_conj = th.substitution(inst)
                    return ProofTerm.equal_intr(pt_conj1.implies_intr(t),
                                                pt_false_implies_conj)
                elif conj2 == false:
                    th = ProofTerm.theorem("falseE")
                    inst = matcher.first_order_match(th.prop.arg, t)
                    pt_false_implies_conj = th.substitution(inst)
                    return ProofTerm.equal_intr(pt_conj2.implies_intr(t),
                                                pt_false_implies_conj)
                if conj1.is_conj():
                    qu.appendleft(pt_conj1)
                else:
                    if conj1.is_not():
                        d_neg[conj1] = pt_conj1
                    else:
                        d_pos[conj1] = pt_conj1
                if conj2.is_conj():
                    qu.appendleft(pt_conj2)
                else:
                    if conj2.is_not():
                        d_neg[conj2] = pt_conj2
                    else:
                        d_pos[conj2] = pt_conj2
            else:
                if pt.prop.is_not():
                    d_neg[pt.prop] = pt
                else:
                    d_pos[pt.prop] = pt

        # first check if there are opposite terms in conjunctions, if there exists, return a false proof term
        for key in d_pos:
            if Not(key) in d_neg:
                pos_pt, neg_pt = d_pos[key], d_neg[Not(key)]
                pt_conj_pos_neg = apply_theorem("conjI", pos_pt, neg_pt)
                pt_conj_implies_false = pt_conj_pos_neg.on_prop(
                    rewr_conv("conj_pos_neg")).implies_intr(t)
                th = ProofTerm.theorem("falseE")
                inst = matcher.first_order_match(th.prop.arg, t)
                pt_false_implies_conj = th.substitution(inst)
                return ProofTerm.equal_intr(pt_conj_implies_false,
                                            pt_false_implies_conj)

        d_pos.update(d_neg)
        d = d_pos

        def right_assoc(ts):
            l = len(ts)
            if l == 1:
                return d[ts[0]]
            elif l == 2:
                return apply_theorem('conjI', d[ts[0]], d[ts[1]])
            else:
                return apply_theorem('conjI', d[ts[0]], right_assoc(ts[1:]))

        # pt_right = functools.reduce(lambda x, y: apply_theorem('conjI', x, d[y]), sorted(d.keys()), d[sorted(d.keys())[0]])
        if true not in d:
            sorted_keys = term_ord.sorted_terms(d.keys())
        else:
            d_keys_without_true = term_ord.sorted_terms(
                [k for k in d if k != true])
            sorted_keys = [true] + d_keys_without_true
        sorted_keys_num = len(sorted_keys)
        pt_right = functools.reduce(lambda x, y: apply_theorem('conjI', d[sorted_keys[sorted_keys_num - y - 2]], x), \
                        range(sorted_keys_num - 1), d[sorted_keys[-1]])
        # pt_right = right_assoc(sorted_keys)
        # order implies original
        dd = dict()
        norm_conj = And(*sorted_keys)
        norm_conj_pt = ProofTerm.assume(norm_conj)
        for k in sorted_keys:
            if k != sorted_keys[-1]:
                dd[k] = apply_theorem('conjD1', norm_conj_pt)
                norm_conj_pt = apply_theorem('conjD2', norm_conj_pt)
            else:
                dd[k] = norm_conj_pt

        def traverse(t):
            if not t.is_conj():
                return dd[t]
            else:
                return apply_theorem('conjI', traverse(t.arg1),
                                     traverse(t.arg))

        pt_left = traverse(t)

        pt_final = ProofTerm.equal_intr(pt_right.implies_intr(t),
                                        pt_left.implies_intr(norm_conj))
        if true in d:
            return pt_final.on_rhs(rewr_conv("conj_true_left"),
                                   top_sweep_conv(sort_disj()))
        else:
            return pt_final.on_rhs(top_sweep_conv(sort_disj()))