def __init__(self, operandA, operandB): r''' Divide two operands in fraction form. ''' Operation.__init__(self, Frac._operator_, [operandA, operandB]) self.numerator = operandA self.denominator = operandB
def __init__(self, *operands): ''' Or together any number of operands: A or B or C ''' Operation.__init__(self, Or._operator_, operands) # deduce trivial disjunctive equivalances with 0 or 1 operand # avoid infinite recursion by storing previously encountered # expressions if self in Or.trivial_disjunctions: return operands = self.operands if operands.num_entries() == 0: Or.trivial_disjunctions.add(self) try: from proveit.logic.booleans.disjunction import empty_disjunction except BaseException: pass # empty_disjunction not initially defined when doing a clean rebuild if operands.is_single(): operand = operands[0] try: Or.trivial_disjunctions.add(self) in_bool(operand).prove(automation=False) self.unary_reduction() except BaseException: pass
def __init__(self, state): ''' Create an INPUT operation (for entering the left-hand side of a circuit) with the given input state. ''' Operation.__init__(self, Input._operator_, state) self.state = state
def __init__(self, base, exponent): r''' Tensor exponentiation to any natural number exponent. ''' Operation.__init__(self, TensorExp._operator_, (base, exponent)) self.base = self.operands[0] self.exponent = self.operands[1]
def __init__(self, numerator, denominator): r''' Divide two operands. ''' Operation.__init__(self, Div._operator_, [numerator, denominator]) self.numerator = self.operands[0] self.denominator = self.operands[1]
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
def __init__(self, operand): # creates the Operation with FACTORIAL as the operator and the provided # operand as its only operand. Operation.__init__( self, Factorial._operator_, operand) # initializes self.operand
def __init__(self, scalar, scaled): r''' Product between a scalar and a matrix (or vector). ''' Operation.__init__(self, ScalarProd._operator_, [scalar, scaled]) self.scalar = scalar self.scaled = scaled
def __init__(self, target_gate): ''' Create a Target operation with the given target_gate as the type of the gate for the target (e.g., X for CNOT and Z for Controlled-Z). ''' Operation.__init__(self, TARGET, target_gate) self.target_gate = target_gate
def __init__(self, operators, operands, doMinSizeCheck=True): from proveit.logic import Equals if doMinSizeCheck and len(operators) < 2: raise ValueError( "Do not use a TransitiveSequence for fewer than two relationship (it is unnecessary)" ) if len(operators) + 1 != len(operands): raise ValueError( "There must be one more operand than operator in a TransitiveSequence" ) Relation = self.__class__.RelationClass() assert issubclass( Relation, TransitiveRelation ), "The Relation class of a TransitiveSequence should be a TransitiveRelation" relation_operators = (Relation.WeakRelationClass()._operator_, Relation.StrongRelationClass()._operator_, Equals._operator_) for operator in operators: if operator not in relation_operators: raise TypeError( "Operators of TransitiveSequence should be %s, %s, or %s" % tuple( str(relation_operator) for relation_operator in relation_operators)) Operation.__init__(self, operators, operands)
def __init__(self, operator, *digits): Operation.__init__(self, operator, digits) if len(digits) <= 1: raise Exception( 'A NumeralSequence should have two or more digits. Single digit number should be represented as the corresponding Literal.' ) self.digits = digits
def __init__(self, base, exponent): r''' Raise base to exponent power. ''' Operation.__init__(self, Exp._operator_, (base, exponent)) self.base = base self.exponent = exponent
def __init__(self, tensor, shape=None): ''' Create a Circuit either with a dense tensor (list of lists ... of lists) or with a dictionary mapping pairs of indices to Expression elements or blocks, composing an ExpressionTensor. ''' from .common import PASS if not isinstance(tensor, dict): # remove identity gates -- these are implicit tensor, _ = ExpressionTensor.TensorDictFromIterables(tensor) fixed_shape = (shape is not None) if not fixed_shape: shape = (0, 0) for idx in list(tensor.keys()): if len(idx) != 2: raise ValueError( 'Circuit operand must be a 2-D ExpressionTensor') if not fixed_shape: shape = (max(shape[0], idx[0] + 1), max(shape[1], idx[1] + 1)) if tensor[idx] == PASS: tensor.pop(idx) self.tensor = ExpressionTensor(tensor, shape) self.shape = self.tensor.shape Operation.__init__(self, CIRCUIT, [self.tensor]) if len(self.shape) != 2: raise ValueError('Circuit operand must be a 2-D ExpressionTensor') # For each row of each nested sub-tensor (including the top level), # determine which sub-tensor, if there are any, has the deepest nesting. # This will impact how we iterate over nested rows to flatten the # display of a nested tensors. tensor = self.tensor # map nested tensor (including self) to a list that indicates the # deepest nested tensor per row self.deepest_nested_tensor_along_row = dict() def determine_deepest_nested_tensors(tensor): ''' Determine and set the deepest nested tensor along each row of tensor, applying this recursively for sub-tensors, and return the depth of this tensor. ''' max_depth = 1 self.deepest_nested_tensor_along_row[ tensor] = deepest_nested_tensor_along_row = [] for row in range(tensor.shape[0]): deepest_nested_tensor = None max_depth_along_row = 1 for col in range(tensor.shape[1]): if (row, col) in tensor: cell = tensor[row, col] if isinstance(cell, ExpressionTensor): sub_depth = determine_deepest_nested_tensors(cell) max_depth_along_row = max(max_depth_along_row, sub_depth + 1) if deepest_nested_tensor is None or sub_depth > max_depth_along_row: deepest_nested_tensor = cell max_depth = max(max_depth, max_depth_along_row + 1) deepest_nested_tensor_along_row.append(deepest_nested_tensor) return max_depth determine_deepest_nested_tensors(self.tensor)
def __init__(self, operandA, operandB): r''' Divide two operands. ''' Operation.__init__(self, Div._operator_, [operandA, operandB], styles={'division':'inline'}) self.numerator = self.operands[0] self.denominator = self.operands[1]
def __init__(self, lambda_fn, operand, *, styles=None): Operation.__init__(self, LambdaApplication._operator_, NamedExprs(('lambda_fn', lambda_fn), ('operand', operand)), styles=styles) # The operand of the Lambda function self.lambda_operand = self.operands['operand']
def __init__(self, base, exponent): r''' Raise base to exponent power. ''' Operation.__init__(self, Exp._operator_, (base, exponent), styles={'exponent':'raised'}) self.base = base self.exponent = exponent
def __init__(self, *operands, styles=None): r''' Matrix dot product of any number of operands. ''' Operation.__init__(self, MatrixMult._operator_, operands, styles=styles)
def __init__(self, base, exponent, *, styles=None): r''' Raise matrix 'base' to exponent power. ''' self.base = base self.exponent = exponent Operation.__init__(self, MatrixExp._operator_, (base, exponent), styles=styles)
def __init__(self, element, domain): Operation.__init__(self, InSet._operator_, (element, domain)) self.element = self.operands[0] self.domain = self.operands[1] if hasattr(self.domain, 'membershipObject'): self.membershipObject = self.domain.membershipObject(element) if not isinstance(self.membershipObject, Membership): raise TypeError("The 'membershipObject' of %s should be from a class derived from 'Membership'"%str(self.domain))
def __init__(self, operator, lhs, rhs): # We need to pass along 'direction':'normal' rather than # relying about StyleOption defaults because we don't want # that to be overwritten by the style of the last expression # with the same meaning. Operation.__init__(self, operator, (lhs, rhs), styles={'direction':'normal'}) assert(self.operands.is_double())
def __init__(self, lambda_fn, operand): Operation.__init__( self, LambdaApplication._operator_, NamedExprs([('lambda_fn', lambda_fn), ('operand', operand)])) # The Lambda function operand self.lambda_fn = self.operands['lambda_fn'] # The operand of the Lambda function self.lambda_operand = self.operands['operand']
def __init__(self, target_gate): ''' Create a Target operation with the given target_gate as the type of the gate for the target (e.g., X for CNOT and Z for Controlled-Z). ''' Operation.__init__(self, Target._operator_, target_gate) self.target_gate = target_gate print("target_gate = {}".format( self.target_gate)) # for testing; delete later
def __init__(self, scalar, scaled, *, styles=None): r''' Product between a scalar and a matrix (or vector). ''' Operation.__init__(self, ScalarMult._operator_, [scalar, scaled], styles=styles) self.scalar = scalar self.scaled = scaled
def __init__(self, n, *, styles=None): ''' QFT circuit for n qubits. ''' Operation.__init__(self, InverseFourierTransform._operator_, n, styles=styles) self.nqubits = n
def __init__(self, field, rows, columns, *, styles=None): ''' Create F^{m x n} as the MatrixSpace for field F with ''' Operation.__init__(self, MatrixSpace._operator_, NamedExprs(('field', field), ('rows', rows), ('columns', columns)), styles=styles)
def __init__(self, gate_operation): ''' Create a quantum circuit gate performing the given operation. ''' Operation.__init__(self, Gate._operator_, gate_operation) self.gate_operation = self.operands[0] print("self.gate_operation = {}".format( self.gate_operation)) # for testing; delete later print("type(self.gate_operation) = {}".format(type( self.gate_operation))) # for testing; delete later
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 __init__(self, integer_part, fractional_part): Operation.__init__(self, Decimal_fraction._operator_, [integer_part, fractional_part]) self.integer_part = integer_part self.fractional_part = fractional_part if not all( isinstance(part, WholeDecimal) for part in (integer_part, fractional_part)): raise Exception( 'A Decimal_fraction may only be composed of WholeNumber integer and fractional parts' )
def __init__(self, element, domain): Operation.__init__(self, InSet._operator_, (element, domain)) self.element = self.operands[0] self.domain = self.operands[1] if hasattr(self.domain, 'membershipObject'): self.membershipObject = self.domain.membershipObject(element) if not isinstance(self.membershipObject, Membership): raise TypeError( "The 'membershipObject' of %s is a %s which " "is not derived from %s as it should be." % (self.domain, self.membershipObject.__class__, Membership))
def __init__(self, operator, normal_lhs, normal_rhs, *, styles): # We need to pass along 'direction':'normal' rather than # relying about StyleOption defaults because we don't want # that to be overwritten by the style of the last expression # with the same meaning. Operation.__init__(self, operator, (normal_lhs, normal_rhs), styles=styles) assert self.operands.is_double(), "%s is not double" % self.operands # lhs and rhs with the "direction" style of "normal" # (not subject to reversal) self.normal_lhs = self.operands[0] self.normal_rhs = self.operands[1]