Skip to content

Commit e489a13

Browse files
committed
Export order keys on input and output nodes.
1 parent d80e05d commit e489a13

3 files changed

Lines changed: 55 additions & 39 deletions

File tree

hugr-core/src/export.rs

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -627,41 +627,47 @@ impl<'a> Context<'a> {
627627
let children = self.hugr.children(node);
628628
let mut region_children = BumpVec::with_capacity_in(children.size_hint().0 - 2, self.bump);
629629

630-
let mut output_node = None;
631-
632630
for child in children {
633631
match self.hugr.get_optype(child) {
634632
OpType::Input(input) => {
635633
sources = self.make_ports(child, Direction::Outgoing, input.types.len());
636634
input_types = Some(&input.types);
635+
636+
if has_order_edges(&self.hugr, child) {
637+
let key = self.make_term(model::Literal::Nat(child.index() as u64).into());
638+
meta.push(self.make_term_apply(model::ORDER_HINT_INPUT_KEY, &[key]));
639+
}
637640
}
638641
OpType::Output(output) => {
639642
targets = self.make_ports(child, Direction::Incoming, output.types.len());
640643
output_types = Some(&output.types);
641-
output_node = Some(child);
644+
645+
if has_order_edges(&self.hugr, child) {
646+
let key = self.make_term(model::Literal::Nat(child.index() as u64).into());
647+
meta.push(self.make_term_apply(model::ORDER_HINT_OUTPUT_KEY, &[key]));
648+
}
642649
}
643-
child_optype => {
650+
_ => {
644651
if let Some(child_id) = self.export_node_shallow(child) {
645652
region_children.push(child_id);
646-
647-
// Record all order edges that originate from this node in metadata.
648-
let successors = child_optype
649-
.other_output_port()
650-
.into_iter()
651-
.flat_map(|port| self.hugr.linked_inputs(child, port))
652-
.map(|(successor, _)| successor)
653-
.filter(|successor| Some(*successor) != output_node);
654-
655-
for successor in successors {
656-
let a =
657-
self.make_term(model::Literal::Nat(child.index() as u64).into());
658-
let b = self
659-
.make_term(model::Literal::Nat(successor.index() as u64).into());
660-
meta.push(self.make_term_apply(model::ORDER_HINT_ORDER, &[a, b]));
661-
}
662653
}
663654
}
664655
}
656+
657+
// Record all order edges that originate from this node in metadata.
658+
let successors = self
659+
.hugr
660+
.get_optype(child)
661+
.other_output_port()
662+
.into_iter()
663+
.flat_map(|port| self.hugr.linked_inputs(child, port))
664+
.map(|(successor, _)| successor);
665+
666+
for successor in successors {
667+
let a = self.make_term(model::Literal::Nat(child.index() as u64).into());
668+
let b = self.make_term(model::Literal::Nat(successor.index() as u64).into());
669+
meta.push(self.make_term_apply(model::ORDER_HINT_ORDER, &[a, b]));
670+
}
665671
}
666672

667673
for child_id in &region_children {
@@ -1100,21 +1106,7 @@ impl<'a> Context<'a> {
11001106
}
11011107

11021108
fn export_node_order_metadata(&mut self, node: Node, meta: &mut Vec<table::TermId>) {
1103-
fn is_relevant_node(hugr: &Hugr, node: Node) -> bool {
1104-
let optype = hugr.get_optype(node);
1105-
!optype.is_input() && !optype.is_output()
1106-
}
1107-
1108-
let optype = self.hugr.get_optype(node);
1109-
1110-
let has_order_edges = Direction::BOTH
1111-
.iter()
1112-
.filter(|dir| optype.other_port_kind(**dir) == Some(EdgeKind::StateOrder))
1113-
.filter_map(|dir| optype.other_port(*dir))
1114-
.flat_map(|port| self.hugr.linked_ports(node, port))
1115-
.any(|(other, _)| is_relevant_node(self.hugr, other));
1116-
1117-
if has_order_edges {
1109+
if has_order_edges(&self.hugr, node) {
11181110
let key = self.make_term(model::Literal::Nat(node.index() as u64).into());
11191111
meta.push(self.make_term_apply(model::ORDER_HINT_KEY, &[key]));
11201112
}
@@ -1229,6 +1221,18 @@ impl Links {
12291221
}
12301222
}
12311223

1224+
/// Returns `true` if a node has any incident order edges.
1225+
fn has_order_edges(hugr: &Hugr, node: Node) -> bool {
1226+
let optype = hugr.get_optype(node);
1227+
Direction::BOTH
1228+
.iter()
1229+
.filter(|dir| optype.other_port_kind(**dir) == Some(EdgeKind::StateOrder))
1230+
.filter_map(|dir| optype.other_port(*dir))
1231+
.flat_map(|port| hugr.linked_ports(node, port))
1232+
.next()
1233+
.is_some()
1234+
}
1235+
12321236
#[cfg(test)]
12331237
mod test {
12341238
use rstest::{fixture, rstest};

hugr-core/tests/snapshots/model__roundtrip_order.snap

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,19 @@ expression: ast
88

99
(import core.meta.description)
1010

11+
(import core.order_hint.input_key)
12+
13+
(import core.order_hint.order)
14+
15+
(import arithmetic.int.types.int)
16+
1117
(import core.nat)
1218

1319
(import core.order_hint.key)
1420

15-
(import core.fn)
16-
17-
(import core.order_hint.order)
21+
(import core.order_hint.output_key)
1822

19-
(import arithmetic.int.types.int)
23+
(import core.fn)
2024

2125
(declare-operation
2226
arithmetic.int.ineg
@@ -48,9 +52,13 @@ expression: ast
4852
(arithmetic.int.types.int 6)
4953
(arithmetic.int.types.int 6)
5054
(arithmetic.int.types.int 6)]))
55+
(meta (core.order_hint.input_key 2))
56+
(meta (core.order_hint.order 2 4))
57+
(meta (core.order_hint.output_key 3))
5158
(meta (core.order_hint.order 4 7))
5259
(meta (core.order_hint.order 5 6))
5360
(meta (core.order_hint.order 5 4))
61+
(meta (core.order_hint.order 5 3))
5462
(meta (core.order_hint.order 6 7))
5563
((arithmetic.int.ineg 6) [%0] [%4]
5664
(signature

hugr-model/tests/fixtures/model-order.edn

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
(meta (core.order_hint.order 1 0))
2929
(meta (core.order_hint.order 2 3))
3030
(meta (core.order_hint.order 0 3))
31+
(meta (core.order_hint.input_key 4))
32+
(meta (core.order_hint.order 4 0))
33+
(meta (core.order_hint.order 1 5))
34+
(meta (core.order_hint.output_key 5))
3135

3236
((arithmetic.int.ineg 6)
3337
[%0] [%4]

0 commit comments

Comments
 (0)