use super::dataflow::DataflowOpTrait;
use super::{impl_op_name, OpTag};
use crate::extension::ExtensionSet;
use crate::{
extension::ExtensionId,
types::{EdgeKind, Signature, Type, TypeRow},
};
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[non_exhaustive]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct Noop {
pub ty: Type,
}
impl Noop {
pub fn new(ty: Type) -> Self {
Self { ty }
}
}
impl Default for Noop {
fn default() -> Self {
Self { ty: Type::UNIT }
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
#[non_exhaustive]
pub struct MakeTuple {
pub tys: TypeRow,
}
impl MakeTuple {
pub fn new(tys: TypeRow) -> Self {
Self { tys }
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
#[non_exhaustive]
pub struct UnpackTuple {
pub tys: TypeRow,
}
impl UnpackTuple {
pub fn new(tys: TypeRow) -> Self {
Self { tys }
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[non_exhaustive]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct Tag {
pub tag: usize,
pub variants: Vec<TypeRow>,
}
impl Tag {
pub fn new(tag: usize, variants: Vec<TypeRow>) -> Self {
Self { tag, variants }
}
}
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
#[non_exhaustive]
pub struct Lift {
pub type_row: TypeRow,
pub new_extension: ExtensionId,
}
impl Lift {
pub fn new(type_row: TypeRow, new_extension: ExtensionId) -> Self {
Self {
type_row,
new_extension,
}
}
}
impl_op_name!(Noop);
impl_op_name!(MakeTuple);
impl_op_name!(UnpackTuple);
impl_op_name!(Tag);
impl_op_name!(Lift);
impl DataflowOpTrait for Noop {
const TAG: OpTag = OpTag::Leaf;
fn description(&self) -> &str {
"Noop gate"
}
fn signature(&self) -> Signature {
Signature::new(vec![self.ty.clone()], vec![self.ty.clone()])
}
fn other_input(&self) -> Option<EdgeKind> {
Some(EdgeKind::StateOrder)
}
fn other_output(&self) -> Option<EdgeKind> {
Some(EdgeKind::StateOrder)
}
}
impl DataflowOpTrait for MakeTuple {
const TAG: OpTag = OpTag::Leaf;
fn description(&self) -> &str {
"MakeTuple operation"
}
fn signature(&self) -> Signature {
Signature::new(self.tys.clone(), vec![Type::new_tuple(self.tys.clone())])
}
fn other_input(&self) -> Option<EdgeKind> {
Some(EdgeKind::StateOrder)
}
fn other_output(&self) -> Option<EdgeKind> {
Some(EdgeKind::StateOrder)
}
}
impl DataflowOpTrait for UnpackTuple {
const TAG: OpTag = OpTag::Leaf;
fn description(&self) -> &str {
"UnpackTuple operation"
}
fn signature(&self) -> Signature {
Signature::new(vec![Type::new_tuple(self.tys.clone())], self.tys.clone())
}
fn other_input(&self) -> Option<EdgeKind> {
Some(EdgeKind::StateOrder)
}
fn other_output(&self) -> Option<EdgeKind> {
Some(EdgeKind::StateOrder)
}
}
impl DataflowOpTrait for Tag {
const TAG: OpTag = OpTag::Leaf;
fn description(&self) -> &str {
"Tag Sum operation"
}
fn signature(&self) -> Signature {
Signature::new(
self.variants
.get(self.tag)
.expect("Not a valid tag")
.clone(),
vec![Type::new_sum(self.variants.clone())],
)
}
fn other_input(&self) -> Option<EdgeKind> {
Some(EdgeKind::StateOrder)
}
fn other_output(&self) -> Option<EdgeKind> {
Some(EdgeKind::StateOrder)
}
}
impl DataflowOpTrait for Lift {
const TAG: OpTag = OpTag::Leaf;
fn description(&self) -> &str {
"Add a extension requirement to an edge"
}
fn signature(&self) -> Signature {
Signature::new(self.type_row.clone(), self.type_row.clone())
.with_extension_delta(ExtensionSet::singleton(&self.new_extension))
}
fn other_input(&self) -> Option<EdgeKind> {
Some(EdgeKind::StateOrder)
}
fn other_output(&self) -> Option<EdgeKind> {
Some(EdgeKind::StateOrder)
}
}