From eeb9e73ded9df7284cd276b3bf7a4299f6a50a62 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Sun, 24 Nov 2024 03:47:30 +0000 Subject: [PATCH 01/17] Add Buildable trait. TODO can we make it return a HugrView+HugrMut ? --- hugr-core/src/builder.rs | 2 +- hugr-core/src/builder/build_traits.rs | 28 ++++++++++++++++++++++++ hugr-core/src/builder/cfg.rs | 18 +++++++++------ hugr-core/src/builder/conditional.rs | 8 +++---- hugr-core/src/builder/dataflow.rs | 16 +++++++------- hugr-core/src/builder/module.rs | 6 ++--- hugr-core/src/builder/tail_loop.rs | 3 ++- hugr-core/src/hugr/rewrite/inline_dfg.rs | 7 +++--- hugr-core/src/hugr/rewrite/replace.rs | 4 ++-- hugr-core/src/package.rs | 2 +- hugr-passes/src/merge_bbs.rs | 8 ++++--- hugr-passes/src/nest_cfgs.rs | 8 +++---- hugr/benches/benchmarks/hugr/examples.rs | 8 +++---- 13 files changed, 75 insertions(+), 43 deletions(-) diff --git a/hugr-core/src/builder.rs b/hugr-core/src/builder.rs index f40703243..3c7f84300 100644 --- a/hugr-core/src/builder.rs +++ b/hugr-core/src/builder.rs @@ -102,7 +102,7 @@ pub use handle::BuildHandle; mod build_traits; pub use build_traits::{ - Container, Dataflow, DataflowHugr, DataflowSubContainer, HugrBuilder, SubContainer, + Buildable, Container, Dataflow, DataflowHugr, DataflowSubContainer, HugrBuilder, SubContainer, }; mod dataflow; diff --git a/hugr-core/src/builder/build_traits.rs b/hugr-core/src/builder/build_traits.rs index cb05f2552..32ca85b86 100644 --- a/hugr-core/src/builder/build_traits.rs +++ b/hugr-core/src/builder/build_traits.rs @@ -33,6 +33,34 @@ use crate::Hugr; use crate::hugr::HugrMut; +/// A thing the builder can operate on. Either a `Hugr` or an `&mut Hugr`. +pub trait Buildable { + /// Gets a reference to the underlying `Hugr` + fn as_ref(&self) -> &Hugr; + /// Gets a mutable reference to the underlying `Hugr` + fn as_mut(&mut self) -> &mut Hugr; +} + +impl Buildable for Hugr { + fn as_ref(&self) -> &Hugr { + self + } + + fn as_mut(&mut self) -> &mut Hugr { + self + } +} + +impl Buildable for &mut Hugr { + fn as_ref(&self) -> &Hugr { + self + } + + fn as_mut(&mut self) -> &mut Hugr { + self + } +} + /// Trait for HUGR container builders. /// Containers are nodes that are parents of sibling graphs. /// Implementations of this trait allow the child sibling graph to be added to diff --git a/hugr-core/src/builder/cfg.rs b/hugr-core/src/builder/cfg.rs index bcb6aff3b..f42daa0cf 100644 --- a/hugr-core/src/builder/cfg.rs +++ b/hugr-core/src/builder/cfg.rs @@ -2,7 +2,7 @@ use super::{ build_traits::SubContainer, dataflow::{DFGBuilder, DFGWrapper}, handle::BuildHandle, - BasicBlockID, BuildError, CfgID, Container, Dataflow, HugrBuilder, Wire, + BasicBlockID, BuildError, Buildable, CfgID, Container, Dataflow, HugrBuilder, Wire, }; use crate::{ @@ -124,7 +124,7 @@ pub struct CFGBuilder { pub(super) n_out_wires: usize, } -impl + AsRef> Container for CFGBuilder { +impl Container for CFGBuilder { #[inline] fn container_node(&self) -> Node { self.cfg_node @@ -141,7 +141,7 @@ impl + AsRef> Container for CFGBuilder { } } -impl + AsRef> SubContainer for CFGBuilder { +impl SubContainer for CFGBuilder { type ContainerHandle = BuildHandle; #[inline] fn finish_sub_container(self) -> Result { @@ -172,7 +172,7 @@ impl HugrBuilder for CFGBuilder { } } -impl + AsRef> CFGBuilder { +impl CFGBuilder { pub(super) fn create( mut base: B, cfg_node: Node, @@ -381,7 +381,7 @@ impl + AsRef> CFGBuilder { /// Builder for a [`DataflowBlock`] child graph. pub type BlockBuilder = DFGWrapper; -impl + AsRef> BlockBuilder { +impl BlockBuilder { /// Set the outputs of the block, with `branch_wire` carrying the value of the /// branch controlling Sum value. `outputs` are the remaining outputs. pub fn set_outputs( @@ -392,7 +392,11 @@ impl + AsRef> BlockBuilder { Dataflow::set_outputs(self, [branch_wire].into_iter().chain(outputs)) } fn create(base: B, block_n: Node) -> Result { - let block_op = base.get_optype(block_n).as_dataflow_block().unwrap(); + let block_op = base + .as_ref() + .get_optype(block_n) + .as_dataflow_block() + .unwrap(); let signature = block_op.inner_signature(); let db = DFGBuilder::create_with_io(base, block_n, signature)?; Ok(BlockBuilder::from_dfg_builder(db)) @@ -505,7 +509,7 @@ pub(crate) mod test { Ok(()) } - pub(crate) fn build_basic_cfg + AsRef>( + pub(crate) fn build_basic_cfg( cfg_builder: &mut CFGBuilder, ) -> Result<(), BuildError> { let sum2_variants = vec![type_row![NAT], type_row![NAT]]; diff --git a/hugr-core/src/builder/conditional.rs b/hugr-core/src/builder/conditional.rs index 685d2c889..a30e7cfb4 100644 --- a/hugr-core/src/builder/conditional.rs +++ b/hugr-core/src/builder/conditional.rs @@ -8,12 +8,12 @@ use crate::ops::handle::CaseID; use super::build_traits::SubContainer; use super::handle::BuildHandle; -use super::HugrBuilder; use super::{ build_traits::Container, dataflow::{DFGBuilder, DFGWrapper}, BuildError, ConditionalID, }; +use super::{Buildable, HugrBuilder}; use crate::Node; use crate::{extension::ExtensionSet, hugr::HugrMut, Hugr}; @@ -51,7 +51,7 @@ pub struct ConditionalBuilder { pub(super) case_nodes: Vec>, } -impl + AsRef> Container for ConditionalBuilder { +impl Container for ConditionalBuilder { #[inline] fn container_node(&self) -> Node { self.conditional_node @@ -68,7 +68,7 @@ impl + AsRef> Container for ConditionalBuilder { } } -impl + AsRef> SubContainer for ConditionalBuilder { +impl SubContainer for ConditionalBuilder { type ContainerHandle = BuildHandle; fn finish_sub_container(self) -> Result { @@ -88,7 +88,7 @@ impl + AsRef> SubContainer for ConditionalBuilder { Ok((self.conditional_node, self.n_out_wires).into()) } } -impl + AsRef> ConditionalBuilder { +impl ConditionalBuilder { /// Return a builder the Case node with index `case`. /// /// # Panics diff --git a/hugr-core/src/builder/dataflow.rs b/hugr-core/src/builder/dataflow.rs index 04ec38b4b..bee75e5d8 100644 --- a/hugr-core/src/builder/dataflow.rs +++ b/hugr-core/src/builder/dataflow.rs @@ -2,7 +2,7 @@ use itertools::Itertools; use super::build_traits::{HugrBuilder, SubContainer}; use super::handle::BuildHandle; -use super::{BuildError, Container, Dataflow, DfgID, FuncID}; +use super::{BuildError, Buildable, Container, Dataflow, DfgID, FuncID}; use std::marker::PhantomData; @@ -27,7 +27,7 @@ pub struct DFGBuilder { pub(crate) num_out_wires: usize, } -impl + AsRef> DFGBuilder { +impl DFGBuilder { pub(super) fn create_with_io( mut base: T, parent: Node, @@ -92,7 +92,7 @@ impl HugrBuilder for DFGBuilder { } } -impl + AsRef> Container for DFGBuilder { +impl Container for DFGBuilder { #[inline] fn container_node(&self) -> Node { self.dfg_node @@ -109,7 +109,7 @@ impl + AsRef> Container for DFGBuilder { } } -impl + AsRef> SubContainer for DFGBuilder { +impl SubContainer for DFGBuilder { type ContainerHandle = BuildHandle; #[inline] fn finish_sub_container(self) -> Result { @@ -117,7 +117,7 @@ impl + AsRef> SubContainer for DFGBuilder { } } -impl + AsRef> Dataflow for DFGBuilder { +impl Dataflow for DFGBuilder { #[inline] fn num_inputs(&self) -> usize { self.num_in_wires @@ -265,7 +265,7 @@ impl FunctionBuilder { } } -impl + AsRef, T> Container for DFGWrapper { +impl Container for DFGWrapper { #[inline] fn container_node(&self) -> Node { self.0.container_node() @@ -282,14 +282,14 @@ impl + AsRef, T> Container for DFGWrapper { } } -impl + AsRef, T> Dataflow for DFGWrapper { +impl Dataflow for DFGWrapper { #[inline] fn num_inputs(&self) -> usize { self.0.num_inputs() } } -impl + AsRef, T: From>> SubContainer for DFGWrapper { +impl>> SubContainer for DFGWrapper { type ContainerHandle = T; #[inline] diff --git a/hugr-core/src/builder/module.rs b/hugr-core/src/builder/module.rs index d2f144e04..e49b91f30 100644 --- a/hugr-core/src/builder/module.rs +++ b/hugr-core/src/builder/module.rs @@ -1,7 +1,7 @@ use super::{ build_traits::HugrBuilder, dataflow::{DFGBuilder, FunctionBuilder}, - BuildError, Container, + BuildError, Buildable, Container, }; use crate::extension::ExtensionRegistry; @@ -20,7 +20,7 @@ use smol_str::SmolStr; #[derive(Debug, Clone, PartialEq)] pub struct ModuleBuilder(pub(super) T); -impl + AsRef> Container for ModuleBuilder { +impl Container for ModuleBuilder { #[inline] fn container_node(&self) -> Node { self.0.as_ref().root() @@ -60,7 +60,7 @@ impl HugrBuilder for ModuleBuilder { } } -impl + AsRef> ModuleBuilder { +impl ModuleBuilder { /// Replace a [`ops::FuncDecl`] with [`ops::FuncDefn`] and return a builder for /// the defining graph. /// diff --git a/hugr-core/src/builder/tail_loop.rs b/hugr-core/src/builder/tail_loop.rs index 29134ce03..1d2703787 100644 --- a/hugr-core/src/builder/tail_loop.rs +++ b/hugr-core/src/builder/tail_loop.rs @@ -6,6 +6,7 @@ use crate::types::{Signature, TypeRow}; use crate::{Hugr, Node}; use super::handle::BuildHandle; +use super::Buildable; use super::{ dataflow::{DFGBuilder, DFGWrapper}, BuildError, Container, Dataflow, TailLoopID, Wire, @@ -14,7 +15,7 @@ use super::{ /// Builder for a [`ops::TailLoop`] node. pub type TailLoopBuilder = DFGWrapper>; -impl + AsRef> TailLoopBuilder { +impl TailLoopBuilder { pub(super) fn create_with_io( base: B, loop_node: Node, diff --git a/hugr-core/src/hugr/rewrite/inline_dfg.rs b/hugr-core/src/hugr/rewrite/inline_dfg.rs index ff400a1d3..0eda5a30c 100644 --- a/hugr-core/src/hugr/rewrite/inline_dfg.rs +++ b/hugr-core/src/hugr/rewrite/inline_dfg.rs @@ -147,8 +147,7 @@ mod test { use crate::std_extensions::arithmetic::int_types::{self, ConstInt}; use crate::types::Signature; use crate::utils::test_quantum_extension; - use crate::{type_row, Direction, HugrView, Node, Port}; - use crate::{Hugr, Wire}; + use crate::{type_row, Direction, HugrView, Node, Port, Wire}; use super::InlineDFG; @@ -167,7 +166,7 @@ mod test { #[case(true)] #[case(false)] fn inline_add_load_const(#[case] nonlocal: bool) -> Result<(), Box> { - use crate::extension::prelude::Lift; + use crate::{builder::Buildable, extension::prelude::Lift}; let reg = ExtensionRegistry::try_new([ PRELUDE.to_owned(), @@ -179,7 +178,7 @@ mod test { let mut outer = DFGBuilder::new(inout_sig(vec![int_ty.clone(); 2], vec![int_ty.clone()]))?; let [a, b] = outer.input_wires_arr(); - fn make_const + AsRef>( + fn make_const( d: &mut DFGBuilder, ) -> Result> { let int_ty = &int_types::INT_TYPES[6]; diff --git a/hugr-core/src/hugr/rewrite/replace.rs b/hugr-core/src/hugr/rewrite/replace.rs index 8967df9a5..d4bc42409 100644 --- a/hugr-core/src/hugr/rewrite/replace.rs +++ b/hugr-core/src/hugr/rewrite/replace.rs @@ -448,7 +448,7 @@ mod test { use itertools::Itertools; use crate::builder::{ - endo_sig, BuildError, CFGBuilder, Container, DFGBuilder, Dataflow, DataflowHugr, + endo_sig, BuildError, Buildable, CFGBuilder, Container, DFGBuilder, Dataflow, DataflowHugr, DataflowSubContainer, HugrBuilder, SubContainer, }; use crate::extension::prelude::{BOOL_T, USIZE_T}; @@ -605,7 +605,7 @@ mod test { .unwrap() } - fn single_node_block + AsMut, O: DataflowOpTrait + Into>( + fn single_node_block>( h: &mut CFGBuilder, op: O, pred_const: &ConstID, diff --git a/hugr-core/src/package.rs b/hugr-core/src/package.rs index 291b61ebe..76f4297e1 100644 --- a/hugr-core/src/package.rs +++ b/hugr-core/src/package.rs @@ -392,7 +392,7 @@ mod test { #[case::simple(simple_package())] fn package_roundtrip(#[case] package: Package) { let json = package.to_json().unwrap(); - let new_package = Package::from_json(&json).unwrap(); + let new_package = Package::from_json(json).unwrap(); assert_eq!(package, new_package); } diff --git a/hugr-passes/src/merge_bbs.rs b/hugr-passes/src/merge_bbs.rs index 249eed6b4..b10ab6703 100644 --- a/hugr-passes/src/merge_bbs.rs +++ b/hugr-passes/src/merge_bbs.rs @@ -162,7 +162,9 @@ mod test { use itertools::Itertools; use rstest::rstest; - use hugr_core::builder::{endo_sig, inout_sig, CFGBuilder, DFGWrapper, Dataflow, HugrBuilder}; + use hugr_core::builder::{ + endo_sig, inout_sig, Buildable, CFGBuilder, DFGWrapper, Dataflow, HugrBuilder, + }; use hugr_core::extension::prelude::{ConstUsize, PRELUDE_ID, QB_T, USIZE_T}; use hugr_core::extension::{ExtensionRegistry, PRELUDE, PRELUDE_REGISTRY}; use hugr_core::hugr::views::sibling::SiblingMut; @@ -170,7 +172,7 @@ mod test { use hugr_core::ops::handle::CfgID; use hugr_core::ops::{LoadConstant, OpTrait, OpType}; use hugr_core::types::{Signature, Type, TypeRow}; - use hugr_core::{const_extension_ids, type_row, Extension, Hugr, HugrView, Wire}; + use hugr_core::{const_extension_ids, type_row, Extension, HugrView, Wire}; use super::merge_basic_blocks; @@ -195,7 +197,7 @@ mod test { e } - fn lifted_unary_unit_sum + AsRef, T>(b: &mut DFGWrapper) -> Wire { + fn lifted_unary_unit_sum(b: &mut DFGWrapper) -> Wire { let lc = b.add_load_value(Value::unary_unit_sum()); let lift = b .add_dataflow_op( diff --git a/hugr-passes/src/nest_cfgs.rs b/hugr-passes/src/nest_cfgs.rs index fa7106432..5860e9cd5 100644 --- a/hugr-passes/src/nest_cfgs.rs +++ b/hugr-passes/src/nest_cfgs.rs @@ -568,7 +568,7 @@ impl EdgeClassifier { pub(crate) mod test { use super::*; use hugr_core::builder::{ - endo_sig, BuildError, CFGBuilder, Container, DataflowSubContainer, HugrBuilder, + endo_sig, BuildError, Buildable, CFGBuilder, Container, DataflowSubContainer, HugrBuilder, }; use hugr_core::extension::PRELUDE_REGISTRY; use hugr_core::extension::{prelude::USIZE_T, ExtensionSet}; @@ -839,7 +839,7 @@ pub(crate) mod test { dataflow_builder.finish_with_outputs([u].into_iter().chain(w)) } - fn build_if_then_else_merge + AsRef>( + fn build_if_then_else_merge( cfg: &mut CFGBuilder, const_pred: &ConstID, unit_const: &ConstID, @@ -849,7 +849,7 @@ pub(crate) mod test { Ok((split, merge)) } - fn build_then_else_merge_from_if + AsRef>( + fn build_then_else_merge_from_if( cfg: &mut CFGBuilder, unit_const: &ConstID, split: BasicBlockID, @@ -902,7 +902,7 @@ pub(crate) mod test { Ok((h, head, tail)) } - pub(crate) fn build_conditional_in_loop + AsRef>( + pub(crate) fn build_conditional_in_loop( cfg_builder: &mut CFGBuilder, separate_headers: bool, ) -> Result<(BasicBlockID, BasicBlockID), BuildError> { diff --git a/hugr/benches/benchmarks/hugr/examples.rs b/hugr/benches/benchmarks/hugr/examples.rs index 3abcee535..659a10d9d 100644 --- a/hugr/benches/benchmarks/hugr/examples.rs +++ b/hugr/benches/benchmarks/hugr/examples.rs @@ -1,8 +1,8 @@ //! Builders and utilities for benchmarks. use hugr::builder::{ - BuildError, CFGBuilder, Container, DFGBuilder, Dataflow, DataflowHugr, DataflowSubContainer, - HugrBuilder, ModuleBuilder, + BuildError, Buildable, CFGBuilder, Container, DFGBuilder, Dataflow, DataflowHugr, + DataflowSubContainer, HugrBuilder, ModuleBuilder, }; use hugr::extension::prelude::{BOOL_T, QB_T, USIZE_T}; use hugr::extension::PRELUDE_REGISTRY; @@ -20,9 +20,7 @@ pub fn simple_dfg_hugr() -> Hugr { dfg_builder.finish_prelude_hugr_with_outputs([i1]).unwrap() } -pub fn simple_cfg_builder + AsRef>( - cfg_builder: &mut CFGBuilder, -) -> Result<(), BuildError> { +pub fn simple_cfg_builder(cfg_builder: &mut CFGBuilder) -> Result<(), BuildError> { let sum2_variants = vec![type_row![USIZE_T], type_row![USIZE_T]]; let mut entry_b = cfg_builder.entry_builder(sum2_variants.clone(), type_row![])?; let entry = { From 8acf6c2fabc4959d2fbf3c938cd39c900dd72ac5 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Sun, 24 Nov 2024 04:02:32 +0000 Subject: [PATCH 02/17] Revert "Add Buildable trait. TODO can we make it return a HugrView+HugrMut ?" This reverts commit 925940be354e0a1294b9d90b8da70778ebcaf867. --- hugr-core/src/builder.rs | 2 +- hugr-core/src/builder/build_traits.rs | 28 ------------------------ hugr-core/src/builder/cfg.rs | 18 ++++++--------- hugr-core/src/builder/conditional.rs | 8 +++---- hugr-core/src/builder/dataflow.rs | 16 +++++++------- hugr-core/src/builder/module.rs | 6 ++--- hugr-core/src/builder/tail_loop.rs | 3 +-- hugr-core/src/hugr/rewrite/inline_dfg.rs | 7 +++--- hugr-core/src/hugr/rewrite/replace.rs | 4 ++-- hugr-core/src/package.rs | 2 +- hugr-passes/src/merge_bbs.rs | 8 +++---- hugr-passes/src/nest_cfgs.rs | 8 +++---- hugr/benches/benchmarks/hugr/examples.rs | 8 ++++--- 13 files changed, 43 insertions(+), 75 deletions(-) diff --git a/hugr-core/src/builder.rs b/hugr-core/src/builder.rs index 3c7f84300..f40703243 100644 --- a/hugr-core/src/builder.rs +++ b/hugr-core/src/builder.rs @@ -102,7 +102,7 @@ pub use handle::BuildHandle; mod build_traits; pub use build_traits::{ - Buildable, Container, Dataflow, DataflowHugr, DataflowSubContainer, HugrBuilder, SubContainer, + Container, Dataflow, DataflowHugr, DataflowSubContainer, HugrBuilder, SubContainer, }; mod dataflow; diff --git a/hugr-core/src/builder/build_traits.rs b/hugr-core/src/builder/build_traits.rs index 32ca85b86..cb05f2552 100644 --- a/hugr-core/src/builder/build_traits.rs +++ b/hugr-core/src/builder/build_traits.rs @@ -33,34 +33,6 @@ use crate::Hugr; use crate::hugr::HugrMut; -/// A thing the builder can operate on. Either a `Hugr` or an `&mut Hugr`. -pub trait Buildable { - /// Gets a reference to the underlying `Hugr` - fn as_ref(&self) -> &Hugr; - /// Gets a mutable reference to the underlying `Hugr` - fn as_mut(&mut self) -> &mut Hugr; -} - -impl Buildable for Hugr { - fn as_ref(&self) -> &Hugr { - self - } - - fn as_mut(&mut self) -> &mut Hugr { - self - } -} - -impl Buildable for &mut Hugr { - fn as_ref(&self) -> &Hugr { - self - } - - fn as_mut(&mut self) -> &mut Hugr { - self - } -} - /// Trait for HUGR container builders. /// Containers are nodes that are parents of sibling graphs. /// Implementations of this trait allow the child sibling graph to be added to diff --git a/hugr-core/src/builder/cfg.rs b/hugr-core/src/builder/cfg.rs index f42daa0cf..bcb6aff3b 100644 --- a/hugr-core/src/builder/cfg.rs +++ b/hugr-core/src/builder/cfg.rs @@ -2,7 +2,7 @@ use super::{ build_traits::SubContainer, dataflow::{DFGBuilder, DFGWrapper}, handle::BuildHandle, - BasicBlockID, BuildError, Buildable, CfgID, Container, Dataflow, HugrBuilder, Wire, + BasicBlockID, BuildError, CfgID, Container, Dataflow, HugrBuilder, Wire, }; use crate::{ @@ -124,7 +124,7 @@ pub struct CFGBuilder { pub(super) n_out_wires: usize, } -impl Container for CFGBuilder { +impl + AsRef> Container for CFGBuilder { #[inline] fn container_node(&self) -> Node { self.cfg_node @@ -141,7 +141,7 @@ impl Container for CFGBuilder { } } -impl SubContainer for CFGBuilder { +impl + AsRef> SubContainer for CFGBuilder { type ContainerHandle = BuildHandle; #[inline] fn finish_sub_container(self) -> Result { @@ -172,7 +172,7 @@ impl HugrBuilder for CFGBuilder { } } -impl CFGBuilder { +impl + AsRef> CFGBuilder { pub(super) fn create( mut base: B, cfg_node: Node, @@ -381,7 +381,7 @@ impl CFGBuilder { /// Builder for a [`DataflowBlock`] child graph. pub type BlockBuilder = DFGWrapper; -impl BlockBuilder { +impl + AsRef> BlockBuilder { /// Set the outputs of the block, with `branch_wire` carrying the value of the /// branch controlling Sum value. `outputs` are the remaining outputs. pub fn set_outputs( @@ -392,11 +392,7 @@ impl BlockBuilder { Dataflow::set_outputs(self, [branch_wire].into_iter().chain(outputs)) } fn create(base: B, block_n: Node) -> Result { - let block_op = base - .as_ref() - .get_optype(block_n) - .as_dataflow_block() - .unwrap(); + let block_op = base.get_optype(block_n).as_dataflow_block().unwrap(); let signature = block_op.inner_signature(); let db = DFGBuilder::create_with_io(base, block_n, signature)?; Ok(BlockBuilder::from_dfg_builder(db)) @@ -509,7 +505,7 @@ pub(crate) mod test { Ok(()) } - pub(crate) fn build_basic_cfg( + pub(crate) fn build_basic_cfg + AsRef>( cfg_builder: &mut CFGBuilder, ) -> Result<(), BuildError> { let sum2_variants = vec![type_row![NAT], type_row![NAT]]; diff --git a/hugr-core/src/builder/conditional.rs b/hugr-core/src/builder/conditional.rs index a30e7cfb4..685d2c889 100644 --- a/hugr-core/src/builder/conditional.rs +++ b/hugr-core/src/builder/conditional.rs @@ -8,12 +8,12 @@ use crate::ops::handle::CaseID; use super::build_traits::SubContainer; use super::handle::BuildHandle; +use super::HugrBuilder; use super::{ build_traits::Container, dataflow::{DFGBuilder, DFGWrapper}, BuildError, ConditionalID, }; -use super::{Buildable, HugrBuilder}; use crate::Node; use crate::{extension::ExtensionSet, hugr::HugrMut, Hugr}; @@ -51,7 +51,7 @@ pub struct ConditionalBuilder { pub(super) case_nodes: Vec>, } -impl Container for ConditionalBuilder { +impl + AsRef> Container for ConditionalBuilder { #[inline] fn container_node(&self) -> Node { self.conditional_node @@ -68,7 +68,7 @@ impl Container for ConditionalBuilder { } } -impl SubContainer for ConditionalBuilder { +impl + AsRef> SubContainer for ConditionalBuilder { type ContainerHandle = BuildHandle; fn finish_sub_container(self) -> Result { @@ -88,7 +88,7 @@ impl SubContainer for ConditionalBuilder { Ok((self.conditional_node, self.n_out_wires).into()) } } -impl ConditionalBuilder { +impl + AsRef> ConditionalBuilder { /// Return a builder the Case node with index `case`. /// /// # Panics diff --git a/hugr-core/src/builder/dataflow.rs b/hugr-core/src/builder/dataflow.rs index bee75e5d8..04ec38b4b 100644 --- a/hugr-core/src/builder/dataflow.rs +++ b/hugr-core/src/builder/dataflow.rs @@ -2,7 +2,7 @@ use itertools::Itertools; use super::build_traits::{HugrBuilder, SubContainer}; use super::handle::BuildHandle; -use super::{BuildError, Buildable, Container, Dataflow, DfgID, FuncID}; +use super::{BuildError, Container, Dataflow, DfgID, FuncID}; use std::marker::PhantomData; @@ -27,7 +27,7 @@ pub struct DFGBuilder { pub(crate) num_out_wires: usize, } -impl DFGBuilder { +impl + AsRef> DFGBuilder { pub(super) fn create_with_io( mut base: T, parent: Node, @@ -92,7 +92,7 @@ impl HugrBuilder for DFGBuilder { } } -impl Container for DFGBuilder { +impl + AsRef> Container for DFGBuilder { #[inline] fn container_node(&self) -> Node { self.dfg_node @@ -109,7 +109,7 @@ impl Container for DFGBuilder { } } -impl SubContainer for DFGBuilder { +impl + AsRef> SubContainer for DFGBuilder { type ContainerHandle = BuildHandle; #[inline] fn finish_sub_container(self) -> Result { @@ -117,7 +117,7 @@ impl SubContainer for DFGBuilder { } } -impl Dataflow for DFGBuilder { +impl + AsRef> Dataflow for DFGBuilder { #[inline] fn num_inputs(&self) -> usize { self.num_in_wires @@ -265,7 +265,7 @@ impl FunctionBuilder { } } -impl Container for DFGWrapper { +impl + AsRef, T> Container for DFGWrapper { #[inline] fn container_node(&self) -> Node { self.0.container_node() @@ -282,14 +282,14 @@ impl Container for DFGWrapper { } } -impl Dataflow for DFGWrapper { +impl + AsRef, T> Dataflow for DFGWrapper { #[inline] fn num_inputs(&self) -> usize { self.0.num_inputs() } } -impl>> SubContainer for DFGWrapper { +impl + AsRef, T: From>> SubContainer for DFGWrapper { type ContainerHandle = T; #[inline] diff --git a/hugr-core/src/builder/module.rs b/hugr-core/src/builder/module.rs index e49b91f30..d2f144e04 100644 --- a/hugr-core/src/builder/module.rs +++ b/hugr-core/src/builder/module.rs @@ -1,7 +1,7 @@ use super::{ build_traits::HugrBuilder, dataflow::{DFGBuilder, FunctionBuilder}, - BuildError, Buildable, Container, + BuildError, Container, }; use crate::extension::ExtensionRegistry; @@ -20,7 +20,7 @@ use smol_str::SmolStr; #[derive(Debug, Clone, PartialEq)] pub struct ModuleBuilder(pub(super) T); -impl Container for ModuleBuilder { +impl + AsRef> Container for ModuleBuilder { #[inline] fn container_node(&self) -> Node { self.0.as_ref().root() @@ -60,7 +60,7 @@ impl HugrBuilder for ModuleBuilder { } } -impl ModuleBuilder { +impl + AsRef> ModuleBuilder { /// Replace a [`ops::FuncDecl`] with [`ops::FuncDefn`] and return a builder for /// the defining graph. /// diff --git a/hugr-core/src/builder/tail_loop.rs b/hugr-core/src/builder/tail_loop.rs index 1d2703787..29134ce03 100644 --- a/hugr-core/src/builder/tail_loop.rs +++ b/hugr-core/src/builder/tail_loop.rs @@ -6,7 +6,6 @@ use crate::types::{Signature, TypeRow}; use crate::{Hugr, Node}; use super::handle::BuildHandle; -use super::Buildable; use super::{ dataflow::{DFGBuilder, DFGWrapper}, BuildError, Container, Dataflow, TailLoopID, Wire, @@ -15,7 +14,7 @@ use super::{ /// Builder for a [`ops::TailLoop`] node. pub type TailLoopBuilder = DFGWrapper>; -impl TailLoopBuilder { +impl + AsRef> TailLoopBuilder { pub(super) fn create_with_io( base: B, loop_node: Node, diff --git a/hugr-core/src/hugr/rewrite/inline_dfg.rs b/hugr-core/src/hugr/rewrite/inline_dfg.rs index 0eda5a30c..ff400a1d3 100644 --- a/hugr-core/src/hugr/rewrite/inline_dfg.rs +++ b/hugr-core/src/hugr/rewrite/inline_dfg.rs @@ -147,7 +147,8 @@ mod test { use crate::std_extensions::arithmetic::int_types::{self, ConstInt}; use crate::types::Signature; use crate::utils::test_quantum_extension; - use crate::{type_row, Direction, HugrView, Node, Port, Wire}; + use crate::{type_row, Direction, HugrView, Node, Port}; + use crate::{Hugr, Wire}; use super::InlineDFG; @@ -166,7 +167,7 @@ mod test { #[case(true)] #[case(false)] fn inline_add_load_const(#[case] nonlocal: bool) -> Result<(), Box> { - use crate::{builder::Buildable, extension::prelude::Lift}; + use crate::extension::prelude::Lift; let reg = ExtensionRegistry::try_new([ PRELUDE.to_owned(), @@ -178,7 +179,7 @@ mod test { let mut outer = DFGBuilder::new(inout_sig(vec![int_ty.clone(); 2], vec![int_ty.clone()]))?; let [a, b] = outer.input_wires_arr(); - fn make_const( + fn make_const + AsRef>( d: &mut DFGBuilder, ) -> Result> { let int_ty = &int_types::INT_TYPES[6]; diff --git a/hugr-core/src/hugr/rewrite/replace.rs b/hugr-core/src/hugr/rewrite/replace.rs index d4bc42409..8967df9a5 100644 --- a/hugr-core/src/hugr/rewrite/replace.rs +++ b/hugr-core/src/hugr/rewrite/replace.rs @@ -448,7 +448,7 @@ mod test { use itertools::Itertools; use crate::builder::{ - endo_sig, BuildError, Buildable, CFGBuilder, Container, DFGBuilder, Dataflow, DataflowHugr, + endo_sig, BuildError, CFGBuilder, Container, DFGBuilder, Dataflow, DataflowHugr, DataflowSubContainer, HugrBuilder, SubContainer, }; use crate::extension::prelude::{BOOL_T, USIZE_T}; @@ -605,7 +605,7 @@ mod test { .unwrap() } - fn single_node_block>( + fn single_node_block + AsMut, O: DataflowOpTrait + Into>( h: &mut CFGBuilder, op: O, pred_const: &ConstID, diff --git a/hugr-core/src/package.rs b/hugr-core/src/package.rs index 76f4297e1..291b61ebe 100644 --- a/hugr-core/src/package.rs +++ b/hugr-core/src/package.rs @@ -392,7 +392,7 @@ mod test { #[case::simple(simple_package())] fn package_roundtrip(#[case] package: Package) { let json = package.to_json().unwrap(); - let new_package = Package::from_json(json).unwrap(); + let new_package = Package::from_json(&json).unwrap(); assert_eq!(package, new_package); } diff --git a/hugr-passes/src/merge_bbs.rs b/hugr-passes/src/merge_bbs.rs index b10ab6703..249eed6b4 100644 --- a/hugr-passes/src/merge_bbs.rs +++ b/hugr-passes/src/merge_bbs.rs @@ -162,9 +162,7 @@ mod test { use itertools::Itertools; use rstest::rstest; - use hugr_core::builder::{ - endo_sig, inout_sig, Buildable, CFGBuilder, DFGWrapper, Dataflow, HugrBuilder, - }; + use hugr_core::builder::{endo_sig, inout_sig, CFGBuilder, DFGWrapper, Dataflow, HugrBuilder}; use hugr_core::extension::prelude::{ConstUsize, PRELUDE_ID, QB_T, USIZE_T}; use hugr_core::extension::{ExtensionRegistry, PRELUDE, PRELUDE_REGISTRY}; use hugr_core::hugr::views::sibling::SiblingMut; @@ -172,7 +170,7 @@ mod test { use hugr_core::ops::handle::CfgID; use hugr_core::ops::{LoadConstant, OpTrait, OpType}; use hugr_core::types::{Signature, Type, TypeRow}; - use hugr_core::{const_extension_ids, type_row, Extension, HugrView, Wire}; + use hugr_core::{const_extension_ids, type_row, Extension, Hugr, HugrView, Wire}; use super::merge_basic_blocks; @@ -197,7 +195,7 @@ mod test { e } - fn lifted_unary_unit_sum(b: &mut DFGWrapper) -> Wire { + fn lifted_unary_unit_sum + AsRef, T>(b: &mut DFGWrapper) -> Wire { let lc = b.add_load_value(Value::unary_unit_sum()); let lift = b .add_dataflow_op( diff --git a/hugr-passes/src/nest_cfgs.rs b/hugr-passes/src/nest_cfgs.rs index 5860e9cd5..fa7106432 100644 --- a/hugr-passes/src/nest_cfgs.rs +++ b/hugr-passes/src/nest_cfgs.rs @@ -568,7 +568,7 @@ impl EdgeClassifier { pub(crate) mod test { use super::*; use hugr_core::builder::{ - endo_sig, BuildError, Buildable, CFGBuilder, Container, DataflowSubContainer, HugrBuilder, + endo_sig, BuildError, CFGBuilder, Container, DataflowSubContainer, HugrBuilder, }; use hugr_core::extension::PRELUDE_REGISTRY; use hugr_core::extension::{prelude::USIZE_T, ExtensionSet}; @@ -839,7 +839,7 @@ pub(crate) mod test { dataflow_builder.finish_with_outputs([u].into_iter().chain(w)) } - fn build_if_then_else_merge( + fn build_if_then_else_merge + AsRef>( cfg: &mut CFGBuilder, const_pred: &ConstID, unit_const: &ConstID, @@ -849,7 +849,7 @@ pub(crate) mod test { Ok((split, merge)) } - fn build_then_else_merge_from_if( + fn build_then_else_merge_from_if + AsRef>( cfg: &mut CFGBuilder, unit_const: &ConstID, split: BasicBlockID, @@ -902,7 +902,7 @@ pub(crate) mod test { Ok((h, head, tail)) } - pub(crate) fn build_conditional_in_loop( + pub(crate) fn build_conditional_in_loop + AsRef>( cfg_builder: &mut CFGBuilder, separate_headers: bool, ) -> Result<(BasicBlockID, BasicBlockID), BuildError> { diff --git a/hugr/benches/benchmarks/hugr/examples.rs b/hugr/benches/benchmarks/hugr/examples.rs index 659a10d9d..3abcee535 100644 --- a/hugr/benches/benchmarks/hugr/examples.rs +++ b/hugr/benches/benchmarks/hugr/examples.rs @@ -1,8 +1,8 @@ //! Builders and utilities for benchmarks. use hugr::builder::{ - BuildError, Buildable, CFGBuilder, Container, DFGBuilder, Dataflow, DataflowHugr, - DataflowSubContainer, HugrBuilder, ModuleBuilder, + BuildError, CFGBuilder, Container, DFGBuilder, Dataflow, DataflowHugr, DataflowSubContainer, + HugrBuilder, ModuleBuilder, }; use hugr::extension::prelude::{BOOL_T, QB_T, USIZE_T}; use hugr::extension::PRELUDE_REGISTRY; @@ -20,7 +20,9 @@ pub fn simple_dfg_hugr() -> Hugr { dfg_builder.finish_prelude_hugr_with_outputs([i1]).unwrap() } -pub fn simple_cfg_builder(cfg_builder: &mut CFGBuilder) -> Result<(), BuildError> { +pub fn simple_cfg_builder + AsRef>( + cfg_builder: &mut CFGBuilder, +) -> Result<(), BuildError> { let sum2_variants = vec![type_row![USIZE_T], type_row![USIZE_T]]; let mut entry_b = cfg_builder.entry_builder(sum2_variants.clone(), type_row![])?; let entry = { From 896127d40979d067aa6dc828937a697614eb44fa Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Sun, 24 Nov 2024 03:07:58 +0000 Subject: [PATCH 03/17] HugrView for &T, but not &mut --- hugr-core/src/hugr/internal.rs | 14 ++++- hugr-core/src/hugr/views.rs | 98 +++++++++++++++++++++++----------- 2 files changed, 79 insertions(+), 33 deletions(-) diff --git a/hugr-core/src/hugr/internal.rs b/hugr-core/src/hugr/internal.rs index 6062e4084..b9845eb0f 100644 --- a/hugr-core/src/hugr/internal.rs +++ b/hugr-core/src/hugr/internal.rs @@ -2,6 +2,7 @@ use std::ops::Range; +use delegate::delegate; use portgraph::{LinkView, MultiPortGraph, PortMut, PortView}; use crate::ops::handle::NodeHandle; @@ -31,7 +32,7 @@ pub trait HugrInternals { fn root_node(&self) -> Node; } -impl> HugrInternals for T { +impl HugrInternals for Hugr { type Portgraph<'p> = &'p MultiPortGraph where Self: 'p; #[inline] @@ -50,6 +51,17 @@ impl> HugrInternals for T { } } +impl HugrInternals for &T { + type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; + delegate! { + to (**self) { + fn portgraph(&self) -> Self::Portgraph<'_>; + fn base_hugr(&self) -> &Hugr; + fn root_node(&self) -> Node; + } + } +} + /// Trait for accessing the mutable internals of a Hugr(Mut). /// /// Specifically, this trait lets you apply arbitrary modifications that may diff --git a/hugr-core/src/hugr/views.rs b/hugr-core/src/hugr/views.rs index 7d744c150..66f20285c 100644 --- a/hugr-core/src/hugr/views.rs +++ b/hugr-core/src/hugr/views.rs @@ -12,6 +12,7 @@ mod tests; pub use self::petgraph::PetgraphWrapper; use self::render::RenderConfig; +use delegate::delegate; pub use descendants::DescendantsGraph; pub use root_checked::RootChecked; pub use sibling::SiblingGraph; @@ -513,41 +514,35 @@ impl ExtractHugr for &mut Hugr { } } -impl> HugrView for T { +impl HugrView for Hugr { #[inline] fn contains_node(&self, node: Node) -> bool { - self.as_ref().graph.contains_node(node.pg_index()) + self.graph.contains_node(node.pg_index()) } #[inline] fn node_count(&self) -> usize { - self.as_ref().graph.node_count() + self.graph.node_count() } #[inline] fn edge_count(&self) -> usize { - self.as_ref().graph.link_count() + self.graph.link_count() } #[inline] fn nodes(&self) -> impl Iterator + Clone { - self.as_ref().graph.nodes_iter().map_into() + self.graph.nodes_iter().map_into() } #[inline] fn node_ports(&self, node: Node, dir: Direction) -> impl Iterator + Clone { - self.as_ref() - .graph - .port_offsets(node.pg_index(), dir) - .map_into() + self.graph.port_offsets(node.pg_index(), dir).map_into() } #[inline] fn all_node_ports(&self, node: Node) -> impl Iterator + Clone { - self.as_ref() - .graph - .all_port_offsets(node.pg_index()) - .map_into() + self.graph.all_port_offsets(node.pg_index()).map_into() } #[inline] @@ -557,54 +552,93 @@ impl> HugrView for T { port: impl Into, ) -> impl Iterator + Clone { let port = port.into(); - let hugr = self.as_ref(); - let port = hugr + + let port = self .graph .port_index(node.pg_index(), port.pg_offset()) .unwrap(); - hugr.graph.port_links(port).map(|(_, link)| { + self.graph.port_links(port).map(|(_, link)| { let port = link.port(); - let node = hugr.graph.port_node(port).unwrap(); - let offset = hugr.graph.port_offset(port).unwrap(); + let node = self.graph.port_node(port).unwrap(); + let offset = self.graph.port_offset(port).unwrap(); (node.into(), offset.into()) }) } #[inline] fn node_connections(&self, node: Node, other: Node) -> impl Iterator + Clone { - let hugr = self.as_ref(); - - hugr.graph + self.graph .get_connections(node.pg_index(), other.pg_index()) .map(|(p1, p2)| { - [p1, p2].map(|link| hugr.graph.port_offset(link.port()).unwrap().into()) + [p1, p2].map(|link| self.graph.port_offset(link.port()).unwrap().into()) }) } #[inline] fn num_ports(&self, node: Node, dir: Direction) -> usize { - self.as_ref().graph.num_ports(node.pg_index(), dir) + self.graph.num_ports(node.pg_index(), dir) } #[inline] fn children(&self, node: Node) -> impl DoubleEndedIterator + Clone { - self.as_ref().hierarchy.children(node.pg_index()).map_into() + self.hierarchy.children(node.pg_index()).map_into() } #[inline] fn neighbours(&self, node: Node, dir: Direction) -> impl Iterator + Clone { - self.as_ref() - .graph - .neighbours(node.pg_index(), dir) - .map_into() + self.graph.neighbours(node.pg_index(), dir).map_into() } #[inline] fn all_neighbours(&self, node: Node) -> impl Iterator + Clone { - self.as_ref() - .graph - .all_neighbours(node.pg_index()) - .map_into() + self.graph.all_neighbours(node.pg_index()).map_into() + } +} + +impl HugrView for &T { + delegate! { + to (**self) { + + #[inline] + fn contains_node(&self, node: Node) -> bool; + + #[inline] + fn node_count(&self) -> usize; + + #[inline] + fn edge_count(&self) -> usize; + + #[inline] + fn nodes(&self) -> impl Iterator + Clone; + + #[inline] + fn node_ports(&self, node: Node, dir: Direction) -> impl Iterator + Clone; + + #[inline] + fn all_node_ports(&self, node: Node) -> impl Iterator + Clone; + + #[inline] + fn linked_ports( + &self, + node: Node, + port: impl Into, + ) -> impl Iterator + Clone; + + #[inline] + fn node_connections(&self, node: Node, other: Node) -> impl Iterator + Clone; + + #[inline] + fn num_ports(&self, node: Node, dir: Direction) -> usize; + + #[inline] + fn children(&self, node: Node) -> impl DoubleEndedIterator + Clone; + + #[inline] + fn neighbours(&self, node: Node, dir: Direction) -> impl Iterator + Clone; + + #[inline] + fn all_neighbours(&self, node: Node) -> impl Iterator + Clone; + } } } From 530f2159ddf71d6068c6ebeed89a04e2088eb228 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Sun, 24 Nov 2024 04:29:57 +0000 Subject: [PATCH 04/17] macro for HugrView methods for both & and &mut. Problems with RootChecked --- hugr-core/src/hugr/internal.rs | 10 +++++ hugr-core/src/hugr/views.rs | 72 +++++++++++++++++++--------------- 2 files changed, 51 insertions(+), 31 deletions(-) diff --git a/hugr-core/src/hugr/internal.rs b/hugr-core/src/hugr/internal.rs index b9845eb0f..4841a3d1e 100644 --- a/hugr-core/src/hugr/internal.rs +++ b/hugr-core/src/hugr/internal.rs @@ -62,6 +62,16 @@ impl HugrInternals for &T { } } +impl HugrInternals for &mut T { + type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; + delegate! { + to (**self) { + fn portgraph(&self) -> Self::Portgraph<'_>; + fn base_hugr(&self) -> &Hugr; + fn root_node(&self) -> Node; + } + } +} /// Trait for accessing the mutable internals of a Hugr(Mut). /// /// Specifically, this trait lets you apply arbitrary modifications that may diff --git a/hugr-core/src/hugr/views.rs b/hugr-core/src/hugr/views.rs index 66f20285c..4819bdaf0 100644 --- a/hugr-core/src/hugr/views.rs +++ b/hugr-core/src/hugr/views.rs @@ -595,53 +595,63 @@ impl HugrView for Hugr { } } -impl HugrView for &T { - delegate! { +macro_rules! hugr_view_methods { + () => { + delegate! { to (**self) { - #[inline] - fn contains_node(&self, node: Node) -> bool; + #[inline] + fn contains_node(&self, node: Node) -> bool; - #[inline] - fn node_count(&self) -> usize; + #[inline] + fn node_count(&self) -> usize; - #[inline] - fn edge_count(&self) -> usize; + #[inline] + fn edge_count(&self) -> usize; - #[inline] - fn nodes(&self) -> impl Iterator + Clone; + #[inline] + fn nodes(&self) -> impl Iterator + Clone; - #[inline] - fn node_ports(&self, node: Node, dir: Direction) -> impl Iterator + Clone; + #[inline] + fn node_ports(&self, node: Node, dir: Direction) -> impl Iterator + Clone; - #[inline] - fn all_node_ports(&self, node: Node) -> impl Iterator + Clone; + #[inline] + fn all_node_ports(&self, node: Node) -> impl Iterator + Clone; - #[inline] - fn linked_ports( - &self, - node: Node, - port: impl Into, - ) -> impl Iterator + Clone; + #[inline] + fn linked_ports( + &self, + node: Node, + port: impl Into, + ) -> impl Iterator + Clone; - #[inline] - fn node_connections(&self, node: Node, other: Node) -> impl Iterator + Clone; + #[inline] + fn node_connections(&self, node: Node, other: Node) -> impl Iterator + Clone; - #[inline] - fn num_ports(&self, node: Node, dir: Direction) -> usize; + #[inline] + fn num_ports(&self, node: Node, dir: Direction) -> usize; - #[inline] - fn children(&self, node: Node) -> impl DoubleEndedIterator + Clone; + #[inline] + fn children(&self, node: Node) -> impl DoubleEndedIterator + Clone; - #[inline] - fn neighbours(&self, node: Node, dir: Direction) -> impl Iterator + Clone; + #[inline] + fn neighbours(&self, node: Node, dir: Direction) -> impl Iterator + Clone; - #[inline] - fn all_neighbours(&self, node: Node) -> impl Iterator + Clone; - } + #[inline] + fn all_neighbours(&self, node: Node) -> impl Iterator + Clone; + } + } } } +impl HugrView for &T { + hugr_view_methods! {} +} + +impl HugrView for &mut T { + hugr_view_methods! {} +} + /// Trait implementing methods on port iterators. pub trait PortIterator

: Iterator where From 24c54c6bf674f1e69e473483033eb92b058ba666 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Sun, 24 Nov 2024 04:27:45 +0000 Subject: [PATCH 05/17] Try to parametrize hugr_view_meths macro, doesn't work --- hugr-core/src/hugr/views.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hugr-core/src/hugr/views.rs b/hugr-core/src/hugr/views.rs index 4819bdaf0..98ba1128e 100644 --- a/hugr-core/src/hugr/views.rs +++ b/hugr-core/src/hugr/views.rs @@ -596,9 +596,9 @@ impl HugrView for Hugr { } macro_rules! hugr_view_methods { - () => { + ($e:expr) => { delegate! { - to (**self) { + to ($e) { #[inline] fn contains_node(&self, node: Node) -> bool; @@ -645,11 +645,11 @@ macro_rules! hugr_view_methods { } impl HugrView for &T { - hugr_view_methods! {} + hugr_view_methods!{**self} } impl HugrView for &mut T { - hugr_view_methods! {} + hugr_view_methods!{**self} } /// Trait implementing methods on port iterators. From ac5ab01ea40a1ef7fdb9f167e2c0038e9a416e33 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Sun, 24 Nov 2024 04:27:47 +0000 Subject: [PATCH 06/17] Revert "Try to parametrize hugr_view_meths macro, doesn't work" This reverts commit 633c5a8112322dda5060ade8dec2e5109f4fdaec. --- hugr-core/src/hugr/views.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hugr-core/src/hugr/views.rs b/hugr-core/src/hugr/views.rs index 98ba1128e..4819bdaf0 100644 --- a/hugr-core/src/hugr/views.rs +++ b/hugr-core/src/hugr/views.rs @@ -596,9 +596,9 @@ impl HugrView for Hugr { } macro_rules! hugr_view_methods { - ($e:expr) => { + () => { delegate! { - to ($e) { + to (**self) { #[inline] fn contains_node(&self, node: Node) -> bool; @@ -645,11 +645,11 @@ macro_rules! hugr_view_methods { } impl HugrView for &T { - hugr_view_methods!{**self} + hugr_view_methods! {} } impl HugrView for &mut T { - hugr_view_methods!{**self} + hugr_view_methods! {} } /// Trait implementing methods on port iterators. From 0290aa0ae7fe11c70bacc38ff0de3f657f50405e Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Sun, 24 Nov 2024 04:21:14 +0000 Subject: [PATCH 07/17] Solve RootChecked by duplicating hugr_view_methods macro :(, few other fixes --- hugr-core/src/builder/cfg.rs | 6 ++- hugr-core/src/hugr/internal.rs | 6 +-- hugr-core/src/hugr/views/root_checked.rs | 65 ++++++++++++++++++++++-- 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/hugr-core/src/builder/cfg.rs b/hugr-core/src/builder/cfg.rs index bcb6aff3b..c2de140d8 100644 --- a/hugr-core/src/builder/cfg.rs +++ b/hugr-core/src/builder/cfg.rs @@ -392,7 +392,11 @@ impl + AsRef> BlockBuilder { Dataflow::set_outputs(self, [branch_wire].into_iter().chain(outputs)) } fn create(base: B, block_n: Node) -> Result { - let block_op = base.get_optype(block_n).as_dataflow_block().unwrap(); + let block_op = base + .as_ref() + .get_optype(block_n) + .as_dataflow_block() + .unwrap(); let signature = block_op.inner_signature(); let db = DFGBuilder::create_with_io(base, block_n, signature)?; Ok(BlockBuilder::from_dfg_builder(db)) diff --git a/hugr-core/src/hugr/internal.rs b/hugr-core/src/hugr/internal.rs index 4841a3d1e..c9be6d90f 100644 --- a/hugr-core/src/hugr/internal.rs +++ b/hugr-core/src/hugr/internal.rs @@ -37,17 +37,17 @@ impl HugrInternals for Hugr { #[inline] fn portgraph(&self) -> Self::Portgraph<'_> { - &self.as_ref().graph + &self.graph } #[inline] fn base_hugr(&self) -> &Hugr { - self.as_ref() + self } #[inline] fn root_node(&self) -> Node { - self.as_ref().root.into() + self.root.into() } } diff --git a/hugr-core/src/hugr/views/root_checked.rs b/hugr-core/src/hugr/views/root_checked.rs index c98943966..d367160a7 100644 --- a/hugr-core/src/hugr/views/root_checked.rs +++ b/hugr-core/src/hugr/views/root_checked.rs @@ -1,11 +1,14 @@ use std::marker::PhantomData; -use crate::hugr::internal::HugrMutInternals; +use delegate::delegate; +use portgraph::MultiPortGraph; + +use crate::hugr::internal::{HugrInternals, HugrMutInternals}; use crate::hugr::{HugrError, HugrMut}; use crate::ops::handle::NodeHandle; -use crate::{Hugr, Node}; +use crate::{Direction, Hugr, Node, Port}; -use super::{check_tag, RootTagged}; +use super::{check_tag, HugrView, RootTagged}; /// A view of the whole Hugr. /// (Just provides static checking of the type of the root node) @@ -45,6 +48,62 @@ impl RootChecked<&mut Hugr, Root> { } } +impl, Root> HugrInternals for RootChecked { + type Portgraph<'p> = &'p MultiPortGraph where Self: 'p; + delegate! { + to self.as_ref() { + fn portgraph(&self) -> Self::Portgraph<'_>; + fn base_hugr(&self) -> &Hugr; + fn root_node(&self) -> Node; + } + } +} +impl, Root> HugrView for RootChecked { + delegate! { + to self.as_ref() { + #[inline] + fn contains_node(&self, node: Node) -> bool; + + #[inline] + fn node_count(&self) -> usize; + + #[inline] + fn edge_count(&self) -> usize; + + #[inline] + fn nodes(&self) -> impl Iterator + Clone; + + #[inline] + fn node_ports(&self, node: Node, dir: Direction) -> impl Iterator + Clone; + + #[inline] + fn all_node_ports(&self, node: Node) -> impl Iterator + Clone; + + #[inline] + fn linked_ports( + &self, + node: Node, + port: impl Into, + ) -> impl Iterator + Clone; + + #[inline] + fn node_connections(&self, node: Node, other: Node) -> impl Iterator + Clone; + + #[inline] + fn num_ports(&self, node: Node, dir: Direction) -> usize; + + #[inline] + fn children(&self, node: Node) -> impl DoubleEndedIterator + Clone; + + #[inline] + fn neighbours(&self, node: Node, dir: Direction) -> impl Iterator + Clone; + + #[inline] + fn all_neighbours(&self, node: Node) -> impl Iterator + Clone; + } + } +} + impl, Root: NodeHandle> RootTagged for RootChecked { type RootHandle = Root; } From fc16a832580f8406b6d356aeee86cf7d1e434270 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Mon, 25 Nov 2024 22:29:30 +0000 Subject: [PATCH 08/17] Give hugr_view_methods extra ident to assign self --> common up RootChecked --- hugr-core/src/hugr/views.rs | 10 +++--- hugr-core/src/hugr/views/root_checked.rs | 46 ++---------------------- 2 files changed, 8 insertions(+), 48 deletions(-) diff --git a/hugr-core/src/hugr/views.rs b/hugr-core/src/hugr/views.rs index 4819bdaf0..6645acecc 100644 --- a/hugr-core/src/hugr/views.rs +++ b/hugr-core/src/hugr/views.rs @@ -596,9 +596,9 @@ impl HugrView for Hugr { } macro_rules! hugr_view_methods { - () => { + ($arg:ident, $e:expr) => { delegate! { - to (**self) { + to ({let $arg=self; $e}) { #[inline] fn contains_node(&self, node: Node) -> bool; @@ -644,12 +644,14 @@ macro_rules! hugr_view_methods { } } +use hugr_view_methods; + impl HugrView for &T { - hugr_view_methods! {} + hugr_view_methods! {this, *this} } impl HugrView for &mut T { - hugr_view_methods! {} + hugr_view_methods! {this, &**this} } /// Trait implementing methods on port iterators. diff --git a/hugr-core/src/hugr/views/root_checked.rs b/hugr-core/src/hugr/views/root_checked.rs index d367160a7..370f27d5e 100644 --- a/hugr-core/src/hugr/views/root_checked.rs +++ b/hugr-core/src/hugr/views/root_checked.rs @@ -8,7 +8,7 @@ use crate::hugr::{HugrError, HugrMut}; use crate::ops::handle::NodeHandle; use crate::{Direction, Hugr, Node, Port}; -use super::{check_tag, HugrView, RootTagged}; +use super::{check_tag, hugr_view_methods, HugrView, RootTagged}; /// A view of the whole Hugr. /// (Just provides static checking of the type of the root node) @@ -59,49 +59,7 @@ impl, Root> HugrInternals for RootChecked { } } impl, Root> HugrView for RootChecked { - delegate! { - to self.as_ref() { - #[inline] - fn contains_node(&self, node: Node) -> bool; - - #[inline] - fn node_count(&self) -> usize; - - #[inline] - fn edge_count(&self) -> usize; - - #[inline] - fn nodes(&self) -> impl Iterator + Clone; - - #[inline] - fn node_ports(&self, node: Node, dir: Direction) -> impl Iterator + Clone; - - #[inline] - fn all_node_ports(&self, node: Node) -> impl Iterator + Clone; - - #[inline] - fn linked_ports( - &self, - node: Node, - port: impl Into, - ) -> impl Iterator + Clone; - - #[inline] - fn node_connections(&self, node: Node, other: Node) -> impl Iterator + Clone; - - #[inline] - fn num_ports(&self, node: Node, dir: Direction) -> usize; - - #[inline] - fn children(&self, node: Node) -> impl DoubleEndedIterator + Clone; - - #[inline] - fn neighbours(&self, node: Node, dir: Direction) -> impl Iterator + Clone; - - #[inline] - fn all_neighbours(&self, node: Node) -> impl Iterator + Clone; - } - } + hugr_view_methods! {this, this.as_ref()} } impl, Root: NodeHandle> RootTagged for RootChecked { From aab834c41c9ea4e87fb099aa8bb994e9e3270693 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Tue, 26 Nov 2024 10:34:43 +0000 Subject: [PATCH 09/17] Remove [inline]s inside delegate --- hugr-core/src/hugr/views.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/hugr-core/src/hugr/views.rs b/hugr-core/src/hugr/views.rs index 6645acecc..38977b6ce 100644 --- a/hugr-core/src/hugr/views.rs +++ b/hugr-core/src/hugr/views.rs @@ -599,45 +599,21 @@ macro_rules! hugr_view_methods { ($arg:ident, $e:expr) => { delegate! { to ({let $arg=self; $e}) { - - #[inline] fn contains_node(&self, node: Node) -> bool; - - #[inline] fn node_count(&self) -> usize; - - #[inline] fn edge_count(&self) -> usize; - - #[inline] fn nodes(&self) -> impl Iterator + Clone; - - #[inline] fn node_ports(&self, node: Node, dir: Direction) -> impl Iterator + Clone; - - #[inline] fn all_node_ports(&self, node: Node) -> impl Iterator + Clone; - - #[inline] fn linked_ports( &self, node: Node, port: impl Into, ) -> impl Iterator + Clone; - - #[inline] fn node_connections(&self, node: Node, other: Node) -> impl Iterator + Clone; - - #[inline] fn num_ports(&self, node: Node, dir: Direction) -> usize; - - #[inline] fn children(&self, node: Node) -> impl DoubleEndedIterator + Clone; - - #[inline] fn neighbours(&self, node: Node, dir: Direction) -> impl Iterator + Clone; - - #[inline] fn all_neighbours(&self, node: Node) -> impl Iterator + Clone; } } From 852f0b330509b0a14bc57b0a809be84a5523ffb1 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Thu, 28 Nov 2024 14:09:39 +0000 Subject: [PATCH 10/17] move all (inc RootChecked) into views/impls.rs, add Rc + Arc --- hugr-core/src/hugr/internal.rs | 25 +++++++++++ hugr-core/src/hugr/views.rs | 37 +---------------- hugr-core/src/hugr/views/impls.rs | 53 ++++++++++++++++++++++++ hugr-core/src/hugr/views/root_checked.rs | 7 +--- 4 files changed, 81 insertions(+), 41 deletions(-) create mode 100644 hugr-core/src/hugr/views/impls.rs diff --git a/hugr-core/src/hugr/internal.rs b/hugr-core/src/hugr/internal.rs index c9be6d90f..1301457a4 100644 --- a/hugr-core/src/hugr/internal.rs +++ b/hugr-core/src/hugr/internal.rs @@ -1,6 +1,8 @@ //! Internal traits, not exposed in the public `hugr` API. use std::ops::Range; +use std::rc::Rc; +use std::sync::Arc; use delegate::delegate; use portgraph::{LinkView, MultiPortGraph, PortMut, PortView}; @@ -72,6 +74,29 @@ impl HugrInternals for &mut T { } } } + +impl HugrInternals for Rc { + type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; + delegate! { + to (**self) { + fn portgraph(&self) -> Self::Portgraph<'_>; + fn base_hugr(&self) -> &Hugr; + fn root_node(&self) -> Node; + } + } +} + +impl HugrInternals for Arc { + type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; + delegate! { + to (**self) { + fn portgraph(&self) -> Self::Portgraph<'_>; + fn base_hugr(&self) -> &Hugr; + fn root_node(&self) -> Node; + } + } +} + /// Trait for accessing the mutable internals of a Hugr(Mut). /// /// Specifically, this trait lets you apply arbitrary modifications that may diff --git a/hugr-core/src/hugr/views.rs b/hugr-core/src/hugr/views.rs index 38977b6ce..30015e2c3 100644 --- a/hugr-core/src/hugr/views.rs +++ b/hugr-core/src/hugr/views.rs @@ -1,6 +1,7 @@ //! Read-only access into HUGR graphs and subgraphs. pub mod descendants; +mod impls; pub mod petgraph; pub mod render; mod root_checked; @@ -12,7 +13,6 @@ mod tests; pub use self::petgraph::PetgraphWrapper; use self::render::RenderConfig; -use delegate::delegate; pub use descendants::DescendantsGraph; pub use root_checked::RootChecked; pub use sibling::SiblingGraph; @@ -595,41 +595,6 @@ impl HugrView for Hugr { } } -macro_rules! hugr_view_methods { - ($arg:ident, $e:expr) => { - delegate! { - to ({let $arg=self; $e}) { - fn contains_node(&self, node: Node) -> bool; - fn node_count(&self) -> usize; - fn edge_count(&self) -> usize; - fn nodes(&self) -> impl Iterator + Clone; - fn node_ports(&self, node: Node, dir: Direction) -> impl Iterator + Clone; - fn all_node_ports(&self, node: Node) -> impl Iterator + Clone; - fn linked_ports( - &self, - node: Node, - port: impl Into, - ) -> impl Iterator + Clone; - fn node_connections(&self, node: Node, other: Node) -> impl Iterator + Clone; - fn num_ports(&self, node: Node, dir: Direction) -> usize; - fn children(&self, node: Node) -> impl DoubleEndedIterator + Clone; - fn neighbours(&self, node: Node, dir: Direction) -> impl Iterator + Clone; - fn all_neighbours(&self, node: Node) -> impl Iterator + Clone; - } - } - } -} - -use hugr_view_methods; - -impl HugrView for &T { - hugr_view_methods! {this, *this} -} - -impl HugrView for &mut T { - hugr_view_methods! {this, &**this} -} - /// Trait implementing methods on port iterators. pub trait PortIterator

: Iterator where diff --git a/hugr-core/src/hugr/views/impls.rs b/hugr-core/src/hugr/views/impls.rs new file mode 100644 index 000000000..354ecf66b --- /dev/null +++ b/hugr-core/src/hugr/views/impls.rs @@ -0,0 +1,53 @@ +use std::rc::Rc; +use std::sync::Arc; + +use delegate::delegate; + +use super::{HugrView, RootChecked}; +use crate::{Direction, Hugr, Node, Port}; + +macro_rules! hugr_view_methods { + // The extra ident here is because invocations of the macro cannot pass `self` as argument + ($arg:ident, $e:expr) => { + delegate! { + to ({let $arg=self; $e}) { + fn contains_node(&self, node: Node) -> bool; + fn node_count(&self) -> usize; + fn edge_count(&self) -> usize; + fn nodes(&self) -> impl Iterator + Clone; + fn node_ports(&self, node: Node, dir: Direction) -> impl Iterator + Clone; + fn all_node_ports(&self, node: Node) -> impl Iterator + Clone; + fn linked_ports( + &self, + node: Node, + port: impl Into, + ) -> impl Iterator + Clone; + fn node_connections(&self, node: Node, other: Node) -> impl Iterator + Clone; + fn num_ports(&self, node: Node, dir: Direction) -> usize; + fn children(&self, node: Node) -> impl DoubleEndedIterator + Clone; + fn neighbours(&self, node: Node, dir: Direction) -> impl Iterator + Clone; + fn all_neighbours(&self, node: Node) -> impl Iterator + Clone; + } + } + } +} + +impl HugrView for &T { + hugr_view_methods! {this, *this} +} + +impl HugrView for &mut T { + hugr_view_methods! {this, &**this} +} + +impl HugrView for Rc { + hugr_view_methods! {this, this.as_ref()} +} + +impl HugrView for Arc { + hugr_view_methods! {this, this.as_ref()} +} + +impl, Root> HugrView for RootChecked { + hugr_view_methods! {this, this.as_ref()} +} diff --git a/hugr-core/src/hugr/views/root_checked.rs b/hugr-core/src/hugr/views/root_checked.rs index 370f27d5e..989719377 100644 --- a/hugr-core/src/hugr/views/root_checked.rs +++ b/hugr-core/src/hugr/views/root_checked.rs @@ -6,9 +6,9 @@ use portgraph::MultiPortGraph; use crate::hugr::internal::{HugrInternals, HugrMutInternals}; use crate::hugr::{HugrError, HugrMut}; use crate::ops::handle::NodeHandle; -use crate::{Direction, Hugr, Node, Port}; +use crate::{Hugr, Node}; -use super::{check_tag, hugr_view_methods, HugrView, RootTagged}; +use super::{check_tag, RootTagged}; /// A view of the whole Hugr. /// (Just provides static checking of the type of the root node) @@ -58,9 +58,6 @@ impl, Root> HugrInternals for RootChecked { } } } -impl, Root> HugrView for RootChecked { - hugr_view_methods! {this, this.as_ref()} -} impl, Root: NodeHandle> RootTagged for RootChecked { type RootHandle = Root; From 743aac7e56870cce1a75b498d72632f7bdb74e90 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Thu, 28 Nov 2024 19:36:08 +0000 Subject: [PATCH 11/17] Try to do via blanked Deref, but lifetime issues --- hugr-core/src/hugr/internal.rs | 40 ++---------------- hugr-core/src/hugr/views/impls.rs | 70 ++++++++++--------------------- 2 files changed, 26 insertions(+), 84 deletions(-) diff --git a/hugr-core/src/hugr/internal.rs b/hugr-core/src/hugr/internal.rs index 1301457a4..dfe68143f 100644 --- a/hugr-core/src/hugr/internal.rs +++ b/hugr-core/src/hugr/internal.rs @@ -1,8 +1,6 @@ //! Internal traits, not exposed in the public `hugr` API. -use std::ops::Range; -use std::rc::Rc; -use std::sync::Arc; +use std::ops::{Deref, Range}; use delegate::delegate; use portgraph::{LinkView, MultiPortGraph, PortMut, PortView}; @@ -53,8 +51,8 @@ impl HugrInternals for Hugr { } } -impl HugrInternals for &T { - type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; +impl> HugrInternals for T { + type Portgraph<'p> = H::Portgraph<'p> where Self: 'p; delegate! { to (**self) { fn portgraph(&self) -> Self::Portgraph<'_>; @@ -64,38 +62,6 @@ impl HugrInternals for &T { } } -impl HugrInternals for &mut T { - type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; - delegate! { - to (**self) { - fn portgraph(&self) -> Self::Portgraph<'_>; - fn base_hugr(&self) -> &Hugr; - fn root_node(&self) -> Node; - } - } -} - -impl HugrInternals for Rc { - type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; - delegate! { - to (**self) { - fn portgraph(&self) -> Self::Portgraph<'_>; - fn base_hugr(&self) -> &Hugr; - fn root_node(&self) -> Node; - } - } -} - -impl HugrInternals for Arc { - type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; - delegate! { - to (**self) { - fn portgraph(&self) -> Self::Portgraph<'_>; - fn base_hugr(&self) -> &Hugr; - fn root_node(&self) -> Node; - } - } -} /// Trait for accessing the mutable internals of a Hugr(Mut). /// diff --git a/hugr-core/src/hugr/views/impls.rs b/hugr-core/src/hugr/views/impls.rs index 354ecf66b..5e354abcb 100644 --- a/hugr-core/src/hugr/views/impls.rs +++ b/hugr-core/src/hugr/views/impls.rs @@ -1,53 +1,29 @@ -use std::rc::Rc; -use std::sync::Arc; +use std::ops::Deref; use delegate::delegate; -use super::{HugrView, RootChecked}; -use crate::{Direction, Hugr, Node, Port}; - -macro_rules! hugr_view_methods { - // The extra ident here is because invocations of the macro cannot pass `self` as argument - ($arg:ident, $e:expr) => { - delegate! { - to ({let $arg=self; $e}) { - fn contains_node(&self, node: Node) -> bool; - fn node_count(&self) -> usize; - fn edge_count(&self) -> usize; - fn nodes(&self) -> impl Iterator + Clone; - fn node_ports(&self, node: Node, dir: Direction) -> impl Iterator + Clone; - fn all_node_ports(&self, node: Node) -> impl Iterator + Clone; - fn linked_ports( - &self, - node: Node, - port: impl Into, - ) -> impl Iterator + Clone; - fn node_connections(&self, node: Node, other: Node) -> impl Iterator + Clone; - fn num_ports(&self, node: Node, dir: Direction) -> usize; - fn children(&self, node: Node) -> impl DoubleEndedIterator + Clone; - fn neighbours(&self, node: Node, dir: Direction) -> impl Iterator + Clone; - fn all_neighbours(&self, node: Node) -> impl Iterator + Clone; - } +use super::HugrView; +use crate::{Direction, Node, Port}; + +impl> HugrView for T { + delegate! { + to (**self) { + fn contains_node(&self, node: Node) -> bool; + fn node_count(&self) -> usize; + fn edge_count(&self) -> usize; + fn nodes(&self) -> impl Iterator + Clone; + fn node_ports(&self, node: Node, dir: Direction) -> impl Iterator + Clone; + fn all_node_ports(&self, node: Node) -> impl Iterator + Clone; + fn linked_ports( + &self, + node: Node, + port: impl Into, + ) -> impl Iterator + Clone; + fn node_connections(&self, node: Node, other: Node) -> impl Iterator + Clone; + fn num_ports(&self, node: Node, dir: Direction) -> usize; + fn children(&self, node: Node) -> impl DoubleEndedIterator + Clone; + fn neighbours(&self, node: Node, dir: Direction) -> impl Iterator + Clone; + fn all_neighbours(&self, node: Node) -> impl Iterator + Clone; } } } - -impl HugrView for &T { - hugr_view_methods! {this, *this} -} - -impl HugrView for &mut T { - hugr_view_methods! {this, &**this} -} - -impl HugrView for Rc { - hugr_view_methods! {this, this.as_ref()} -} - -impl HugrView for Arc { - hugr_view_methods! {this, this.as_ref()} -} - -impl, Root> HugrView for RootChecked { - hugr_view_methods! {this, this.as_ref()} -} From 966c52b4075d1259981c1769e517329740eddc77 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Thu, 28 Nov 2024 19:37:21 +0000 Subject: [PATCH 12/17] Revert "Try to do via blanked Deref, but lifetime issues" This reverts commit 743aac7e56870cce1a75b498d72632f7bdb74e90. --- hugr-core/src/hugr/internal.rs | 40 ++++++++++++++++-- hugr-core/src/hugr/views/impls.rs | 70 +++++++++++++++++++++---------- 2 files changed, 84 insertions(+), 26 deletions(-) diff --git a/hugr-core/src/hugr/internal.rs b/hugr-core/src/hugr/internal.rs index dfe68143f..1301457a4 100644 --- a/hugr-core/src/hugr/internal.rs +++ b/hugr-core/src/hugr/internal.rs @@ -1,6 +1,8 @@ //! Internal traits, not exposed in the public `hugr` API. -use std::ops::{Deref, Range}; +use std::ops::Range; +use std::rc::Rc; +use std::sync::Arc; use delegate::delegate; use portgraph::{LinkView, MultiPortGraph, PortMut, PortView}; @@ -51,8 +53,8 @@ impl HugrInternals for Hugr { } } -impl> HugrInternals for T { - type Portgraph<'p> = H::Portgraph<'p> where Self: 'p; +impl HugrInternals for &T { + type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; delegate! { to (**self) { fn portgraph(&self) -> Self::Portgraph<'_>; @@ -62,6 +64,38 @@ impl> HugrInternals for T { } } +impl HugrInternals for &mut T { + type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; + delegate! { + to (**self) { + fn portgraph(&self) -> Self::Portgraph<'_>; + fn base_hugr(&self) -> &Hugr; + fn root_node(&self) -> Node; + } + } +} + +impl HugrInternals for Rc { + type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; + delegate! { + to (**self) { + fn portgraph(&self) -> Self::Portgraph<'_>; + fn base_hugr(&self) -> &Hugr; + fn root_node(&self) -> Node; + } + } +} + +impl HugrInternals for Arc { + type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; + delegate! { + to (**self) { + fn portgraph(&self) -> Self::Portgraph<'_>; + fn base_hugr(&self) -> &Hugr; + fn root_node(&self) -> Node; + } + } +} /// Trait for accessing the mutable internals of a Hugr(Mut). /// diff --git a/hugr-core/src/hugr/views/impls.rs b/hugr-core/src/hugr/views/impls.rs index 5e354abcb..354ecf66b 100644 --- a/hugr-core/src/hugr/views/impls.rs +++ b/hugr-core/src/hugr/views/impls.rs @@ -1,29 +1,53 @@ -use std::ops::Deref; +use std::rc::Rc; +use std::sync::Arc; use delegate::delegate; -use super::HugrView; -use crate::{Direction, Node, Port}; - -impl> HugrView for T { - delegate! { - to (**self) { - fn contains_node(&self, node: Node) -> bool; - fn node_count(&self) -> usize; - fn edge_count(&self) -> usize; - fn nodes(&self) -> impl Iterator + Clone; - fn node_ports(&self, node: Node, dir: Direction) -> impl Iterator + Clone; - fn all_node_ports(&self, node: Node) -> impl Iterator + Clone; - fn linked_ports( - &self, - node: Node, - port: impl Into, - ) -> impl Iterator + Clone; - fn node_connections(&self, node: Node, other: Node) -> impl Iterator + Clone; - fn num_ports(&self, node: Node, dir: Direction) -> usize; - fn children(&self, node: Node) -> impl DoubleEndedIterator + Clone; - fn neighbours(&self, node: Node, dir: Direction) -> impl Iterator + Clone; - fn all_neighbours(&self, node: Node) -> impl Iterator + Clone; +use super::{HugrView, RootChecked}; +use crate::{Direction, Hugr, Node, Port}; + +macro_rules! hugr_view_methods { + // The extra ident here is because invocations of the macro cannot pass `self` as argument + ($arg:ident, $e:expr) => { + delegate! { + to ({let $arg=self; $e}) { + fn contains_node(&self, node: Node) -> bool; + fn node_count(&self) -> usize; + fn edge_count(&self) -> usize; + fn nodes(&self) -> impl Iterator + Clone; + fn node_ports(&self, node: Node, dir: Direction) -> impl Iterator + Clone; + fn all_node_ports(&self, node: Node) -> impl Iterator + Clone; + fn linked_ports( + &self, + node: Node, + port: impl Into, + ) -> impl Iterator + Clone; + fn node_connections(&self, node: Node, other: Node) -> impl Iterator + Clone; + fn num_ports(&self, node: Node, dir: Direction) -> usize; + fn children(&self, node: Node) -> impl DoubleEndedIterator + Clone; + fn neighbours(&self, node: Node, dir: Direction) -> impl Iterator + Clone; + fn all_neighbours(&self, node: Node) -> impl Iterator + Clone; + } } } } + +impl HugrView for &T { + hugr_view_methods! {this, *this} +} + +impl HugrView for &mut T { + hugr_view_methods! {this, &**this} +} + +impl HugrView for Rc { + hugr_view_methods! {this, this.as_ref()} +} + +impl HugrView for Arc { + hugr_view_methods! {this, this.as_ref()} +} + +impl, Root> HugrView for RootChecked { + hugr_view_methods! {this, this.as_ref()} +} From 2c62e4bde0b92a0ded06f35bdc91552ef758b888 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Thu, 28 Nov 2024 20:02:15 +0000 Subject: [PATCH 13/17] Add test/demo --- hugr-core/src/hugr/views/impls.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/hugr-core/src/hugr/views/impls.rs b/hugr-core/src/hugr/views/impls.rs index 354ecf66b..159186bdc 100644 --- a/hugr-core/src/hugr/views/impls.rs +++ b/hugr-core/src/hugr/views/impls.rs @@ -51,3 +51,34 @@ impl HugrView for Arc { impl, Root> HugrView for RootChecked { hugr_view_methods! {this, this.as_ref()} } + +#[cfg(test)] +mod test { + use crate::hugr::views::{DescendantsGraph, HierarchyView}; + use crate::{Hugr, HugrView, Node}; + + struct ViewWrapper(H); + impl ViewWrapper { + fn nodes<'a>(&'a self) -> impl Iterator + 'a { + self.0.nodes() + } + } + + #[test] + fn test_views() { + let h = Hugr::default(); + let v = ViewWrapper(&h); + let c = h.nodes().count(); + assert_eq!(v.nodes().count(), c); + let v2 = ViewWrapper(DescendantsGraph::::try_new(&h, h.root()).unwrap()); + // v2 owns the DescendantsGraph, but that only borrows `h`, so we still have both + assert_eq!(v2.nodes().count(), v.nodes().count()); + // And we can borrow the DescendantsGraph, even just a reference to that counts as a HugrView + assert_eq!(ViewWrapper(&v2.0).nodes().count(), v.nodes().count()); + + let vh = ViewWrapper(h); + assert_eq!(vh.nodes().count(), c); + let h: Hugr = vh.0; + assert_eq!(h.nodes().count(), c); + } +} From 6d63747332d9a97246a7e69cfaeb8b03e36b3deb Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Thu, 28 Nov 2024 20:07:15 +0000 Subject: [PATCH 14/17] clippy - yes it is that simple - thought I had tried that first! --- hugr-core/src/hugr/views/impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hugr-core/src/hugr/views/impls.rs b/hugr-core/src/hugr/views/impls.rs index 159186bdc..634654d4f 100644 --- a/hugr-core/src/hugr/views/impls.rs +++ b/hugr-core/src/hugr/views/impls.rs @@ -59,7 +59,7 @@ mod test { struct ViewWrapper(H); impl ViewWrapper { - fn nodes<'a>(&'a self) -> impl Iterator + 'a { + fn nodes(&self) -> impl Iterator + '_ { self.0.nodes() } } From d878edd49c5c3c9f8e3d48717832513394656928 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Fri, 29 Nov 2024 08:31:05 +0000 Subject: [PATCH 15/17] Upgrade to 1.83 and redo cargo fmt --- hugr-core/src/hugr/internal.rs | 25 +++++++++++++++++++----- hugr-core/src/hugr/views/root_checked.rs | 5 ++++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/hugr-core/src/hugr/internal.rs b/hugr-core/src/hugr/internal.rs index 1301457a4..ef9030557 100644 --- a/hugr-core/src/hugr/internal.rs +++ b/hugr-core/src/hugr/internal.rs @@ -35,7 +35,10 @@ pub trait HugrInternals { } impl HugrInternals for Hugr { - type Portgraph<'p> = &'p MultiPortGraph where Self: 'p; + type Portgraph<'p> + = &'p MultiPortGraph + where + Self: 'p; #[inline] fn portgraph(&self) -> Self::Portgraph<'_> { @@ -54,7 +57,10 @@ impl HugrInternals for Hugr { } impl HugrInternals for &T { - type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; + type Portgraph<'p> + = T::Portgraph<'p> + where + Self: 'p; delegate! { to (**self) { fn portgraph(&self) -> Self::Portgraph<'_>; @@ -65,7 +71,10 @@ impl HugrInternals for &T { } impl HugrInternals for &mut T { - type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; + type Portgraph<'p> + = T::Portgraph<'p> + where + Self: 'p; delegate! { to (**self) { fn portgraph(&self) -> Self::Portgraph<'_>; @@ -76,7 +85,10 @@ impl HugrInternals for &mut T { } impl HugrInternals for Rc { - type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; + type Portgraph<'p> + = T::Portgraph<'p> + where + Self: 'p; delegate! { to (**self) { fn portgraph(&self) -> Self::Portgraph<'_>; @@ -87,7 +99,10 @@ impl HugrInternals for Rc { } impl HugrInternals for Arc { - type Portgraph<'p> = T::Portgraph<'p> where Self: 'p; + type Portgraph<'p> + = T::Portgraph<'p> + where + Self: 'p; delegate! { to (**self) { fn portgraph(&self) -> Self::Portgraph<'_>; diff --git a/hugr-core/src/hugr/views/root_checked.rs b/hugr-core/src/hugr/views/root_checked.rs index 989719377..88b0ad020 100644 --- a/hugr-core/src/hugr/views/root_checked.rs +++ b/hugr-core/src/hugr/views/root_checked.rs @@ -49,7 +49,10 @@ impl RootChecked<&mut Hugr, Root> { } impl, Root> HugrInternals for RootChecked { - type Portgraph<'p> = &'p MultiPortGraph where Self: 'p; + type Portgraph<'p> + = &'p MultiPortGraph + where + Self: 'p; delegate! { to self.as_ref() { fn portgraph(&self) -> Self::Portgraph<'_>; From cf31c090d52b70a78cbb58c4f30a2b561b48e4a1 Mon Sep 17 00:00:00 2001 From: Douglas Wilson <141026920+doug-q@users.noreply.github.com> Date: Tue, 3 Dec 2024 10:39:25 +0000 Subject: [PATCH 16/17] add HugrView impls for Box and Cow (#1730) --- hugr-core/src/hugr/internal.rs | 28 ++++++++++++++++++++++++++++ hugr-core/src/hugr/views/impls.rs | 10 +++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/hugr-core/src/hugr/internal.rs b/hugr-core/src/hugr/internal.rs index ef9030557..3f1c6b6ff 100644 --- a/hugr-core/src/hugr/internal.rs +++ b/hugr-core/src/hugr/internal.rs @@ -1,5 +1,6 @@ //! Internal traits, not exposed in the public `hugr` API. +use std::borrow::Cow; use std::ops::Range; use std::rc::Rc; use std::sync::Arc; @@ -112,6 +113,33 @@ impl HugrInternals for Arc { } } +impl HugrInternals for Box { + type Portgraph<'p> + = T::Portgraph<'p> + where + Self: 'p; + delegate! { + to (**self) { + fn portgraph(&self) -> Self::Portgraph<'_>; + fn base_hugr(&self) -> &Hugr; + fn root_node(&self) -> Node; + } + } +} + +impl HugrInternals for Cow<'_, T> { + type Portgraph<'p> + = T::Portgraph<'p> + where + Self: 'p; + delegate! { + to self.as_ref() { + fn portgraph(&self) -> Self::Portgraph<'_>; + fn base_hugr(&self) -> &Hugr; + fn root_node(&self) -> Node; + } + } +} /// Trait for accessing the mutable internals of a Hugr(Mut). /// /// Specifically, this trait lets you apply arbitrary modifications that may diff --git a/hugr-core/src/hugr/views/impls.rs b/hugr-core/src/hugr/views/impls.rs index 634654d4f..4b86f18ba 100644 --- a/hugr-core/src/hugr/views/impls.rs +++ b/hugr-core/src/hugr/views/impls.rs @@ -1,5 +1,5 @@ -use std::rc::Rc; use std::sync::Arc; +use std::{borrow::Cow, rc::Rc}; use delegate::delegate; @@ -48,6 +48,14 @@ impl HugrView for Arc { hugr_view_methods! {this, this.as_ref()} } +impl HugrView for Box { + hugr_view_methods! {this, this.as_ref()} +} + +impl HugrView for Cow<'_, T> { + hugr_view_methods! {this, this.as_ref()} +} + impl, Root> HugrView for RootChecked { hugr_view_methods! {this, this.as_ref()} } From 7d460f81d649c76841feb24d3064192e46229788 Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Wed, 4 Dec 2024 09:44:59 +0000 Subject: [PATCH 17/17] test Rc, Arc, Box --- hugr-core/src/hugr/views/impls.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/hugr-core/src/hugr/views/impls.rs b/hugr-core/src/hugr/views/impls.rs index 4b86f18ba..7f3f45386 100644 --- a/hugr-core/src/hugr/views/impls.rs +++ b/hugr-core/src/hugr/views/impls.rs @@ -1,5 +1,4 @@ -use std::sync::Arc; -use std::{borrow::Cow, rc::Rc}; +use std::{borrow::Cow, rc::Rc, sync::Arc}; use delegate::delegate; @@ -62,6 +61,8 @@ impl, Root> HugrView for RootChecked { #[cfg(test)] mod test { + use std::{rc::Rc, sync::Arc}; + use crate::hugr::views::{DescendantsGraph, HierarchyView}; use crate::{Hugr, HugrView, Node}; @@ -73,7 +74,7 @@ mod test { } #[test] - fn test_views() { + fn test_refs_to_view() { let h = Hugr::default(); let v = ViewWrapper(&h); let c = h.nodes().count(); @@ -88,5 +89,13 @@ mod test { assert_eq!(vh.nodes().count(), c); let h: Hugr = vh.0; assert_eq!(h.nodes().count(), c); + + let vb = ViewWrapper(Box::new(&h)); + assert_eq!(vb.nodes().count(), c); + let va = ViewWrapper(Arc::new(h)); + assert_eq!(va.nodes().count(), c); + let h = Arc::try_unwrap(va.0).unwrap(); + let vr = Rc::new(&h); + assert_eq!(ViewWrapper(&vr).nodes().count(), h.nodes().count()); } }