def strip_disj(t): def rec(t): if t.is_disj(): return rec(t.arg1) + rec(t.arg) else: return [t] return term_ord.sorted_terms(rec(t))
def __init__(self, hyps, prop): """Create a theorem with the given list of hypotheses and proposition. """ typecheck.checkinstance('Thm', hyps, [Term], prop, Term) self.hyps = tuple(term_ord.sorted_terms(hyps)) self.prop = prop
def get_vars(t): """Returns list of variables in a term or a list of terms.""" if isinstance(t, Term): return t.get_vars() elif isinstance(t, list): return term_ord.sorted_terms(sum([s.get_vars() for s in t], [])) else: raise TypeError
def get_proof_term(self, t): def strip_conj_all(t): if t.is_conj(): return strip_conj_all(t.arg1) + strip_conj_all(t.arg) else: return [t] conj_terms = term_ord.sorted_terms(strip_conj_all(t)) goal = Eq(t, And(*conj_terms)) return imp_conj_iff(goal)
def logic_subterms(t): """Returns the list of logical subterms for a term t.""" def rec(t): if not is_logical(t): return [t] elif t.is_not(): return rec(t.arg) + [t] else: return rec(t.arg1) + rec(t.arg) + [t] return term_ord.sorted_terms(rec(t))
def get_consts(self): def rec(t): if t.is_const(): return [t] elif t.is_comb(): return rec(t.fun) + rec(t.arg) elif t.is_abs(): return rec(t.body) else: return [] return term_ord.sorted_terms(rec(self))
def __init__(self, ineqs): """ Must guarantee the input inequalities are all integer terms. """ assert isinstance(ineqs, collections.abc.Iterable) and all( is_integer_ineq(t) for t in ineqs) self.ineqs = ineqs # store all the normal form inequlities: 0 <= Σ ai * xi + c self.norm_pts = dict() self.norm_ineqs = list() occr_vars = set() for i in range(len(self.ineqs)): pt = proofterm.ProofTerm.assume(self.ineqs[i]).on_prop( integer.omega_form_conv()) self.norm_pts[self.ineqs[i]] = pt self.norm_ineqs.append(pt.prop) # occr_vars |= set(self.ineqs[i].get_vars()) norm_ineq = pt.prop occr_vars |= set([ t.arg if t.is_times() else t for t in integer.strip_plus(norm_ineq.arg) ]) # store ordered vars self.vars = term_ord.sorted_terms(occr_vars) # convert inequalities to factoids self.factoids = [ term_to_factoid(self.vars, t) for t in self.norm_ineqs ] # mapping from factoids to HOL terms self.fact_hol = { f: factoid_to_term(self.vars, f) for f in self.factoids }
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()))