Macro qip::program[][src]

macro_rules! program {
    (@ name_tuple() <- $name : ident ; $($tail : tt) *) => { ... };
    (@ name_tuple($($body : tt) *) <- $name : ident ; $($tail : tt) *) => { ... };
    (@ name_tuple($($body : tt) *) <- $name : ident, $($tail : tt) *) => { ... };
    (@ splitter($builder : expr, $reg_man : ident) $name : ident ; $($tail : tt)
 *) => { ... };
    (@ splitter($builder : expr, $reg_man : ident) $name : ident, $($tail : tt) *) => { ... };
    (@ joiner($builder : expr, $reg_man : ident) $name : ident ; $($tail : tt) *) => { ... };
    (@ joiner($builder : expr, $reg_man : ident) $name : ident, $($tail : tt) *) => { ... };
    (@
 args_acc($builder : expr, $reg_man : ident, $args : ident, $group_vec :
          ident) $name : ident, | ; $($tail : tt) *) => { ... };
    (@
 args_acc($builder : expr, $reg_man : ident, $args : ident, $group_vec :
          ident) $name : ident, | $($tail : tt) *) => { ... };
    (@
 args_acc($builder : expr, $reg_man : ident, $args : ident, $group_vec :
          ident) $name : ident, $($tail : tt) *) => { ... };
    (@ args_acc($builder : expr, $reg_man : ident, $args : ident) | $name : ident,
 $($tail : tt) *) => { ... };
    (@
 args_acc($builder : expr, $reg_man : ident, $args : ident, $group_vec :
          ident) $name : ident $indices : expr, | ; $($tail : tt) *) => { ... };
    (@
 args_acc($builder : expr, $reg_man : ident, $args : ident, $group_vec :
          ident) $name : ident $indices : expr, | $($tail : tt) *) => { ... };
    (@
 args_acc($builder : expr, $reg_man : ident, $args : ident, $group_vec :
          ident) $name : ident $indices : expr, $($tail : tt) *) => { ... };
    (@ args_acc($builder : expr, $reg_man : ident, $args : ident) | $name : ident
 $indices : expr, $($tail : tt) *) => { ... };
    (@ args_acc($builder : expr, $reg_man : ident, $args : ident) $name : ident ;
 $($tail : tt) *) => { ... };
    (@ args_acc($builder : expr, $reg_man : ident, $args : ident) $name : ident,
 $($tail : tt) *) => { ... };
    (@ args_acc($builder : expr, $reg_man : ident, $args : ident) $name : ident
 $indices : expr, $($tail : tt) *) => { ... };
    (@ args_acc($builder : expr, $reg_man : ident, $args : ident) $name : ident
 $indices : expr ;) => { ... };
    (@ args_acc($builder : expr, $reg_man : ident, $args : ident) $name : ident
 $indices : expr ; $($tail : tt) *) => { ... };
    (@ extract_to_args($builder : expr, $reg_man : ident, $args : ident) $name :
 ident $indices : expr) => { ... };
    (@ extract_to_args($builder : expr, $reg_man : ident, $args : ident) $name :
 ident) => { ... };
    (@ replace_registers($builder : expr, $reg_man : ident, $to_replace : ident)) => { ... };
    (@ skip_to_next_program($builder : expr, $reg_man : ident) $name : ident ;) => { ... };
    (@ skip_to_next_program($builder : expr, $reg_man : ident) $name : ident
 $indices : expr ;) => { ... };
    (@ skip_to_next_program($builder : expr, $reg_man : ident) $name : ident, | ;) => { ... };
    (@ skip_to_next_program($builder : expr, $reg_man : ident) $name : ident
 $indices : expr, | ;) => { ... };
    (@ skip_to_next_program($builder : expr, $reg_man : ident) | $name : ident,
 $($tail : tt) *) => { ... };
    (@ skip_to_next_program($builder : expr, $reg_man : ident) | $name : ident
 $indices : expr, $($tail : tt) *) => { ... };
    (@ skip_to_next_program($builder : expr, $reg_man : ident) $name : ident, | ;
 $($tail : tt) *) => { ... };
    (@ skip_to_next_program($builder : expr, $reg_man : ident) $name : ident
 $indices : expr, | ; $($tail : tt) *) => { ... };
    (@ skip_to_next_program($builder : expr, $reg_man : ident) $name : ident, |
 $($tail : tt) *) => { ... };
    (@ skip_to_next_program($builder : expr, $reg_man : ident) $name : ident
 $indices : expr, | $($tail : tt) *) => { ... };
    (@ skip_to_next_program($builder : expr, $reg_man : ident) $name : ident ;
 $($tail : tt) *) => { ... };
    (@ skip_to_next_program($builder : expr, $reg_man : ident) $name : ident
 $indices : expr ; $($tail : tt) *) => { ... };
    (@ skip_to_next_program($builder : expr, $reg_man : ident) $name : ident,
 $($tail : tt) *) => { ... };
    (@ skip_to_next_program($builder : expr, $reg_man : ident) $name : ident
 $indices : expr, $($tail : tt) *) => { ... };
    (@ program($builder : expr, $reg_man : ident) control $func :
 ident($funcargs : expr) $($tail : tt) *) => { ... };
    (@ program($builder : expr, $reg_man : ident) control($control : expr) $func :
 ident($funcargs : expr) $($tail : tt) *) => { ... };
    (@ program($builder : expr, $reg_man : ident) control $func : ident
 $($tail : tt) *) => { ... };
    (@ program($builder : expr, $reg_man : ident) control($control : expr) $func :
 ident $($tail : tt) *) => { ... };
    (@ program($builder : expr, $reg_man : ident) $func : ident($funcargs : expr)
 $($tail : tt) *) => { ... };
    (@ program($builder : expr, $reg_man : ident) $func : ident $($tail : tt) *) => { ... };
    (@ skip_to_program($builder : expr, $reg_man : ident) $name : ident ;
 $($tail : tt) *) => { ... };
    (@ skip_to_program($builder : expr, $reg_man : ident) $name : ident,
 $($tail : tt) *) => { ... };
    ($builder : expr, $($tail : tt) *) => { ... };
}
Expand description

A helper macro for applying functions to specific qubits in registers.

The macro takes an expression which yields &mut dyn UnitaryBuilder, a list of registers, then a series of function call expressions of the form: function [register <indices?>, ...];

Registers can be groups by surrounding them with vertical bars, for example: function |ra, rb[0,2],| rc (Notice the comma is inside the bars, not the best syntax but macros are restrictive).

Example

use qip::*;

let n = 3;
let mut b = OpBuilder::new();
let ra = b.register(n)?;
let rb = b.register(n)?;

let gamma = |b: &mut dyn UnitaryBuilder, mut rs: Vec<Register>| -> Result<Vec<Register>, CircuitError> {
    let rb = rs.pop().unwrap();
    let ra = rs.pop().unwrap();
    let (ra, rb) = b.cnot(ra, rb);
    Ok(vec![ra, rb])
};

// Gamma |ra>|rb[2]>
// Gamma |ra[0]>|rb>
let (ra, rb) = program!(&mut b, ra, rb;
    gamma ra, rb[2];
    gamma ra[0], rb;
)?;
let r = b.merge(vec![ra, rb])?;

Example with grouping

use qip::*;

let n = 3;
let mut b = OpBuilder::new();
let ra = b.register(n)?;
let rb = b.register(n)?;

let gamma = |b: &mut dyn UnitaryBuilder, mut rs: Vec<Register>| -> Result<Vec<Register>, CircuitError> {
    let rb = rs.pop().unwrap();
    let ra = rs.pop().unwrap();
    let (ra, rb) = b.cnot(ra, rb);
    Ok(vec![ra, rb])
};

// Gamma |ra[0] ra[2]>|rb[2]>
// Gamma |ra>|rb[0] rb[2]>
// Gamma |ra[0]>|ra[1,2] rb>
// Gamma |rb[0]>|ra rb[1,2]>
let (ra, rb) = program!(&mut b, ra, rb;
    gamma |ra[0], ra[2],| rb[2];
    gamma ra, |rb[0], rb[2],|;
    gamma ra[0], |ra[1, 2], rb,|;
    gamma rb[0], |ra, rb[1, 2],|;
)?;
let r = b.merge(vec![ra, rb])?;

Example with inline ranges:

use qip::*;

let n = 3;
let mut b = OpBuilder::new();
let ra = b.register(n)?;
let rb = b.register(n)?;

let gamma = |b: &mut dyn UnitaryBuilder, mut rs: Vec<Register>| -> Result<Vec<Register>, CircuitError> {
    let rb = rs.pop().unwrap();
    let ra = rs.pop().unwrap();
    let (ra, rb) = b.cnot(ra, rb);
    Ok(vec![ra, rb])
};

// Gamma |ra[0] ra[1]>|ra[2]>
let (ra, rb) = program!(&mut b, ra, rb;
    gamma ra[0..2], ra[2];
)?;
let r = b.merge(vec![ra, rb])?;

Example with inline control:

use qip::*;

let n = 3;
let mut b = OpBuilder::new();
let ra = b.register(n)?;
let rb = b.register(n)?;

let gamma = |b: &mut dyn UnitaryBuilder, mut rs: Vec<Register>| -> Result<Vec<Register>, CircuitError> {
    let ra = rs.pop().unwrap();
    let ra = b.not(ra);
    Ok(vec![ra])
};

// |ra[0] ra[1]> control Gamma |rb[2]>
let (ra, rb) = program!(&mut b, ra, rb;
    control gamma ra[0..2], rb[2];
)?;
let r = b.merge(vec![ra, rb])?;