class DecimalSequence(NumeralSequence): # operator of the WholeDecimal operation. _operator_ = Literal(stringFormat='Decimal', context=__file__) def __init__(self, *digits): NumeralSequence.__init__(self, DecimalSequence._operator_, *digits) if not all(digit in DIGITS for digit in self.digits): raise Exception( 'A DecimalSequence may only be composed of 0-9 digits') def asInt(self): return int(self.formatted('string'))
class CartProd(Operation): ''' A CartProd represents the Cartesian product of sets to produce a new set. ''' _operator_ = Literal(string_format='X', latex_format=r'\times', theory=__file__) def __init__(self, *operands, styles=None): Operation.__init__(self, CartProd._operator_, operands, styles=styles)
class Meas(Function): ''' Class to represent the making of a measurement on a ket |𝜑⟩. ''' # the literal operator of the Meas operation _operator_ = Literal(stringFormat='MEAS', latexFormat=r'\mathcal{M}', context=__file__) def __init__(self, ket): Function.__init__(self, Meas._operator_, ket) self.ket = ket
class Prob(Function): ''' Updated Sun 1/26/2020 by wdc: updating the __init__ and _formatted methods, import statements. deduce_in_interval and deduce_in_real methods untouched. ''' # the literal operator of the Prob operation class _operator_ = Literal('Pr', latex_format=r'\textrm{Pr}', theory=__file__) def __init__(self, event, *, styles=None): Function.__init__(self, Prob._operator_, event, styles=styles) self.event = self.operand
class Disjoint(Function): ''' The Disjoint operation defines a property for a collection of sets. It evaluates to True iff the sets are mutually/pairwise disjoint; that is, the intersection of any two of the sets is the empty set. We define this property to be True when given zero or one set (there are no pairs of sets, so all pairs are vacuously disjoint). ''' _operator_ = Literal('disjoint', r'{\rm disjoint}', context=__file__) def __init__(self, *sets): Function.__init__(self, Disjoint._operator_, sets)
class PowerSet(Function): # operator for the PowerSet function _operator_ = Literal(string_format='power_set', latex_format=r'\mathcal{P}', theory=__file__) def __init__(self, operand, *, styles=None): ''' Power set of a set. ''' Function.__init__(self, PowerSet._operator_, operand, styles=styles) """
class PowerSet(Function): # operator of the Intersect operation _operator_ = Literal(string_format='power_set', latex_format=r'\mathbb{P}', theory=__file__) def __init__(self, operand): ''' Power set of a set. ''' Function.__init__(self, PowerSet._operator_, operand) """
class ModAbs(Operation): # operator of the ModAbs operation. _operator_ = Literal(string_format='ModAbs', theory=__file__) def __init__(self, value, divisor): Operation.__init__(self, ModAbs._operator_, (value, divisor)) self.value = value self.divisor = divisor def string(self, **kwargs): return ('|' + self.value.string(fence=False) + '|_{mod ' + self.divisor.string(fence=False) + '}') def latex(self, **kwargs): return (r'\left|' + self.value.latex(fence=False) + r'\right|_{\textup{mod}\thinspace ' + self.divisor.latex(fence=False) + r'}') def deduce_in_number_set(self, number_set, assumptions=USE_DEFAULTS): ''' Given a number set number_set (such as Integer, Real, etc), attempt to prove that the given ModAbs expression is in that number set using the appropriate closure theorem. ''' from proveit import a, b from proveit.logic import InSet from proveit.numbers.modular import (mod_abs_int_closure, mod_abs_real_closure) from proveit.numbers import Integer, Real # among other things, make sure non-existent assumptions # manifest as empty tuple () rather than None assumptions = defaults.checked_assumptions(assumptions) if number_set == Integer: return mod_abs_int_closure.instantiate( { a: self.value, b: self.divisor }, assumptions=assumptions) if number_set == Real: return mod_abs_real_closure.instantiate( { a: self.value, b: self.divisor }, assumptions=assumptions) msg = ("'ModAbs.deduce_in_number_set()' not implemented for " "the %s set" % str(number_set)) raise ProofFailure(InSet(self, number_set), assumptions, msg)
class Difference(Operation): # operator of the Difference operation _operator_ = Literal(string_format='-', theory=__file__) def __init__(self, A, B): Operation.__init__(self, Difference._operator_, [A, B]) def membership_equivalence(self, element, assumptions=USE_DEFAULTS): ''' Deduce and return and [element in (A - B)] = [(element in A) and (element not in B) where self = (A - B). ''' from . import difference_def return difference_def.instantiate( {x: element, A: self.operands[0], B: self.operands[1]}, assumptions=assumptions) def nonmembership_equivalence(self, element, assumptions=USE_DEFAULTS): ''' Deduce and return and [element not in (A - B)] = [(element not in A) or (element in B)] where self = (A - B). ''' from . import nonmembership_equiv return nonmembership_equiv.instantiate( {x: element, A: self.operands[0], B: self.operands[1]}) def unfold_membership(self, element, assumptions=USE_DEFAULTS): ''' From [element in (A - B)], derive and return [(element in A) and (element not in B)], where self represents (A - B). ''' from . import difference_def return difference_def.instantiate( {x: element, A: self.operands[0], B: self.operands[1]}, assumptions=assumptions) def deduce_membership(self, element, assumptions=USE_DEFAULTS): ''' From [element in A] and [element not in B], derive and return [element in (A - B)], where self represents (A - B). ''' from . import membership_folding return membership_folding.instantiate( {x: element, A: self.operands[0], B: self.operands[1]}, assumptions=assumptions) def deduce_nonmembership(self, element, assumptions=USE_DEFAULTS): ''' From either [element not in A] or [element in B], derive and return [element not in (A - B)], where self represents (A - B). ''' from . import nonmembership_folding return nonmembership_folding.instantiate( {x: element, A: self.operands[0], B: self.operands[1]}, assumptions=assumptions)
class Norm(Operation): ''' We define the norm of a vector to be the square root of its inner product with itself. More generally, norms map vectors to non-negative real values and obey: ‖a v‖ = |a| ‖v‖ ‖u + v‖ ≤ ‖u‖ + ‖v‖ Theorems using these only these general norm properties could generalize the Norm operator (via literal generalization) for expanded uses, but our literal operator will be defined as the InnerProd. ''' # operator of the Norm operation. _operator_ = Literal(string_format='Abs', theory=__file__) def __init__(self, operand, *, styles=None): Operation.__init__(self, Norm._operator_, operand, styles=styles) def string(self, **kwargs): return '||' + self.operand.string() + '||' def latex(self, **kwargs): return r'\left \|' + self.operand.latex() + r'\right \|' @equality_prover('shallow_simplified', 'shallow_simplify') def shallow_simplification(self, *, must_evaluate=False, **defaults_config): if must_evaluate and hasattr(self.operand, 'compute_norm'): return self.evaluation() return Operation.shallow_simplification(self) @equality_prover('computed', 'compute') def computation(self, **defaults_config): if hasattr(self.operand, 'compute_norm'): # If the operand has a 'deduce_norm' method, use # it in an attempt to evaluate the norm. return self.operand.compute_norm() # If there is no 'compute_norm' method, see if there is a # known evaluation. return self.evaluation() @equality_prover('evaluated', 'evaluate') def evaluation(self, **defaults_config): if hasattr(self.operand, 'compute_norm'): # If the operand has a 'deduce_norm' method, use # it in an attempt to evaluate the norm. return self.computation().inner_expr().rhs.evaluate() return Operation.evaluation(self)
class Round(Function): # operator of the Round operation. _operator_ = Literal(stringFormat='round', context=__file__) def __init__(self, A): Function.__init__(self, Round._operator_, A) self.operand = A def _closureTheorem(self, numberSet): import theorems if numberSet == Naturals: return theorems.roundRealPosClosure elif numberSet == Integers: return theorems.roundRealClosure
class Difference(Operation): # operator of the Difference operation _operator_ = Literal(string_format='-', theory=__file__) def __init__(self, A, B, *, styles=None): Operation.__init__(self, Difference._operator_, [A, B], styles=styles) def membership_object(self, element): from .difference_membership import DifferenceMembership return DifferenceMembership(element, self) def nonmembership_object(self, element): from .difference_membership import DifferenceNonmembership return DifferenceNonmembership(element, self)
class QPE(Operation): ''' Represents the quantum circuit for the quantum phase estimation algorithm. ''' # the literal operator of the QPE operation _operator_ = Literal(string_format='QPE', latex_format=r'{\rm QPE}', theory=__file__) def __init__(self, U, t): ''' Phase estimator circuit for Unitary U and t register qubits. ''' Operation.__init__(self, QPE._operator_, (U, t))
class SU(Operation): ''' ''' # the literal operator of the SU operation _operator_ = Literal(stringFormat='SU', context=__file__) def __init__(self, n): ''' Create some SU(n), the special unitary of degree n. ''' Operation.__init__(self, SU._operator_, n) # self.operand = n self.degree = n
class VecZero(Function): ''' The VecZero Function equate the the zero vector of a given vector space. The zero vector satisfies the property that v + 0 = v for any v in the vector space. ''' _operator_ = Literal(string_format=r'0', latex_format=r'\vec{0}', theory=__file__) def __init__(self, vec_space, *, styles=None): Function.__init__(self, VecZero._operator_, vec_space, styles=styles)
class Measure(QcircuitElement): ''' Represents a measurement element of a quantum circuit. ''' # the literal operator of the Output operation class _operator_ = Literal('MEASURE', theory=__file__) def __init__(self, basis, *, part=None, styles=None): ''' Create an OUTPUT operation with the given input state. ''' if part is None: operands = NamedExprs(("basis", basis)) else: operands = NamedExprs(("basis", basis), ("part", part)) QcircuitElement.__init__(self, Measure._operator_, operands, styles=styles) def style_options(self): ''' Return the StyleOptions object for this Gate object. ''' from proveit.physics.quantum import Z options = StyleOptions(self) if self.basis == Z: # For an Z measurement, we can use an implicit meter # representation. options.add_option( name='representation', description=("The 'implicit' option formats the Z-measurement " "as a generic meter."), default='implicit', related_methods=()) return options def circuit_elem_latex(self, *, show_explicitly): ''' Display the LaTeX for this Output circuit element. ''' from proveit.physics.quantum import Z if show_explicitly and hasattr(self, 'part'): return r'& \measure{%s~\mbox{part}~%s}' % (self.basis.latex(), self.part.latex()) if self.basis == Z and self.get_style('Z', 'implicit') == 'implicit': return r'& \meter' return r'& \measure{' + self.basis.latex() + r'}'
class Max(Operation): # operator of the Max operation. _operator_ = Literal(string_format='Max', latex_format=r'{\rm Max}', theory=__file__) def __init__(self, *operands): Operation.__init__(self, Max._operator_, operands) def _closureTheorem(self, number_set): from . import theorems if number_set == Real: return theorems.max_real_closure elif number_set == RealPos: return theorems.max_real_pos_closure
class Min(Function): # operator of the Min operation. _operator_ = Literal(string_format='Min', latex_format=r'{\rm Min}', theory=__file__) def __init__(self, *operands): Function.__init__(self, Min._operator_, operands) def _closureTheorem(self, number_set): from . import theorems if number_set == Real: return theorems.min_real_closure elif number_set == RealPos: return theorems.min_real_pos_closure
class IsMatch(Operation): # operator of the ContainsMatch operation _operator_ = Literal(stringFormat='IsMatch', latexFormat=r'{\rm IsMatch}', context=__file__) def __init__(self, a, b): self.a, self.b = a, b return Operation.__init__(self, IsMatch._operator_, [a, b]) def definition(self, assumptions=USE_DEFAULTS): ''' Derive the definition of this IsMatch(a, b) in the form of an equation. ''' from _axioms_ import isMatchDef from proveit._common_ import a, b return isMatchDef.specialize({a:self.a, b:self.b}, assumptions=assumptions)
class Pfail(Operation): ''' Probability of failure for a given epsilon where success is defined as the measured theta_m being within epsilon of the true theta (phase). ''' # the literal operator of the Pfail operation _operator_ = Literal(string_format='Pfail', latex_format=r'P_{\rm fail}', theory=__file__) def __init__(self, eps): ''' P_fail(eps) ''' Operation.__init__(self, Pfail._operator_, eps)
class Min(Function): # operator of the Min operation. _operator_ = Literal(stringFormat='Min', latexFormat=r'{\rm Min}', context=__file__) def __init__(self, *operands): Function.__init__(self, Min._operator_, operands) def _closureTheorem(self, numberSet): import theorems if numberSet == Reals: return theorems.minRealClosure elif numberSet == RealsPos: return theorems.minRealPosClosure
class PhaseEst(Operation): ''' Represents the quantum circuit for estimating the phase. The quantum phase estimation algorithm consists of a PHASE_ESTIMATOR followed by quantum fourier transform. ''' # the literal operator of the PhaseEst operation _operator_ = Literal(string_format='PHASE_EST', latex_format=r'{\rm PHASE\_EST}', theory=__file__) def __init__(self, U, t): ''' Phase estimator circuit for Unitary U and t register qubits. ''' Operation.__init__(self, PhaseEst._operator_, (U, t))
class Max(Operation): # operator of the Max operation. _operator_ = Literal(stringFormat='Max', latexFormat=r'{\rm Max}', context=__file__) def __init__(self, *operands): Operation.__init__(self, Max._operator_, operands) def _closureTheorem(self, numberSet): import theorems if numberSet == Reals: return theorems.maxRealClosure elif numberSet == RealsPos: return theorems.maxRealPosClosure
class TensorExp(Operation): ''' A Tensor exponentation represents a tensor product repeated a whole number of times. ''' # the literal operator of the TensorExp operation _operator_ = Literal(string_format=r'TensorExp', theory=__file__) def __init__(self, base, exponent, *, styles=None): r''' Tensor exponentiation to any natural number exponent. ''' Operation.__init__(self, TensorExp._operator_, (base, exponent), styles=styles) self.base = self.operands[0] self.exponent = self.operands[1] def membership_object(self, element): return TesorExpMembership(element, self) def _formatted(self, format_type, fence=True): # changed from formatted to _formatted 2/14/2020 (wdc) formatted_base = self.base.formatted(format_type, fence=True, force_fence=True) formatted_exp = self.exponent.formatted(format_type, fence=True, force_fence=True) if format_type == 'latex': return formatted_base + r'^{\otimes ' + formatted_exp + '}' elif format_type == 'string': return formatted_base + '^{otimes ' + formatted_exp + '}' @equality_prover('do_reduced_simplified', 'do_reduced_simplify') def do_reduced_simplification(self, **defaults_config): ''' For the trivial cases of a one exponent, derive and return this tensor-exponentiated expression equated with a simplified form. Assumptions may be necessary to deduce necessary conditions for the simplification. For example, TensorExp(x, one).do_reduced_simplification() ''' from proveit.numbers import zero, one from . import tensor_exp_one if self.exponent == one: return tensor_exp_one.instantiate({x: self.base}) raise ValueError('Only trivial simplification is implemented ' '(tensor exponent of one). Submitted tensor ' 'exponent was {}.'.format(self.exponent))
class Psuccess(Operation): ''' Probability of success for a given epsilon where success is defined as the measured theta_m being with epsilon of the true theta (phase). ''' # the literal operator of the Psuccess operation _operator_ = Literal(string_format='Psuccess', latex_format=r'P_{\rm success}', theory=__file__) def __init__(self, eps, *, styles=None): ''' P_success(eps) ''' Operation.__init__(self, Psuccess._operator_, eps, styles=styles)
class QPE1(Function): ''' Represents the first stage of the quantum circuit for the quantum phase estimation algorithm (up to the quantum Fourier transform part). ''' # the literal operator of the QPE operation _operator_ = Literal(string_format='QPE1', latex_format=r'\textrm{QPE}_1', theory=__file__) def __init__(self, U, t, *, styles=None): ''' Phase estimator circuit for Unitary U and t register qubits. ''' Operation.__init__(self, QPE1._operator_, (U, t), styles=styles)
class VecNeg(Operation): ''' The VecAdd operation is the default for the addition of vectors in a vector space. ''' _operator_ = Literal(string_format='-', theory=__file__) def __init__(self, *operands, styles=None): Operation.__init__(self, VecNeg._operator_, operands, styles=styles) def string(self, **kwargs): return Neg.string(self, **kwargs) def latex(self, **kwargs): return Neg.latex(self, **kwargs)
class Difference(Operation): # operator of the Difference operation _operator_ = Literal(stringFormat='-', context=__file__) def __init__(self, A, B): Operation.__init__(self, Difference._operator_, [A, B]) def membershipEquivalence(self, element, assumptions=USE_DEFAULTS): ''' Deduce and return and [element in (A - B)] = [(element in A) and (element not in B) where self = (A - B). ''' from ._axioms_ import differenceDef return differenceDef.specialize({x:element,A:self.operands[0], B:self.operands[1]}, assumptions=assumptions) def nonmembershipEquivalence(self, element, assumptions=USE_DEFAULTS): ''' Deduce and return and [element not in (A - B)] = [(element not in A) or (element in B)] where self = (A - B). ''' from ._theorems_ import nonmembershipEquiv return nonmembershipEquiv.specialize({x:element, A:self.operands[0], B:self.operands[1]}) def unfoldMembership(self, element, assumptions=USE_DEFAULTS): ''' From [element in (A - B)], derive and return [(element in A) and (element not in B)], where self represents (A - B). ''' from ._axioms_ import differenceDef return differenceDef.specialize({x:element, A:self.operands[0], B:self.operands[1]}, assumptions=assumptions) def deduceMembership(self, element, assumptions=USE_DEFAULTS): ''' From [element in A] and [element not in B], derive and return [element in (A - B)], where self represents (A - B). ''' from ._theorems_ import membershipFolding return membershipFolding.specialize({x:element, A:self.operands[0], B:self.operands[1]}, assumptions=assumptions) def deduceNonmembership(self, element, assumptions=USE_DEFAULTS): ''' From either [element not in A] or [element in B], derive and return [element not in (A - B)], where self represents (A - B). ''' from ._theorems_ import nonmembershipFolding return nonmembershipFolding.specialize({x:element, A:self.operands[0], B:self.operands[1]}, assumptions=assumptions)
class Ceil(Function): # operator of the Ceil operation. _operator_ = Literal(stringFormat='ceil', context=__file__) def __init__(self, A): Function.__init__(self, Ceil._operator_, A) self.operand = A def _closureTheorem(self, numberSet): from . import theorems if numberSet == NaturalsPos: return theorems.ceilRealPosClosure elif numberSet == Integers: return theorems.ceilRealClosure def latex(self, **kwargs): return r'\lceil ' + self.operand.latex(fence=False) + r'\rceil'
class Floor(Function): # operator of the Floor operation. _operator_ = Literal(stringFormat='floor', context=__file__) def __init__(self, A): Function.__init__(self, Floor._operator_, A) self.operand = A def _closureTheorem(self, numberSet): from . import theorems if numberSet == Naturals: return theorems.floorRealPosClosure elif numberSet == Integers: return theorems.floorRealClosure def latex(self, **kwargs): return r'\lfloor ' + self.operand.latex(fence=False) + r'\rfloor'