expandPortThrough method
Incrementally expand a port with pass-through traversal.
Like expandPort, but continues through trivial gates (buffers,
inverters, slicers, concatenators) until non-trivial children or
external ports of nodeId are reached.
Direction semantics:
- WEST ports (inputs) — the signal flows inward; traversal follows hyperedge targets from the parent port to child INPUT ports, then exits through child OUTPUT ports. CONCAT children may fanout (one output → many sources in the next hyperedge).
- EAST ports (outputs) — the signal flows outward; traversal follows hyperedge sources from the parent port to child OUTPUT ports, then exits through child INPUT ports. SLICE children may fanout (one input → many targets in the next hyperedge).
The traversal uses a BFS queue of port IDs (child-side) that still need to be matched against hyperedges. Each newly discovered trivial child enqueues its "exit" ports for further exploration.
Returns true if new children/edges were revealed.
Implementation
bool expandPortThrough(String nodeId, String portId) {
final node = nodeMap[nodeId];
if (node == null) {
return false;
}
if (node.hiddenChildren == null || node.hiddenChildren!.isEmpty) {
return false;
}
final hyperedges = node.hyperedges;
if (hyperedges == null || hyperedges.isEmpty) {
return false;
}
// Use shared collection logic to find gates and edges on this port path.
final (collectedChildIds, collectedHyperedgeIds) =
_collectPortThroughGatesAndEdges(node, portId);
if (collectedChildIds.isEmpty && collectedHyperedgeIds.isEmpty) {
return false;
}
// Check idempotency.
final existingChildren = node.partialChildIds ?? {};
final existingEdges = node.partialHyperedgeIds ?? {};
if (existingChildren.containsAll(collectedChildIds) &&
existingEdges.containsAll(collectedHyperedgeIds)) {
return false;
}
// Additive: merge into existing partial sets.
final mergedChildren = {...existingChildren, ...collectedChildIds};
final mergedEdges = {...existingEdges, ...collectedHyperedgeIds};
node
..partialChildIds = mergedChildren
..partialHyperedgeIds = mergedEdges;
return true;
}