///|
/// An effect bound to distinct, ordered quantum IDs.
struct Operation[Q] {
effect : &Effect
wires : Array[Q]
}
///|
pub fn[Q : Qid] Operation::new(
effect : &Effect,
targets : Array[Q],
) -> Operation[Q] raise QuantumError {
let shape = effect.dimensions()
if shape.length() != targets.length() {
raise TargetCount(shape.length(), targets.length())
}
let seen : Map[Q, Bool] = Map([])
for i, q in targets {
if seen.contains(q) {
raise DuplicateQid(i)
}
seen[q] = true
let actual = q.dimension()
let expected = shape[i]
if actual != expected {
raise DimensionMismatch(i, expected, actual)
}
}
{ effect, wires: targets.copy(), }
}
///|
/// Return the effect's direct unitary capability, if present.
pub fn[Q] Operation::gate(self : Operation[Q]) -> Gate? {
self.effect.try_unitary()
}
///|
/// Return the immutable effect bound by this operation.
pub fn[Q] Operation::effect(self : Operation[Q]) -> &Effect {
self.effect
}
///|
/// Return a copy of the logical targets in effect wire order.
pub fn[Q] Operation::targets(self : Operation[Q]) -> Array[Q] {
self.wires.copy()
}
///|
pub impl[Q : Debug] Debug for Operation[Q] with fn to_repr(self) {
Debug::to_repr((self.effect.name(), self.wires))
}
///|
pub extend Operation with Debug::{to_repr}