#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Step {
H(u8),
S(u8),
Cx(u8, u8),
}
pub struct GateDef {
pub name: &'static str,
pub arity: u8,
pub steps: &'static [Step],
pub aliases: &'static [&'static str],
}
pub const GATES: &[GateDef] = &[
GateDef { name: "CXSWAP", arity: 2, steps: &[Step::Cx(1, 0), Step::Cx(0, 1)], aliases: &[] },
GateDef { name: "CY", arity: 2, steps: &[Step::H(0), Step::Cx(1, 0), Step::H(0), Step::S(0), Step::Cx(0, 1)], aliases: &["ZCY"] },
GateDef { name: "CZSWAP", arity: 2, steps: &[Step::H(0), Step::Cx(0, 1), Step::Cx(1, 0), Step::H(1)], aliases: &["SWAPCZ"] },
GateDef { name: "C_NXYZ", arity: 1, steps: &[Step::H(0), Step::S(0), Step::H(0), Step::S(0), Step::S(0), Step::S(0)], aliases: &[] },
GateDef { name: "C_NZYX", arity: 1, steps: &[Step::H(0), Step::S(0), Step::H(0), Step::S(0), Step::S(0), Step::H(0)], aliases: &[] },
GateDef { name: "C_XNYZ", arity: 1, steps: &[Step::S(0), Step::H(0)], aliases: &[] },
GateDef { name: "C_XYNZ", arity: 1, steps: &[Step::S(0), Step::H(0), Step::S(0), Step::S(0)], aliases: &[] },
GateDef { name: "C_XYZ", arity: 1, steps: &[Step::H(0), Step::S(0), Step::H(0), Step::S(0)], aliases: &[] },
GateDef { name: "C_ZNYX", arity: 1, steps: &[Step::H(0), Step::S(0), Step::S(0), Step::S(0)], aliases: &[] },
GateDef { name: "C_ZYNX", arity: 1, steps: &[Step::S(0), Step::S(0), Step::H(0), Step::S(0)], aliases: &[] },
GateDef { name: "C_ZYX", arity: 1, steps: &[Step::H(0), Step::S(0)], aliases: &[] },
GateDef { name: "H_NXY", arity: 1, steps: &[Step::S(0), Step::H(0), Step::S(0), Step::S(0), Step::H(0)], aliases: &[] },
GateDef { name: "H_NXZ", arity: 1, steps: &[Step::S(0), Step::S(0), Step::H(0), Step::S(0), Step::S(0)], aliases: &[] },
GateDef { name: "H_NYZ", arity: 1, steps: &[Step::S(0), Step::H(0), Step::S(0), Step::S(0), Step::S(0)], aliases: &[] },
GateDef { name: "H_XY", arity: 1, steps: &[Step::H(0), Step::S(0), Step::S(0), Step::H(0), Step::S(0)], aliases: &[] },
GateDef { name: "H_YZ", arity: 1, steps: &[Step::H(0), Step::S(0), Step::H(0), Step::S(0), Step::S(0)], aliases: &[] },
GateDef { name: "II", arity: 2, steps: &[], aliases: &[] },
GateDef { name: "ISWAP", arity: 2, steps: &[Step::Cx(0, 1), Step::S(1), Step::Cx(1, 0), Step::Cx(0, 1)], aliases: &[] },
GateDef { name: "ISWAP_DAG", arity: 2, steps: &[Step::Cx(0, 1), Step::S(1), Step::S(1), Step::S(1), Step::Cx(1, 0), Step::Cx(0, 1)], aliases: &[] },
GateDef { name: "SQRT_X", arity: 1, steps: &[Step::H(0), Step::S(0), Step::H(0)], aliases: &[] },
GateDef { name: "SQRT_XX", arity: 2, steps: &[Step::Cx(0, 1), Step::H(0), Step::S(0), Step::H(0), Step::Cx(0, 1)], aliases: &[] },
GateDef { name: "SQRT_XX_DAG", arity: 2, steps: &[Step::S(0), Step::Cx(0, 1), Step::H(0), Step::S(0), Step::Cx(0, 1)], aliases: &[] },
GateDef { name: "SQRT_X_DAG", arity: 1, steps: &[Step::S(0), Step::H(0), Step::S(0)], aliases: &[] },
GateDef { name: "SQRT_Y", arity: 1, steps: &[Step::S(0), Step::S(0), Step::H(0)], aliases: &[] },
GateDef { name: "SQRT_YY", arity: 2, steps: &[Step::S(0), Step::Cx(1, 0), Step::H(1), Step::S(0), Step::S(0), Step::Cx(1, 0), Step::S(0)], aliases: &[] },
GateDef { name: "SQRT_YY_DAG", arity: 2, steps: &[Step::Cx(0, 1), Step::H(0), Step::S(0), Step::H(0), Step::S(1), Step::Cx(1, 0), Step::Cx(0, 1)], aliases: &[] },
GateDef { name: "SQRT_Y_DAG", arity: 1, steps: &[Step::H(0), Step::S(0), Step::S(0)], aliases: &[] },
GateDef { name: "SQRT_ZZ", arity: 2, steps: &[Step::Cx(0, 1), Step::S(1), Step::Cx(0, 1)], aliases: &[] },
GateDef { name: "SQRT_ZZ_DAG", arity: 2, steps: &[Step::Cx(0, 1), Step::S(1), Step::S(1), Step::S(1), Step::Cx(0, 1)], aliases: &[] },
GateDef { name: "SWAP", arity: 2, steps: &[Step::Cx(0, 1), Step::Cx(1, 0), Step::Cx(0, 1)], aliases: &[] },
GateDef { name: "SWAPCX", arity: 2, steps: &[Step::Cx(0, 1), Step::Cx(1, 0)], aliases: &[] },
GateDef { name: "S_DAG", arity: 1, steps: &[Step::S(0), Step::S(0), Step::S(0)], aliases: &["SQRT_Z_DAG"] },
GateDef { name: "XCX", arity: 2, steps: &[Step::H(0), Step::Cx(0, 1), Step::H(0)], aliases: &[] },
GateDef { name: "XCY", arity: 2, steps: &[Step::Cx(1, 0), Step::H(0), Step::S(0), Step::Cx(0, 1), Step::H(0)], aliases: &[] },
GateDef { name: "XCZ", arity: 2, steps: &[Step::Cx(1, 0)], aliases: &[] },
GateDef { name: "YCX", arity: 2, steps: &[Step::Cx(0, 1), Step::H(1), Step::S(1), Step::Cx(1, 0), Step::H(1)], aliases: &[] },
GateDef { name: "YCY", arity: 2, steps: &[Step::H(0), Step::H(1), Step::S(0), Step::Cx(1, 0), Step::H(1), Step::Cx(1, 0), Step::S(0)], aliases: &[] },
GateDef { name: "YCZ", arity: 2, steps: &[Step::H(0), Step::S(1), Step::Cx(1, 0), Step::H(0), Step::Cx(1, 0)], aliases: &[] },
];
pub fn find(name: &str) -> Option<&'static GateDef> {
GATES.iter().find(|g| g.name == name || g.aliases.contains(&name))
}