Skip to content

Commit

Permalink
feat: Implement petgraph traits on Hugr (#498)
Browse files Browse the repository at this point in the history
This lets us treat HUGRs in the same way as views everywhere (e.g. use
them as Circuits) requiring `T: PetgraphHugr` where before we had `T:
HierarchyView`.

---------

Co-authored-by: Alan Lawrence <alan.lawrence@quantinuum.com>
  • Loading branch information
aborgna-q and acl-cqc committed Sep 7, 2023
1 parent 5a97a63 commit 681db93
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 174 deletions.
9 changes: 6 additions & 3 deletions src/hugr/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ impl<'a, 'b> ValidationContext<'a, 'b> {
fn compute_dominator(&self, parent: Node) -> Dominators<Node> {
let region: SiblingGraph = SiblingGraph::new(self.hugr, parent);
let entry_node = self.hugr.children(parent).next().unwrap();
dominators::simple_fast(&region, entry_node)
dominators::simple_fast(&region.as_petgraph(), entry_node)
}

/// Check the constraints on a single node.
Expand Down Expand Up @@ -365,8 +365,11 @@ impl<'a, 'b> ValidationContext<'a, 'b> {
};

let region: SiblingGraph = SiblingGraph::new(self.hugr, parent);
let postorder = Topo::new(&region);
let nodes_visited = postorder.iter(&region).filter(|n| *n != parent).count();
let postorder = Topo::new(&region.as_petgraph());
let nodes_visited = postorder
.iter(&region.as_petgraph())
.filter(|n| *n != parent)
.count();
let node_count = self.hugr.children(parent).count();
if nodes_visited != node_count {
return Err(ValidationError::NotADag {
Expand Down
27 changes: 12 additions & 15 deletions src/hugr/views.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
//! Read-only access into HUGR graphs and subgraphs.

pub mod descendants;
mod petgraph;
pub mod petgraph;
pub mod sibling;
pub mod sibling_subgraph;

#[cfg(test)]
mod tests;

pub use self::petgraph::PetgraphWrapper;
pub use descendants::DescendantsGraph;
pub use sibling::SiblingGraph;
pub use sibling_subgraph::SiblingSubgraph;
Expand All @@ -22,7 +23,6 @@ use crate::ops::handle::NodeHandle;
use crate::ops::{FuncDecl, FuncDefn, OpName, OpTag, OpType, DFG};
use crate::types::{EdgeKind, FunctionType};
use crate::{Direction, Node, Port};
use ::petgraph::visit as pv;

/// A trait for inspecting HUGRs.
/// For end users we intend this to be superseded by region-specific APIs.
Expand Down Expand Up @@ -181,6 +181,15 @@ pub trait HugrView: sealed::HugrInternals {
/// type. Otherwise return None.
fn get_function_type(&self) -> Option<&FunctionType>;

/// Return a wrapper over the view that can be used in petgraph algorithms.
#[inline]
fn as_petgraph(&self) -> PetgraphWrapper<'_, Self>
where
Self: Sized,
{
PetgraphWrapper { hugr: self }
}

/// Return dot string showing underlying graph and hierarchy side by side.
fn dot_string(&self) -> String {
let hugr = self.base_hugr();
Expand Down Expand Up @@ -232,19 +241,7 @@ pub trait HugrView: sealed::HugrInternals {
}

/// A common trait for views of a HUGR hierarchical subgraph.
pub trait HierarchyView<'a>:
HugrView
+ pv::GraphBase<NodeId = Node>
+ pv::GraphProp
+ pv::NodeCount
+ pv::NodeIndexable
+ pv::EdgeCount
+ pv::Visitable
+ pv::GetAdjacencyMatrix
+ pv::Visitable
where
for<'g> &'g Self: pv::IntoNeighborsDirected + pv::IntoNodeIdentifiers,
{
pub trait HierarchyView<'a>: HugrView {
/// The base from which the subgraph is derived.
type Base;

Expand Down
4 changes: 2 additions & 2 deletions src/hugr/views/descendants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ type RegionGraph<'g> = portgraph::view::Region<'g, &'g MultiPortGraph>;
/// its immediate children. Prefer using [`SiblingGraph`] when possible,
/// as it is more efficient.
///
/// Implements the [`HierarchyView`] trait, as well as [`HugrView`] and petgraph's
/// _visit_ traits, so can be used interchangeably with [`SiblingGraph`].
/// Implements the [`HierarchyView`] trait, as well as [`HugrView`], it can be
/// used interchangeably with [`SiblingGraph`].
///
/// [`SiblingGraph`]: super::SiblingGraph
pub struct DescendantsGraph<'g, Root = Node, Base = Hugr>
Expand Down
Loading

0 comments on commit 681db93

Please sign in to comment.