def formatted(self, formatType, **kwargs): # begin building the inner_str inner_str = self.base.formatted(formatType, fence=True, forceFence=True) if self.getStyle('exponent') == 'raised': inner_str = ( inner_str + r'^{'+self.exponent.formatted(formatType, fence=False) + '}') elif self.getStyle('exponent') == 'radical': if self.exponent == frac(one, two): if formatType == 'string': inner_str = ( r'sqrt(' + self.base.formatted(formatType, fence=True, forceFence=True) + ')') elif formatType == 'latex': inner_str = ( r'\sqrt{' + self.base.formatted(formatType, fence=True, forceFence=True) + '}') else: raise ValueError("Unkown radical type, exponentiating to the power " "of %s"%str(self.exponent)) # only fence if forceFence=True (nested exponents is an # example of when fencing must be forced) kwargs['fence'] = ( kwargs['forceFence'] if 'forceFence' in kwargs else False) return maybeFencedString(inner_str, **kwargs)
def remakeConstructor(self): if self.getStyle('exponent') == 'radical': # Use a different constructor if using the 'radical' style. if self.exponent == frac(one, two): return 'sqrt' else: raise ValueError("Unkown radical type, exponentiating to the power " "of %s"%str(self.exponent)) return Operation.remakeConstructor(self)
def sqrt(base): ''' Special function for square root version of an exponential. Formatting depends on the argument supplied to the withStyles() method called on the Expression superclass, which then sets things up so the Exp latex() method will display the expression using a traditional square root radical. If you want a square root to be displayed more literally as a base to the 1/2 power, use Exp(_, frac(1/2)) directly. Could later generalize this to cube roots or general nth roots. ''' return Exp(base, frac(one, two)).withStyles(exponent='radical')
def distribution(self, idx=None, assumptions=USE_DEFAULTS): r''' Distribute through the operand at the given index. Returns the equality that equates self to this new version. Examples: :math:`a (b + c + a) d = a b d + a c d + a a d` :math:`a (b - c) d = a b d - a c d` :math:`a \left(\sum_x f(x)\right c = \sum_x a f(x) c` Give any assumptions necessary to prove that the operands are in Complexes so that the associative and commutation theorems are applicable. ''' from ._theorems_ import distributeThroughSum, distributeThroughSubtract, distributeThroughSummation from proveit.number.division._theorems_ import fracInProd, prodOfFracs from proveit.number import frac, Div, Add, subtract, Sum if idx is None and len(self.factors) == 2 and all(isinstance(factor, Div) for factor in self.factors): return prodOfFracs.specialize({x:self.factors[0].numerator, y:self.factors[1].numerator, z:self.factors[0].denominator, w:self.factors[1].denominator}, assumptions=assumptions) operand = self.operands[idx] if isinstance(operand, Add): return distributeThroughSum.specialize({xMulti:self.operands[:idx], yMulti:self.operands[idx].operands, zMulti:self.operands[idx+1:]}, assumptions=assumptions) elif isinstance(operand, subtract): return distributeThroughSubtract.specialize({wMulti:self.operands[:idx], x:self.operands[idx].operands[0], y:self.operands[idx].operands[1], zMulti:self.operands[idx+1:]}, assumptions=assumptions) elif isinstance(operand, Div): eqn = fracInProd.specialize({wMulti:self.operands[:idx], x:self.operands[idx].operands[0], y:self.operands[idx].operands[1], zMulti:self.operands[idx+1:]}, assumptions=assumptions) try: # see if the numerator can simplify (e.g., with a one factor) numerSimplification = eqn.rhs.numerator.simplification(assumptions=assumptions) dummyVar = eqn.safeDummyVar() return numerSimplification.subRightSideInto(Equals(eqn.lhs, frac(dummyVar, eqn.rhs.denominator)), dummyVar) except: return eqn elif isinstance(operand, Sum): yMultiSub = operand.indices Pop, Pop_sub = Operation(P, operand.indices), operand.summand S_sub = operand.domain xDummy, zDummy = self.safeDummyVars(2) spec1 = distributeThroughSummation.specialize({Pop:Pop_sub, S:S_sub, yMulti:yMultiSub, xMulti:Etcetera(MultiVariable(xDummy)), zMulti:Etcetera(MultiVariable(zDummy))}, assumptions=assumptions) return spec1.deriveConclusion().specialize({Etcetera(MultiVariable(xDummy)):self.operands[:idx], \ Etcetera(MultiVariable(zDummy)):self.operands[idx+1:]}, assumptions=assumptions) else: raise Exception("Unsupported operand type to distribute over: " + str(operand.__class__))
diffInExp = Forall([a, b, c], Equals(Exp(a, Sub(b, c)), Mult(Exp(a, b), Exp(a, Neg(c)))), domain=Complexes, conditions=[NotEquals(a, zero)]) diffInExp diffInExpRev = Forall([a, b, c], Equals(Mult(Exp(a, b), Exp(a, Neg(c))), Exp(a, Sub(b, c))), domain=Complexes, conditions=[NotEquals(a, zero)]) diffInExpRev diffFracInExp = Forall([a, b, c, d], Equals(Exp(a, Sub(b, frac(c, d))), Mult(Exp(a, b), Exp(a, frac(Neg(c), d)))), domain=Complexes, conditions=[NotEquals(a, zero), NotEquals(d, zero)]) diffFracInExp diffFracInExpRev = Forall([a, b, c, d], Equals(Mult(Exp(a, b), Exp(a, frac(Neg(c), d))), Exp(a, Sub(b, frac(c, d)))), domain=Complexes, conditions=[NotEquals(a, zero), NotEquals(d, zero)]) diffFracInExpRev # works because log[a^c b^c] = c log a + c log b
def deduceInNumberSet(self, number_set, assumptions=USE_DEFAULTS): ''' Given a number set number_set, attempt to prove that the given expression is in that number set using the appropriate closure theorem. This method uses specialized thms for the sqrt() cases. Created: 2/20/2020 by wdc, based on the same method in the Add class. Last modified: 2/28/2020 by wdc. Added specialization for sqrt() cases created using the sqrt() fxn. Last Modified: 2/20/2020 by wdc. Creation. Once established, these authorship notations can be deleted. ''' from proveit.logic import InSet from proveit.number.exponentiation._theorems_ import ( expComplexClosure, expNatClosure, expRealClosure, expRealClosureExpNonZero,expRealClosureBasePos, expRealPosClosure, sqrtComplexClosure, sqrtRealClosure, sqrtRealPosClosure) from proveit.number import Complexes, NaturalsPos, Reals, RealsPos if number_set == NaturalsPos: return expNatClosure.specialize({a:self.base, b:self.exponent}, assumptions=assumptions) # the following would be useful to replace the next two Reals # closure theorems, once we get the system to deal # effectively with the Or(A, And(B, C)) conditions # if number_set == Reals: # return expRealClosure.specialize( # {a:self.base, b:self.exponent}, # assumptions=assumptions) if number_set == Reals: # Would prefer the more general approach commented-out # above; in the meantime, allowing for 2 possibilities here: # if base is positive real, exp can be any real; # if base is real ≥ 0, exp must be non-zero if self.exponent==frac(one, two): return sqrtRealClosure.specialize( {a:self.base},assumptions=assumptions) else: err_string = '' try: return expRealClosureBasePos.specialize( {a:self.base, b:self.exponent}, assumptions=assumptions) except: err_string = 'Positive base condition failed ' try: return expRealClosureExpNonZero.specialize( {a:self.base, b:self.exponent}, assumptions=assumptions) except: err_string += ( 'and non-zero exponent condition failed. ' 'Need base ≥ 0 and exponent ≠ 0, OR base > 0.') raise Exception(err_string) if number_set == RealsPos: if self.exponent==frac(one, two): return sqrtRealPosClosure.specialize( {a:self.base},assumptions=assumptions) else: return expRealPosClosure.specialize( {a:self.base, b:self.exponent},assumptions=assumptions) if number_set == Complexes: if self.exponent==frac(one, two): return sqrtComplexClosure.specialize( {a:self.base}, assumptions=assumptions) else: return expComplexClosure.specialize( {a:self.base, b:self.exponent}, assumptions=assumptions) msg = "'deduceInNumberSet' not implemented for the %s set"%str(number_set) raise ProofFailure(InSet(self, number_set), assumptions, msg)
# transferred by wdc 3/11/2020 triangleInequality = Forall([a, b], LessThanEquals(Abs(Add(a, b)), Add(Abs(a), Abs(b))), domain=Complexes) triangleInequality # transferred by wdc 3/11/2020 absProd = Forall(xEtc, Equals(Abs(Mult(xEtc)), Mult(Etcetera(Abs(xMulti)))), domain=Complexes) absProd # transferred by wdc 3/11/2020 absFrac = Forall([a, b], Equals(Abs(frac(a, b)), frac(Abs(a), Abs(b))), domain=Complexes) absFrac # transferred by wdc 3/11/2020 modAbsScaled = Forall((a, b, c), Equals(Mult(a, ModAbs(b, c)), ModAbs(Mult(a, b), Mult(a, c))), domain=Reals) modAbsScaled # transferred by wdc 3/11/2020 modAbsSubtractCancel = Forall( (a, b, c), LessThanEquals(ModAbs(Sub(Mod(Add(b, a), c), b), c), Abs(a)), domain=Reals)
Zgate = Gate(Z) Hgate = Gate(H) CTRL_UP = Literal(pkg, 'CTRL_UP') CTRL_DN = Literal(pkg, 'CTRL_DN') CTRL_UPDN = Literal(pkg, 'CTRL_UPDN') WIRE_UP = Literal(pkg, 'WIRE_UP') # wire goes up to link with another wire WIRE_DN = Literal(pkg, 'WIRE_DN') # wire goes down to link with another wire WIRE_LINK = Literal(pkg, 'WIRE_LINK') # link destination for WIRE_UP or WIRE_DN QubitSpace = Exp(Complexes, two) QubitRegisterSpace = lambda n : TensorExp(Exp(Complexes, two), n) RegisterSU = lambda n : SU(Exp(two, n)) invRoot2 = frac(one, sqrt(two)) B1 = Variable('B1') B2 = Variable('B2') B3 = Variable('B3') C1 = Variable('C1') C2 = Variable('C2') C3 = Variable('C3') I = Variable('I') IB = Variable('IB') IC = Variable('IC') # some Variable labels Ablock = Block(A) Bblock = Block(B) B1block = Block(B1)
beginTheorems(locals()) divideRealClosure = Forall([a, b], InSet(Divide(a, b), Reals), domain=Reals, conditions=[NotEquals(b, zero)]) divideRealClosure divideRealPosClosure = Forall([a, b], InSet(Divide(a, b), RealsPos), domain=RealsPos, conditions=[NotEquals(b, zero)]) divideRealPosClosure fractionRealClosure = Forall([a, b], InSet(frac(a, b), Reals), domain=Reals, conditions=[NotEquals(b, zero)]) fractionRealClosure fractionPosClosure = Forall([a, b], InSet(frac(a, b), RealsPos), domain=RealsPos, conditions=[NotEquals(b, zero)]) fractionPosClosure divideComplexClosure = Forall([a, b], InSet(Divide(a, b), Complexes), domain=Complexes, conditions=[NotEquals(b, zero)]) divideComplexClosure