def raise_contradiction(self, i, comp, coeff, j): """ Called when the given information contradicts something already known. """ msg = 'Contradiction: {0!s}\n'.format( terms.TermComparison(terms.IVar(i), comp, coeff * terms.IVar(j))) msg += ' := {0!s}'.format( terms.TermComparison(self.terms[i], comp, coeff * self.terms[j])) raise terms.Contradiction(msg)
def announce_zero_comparison(self, i, comp): """ Reports a successful assertion to the user. """ if messages.visible(messages.ASSERTION): messages.announce_strong('Asserting {0!s}'.format( terms.TermComparison(terms.IVar(i), comp, terms.zero))) if messages.visible(messages.ASSERTION_FULL): messages.announce_strong(' := {0!s}'.format( terms.TermComparison(self.terms[i], comp, terms.zero)))
def negate(self): """ Pushes the negation through self.formula to remove the not. """ if isinstance(self.formula, terms.TermComparison): return terms.TermComparison(self.formula.term1, terms.comp_negate(self.formula.comp), self.formula.term2) elif isinstance(self.formula, And): return Or(*[Not(a) for a in self.formula.conjuncts]) elif isinstance(self.formula, Or): return And(*[Not(a) for a in self.formula.disjuncts]) elif isinstance(self.formula, Not): return self.formula.formula elif isinstance(self.formula, Implies): return And(self.formula.hyp, Not(self.formula.con)) elif isinstance(self.formula, Univ): return Exist(self.formula.vars, Not(self.formula.formula)) elif isinstance(self.formula, Exist): return Univ(self.formula.vars, Not(self.formula.formula))
def get_additive_information(B): """ Retrieves the relevant information from the blackboard. """ comparisons = B.get_inequalities() + B.get_equalities() for key in B.term_defs: if isinstance(B.term_defs[key], terms.AddTerm): comparisons.append( terms.TermComparison(B.term_defs[key], terms.EQ, terms.IVar(key)) ) return comparisons
def assert_comparison(self, c): """ Take an instance of terms.TermComparison, and adds the comparison to the blackboard. If the comparison terms are not both IVars, finds or creates indices for the terms. """ c = c.canonize() # c is now of the form "term comp sterm" term1, comp, coeff, term2 = c.term1, c.comp, c.term2.coeff, c.term2.term if coeff == 0: term2 = terms.IVar(0) if not isinstance(term1, terms.IVar) or not isinstance( term2, terms.IVar): ivar1 = term1 if isinstance(term1, terms.IVar) else self.term_name(term1) ivar2 = term2 if isinstance(term2, terms.IVar) else self.term_name(term2) c = terms.TermComparison(ivar1, comp, coeff * ivar2).canonize() term1, comp, coeff, term2 = c.term1, c.comp, c.term2.coeff, c.term2.term if coeff == 0: term2 = terms.IVar(0) if self.implies(term1.index, comp, coeff, term2.index): return elif self.implies(term1.index, terms.comp_negate(comp), coeff, term2.index): self.raise_contradiction(term1.index, comp, coeff, term2.index) if comp in (terms.GE, terms.GT, terms.LE, terms.LT): if coeff == 0: self.assert_zero_inequality(term1.index, comp) else: self.assert_inequality(term1.index, comp, coeff, term2.index) elif comp == terms.EQ: if coeff == 0: self.assert_zero_equality(term1.index) else: self.assert_equality(term1.index, coeff, term2.index) elif comp == terms.NE: if coeff == 0: self.assert_zero_disequality(term1.index) else: self.assert_disequality(term1.index, coeff, term2.index) else: raise Error('Unrecognized comparison: {0!s}'.format())
def prove(self, claim): """ Tries to establish the truth of TermComparison claim from what is already known. Returns true if claim follows from the current blackboard, false otherwise. Argument: -- claim: a TermComparison, ie 3*x > 2*y**2 """ if self.contradiction: return True a = terms.TermComparison(claim.term1, terms.comp_negate(claim.comp), claim.term2) try: B = run_util.copy_and_add(self.B, a) except terms.Contradiction as e: messages.announce(e.msg + '\n', messages.ASSERTION) self.contradiction = True return True else: return run_util.run_modules(B, self.modules, self.split_depth, self.split_breadth)
def get_multiplicative_information(B): """ Retrieves the relevant information from the blackboard. Filters to only comparisons and equations where sign information is known, and converts to absolute value form. Note: in the returned comparisons, t_j represents |t_j| """ comparisons = [] for c in (c for c in B.get_inequalities() + B.get_equalities() if c.term2.coeff != 0): ind1 = c.term1.index ind2 = c.term2.term.index if B.sign(ind1) != 0 and B.sign(ind2) != 0: comparisons.append(make_term_comparison_abs(c, B)) for key in B.term_defs: if (isinstance(B.term_defs[key], terms.MulTerm) and B.sign(key) != 0 and all(B.sign(p.term.index) != 0 for p in B.term_defs[key].args)): lhs, rhs = reduce_mul_term(B.term_defs[key]), terms.IVar(key) comparisons.append( terms.TermComparison(lhs, terms.EQ, rhs) ) return comparisons
def process_tc(tc): return terms.TermComparison(replace_vars(tc.term1), tc.comp, replace_vars(tc.term2))