Skip to content

Commit

Permalink
feat: Add ConvexChecker (#487)
Browse files Browse the repository at this point in the history
Exposing a HUGR-specific convex checker is required to be able to
construct it from outside the hugr crate.
  • Loading branch information
lmondada authored Sep 4, 2023
1 parent d376eee commit ea243fb
Showing 1 changed file with 23 additions and 7 deletions.
30 changes: 23 additions & 7 deletions src/hugr/views/sibling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use std::collections::HashSet;

use itertools::Itertools;
use portgraph::{algorithms::ConvexChecker, view::Subgraph, Direction, PortView};
use portgraph::{view::Subgraph, Direction, PortView};
use thiserror::Error;

use crate::{
Expand Down Expand Up @@ -149,7 +149,7 @@ impl<'g, Base: HugrView> SiblingSubgraph<'g, Base> {
where
Base: HugrView,
{
let mut checker = ConvexChecker::new(base.portgraph());
let mut checker = ConvexChecker::new(base);
Self::try_from_boundary_ports_with_checker(base, incoming, outgoing, &mut checker)
}

Expand All @@ -165,7 +165,7 @@ impl<'g, Base: HugrView> SiblingSubgraph<'g, Base> {
base: &'g Base,
inputs: IncomingPorts,
outputs: OutgoingPorts,
checker: &mut ConvexChecker<&'g Base::Portgraph>,
checker: &mut ConvexChecker<'g, Base>,
) -> Result<Self, InvalidSubgraph>
where
Base: HugrView,
Expand All @@ -187,7 +187,7 @@ impl<'g, Base: HugrView> SiblingSubgraph<'g, Base> {

validate_subgraph(base, &nodes, &inputs, &outputs)?;

if !subpg.is_convex_with_checker(checker) {
if !subpg.is_convex_with_checker(&mut checker.0) {
return Err(InvalidSubgraph::NotConvex);
}

Expand All @@ -212,7 +212,7 @@ impl<'g, Base: HugrView> SiblingSubgraph<'g, Base> {
where
Base: HugrView,
{
let mut checker = ConvexChecker::new(base.portgraph());
let mut checker = ConvexChecker::new(base);
Self::try_new_with_checker(base, nodes, inputs, outputs, &mut checker)
}

Expand All @@ -228,14 +228,14 @@ impl<'g, Base: HugrView> SiblingSubgraph<'g, Base> {
nodes: Vec<Node>,
inputs: IncomingPorts,
outputs: OutgoingPorts,
checker: &mut ConvexChecker<&'g Base::Portgraph>,
checker: &mut ConvexChecker<'g, Base>,
) -> Result<Self, InvalidSubgraph>
where
Base: HugrView,
{
validate_subgraph(base, &nodes, &inputs, &outputs)?;

if !checker.is_node_convex(nodes.iter().map(|n| n.index)) {
if !checker.0.is_node_convex(nodes.iter().map(|n| n.index)) {
return Err(InvalidSubgraph::NotConvex);
}

Expand Down Expand Up @@ -373,6 +373,22 @@ impl<'g, Base: HugrView> SiblingSubgraph<'g, Base> {
}
}

/// Precompute convexity information for a HUGR.
///
/// This can be used when constructing multiple sibling subgraphs to speed up
/// convexity checking.
pub struct ConvexChecker<'g, Base: HugrView>(
portgraph::algorithms::ConvexChecker<&'g Base::Portgraph>,
);

impl<'g, Base: HugrView> ConvexChecker<'g, Base> {
/// Create a new convexity checker.
pub fn new(base: &'g Base) -> Self {
let pg = base.portgraph();
Self(portgraph::algorithms::ConvexChecker::new(pg))
}
}

/// The type of all ports in the iterator.
///
/// If the array is empty or a port does not exist, returns `None`.
Expand Down

0 comments on commit ea243fb

Please sign in to comment.