From 13c17181d32254e6cc1bdad304423ad1db1ae9e4 Mon Sep 17 00:00:00 2001 From: Agustin Borgna Date: Wed, 12 Jul 2023 12:10:06 +0100 Subject: [PATCH] feat: Move `dot_string` to `HugrView` --- Cargo.toml | 2 +- src/hugr.rs | 53 ++---------------------------------------------- src/hugr/view.rs | 53 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 53 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1335b6bd9..84e5250c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ path = "src/lib.rs" [dependencies] thiserror = "1.0.28" -portgraph = { version = "0.7.0", features = ["serde", "petgraph"] } +portgraph = { version = "0.7.1", features = ["serde", "petgraph"] } pyo3 = { version = "0.19.0", optional = true, features = [ "multiple-pymethods", ] } diff --git a/src/hugr.rs b/src/hugr.rs index 168a6b951..b90639c33 100644 --- a/src/hugr.rs +++ b/src/hugr.rs @@ -18,14 +18,12 @@ pub use self::validate::ValidationError; use derive_more::From; pub use rewrite::{Rewrite, SimpleReplacement, SimpleReplacementError}; -use portgraph::dot::{DotFormat, EdgeStyle, NodeStyle, PortStyle}; use portgraph::multiportgraph::MultiPortGraph; -use portgraph::{Hierarchy, LinkView, PortMut, PortView, UnmanagedDenseMap}; +use portgraph::{Hierarchy, PortMut, UnmanagedDenseMap}; use thiserror::Error; pub use self::view::HugrView; -use crate::ops::{OpName, OpType}; -use crate::types::EdgeKind; +use crate::ops::OpType; /// The Hugr data structure. #[derive(Clone, Debug, PartialEq)] @@ -103,53 +101,6 @@ impl Hugr { pub fn apply_rewrite(&mut self, rw: impl Rewrite) -> Result<(), E> { rw.apply(self) } - - /// Return dot string showing underlying graph and hierarchy side by side. - pub fn dot_string(&self) -> String { - self.graph - .dot_format() - .with_hierarchy(&self.hierarchy) - .with_node_style(|n| { - NodeStyle::Box(format!( - "({ni}) {name}", - ni = n.index(), - name = self.op_types[n].name() - )) - }) - .with_port_style(|port| { - let node = self.graph.port_node(port).unwrap(); - let optype = self.op_types.get(node); - let offset = self.graph.port_offset(port).unwrap(); - match optype.port_kind(offset).unwrap() { - EdgeKind::Static(ty) => { - PortStyle::new(html_escape::encode_text(&format!("{}", ty))) - } - EdgeKind::Value(ty) => { - PortStyle::new(html_escape::encode_text(&format!("{}", ty))) - } - EdgeKind::StateOrder => match self.graph.port_links(port).count() > 0 { - true => PortStyle::text("", false), - false => PortStyle::Hidden, - }, - _ => PortStyle::text("", true), - } - }) - .with_edge_style(|src, tgt| { - let src_node = self.graph.port_node(src).unwrap(); - let src_optype = self.op_types.get(src_node); - let src_offset = self.graph.port_offset(src).unwrap(); - let tgt_node = self.graph.port_node(tgt).unwrap(); - - if self.hierarchy.parent(src_node) != self.hierarchy.parent(tgt_node) { - EdgeStyle::Dashed - } else if src_optype.port_kind(src_offset) == Some(EdgeKind::StateOrder) { - EdgeStyle::Dotted - } else { - EdgeStyle::Solid - } - }) - .finish() - } } /// Arbitrary metadata for a node. diff --git a/src/hugr/view.rs b/src/hugr/view.rs index e543770c3..25a248850 100644 --- a/src/hugr/view.rs +++ b/src/hugr/view.rs @@ -6,11 +6,13 @@ use std::ops::Deref; use context_iterators::{ContextIterator, IntoContextIterator, MapCtx, MapWithCtx, WithCtx}; use itertools::{Itertools, MapInto}; +use portgraph::dot::{DotFormat, EdgeStyle, NodeStyle, PortStyle}; use portgraph::{multiportgraph, LinkView, MultiPortGraph, PortView}; use super::{Hugr, NodeMetadata}; use super::{Node, Port}; -use crate::ops::OpType; +use crate::ops::{OpName, OpType}; +use crate::types::EdgeKind; use crate::Direction; /// A trait for inspecting HUGRs. @@ -135,6 +137,55 @@ pub trait HugrView: sealed::HugrInternals { /// Iterates over the input and output neighbours of the `node` in sequence. fn all_neighbours(&self, node: Node) -> Self::Neighbours<'_>; + + /// Return dot string showing underlying graph and hierarchy side by side. + fn dot_string(&self) -> String { + let hugr = self.base_hugr(); + let graph = self.portgraph(); + graph + .dot_format() + .with_hierarchy(&hugr.hierarchy) + .with_node_style(|n| { + NodeStyle::Box(format!( + "({ni}) {name}", + ni = n.index(), + name = self.get_optype(n.into()).name() + )) + }) + .with_port_style(|port| { + let node = graph.port_node(port).unwrap(); + let optype = self.get_optype(node.into()); + let offset = graph.port_offset(port).unwrap(); + match optype.port_kind(offset).unwrap() { + EdgeKind::Static(ty) => { + PortStyle::new(html_escape::encode_text(&format!("{}", ty))) + } + EdgeKind::Value(ty) => { + PortStyle::new(html_escape::encode_text(&format!("{}", ty))) + } + EdgeKind::StateOrder => match graph.port_links(port).count() > 0 { + true => PortStyle::text("", false), + false => PortStyle::Hidden, + }, + _ => PortStyle::text("", true), + } + }) + .with_edge_style(|src, tgt| { + let src_node = graph.port_node(src).unwrap(); + let src_optype = self.get_optype(src_node.into()); + let src_offset = graph.port_offset(src).unwrap(); + let tgt_node = graph.port_node(tgt).unwrap(); + + if hugr.hierarchy.parent(src_node) != hugr.hierarchy.parent(tgt_node) { + EdgeStyle::Dashed + } else if src_optype.port_kind(src_offset) == Some(EdgeKind::StateOrder) { + EdgeStyle::Dotted + } else { + EdgeStyle::Solid + } + }) + .finish() + } } impl HugrView for T