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()))
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)