示例#1
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()))
示例#2
0
def imp_disj_iff(goal):
    """Goal is of the form A_1 | ... | A_m <--> B_1 | ... | B_n, where
    the sets {A_1, ..., A_m} and {B_1, ..., B_n} are equal."""
    pt1 = ProofTerm('imp_disj', Implies(goal.lhs, goal.rhs))
    pt2 = ProofTerm('imp_disj', Implies(goal.rhs, goal.lhs))
    return ProofTerm.equal_intr(pt1, pt2)