def sorted_items(cls, items, reorder=True, assumptions=USE_DEFAULTS): ''' Return the given items in sorted order with respect to this TransitivityRelation class (cls) under the given assumptions using known transitive relations. If reorder is False, raise a TransitivityException if the items are not in sorted order as provided. Weak relations (e.g., <=) are only considered when calling this method on a weak relation class (otherwise, only equality and strong relations are used in the sorting). ''' from proveit.number import isLiteralInt assumptions = defaults.checkedAssumptions(assumptions) if all(isLiteralInt(item) for item in items): # All the items are integers. Use efficient n log(n) sorting to # get them in the proper order and then use fixedTransitivitySort # to efficiently prove this order. items = sorted(items, key=lambda item: item.asInt()) reorder = False if reorder: sorter = TransitivitySorter(cls, items, assumptions=assumptions) return list(sorter) else: return cls._fixedTransitivitySort(items, assumptions=assumptions).operands
def conclude(self, assumptions=USE_DEFAULTS): ''' Attempt to conclude that the element is in the exponentiated set. ''' from proveit.logic import InSet from proveit.logic.set_theory.membership._theorems_ import exp_set_0, exp_set_1, exp_set_2, exp_set_3, exp_set_4, exp_set_5, exp_set_6, exp_set_7, exp_set_8, exp_set_9 from proveit.number import zero, isLiteralInt, DIGITS element = self.element domain = self.domain elem_in_set = InSet(element, domain) if not isinstance(element, ExprList): raise ProofFailure( elem_in_set, assumptions, "Can only automatically deduce membership in exponentiated sets for an element that is a list" ) exponent_eval = domain.exponent.evaluation(assumptions=assumptions) exponent = exponent_eval.rhs base = domain.base #print(exponent, base, exponent.asInt(),element, domain, len(element)) if isLiteralInt(exponent): if exponent == zero: return exp_set_0.specialize({ x: element, S: base }, assumptions=assumptions) if len(element) != exponent.asInt(): raise ProofFailure( elem_in_set, assumptions, "Element not a member of the exponentiated set; incorrect list length" ) elif exponent in DIGITS: # thm = forall_S forall_{a, b... in S} (a, b, ...) in S^n thm = locals()['exp_set_%d' % exponent.asInt()] expr_map = {S: base} # S is the base # map a, b, ... to the elements of element. expr_map.update({ proveit._common_.__getattr__(chr(ord('a') + k)): elem_k for k, elem_k in enumerate(element) }) elem_in_set = thm.specialize(expr_map, assumptions=assumptions) else: raise ProofFailure( elem_in_set, assumptions, "Automatic deduction of membership in exponentiated sets is not supported beyond an exponent of 9" ) else: raise ProofFailure( elem_in_set, assumptions, "Automatic deduction of membership in exponentiated sets is only supported for an exponent that is a literal integer" ) if exponent_eval.lhs != exponent_eval.rhs: # after proving that the element is in the set taken to the evaluation of the exponent, # substitute back in the original exponent. return exponent_eval.subLeftSideInto(elem_in_set, assumptions=assumptions) return elem_in_set
def __init__(self, operandA, operandB): r''' Sub one number from another ''' from proveit.number import Add, isLiteralInt, num Operation.__init__(self, Subtract._operator_, (operandA, operandB)) if all(isLiteralInt(operand) for operand in self.operands): # With literal integer operands, we can import useful theorems for evaluation. # From c - b, make the a+b which equals c. This will import the theorems we need. Add(num(self.operands[0].asInt() - self.operands[1].asInt()), self.operands[1])
def substituted(self, exprMap, relabelMap=None, reservedVars=None, assumptions=USE_DEFAULTS, requirements=None): ''' Returns this expression with the substitutions made according to exprMap and/or relabeled according to relabelMap. If the indexed variable has been replaced with a Composite (ExprList or ExprTensor), this should return the indexed element. Only a Variable should be indexed via a Indexed expression; once the Variable is replaced with a Composite, the indexing should be actualized. ''' from composite import Composite, _simplifiedCoord from proveit.number import num, Subtract, isLiteralInt from expr_list import ExprList from expr_tensor import ExprTensor new_requirements = [] subbed_var = self.var.substituted( exprMap, relabelMap, reservedVars) # requirements not needed for variable substitution subbed_indices = self.indices.substituted( exprMap, relabelMap, reservedVars, assumptions=assumptions, requirements=new_requirements) result = None if isinstance(subbed_var, Composite): # The indexed expression is a composite. # Now see if the indices can be simplified to integers; if so, # we can attempt to extract the specific element. # If there is an IndexingError (i.e., we cannot get the element # because the Composite has an unexpanding Iter), # default to returning the subbed Indexed. indices = subbed_indices if isinstance(subbed_var, ExprTensor) and self.base != 0: # subtract off the base if it is not zero indices = [ Subtract(index, num(self.base)) for index in indices ] indices = [ _simplifiedCoord(index, assumptions, new_requirements) for index in indices ] if isinstance(subbed_var, ExprList): if isLiteralInt(indices[0]): result = subbed_var[indices[0].asInt() - self.base] else: raise IndexedError( "Indices must evaluate to literal integers when substituting an Indexed expression, got " + str(indices[0])) elif isinstance(subbed_var, ExprTensor): result = subbed_var.getElem(indices, assumptions=assumptions, requirements=new_requirements) for requirement in new_requirements: requirement._restrictionChecked( reservedVars ) # make sure requirements don't use reserved variable in a nested scope if requirements is not None: requirements += new_requirements # append new requirements # If the subbed_var has not been replaced with a Composite, # just return the Indexed operation with the substitutions made. if result is not None: return result else: return Indexed(subbed_var, subbed_indices, base=self.base)