The Quipper System

Description

This module provides a high-level circuit building interface intended to look "functional". At a given time, there is a circuit being assembled. This circuit has free endpoints (on the left and right) that can be bound to variables. A qubit or bit is simply an endpoint in such a circuit. "Applying" an operation to a qubit or bit simply appends the operation to the current circuit. We use the Circ monad to capture the side effect of assembling a circuit.

Synopsis

The ReadWrite monad describes a standard read-write computation, here specialized to the case where writes are Gates, prompts are Bits, and reads are Bools. Thus, a read-write computation can do three things:

• terminate with a result. This is the case RW_Return.
• write a single Gate and continue. This is the case RW_Write.
• issue a prompt, which is a Wire, then read a Bool, then continue. This is the case RW_Read.

Constructors

Instances

# Some types

data Qubit Source #

The type of qubits.

Instances
 # Instance detailsDefined in Quipper.Internal.Monad Methods(==) :: Qubit -> Qubit -> Bool #(/=) :: Qubit -> Qubit -> Bool # # Instance detailsDefined in Quipper.Internal.Monad Methods(<) :: Qubit -> Qubit -> Bool #(<=) :: Qubit -> Qubit -> Bool #(>) :: Qubit -> Qubit -> Bool #(>=) :: Qubit -> Qubit -> Bool #max :: Qubit -> Qubit -> Qubit #min :: Qubit -> Qubit -> Qubit # # Instance detailsDefined in Quipper.Internal.Monad MethodsshowsPrec :: Int -> Qubit -> ShowS #show :: Qubit -> String #showList :: [Qubit] -> ShowS # # Instance detailsDefined in Quipper.Internal.Monad Methods # Instance detailsDefined in Quipper.Internal.QData # Instance detailsDefined in Quipper.Internal.QData Methods # Instance detailsDefined in Quipper.Internal.QData Methodsqcdata_mapM :: Monad m => Qubit -> (q -> m q') -> (c -> m c') -> QCType q c Qubit -> m (QCType q' c' Qubit) Source #qcdata_zip :: Qubit -> q -> c -> q' -> c' -> QCType q c Qubit -> QCType q' c' Qubit -> ErrMsg -> QCType (q, q') (c, c') Qubit Source # # Instance detailsDefined in Quipper.Internal.Labels Methods # Instance detailsDefined in Quipper.Internal.Monad Methods # Instance detailsDefined in Quipper.Internal.CircLifting Methods type QCType x y Qubit # Instance detailsDefined in Quipper.Internal.QData type QCType x y Qubit = x

data Bit Source #

The type of run-time classical bits (i.e., boolean wires in a circuit).

Instances
 # Instance detailsDefined in Quipper.Internal.Monad Methods(==) :: Bit -> Bit -> Bool #(/=) :: Bit -> Bit -> Bool # # Instance detailsDefined in Quipper.Internal.Monad Methodscompare :: Bit -> Bit -> Ordering #(<) :: Bit -> Bit -> Bool #(<=) :: Bit -> Bit -> Bool #(>) :: Bit -> Bit -> Bool #(>=) :: Bit -> Bit -> Bool #max :: Bit -> Bit -> Bit #min :: Bit -> Bit -> Bit # # Instance detailsDefined in Quipper.Internal.Monad MethodsshowsPrec :: Int -> Bit -> ShowS #show :: Bit -> String #showList :: [Bit] -> ShowS # # Instance detailsDefined in Quipper.Internal.Monad Methods # Instance detailsDefined in Quipper.Internal.QData # Instance detailsDefined in Quipper.Internal.QData Methods # Instance detailsDefined in Quipper.Internal.QData Methodsqcdata_mapM :: Monad m => Bit -> (q -> m q') -> (c -> m c') -> QCType q c Bit -> m (QCType q' c' Bit) Source #qcdata_zip :: Bit -> q -> c -> q' -> c' -> QCType q c Bit -> QCType q' c' Bit -> ErrMsg -> QCType (q, q') (c, c') Bit Source # # Instance detailsDefined in Quipper.Internal.Labels Methods # Instance detailsDefined in Quipper.Internal.Monad Methods type QCType x y Bit # Instance detailsDefined in Quipper.Internal.QData type QCType x y Bit = y

An endpoint in a circuit. This is either a Qubit or a Bit.

data Signed a Source #

A signed item of type a. Signed x True represents a positive item, and Signed x False represents a negative item.

When used with wires in a circuit, a positive sign is used to represent a positive control, i.e., a filled dot, and a negative sign is used to represent a negative control, i.e., an empty dot.

Constructors

 Signed a Bool
Instances
 Show a => Show (Signed a) # Instance detailsDefined in Quipper.Internal.Circuit MethodsshowsPrec :: Int -> Signed a -> ShowS #show :: Signed a -> String #showList :: [Signed a] -> ShowS # # Instance detailsDefined in Quipper.Internal.Control Methods (ControlSource (Signed a), ControlSource (Signed b)) => ControlSource (Signed (B_Endpoint a b)) # Instance detailsDefined in Quipper.Internal.Monad Methods # Instance detailsDefined in Quipper.Internal.Monad Methods # Instance detailsDefined in Quipper.Internal.Monad Methods QCData a => QCData (Signed a) # Instance detailsDefined in Quipper.Internal.QData Methodsqcdata_mapM :: Monad m => Signed a -> (q -> m q') -> (c -> m c') -> QCType q c (Signed a) -> m (QCType q' c' (Signed a)) Source #qcdata_zip :: Signed a -> q -> c -> q' -> c' -> QCType q c (Signed a) -> QCType q' c' (Signed a) -> ErrMsg -> QCType (q, q') (c, c') (Signed a) Source #qcdata_promote :: BType (Signed a) -> Signed a -> ErrMsg -> BType (Signed a) Source # # Instance detailsDefined in Quipper.Internal.Labels Methodslabel_rec :: Signed a -> String -> LabelMonad () Source # # Instance detailsDefined in Quipper.Internal.Labels Methods type QCType x y (Signed a) # Instance detailsDefined in Quipper.Internal.QData type QCType x y (Signed a) = Signed (QCType x y a) type QTypeB (Signed a) # Instance detailsDefined in Quipper.Internal.QData type QTypeB (Signed a) = Signed (QTypeB a)

A control consists of an Endpoint and a boolean (True = perform gate when control wire is 1; False = perform gate when control wire is 0). Note that gates can be controlled by qubits and classical bits.

type Qulist = [Qubit] Source #

Synonym for a qubit list, for convenience.

type Bitlist = [Bit] Source #

Synonym for a bit list, for convenience.

A time step is a small floating point number used as a parameter to certain gates, such as rotation gates or the eiZt gate.

A flag that, if True, indicates that the gate is inverted.

# Conversions for wires, qubits, bits, endpoints

Extract the underlying low-level wire of a qubit.

Extract the underlying low-level wire of a bit.

Extract the underlying low-level Wire of an Endpoint.

wires_with_arity_of_endpoints :: [Endpoint] -> ([Wire], Arity) Source #

Break a list of Endpoints down into a list of Wires together with an Arity. (Partial inverse to endpoints_of_wires_in_arity.)

Construct a qubit from a wire.

Construct a bit from a wire.

Create an Endpoint from a low-level Wire and Wiretype.

endpoints_of_wires_in_arity :: Arity -> [Wire] -> [Endpoint] Source #

Create a list of Endpoints from a list of Wires together with an Arity, assuming all wires are present in the arity.

# Bindings for qubits and bits

bind_qubit :: Qubit -> a -> Bindings a b -> Bindings a b Source #

Bind a qubit wire to a value, and add it to the given bindings.

bind_bit :: Bit -> b -> Bindings a b -> Bindings a b Source #

Bind a bit wire to a value, and add it to the given bindings.

unbind_qubit :: Bindings a b -> Qubit -> a Source #

Retrieve the value of a qubit wire from the given bindings. Throws an error if the wire was bound to a classical bit.

unbind_bit :: Bindings a b -> Bit -> b Source #

Retrieve the value of a bit wire from the given bindings. Throws an error if the wire was bound to a qubit.

# Controls for qubits and bits

Add a single signed qubit as a control to a control list.

Add a single signed bit as a control to a control list.

# Namespace management

provide_simple_subroutine name circ in_struct out_struct is_classically_controllable: if name not already bound, binds it to circ. Note: when there’s an existing value, does not check that it’s equal to circ.

provide_subroutine :: (Typeable a, Typeable b) => BoxId -> OBCircuit -> CircuitTypeStructure a -> CircuitTypeStructure b -> Bool -> Circ () Source #

provide_subroutine name circ: if name not already bound, binds it to the main circuit of circ, and additionally provides any missing subroutines of circ.

provide_subroutines namespace: Add each subroutine from the namespace to the current circuit, unless a subroutine of that name already exists.

call_subroutine :: (Typeable a, Typeable b) => BoxId -> RepeatFlag -> a -> Circ b Source #

Look up the specified subroutine in the namespace, and apply it to the specified inputs, or throw an error if they are not appropriately typed.

The input/output types of this function are determined dynamically by the CircuitTypeStructure stored with the subroutine.

Get the namespace part of the Circ monad's state.

Set the namespace part of the Circ monad's state.

Issue a RW_Subroutine primitive

# Basic gates

## Gates in functional style

Apply a NOT gate to a qubit.

An alternate name for the Hadamard gate.

Apply a Pauli X gate.

Apply a Pauli Y gate.

Apply a Pauli Z gate.

Apply a Clifford S-gate.

Apply the inverse of an S-gate.

Apply a T = √S gate.

Apply the inverse of a T-gate.

Apply a Clifford E = HS3ω3 gate.

This gate is the unique Clifford operator with the properties E³ = I, EXE⁻¹ = Y, EYE⁻¹ = Z, and EZE⁻¹ = X. It is a convenient gate for calculations. For example, every Clifford operator can be uniquely written of the form

• EaXbScωd,

where a, b, c, and d are taken modulo 3, 2, 4, and 8, respectively.

Apply the inverse of an E-gate.

Apply the scalar ω = eiπ/4, as a single-qubit gate.

Apply a V = √X gate. This is by definition the following gate (see also Nielsen and Chuang, p.182):

Apply the inverse of a V-gate.

Apply a SWAP gate.

Apply an eiZt gate. The timestep t is a parameter.

Apply a rotation by angle 2πi/2n about the z-axis.

Apply a W gate. The W gate is self-inverse and diagonalizes the SWAP gate.

The arguments are such that

gate_W |0〉 |0〉 = |00〉
gate_W |0〉 |1〉 = (|01〉+|10〉) / √2
gate_W |1〉 |0〉 = (|01〉-|10〉) / √2
gate_W |1〉 |1〉 = |11〉.

In circuit diagrams, W1 denotes the "left" qubit, and W2 denotes the "right" qubit.

Apply an iX gate. This gate is used similarly to the Pauli X gate, but with two advantages:

• the doubly-controlled iX gate can be implemented in the Clifford+T gate base with T-count 4 (the doubly-controlled X gate requires T-count 7);
• the iX-gate has determinant 1, and therefore an n-times controlled iX gate can be implemented in the Clifford+T gate base with no ancillas.

In particular, the iX gate can be used to implement an additional control with T-count 8, like this:

Apply a −iX gate. This is the inverse of gate_iX.

Apply a global phase change eiπt, where typically t ∈ [0,2]. This gate is uninteresting if not controlled; however, it has non-trivial effect if it is used as a controlled gate.

Like global_phase, except the gate is also "anchored" at a particular bit or qubit. This is strictly for graphical presentation purposes, to provide a hint for where the gate should be printed in a circuit diagram. Backends are free to ignore this hint altogether. The anchor is not actually an input to the gate, and it is legal for the anchoring qubit to also be used as a control control.

qmultinot_list :: [(Qubit, Bool)] -> Circ [Qubit] Source #

Apply a multiple-not gate, as specified by a list of booleans and qubits: qmultinot_list [(True,q1), (False,q2), (True,q3)] applies a not gate to q1 and q3, but not to q2.

cmultinot_list :: [(Bit, Bool)] -> Circ [Bit] Source #

Like qmultinot_list, but applies to classical bits instead of qubits.

named_gate_qulist :: String -> InverseFlag -> [Qubit] -> [Qubit] -> Circ ([Qubit], [Qubit]) Source #

Apply a generic quantum gate to a given list of qubits and a given list of generalized controls. The generalized controls are really inputs to the gate, but are guaranteed not to be modified if they are in a computational basis state.

named_rotation_qulist :: String -> InverseFlag -> Timestep -> [Qubit] -> [Qubit] -> Circ ([Qubit], [Qubit]) Source #

Like named_gate_qulist, but produce a named gate that also depends on a real parameter. This is typically used for rotations or phase gates parameterized by an angle. The name can contain '%' as a place holder for the parameter, for example "exp(-i%Z)".

Apply a NOT gate to a classical bit.

swap_bit :: Bit -> Bit -> Circ (Bit, Bit) Source #

Apply a classical SWAP gate.

## Gates in imperative style

qnot_at :: Qubit -> Circ () Source #

Apply a NOT gate to a qubit.

An alternate name for the Hadamard gate.

Apply a Pauli X gate.

Apply a Pauli Y gate.

Apply a Pauli Z gate.

Apply a Clifford S-gate.

Apply the inverse of an S-gate.

Apply a T = √S gate.

Apply the inverse of a T-gate.

Apply a Clifford E = HS3ω3 gate.

This gate is the unique Clifford operator with the properties E³ = I, EXE⁻¹ = Y, EYE⁻¹ = Z, and EZE⁻¹ = X. It is a convenient gate for calculations. For example, every Clifford operator can be uniquely written of the form

• EaXbScωd,

where a, b, c, and d are taken modulo 3, 2, 4, and 8, respectively.

Apply the inverse of an E-gate.

Apply the scalar ω = eiπ/4, as a single-qubit gate.

Apply a V = √X gate. This is by definition the following gate (see also Nielsen and Chuang, p.182):

Apply the inverse of a V-gate.

Apply a SWAP gate.

expZt_at :: Timestep -> Qubit -> Circ () Source #

Apply an eiZt gate. The timestep t is a parameter.

rGate_at :: Int -> Qubit -> Circ () Source #

Apply a rotation by angle 2πi/2n about the z-axis.

gate_W_at :: Qubit -> Qubit -> Circ () Source #

Apply a W gate. The W gate is self-inverse and diagonalizes the SWAP gate.

The arguments are such that

gate_W |0〉 |0〉 = |00〉
gate_W |0〉 |1〉 = (|01〉+|10〉) / √2
gate_W |1〉 |0〉 = (|01〉-|10〉) / √2
gate_W |1〉 |1〉 = |11〉.

In circuit diagrams, W1 denotes the "left" qubit, and W2 denotes the "right" qubit.

Apply an iX gate. This gate is used similarly to the Pauli X gate, but with two advantages:

• the doubly-controlled iX gate can be implemented in the Clifford+T gate base with T-count 4 (the doubly-controlled X gate requires T-count 7);
• the iX-gate has determinant 1, and therefore an n-times controlled iX gate can be implemented in the Clifford+T gate base with no ancillas.

In particular, the iX gate can be used to implement an additional control with T-count 8, like this:

Apply a −iX gate. This is the inverse of gate_iX_at.

qmultinot_list_at :: [(Qubit, Bool)] -> Circ () Source #

Apply a qmultinot_list gate, as specified by a list of booleans and qubits: qmultinot_list [(True,q1), (False,q2), (True,q3)] applies a not gate to q1 and q3, but not to q2.

cmultinot_list_at :: [(Bit, Bool)] -> Circ () Source #

Like qmultinot_list_at, but applies to classical bits instead of qubits.

named_gate_qulist_at :: String -> InverseFlag -> [Qubit] -> [Qubit] -> Circ () Source #

Apply a generic quantum gate to a given list of qubits and a given list of generalized controls. The generalized controls are really inputs to the gate, but are guaranteed not to be modified if they are in a computational basis state.

named_rotation_qulist_at :: String -> InverseFlag -> Timestep -> [Qubit] -> [Qubit] -> Circ () Source #

Like named_gate_qulist_at, but produce a named gate that also depends on a real parameter. This is typically used for rotations or phase gates parameterized by an angle. The name can contain '%' as a place holder for the parameter, for example "exp(-i%Z)".

cnot_at :: Bit -> Circ () Source #

Apply a NOT gate to a classical bit.

swap_bit_at :: Bit -> Bit -> Circ () Source #

Apply a classical SWAP gate.

## Bitwise initialization and termination functions

Generate a new qubit, initialized to the parameter Bool.

qterm_qubit :: Bool -> Qubit -> Circ () Source #

Terminate a qubit asserted to be in state b.

We note that the assertion is relative to the precision: when gates in a circuit are implemented up to some precision ε (either due to physical limitations, or due to decomposition into a discrete gate base), the assertion may only hold up to a corresponding precision as well.

Generate a new qubit, initialized from a classical bit. Note that the classical bit is simultaneously terminated.

Unprepare a qubit asserted to be in a computational basis state. This is the same as a measurement, but must only be applied to qubits that are already known to be in one of the states |0〉 or |1〉, and not in superposition. This operation is rarely (perhaps never?) used in any quantum algorithms, but we include it for consistency reasons, because it is formally the inverse of prepare_qubit.

Apply a measurement gate (turns a qubit into a bit).

Generate a new classical bit, initialized to a boolean parameter b.

cterm_bit :: Bool -> Bit -> Circ () Source #

Terminate a classical Bit asserted to be in state Bool.

dterm_bit :: Bool -> Bit -> Circ () Source #

Terminate a classical Bit with a comment indicating what the observed state of the Bit was, in this particular dynamic run of the circuit. This is typically used to terminate a wire right after a dynamic lifting has been performed. It is not intended to be a user-level operation.

It is important to note that a DTerm gate does not, in any way, represent an assertion. Unlike a CTerm gate, which asserts that the classical bit will have the stated value at every run of the circuit, the DTerm gate simply records that the classical bit had the stated value at some particular run of the circuit.

Operationally (e.g., in a simulator), the DTerm gate can be interpreted in multiple ways. In the simplest case, it is just treated like a CDiscard gate, and the boolean comment ignored. Alternatively, it can be treated as a post-selection gate: if the actual value does not equal the stated value, the entire computation is aborted. Normally, DTerm gates should appear in the output, not the input of simulators; therefore, the details of the behavior of any particular simulator on a DTerm gate are implementation dependent.

## Classical gates

The gates in this section are for constructing classical circuits. None of these gates alter or discard their inputs; each gate produces a new wire holding the output of the gate.

cgate_xor :: [Bit] -> Circ Bit Source #

Return the "exclusive or" of a list of bits.

Test equality of two bits, and return True iff they are equal.

If a is True, then return b, else return c.

Return the negation of its input. Note that unlike cnot or cnot_at, this gate does not alter its input, but returns a newly created bit.

cgate_and :: [Bit] -> Circ Bit Source #

Return the conjunction of a list of bits.

cgate_or :: [Bit] -> Circ Bit Source #

Return the disjunction of a list of bits.

cgate :: String -> [Bit] -> Circ Bit Source #

Apply a named classical gate. This is used to define all of the above classical gates, but should not usually be directly used by user code.

cgateinv :: String -> Bit -> [Bit] -> Circ () Source #

cgateinv name w inputs: Uncompute a named classical gate. This asserts that w is in the state determined by the gate type and the inputs, then uncomputes w in a reversible way. This rarely used gate is formally the inverse of cgate.

## Subroutines

subroutine :: BoxId -> InverseFlag -> ControllableFlag -> RepeatFlag -> [Wire] -> Arity -> [Wire] -> Arity -> [Endpoint] -> Circ [Endpoint] Source #

Insert a subroutine gate with specified name, and input/output output types, and attach it to the given endpoints. Return the new endpoints.

Note that the [Wire] and Arity arguments are used as a pattern for the locations/types of wires of the subroutine; the [Endpoint] argument (and output) specify what is attached in the current circuit. The two aspects of this pattern that are respected are: the lingeringness of any inputs; and the number and types of wires.

For instance (assuming for simplicity that all wires are qubits), if the patterns given are “inputs [1,3,5], outputs [1,3,4]”, and the actual inputs specified are [20,21,25], then the output wires produced might be e.g. [20,21,23], [20,21,36], or [20,21,8], depending on the next available free wire.

More subtly, if the patterns given are “inputs [1,2,3], outputs [3,7,8,1]”, and the inputs given are [10,5,4], then the outputs will be [4,x,y,10], where x, y are two fresh wires.

Note that lingering wires may change type, for e.g. subroutines that include measurements.

It is currently assumed that all these lists are linear, i.e. contain no duplicates.

comment_label :: String -> InverseFlag -> [(Wire, String)] -> Circ () Source #

Insert a comment in the circuit. This is not a gate, and has no effect, except to mark a spot in the circuit. The comment has two parts: a string (possibly empty), and a list of labelled wires (possibly empty). This is a low-level function. Users should use comment instead.

Disable labels and comments for a block of code. The intended usage is like this:

without_comments $do { <<<code block>>> } This is sometimes useful in situations where code is being re-used, for example when one function is implemented in terms of another, but should not inherit comments from it. It is also useful in the definition of recursive function, where a comment should only be applied at the outermost level. Finally, it can be used to suppress comments from parts of circuits for presentation purposes. ## Dynamic lifting Convert a Bit (boolean circuit output) to a Bool (boolean parameter). For use in algorithms that require the output of a measurement to be used as a circuit-generation parameter. This is the case, for example, for sieving methods, and also for some iterative algorithms. Note that this is not a gate, but a meta-operation. The input consists of classical circuit endpoints (whose values are known at circuit execution time), and the output is a boolean parameter (whose value is known at circuit generation time). The use of this operation implies an interleaving between circuit execution and circuit generation. It is therefore a (physically) expensive operation and should be used sparingly. Using the dynamic_lift_bit operation interrupts the batch mode operation of the quantum device (where circuits are generated ahead of time), and forces interactive operation (the quantum device must wait for the next portion of the circuit to be generated). This operation is especially expensive if the current circuit contains unmeasured qubits; in this case, the qubits must be preserved while the quantum device remains on standby. Also note that this operation is not supported in all contexts. It is an error, for example, to use this operation in a circuit that is going to be reversed, or in the body of a boxed subroutine. Also, not all output devices (such as circuit viewers) support this operation. # Other circuit-building functions Generate a new qubit initialized to |+〉 when b=False and |−〉 when b=True. Generate a new qubit initialized to one of |0〉, |1〉, |+〉, |−〉, depending on a character c which is '0', '1', '+', or '-'. Generate a list of qubits initialized to a sequence of |0〉, |1〉, |+〉, |−〉, defined by a string argument e.g. "00+0+++". qinit_list :: [Bool] -> Circ [Qubit] Source # A version of qinit_qubit that operates on lists. qterm_list :: [Bool] -> [Qubit] -> Circ () Source # A version of qterm_qubit that operates on lists. We initialize left-to-right and terminate right-to-left, as this leads to more symmetric and readable circuits, more stable under reversal. Note: if the left argument to qterm_list is longer than the right argument, then it is truncated. So the first argument can be (repeat False). It is an error if the left argument is shorter than the right one. cinit_list :: [Bool] -> Circ [Bit] Source # A version of cinit_bit for lists. # Higher-order functions with_ancilla :: (Qubit -> Circ a) -> Circ a Source # Convenient wrapper around qinit and qterm. This can be used to introduce an ancilla with a local scope, like this: with_ancilla$ \h -> do {
<<<code block using ancilla h>>>
}

The ancilla will be initialized to |0〉 at the beginning of the block, and it is the programmer's responsibility to ensure that it will be returned to state |0〉 at the end of the block.

A block created with with_ancilla is controllable, provided that the body is controllable.

with_controls :: ControlSource c => c -> Circ a -> Circ a Source #

A syntax for "if"-style (classical and quantum) controls. This can be used as follows:

gate1
with_controls <<controls>> $do { gate2 gate3 } gate4 The specified controls will be applied to gate2 and gate3. It is an error to specify a control for a gate that cannot be controlled (such as measurement). controlled :: ControlSource c => Circ a -> c -> Circ a infixl 2 Source # An infix operator to apply the given controls to a gate: gate controlled <<controls>> It also works with functional-style gates: result <- gate controlled <<controls>> The infix operator is left associative, so it can be applied multiple times: result <- gate controlled <<controls1>> controlled <<controls2>> The latter is equivalent to result <- gate controlled <<controls1>> .&&. <<controls2>> Apply a block of gates while temporarily suspending the application of controls. This can be used to omit controls on gates where they are known to be unnecessary. This is a relatively low-level function and should not normally be called directly by user code. Instead, it is safer to use a higher-level function such as with_basis_change. However, the without_controls operator is useful in certain situations, e.g., it can be used to preserve the NoControlFlag when defining transformers. Usage: without_controls$ do
<<code block>>

or:

without_controls (gate)

Note that all controls specified in the surrounding code are disabled within the without_controls block. This is even true if the without_controls block appears in a subroutine, and the subroutine is later called in a controlled context. On the other hand, it is possible to specify controls inside the without_controls block. Consider this example:

my_subcircuit = do
gate1
without_controls \$ do {
gate2
gate3 controlled <<controls1>>
}
gate4

my_circuit = do
my_subcircuit controlled <<controls2>>

In this example, controls 1 will be applied to gate 3, controls 2 will be applied to gates 1 and 4, and no controls will be applied to gate 2.

Apply without_controls if NoControlFlag is True, otherwise do nothing.

## Deprecated special cases

Generate a new qubit, initialized to the parameter Bool, that is guaranteed to be used as an ancilla and terminated with qterm_qubit_ancilla. Deprecated.

Terminate an ancilla asserted to be in state b. Deprecated.

# Circuit transformers

The identity transformer. This just maps a low-level circuits to the corresponding circuit-generating function. It can also be used as a building block in other transformers, to define "catch-all" clauses for gates that don't need to be transformed.

The identity DynamicTransformer uses the built in do_read operation

Append the entire circuit c to the current circuit, using the given bindings. Return the new bindings.

Append the entire circuit c to the current circuit, using the given bindings, and return the new bindings. Also, add to the current namespace state any subroutines of c that are not already provided.

Append the entire dynamic circuit c to the current circuit, using the given bindings, and return the new bindings. Also, add to the current namespace state any subroutines of c that are not already provided.

# Encapsulated circuits

extract_simple :: ErrMsg -> ExtArity -> Circ a -> (BCircuit, a) Source #

Extract a circuit from a monadic term, starting from the given arity. This is the "simple" extract function, which does not allow dynamic lifting. The ErrMsg argument is a stub error message to be used in case an illegal operation is encountered.

Run a monadic term in the initial arity, and extract a dynamic boxed circuit.

extract_in_context :: ErrMsg -> Circ a -> Circ (BCircuit, IntSet, a) Source #

Similar to extract_simple, except we take the current output arity of the current circuit and make that the input arity of the extracted circuit. Therefore, endpoints defined in the current context can be used in f. This is a low-level operator, intended for the construction of primitives, such as with_computed or with_basis_change, where the inner block can re-use some variables without declaring them explicitly.

We also reuse the namespace of the current context, to avoid recomputation of shared subroutines.

As a special feature, also return the set of "dirty" wires, i.e., wires that were used during the execution of the body, but are free at the end.

Intermediate between extract_simple and extract_in_context: we build the circuit in the namespace of the current circuit, to avoid recomputing any shared subroutines.

Append the BCircuit to the end of the current circuit, using the identity binding. This means, the input wires of BCircuit must be endpoints in the current circuits. This typically happens when BCircuit was obtained from extract_in_context in the current context, or when BCircuit is the inverse of a circuit that has just been applied using unextract_in_context.

Note that this is a low-level function, intended for the construction of user-level primitives such as with_computed and with_basis_change, and classical_to_reversible.

unextract_in_context uses apply_gate to do the appending, so the current ControlList and NoControlFlag are respected. However, it does not pass through the transformer interface, and therefore low-level wire id's will be exactly preserved.

reverse_encapsulated :: (i, BCircuit, o) -> (o, BCircuit, i) Source #

Reverse an encapsulated circuit

An encapsulated circuit is a circuit together with data structures holding the input endpoints and output endpoints. The type of the encapsulated circuit depends on the type of data in the endpoints, so functions to encapsulate and unencapsulate circuits are provided in Quipper.Internal.Generic.

with_reserve :: IntSet -> Circ a -> Circ a Source #

Perform the computation in the body, but temporarily reserve a set of wires. These wires must be initially free, and they must not be used by the body (i.e., the body must respect reserved wires).

# Orphan instances

 (ControlSource (Signed a), ControlSource (Signed b)) => ControlSource (Signed (B_Endpoint a b)) # Instance details Methods (ControlSource a, ControlSource b) => ControlSource (B_Endpoint a b) # Instance details Methods