Skip to content

Commit

Permalink
fix: allow add_input/add_output on all DFGs
Browse files Browse the repository at this point in the history
Closes: #1819
  • Loading branch information
qartik committed Dec 19, 2024
1 parent b7b2bcd commit be7c998
Showing 1 changed file with 84 additions and 84 deletions.
168 changes: 84 additions & 84 deletions hugr-core/src/builder/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,86 +79,6 @@ impl DFGBuilder<Hugr> {
let root = base.root();
DFGBuilder::create_with_io(base, root, signature)
}
}

impl HugrBuilder for DFGBuilder<Hugr> {
fn finish_hugr(mut self) -> Result<Hugr, ValidationError> {
if cfg!(feature = "extension_inference") {
self.base.infer_extensions(false)?;
}
self.base.validate()?;
Ok(self.base)
}
}

impl<T: AsMut<Hugr> + AsRef<Hugr>> Container for DFGBuilder<T> {
#[inline]
fn container_node(&self) -> Node {
self.dfg_node
}

#[inline]
fn hugr_mut(&mut self) -> &mut Hugr {
self.base.as_mut()
}

#[inline]
fn hugr(&self) -> &Hugr {
self.base.as_ref()
}
}

impl<T: AsMut<Hugr> + AsRef<Hugr>> SubContainer for DFGBuilder<T> {
type ContainerHandle = BuildHandle<DfgID>;
#[inline]
fn finish_sub_container(self) -> Result<Self::ContainerHandle, BuildError> {
Ok((self.dfg_node, self.num_out_wires).into())
}
}

impl<T: AsMut<Hugr> + AsRef<Hugr>> Dataflow for DFGBuilder<T> {
#[inline]
fn num_inputs(&self) -> usize {
self.num_in_wires
}
}

/// Wrapper around [`DFGBuilder`] used to build other dataflow regions.
// Stores option of DFGBuilder so it can be taken out without moving.
#[derive(Debug, Clone, PartialEq)]
pub struct DFGWrapper<B, T>(DFGBuilder<B>, PhantomData<T>);

impl<B, T> DFGWrapper<B, T> {
pub(super) fn from_dfg_builder(db: DFGBuilder<B>) -> Self {
Self(db, PhantomData)
}
}

/// Builder for a [`ops::FuncDefn`] node
pub type FunctionBuilder<B> = DFGWrapper<B, BuildHandle<FuncID<true>>>;

impl FunctionBuilder<Hugr> {
/// Initialize a builder for a FuncDefn rooted HUGR
/// # Errors
///
/// Error in adding DFG child nodes.
pub fn new(
name: impl Into<String>,
signature: impl Into<PolyFuncType>,
) -> Result<Self, BuildError> {
let signature = signature.into();
let body = signature.body().clone();
let op = ops::FuncDefn {
signature,
name: name.into(),
};

let base = Hugr::new(op);
let root = base.root();

let db = DFGBuilder::create_with_io(base, root, body)?;
Ok(Self::from_dfg_builder(db))
}

/// Add a new input to the function being constructed.
///
Expand Down Expand Up @@ -194,7 +114,7 @@ impl FunctionBuilder<Hugr> {
}

// Update the builder metadata
self.0.num_in_wires += 1;
self.num_in_wires += 1;

self.input_wires().last().unwrap()
}
Expand Down Expand Up @@ -231,7 +151,7 @@ impl FunctionBuilder<Hugr> {
}

// Update the builder metadata
self.0.num_out_wires += 1;
self.num_out_wires += 1;
}

/// Update the function builder's parent signature.
Expand Down Expand Up @@ -264,6 +184,86 @@ impl FunctionBuilder<Hugr> {
}
}

impl HugrBuilder for DFGBuilder<Hugr> {
fn finish_hugr(mut self) -> Result<Hugr, ValidationError> {
if cfg!(feature = "extension_inference") {
self.base.infer_extensions(false)?;
}
self.base.validate()?;
Ok(self.base)
}
}

impl<T: AsMut<Hugr> + AsRef<Hugr>> Container for DFGBuilder<T> {
#[inline]
fn container_node(&self) -> Node {
self.dfg_node
}

#[inline]
fn hugr_mut(&mut self) -> &mut Hugr {
self.base.as_mut()
}

#[inline]
fn hugr(&self) -> &Hugr {
self.base.as_ref()
}
}

impl<T: AsMut<Hugr> + AsRef<Hugr>> SubContainer for DFGBuilder<T> {
type ContainerHandle = BuildHandle<DfgID>;
#[inline]
fn finish_sub_container(self) -> Result<Self::ContainerHandle, BuildError> {
Ok((self.dfg_node, self.num_out_wires).into())
}
}

impl<T: AsMut<Hugr> + AsRef<Hugr>> Dataflow for DFGBuilder<T> {
#[inline]
fn num_inputs(&self) -> usize {
self.num_in_wires
}
}

/// Wrapper around [`DFGBuilder`] used to build other dataflow regions.
// Stores option of DFGBuilder so it can be taken out without moving.
#[derive(Debug, Clone, PartialEq)]
pub struct DFGWrapper<B, T>(DFGBuilder<B>, PhantomData<T>);

impl<B, T> DFGWrapper<B, T> {
pub(super) fn from_dfg_builder(db: DFGBuilder<B>) -> Self {
Self(db, PhantomData)
}
}

/// Builder for a [`ops::FuncDefn`] node
pub type FunctionBuilder<B> = DFGWrapper<B, BuildHandle<FuncID<true>>>;

impl FunctionBuilder<Hugr> {
/// Initialize a builder for a FuncDefn rooted HUGR
/// # Errors
///
/// Error in adding DFG child nodes.
pub fn new(
name: impl Into<String>,
signature: impl Into<PolyFuncType>,
) -> Result<Self, BuildError> {
let signature = signature.into();
let body = signature.body().clone();
let op = ops::FuncDefn {
signature,
name: name.into(),
};

let base = Hugr::new(op);
let root = base.root();

let db = DFGBuilder::create_with_io(base, root, body)?;
Ok(Self::from_dfg_builder(db))
}
}

impl<B: AsMut<Hugr> + AsRef<Hugr>, T> Container for DFGWrapper<B, T> {
#[inline]
fn container_node(&self) -> Node {
Expand Down Expand Up @@ -465,8 +465,8 @@ pub(crate) mod test {
f_build.set_order(&noop0.node(), &f_build.io()[1]);

// Add a new input and output, and connect them with a noop in between
f_build.add_output(qb_t());
let i1 = f_build.add_input(qb_t());
f_build.0.add_output(qb_t());
let i1 = f_build.0.add_input(qb_t());
let noop1 = f_build.add_dataflow_op(Noop(qb_t()), [i1])?;

let hugr = f_build.finish_hugr_with_outputs([noop0.out_wire(0), noop1.out_wire(0)])?;
Expand Down

0 comments on commit be7c998

Please sign in to comment.