Skip to content

Commit 972c878

Browse files
committed
switched to outgoing ports
1 parent 0259a4e commit 972c878

File tree

3 files changed

+87
-56
lines changed

3 files changed

+87
-56
lines changed

hugr-core/src/hugr/patch/simple_replace.rs

+43-35
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Implementation of the `SimpleReplace` operation.
22
33
use std::collections::{BTreeSet, HashMap};
4+
use std::hash::Hash;
45

56
use crate::core::HugrNode;
67
use crate::hugr::hugrmut::InsertionResult;
@@ -353,41 +354,6 @@ impl<
353354
.map(Into::into)
354355
}
355356

356-
/// Map the host nodes in `self` according to `node_map`.
357-
///
358-
/// `node_map` must map nodes in the current HUGR of the subgraph to
359-
/// its equivalent nodes in some `new_hugr`.
360-
///
361-
/// This converts a replacement that acts on nodes of type `HostNode` to
362-
/// a replacement that acts on `new_hugr`, with nodes of type `N`.
363-
///
364-
/// This does not check convexity. It is up to the caller to ensure that
365-
/// the mapped replacement obtained from this applies on a convex subgraph
366-
/// of the new HUGR.
367-
pub(crate) fn map_host_nodes<N: HugrNode>(
368-
&self,
369-
node_map: impl Fn(HostNode) -> N,
370-
) -> SimpleReplacement<N> {
371-
let Self {
372-
subgraph,
373-
replacement,
374-
nu_inp,
375-
nu_out,
376-
} = self;
377-
let nu_inp = nu_inp
378-
.iter()
379-
.map(|(&(node, port), &(host_node, host_port))| {
380-
((node, port), (node_map(host_node), host_port))
381-
})
382-
.collect();
383-
let nu_out = nu_out
384-
.iter()
385-
.map(|(&(host_node, host_port), &port)| ((node_map(host_node), host_port), port))
386-
.collect();
387-
let subgraph = subgraph.map_nodes(node_map);
388-
SimpleReplacement::new(subgraph, replacement.clone(), nu_inp, nu_out)
389-
}
390-
391357
/// Get all edges that the replacement would add between `host` and
392358
/// `self.replacement`.
393359
///
@@ -421,6 +387,48 @@ impl<
421387
}
422388
}
423389

390+
impl<HostNode: HugrNode, P: Copy + Eq + Hash>
391+
SimpleReplacement<HostNode, DefaultInMap<HostNode>, OutputNodeBoundaryMap<HostNode, P>>
392+
{
393+
/// Map the host nodes in `self` according to `node_map`.
394+
///
395+
/// `node_map` must map nodes in the current HUGR of the subgraph to
396+
/// its equivalent nodes in some `new_hugr`.
397+
///
398+
/// This converts a replacement that acts on nodes of type `HostNode` to
399+
/// a replacement that acts on `new_hugr`, with nodes of type `N`.
400+
///
401+
/// This does not check convexity. It is up to the caller to ensure that
402+
/// the mapped replacement obtained from this applies on a convex subgraph
403+
/// of the new HUGR.
404+
pub(crate) fn map_host_nodes<N: HugrNode>(
405+
&self,
406+
node_map: impl Fn(HostNode) -> N,
407+
) -> SimpleReplacement<N, DefaultInMap<N>, OutputNodeBoundaryMap<N, P>> {
408+
let Self {
409+
subgraph,
410+
replacement,
411+
nu_inp,
412+
nu_out,
413+
} = self;
414+
let nu_inp = nu_inp
415+
.iter()
416+
.map(|(&repl_node_port, &(host_node, host_port))| {
417+
(repl_node_port, (node_map(host_node), host_port))
418+
})
419+
.collect();
420+
let nu_out: HashMap<_, _> = nu_out
421+
.0
422+
.iter()
423+
.map(|(&(host_node, host_port), &repl_port)| {
424+
((node_map(host_node), host_port), repl_port)
425+
})
426+
.collect();
427+
let subgraph = subgraph.map_nodes(node_map);
428+
SimpleReplacement::new_unsafe(subgraph, replacement.clone(), nu_inp, nu_out.into())
429+
}
430+
}
431+
424432
fn check_valid_boundary<HostNode, InMap, OutMap>(
425433
subgraph: &SiblingSubgraph<HostNode>,
426434
host: &impl HugrView<Node = HostNode>,

hugr-core/src/hugr/persistent.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,17 @@ pub use resolver::PointerEqResolver;
8080

8181
use crate::{
8282
hugr::patch::{simple_replace, Patch, PatchVerification},
83-
Hugr, HugrView, Node, SimpleReplacement,
83+
Hugr, HugrView, Node, OutgoingPort, SimpleReplacement,
8484
};
8585

86+
use super::patch::{simple_replace::DefaultInMap, OutputNodeBoundaryMap};
87+
8688
/// A replacement operation that can be applied to a [`PersistentHugr`].
87-
pub type PersistentReplacement = SimpleReplacement<PatchNode>;
89+
pub type PersistentReplacement = SimpleReplacement<
90+
PatchNode,
91+
DefaultInMap<PatchNode>,
92+
OutputNodeBoundaryMap<PatchNode, OutgoingPort>,
93+
>;
8894

8995
/// A patch that can be applied to a [`PersistentHugr`] or a
9096
/// [`CommitStateSpace`] as an atomic commit.
@@ -139,11 +145,7 @@ impl Commit {
139145
&self.0
140146
}
141147

142-
fn all_parents(&self) -> impl Iterator<Item = &Commit> + '_ {
143-
self.0.all_parents().map_into()
144-
}
145-
146-
fn replacement(&self) -> Option<&SimpleReplacement<PatchNode>> {
148+
fn replacement(&self) -> Option<&PersistentReplacement> {
147149
match self.0.value() {
148150
CommitData::Base(_) => None,
149151
CommitData::Replacement(replacement) => Some(replacement),
@@ -278,7 +280,7 @@ impl PersistentHugr {
278280
let new_invalid_nodes = replacement
279281
.subgraph()
280282
.nodes()
281-
.into_iter()
283+
.iter()
282284
.map(|&PatchNode(id, node)| (id, node))
283285
.into_grouping_map()
284286
.collect::<BTreeSet<_>>();

hugr-core/src/hugr/persistent/tests.rs

+34-13
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ use rstest::*;
55
use crate::{
66
builder::{inout_sig, DFGBuilder, Dataflow, DataflowHugr},
77
extension::prelude::bool_t,
8-
hugr::{patch::Patch, persistent::PatchNode, views::SiblingSubgraph, Hugr, HugrView},
8+
hugr::{
9+
patch::{simple_replace::DefaultInMap, OutputNodeBoundaryMap, Patch},
10+
persistent::PatchNode,
11+
views::SiblingSubgraph,
12+
Hugr, HugrView,
13+
},
914
ops::handle::NodeHandle,
1015
std_extensions::logic::LogicOp,
1116
IncomingPort, Node, OutgoingPort, SimpleReplacement,
@@ -48,7 +53,10 @@ fn simple_hugr() -> (Hugr, [Node; 3]) {
4853
}
4954

5055
/// Creates a replacement that replaces a node with a sequence of two NOT gates
51-
fn create_double_not_replacement(hugr: &Hugr, node_to_replace: Node) -> SimpleReplacement {
56+
fn create_double_not_replacement(
57+
hugr: &Hugr,
58+
node_to_replace: Node,
59+
) -> SimpleReplacement<Node, DefaultInMap<Node>, OutputNodeBoundaryMap<Node, OutgoingPort>> {
5260
// Create a simple hugr with two NOT gates in sequence
5361
let mut dfg_builder = DFGBuilder::new(inout_sig(vec![bool_t()], vec![bool_t()])).unwrap();
5462
let [input_wire] = dfg_builder.input_wires_arr();
@@ -67,11 +75,6 @@ fn create_double_not_replacement(hugr: &Hugr, node_to_replace: Node) -> SimpleRe
6775

6876
let replacement_hugr = dfg_builder.finish_hugr_with_outputs([not2_out]).unwrap();
6977

70-
// Find the input and output of the node to replace
71-
let host_output_target = hugr
72-
.single_linked_input(node_to_replace, OutgoingPort::from(0))
73-
.unwrap();
74-
7578
// Create the mappings
7679
let mut nu_inp = HashMap::new();
7780
nu_inp.insert(
@@ -80,18 +83,30 @@ fn create_double_not_replacement(hugr: &Hugr, node_to_replace: Node) -> SimpleRe
8083
);
8184

8285
let mut nu_out = HashMap::new();
83-
nu_out.insert(host_output_target, IncomingPort::from(0));
86+
nu_out.insert(
87+
(node_to_replace, OutgoingPort::from(0)),
88+
IncomingPort::from(0),
89+
);
8490

8591
// Create the subgraph with the single node
8692
let subgraph = SiblingSubgraph::try_from_nodes(vec![node_to_replace], hugr).unwrap();
8793

8894
// Create the replacement
89-
SimpleReplacement::new(subgraph, replacement_hugr, nu_inp, nu_out)
95+
SimpleReplacement::try_new(
96+
subgraph,
97+
hugr,
98+
replacement_hugr,
99+
nu_inp,
100+
OutputNodeBoundaryMap::from(nu_out),
101+
)
102+
.unwrap()
90103
}
91104

92105
/// Creates a replacement that replaces the unique AND gate in `hugr` and its
93106
/// predecessor NOT gate on 1st input with an XOR gate
94-
fn create_not_and_to_xor_replacement(hugr: &Hugr) -> SimpleReplacement {
107+
fn create_not_and_to_xor_replacement(
108+
hugr: &Hugr,
109+
) -> SimpleReplacement<Node, DefaultInMap<Node>, OutputNodeBoundaryMap<Node, OutgoingPort>> {
95110
// Create second replacement that replaces the second NOT gate from the first
96111
// replacement
97112
// Find the AND gate in the hugr
@@ -133,13 +148,19 @@ fn create_not_and_to_xor_replacement(hugr: &Hugr) -> SimpleReplacement {
133148

134149
// Output mapping - AND gate's output to XOR's output
135150
let mut nu_out = HashMap::new();
136-
let and_output_port = hugr.single_linked_input(and_gate, 0).unwrap();
137-
nu_out.insert(and_output_port, IncomingPort::from(0));
151+
nu_out.insert((and_gate, OutgoingPort::from(0)), IncomingPort::from(0));
138152

139153
// Create subgraph with both the AND gate and NOT0 node
140154
let subgraph = SiblingSubgraph::try_from_nodes(vec![not_node, and_gate], &hugr).unwrap();
141155

142-
SimpleReplacement::new(subgraph, replacement_hugr, nu_inp, nu_out)
156+
SimpleReplacement::try_new(
157+
subgraph,
158+
hugr,
159+
replacement_hugr,
160+
nu_inp,
161+
OutputNodeBoundaryMap::from(nu_out),
162+
)
163+
.unwrap()
143164
}
144165

145166
#[fixture]

0 commit comments

Comments
 (0)