-
Notifications
You must be signed in to change notification settings - Fork 8
feat: PersistentHugr Walker API #2168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: luca/persistent-impl-hugrview
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## luca/persistent-impl-hugrview #2168 +/- ##
=================================================================
+ Coverage 82.24% 82.38% +0.14%
=================================================================
Files 235 237 +2
Lines 41984 42173 +189
Branches 38083 38272 +189
=================================================================
+ Hits 34528 34743 +215
+ Misses 5479 5452 -27
- Partials 1977 1978 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
a7729f3
to
cb812be
Compare
fd0c21f
to
3b27b4d
Compare
2206368
to
b81ed94
Compare
EDIT: resolved!
|
782e1ba
to
ca5d841
Compare
ca5d841
to
7874237
Compare
7874237
to
b1685fd
Compare
b1685fd
to
654c4fc
Compare
654c4fc
to
b4bae59
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @lmondada, this is great! Not what you'd call easy stuff, but great job in making it comprehensible :-). I have about 60 small suggestions, there are only two big enough to justify not immediately approving:
- Have I understand PinnedWire always has at least one endpoint pinned? I wasn't clear from the doc so I had to guess a bit, if that's not right then this may need some more thought
- That
equivalent_descendant_ports
method....what is all the direction-changing doing...
@@ -0,0 +1,624 @@ | |||
//! Exploration of a [`PersistentHugr`] through incremental traversal of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with "exploration of a [CommitStateSpace
]" just below, but a PersistentHugr is a non-conflicting subgraph of a CommitStateSpace, right?
Maybe "Explores a CommitStateSpace (and allows) to establish/identify/build a PersistentHugr by incrementally" and then either "traversing connected subgraphs" as you have here (not sure if I've quite followed that yet though) or "pinning nodes resulting from particular rewrites" ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right! How do you find the following
Incremental traversal and construction of [
PersistentHugr
]s from [CommitStateSpace
]s
?
It's hard to keep it to a high-level one-line summary
//! This module provides the [`Walker`] type, which enables intuitive | ||
//! exploration of a [`CommitStateSpace`] by traversing wires and gradually | ||
//! pinning (selecting) nodes that match a desired pattern. Unlike direct | ||
//! manipulation of a [`PersistentHugr`], the Walker presents a familiar |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what this "direct manipulation of a PersistentHugr" is that is so different from the "familiar nodes-and-wires interface". PersistentHugr implements HugrView, which is exactly that familiar nodes-and-wires interface....?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, PersistentHugr
-> CommitStateSpace
. I've added a bit more context to this sentence, does it make sense in its new form?
//! The key concept is that of "pinning" nodes - marking specific nodes as fixed | ||
//! points in the exploration. As more nodes are pinned, the space of possible | ||
//! HUGRs that are considered narrows; a Walker instance where all nodes are | ||
//! pinned corresponds to a unique HUGR in the [`PersistentHugr`]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like this, but don't you mean "...corresponds to a particular PersistentHugr (in the CommitStateSpace)"? As a PersistentHugr is a Hugr(View)...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Re-reading this makes me think I must have done a wrong renaming operation (in one of the many renames haha) -- or just brain fog. Mostly we are refering to CommitStateSpace
s, not PersistentHugr
s!
//! exploration typically branches out into several parallel walkers. | ||
//! 4. As walkers are expanded, more nodes get pinned, narrowing down the space | ||
//! of possible HUGRs. | ||
//! 5. Once exploration is complete (e.g. a pattern was fully matched), the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! Nice :)
//! 5. Once exploration is complete (e.g. a pattern was fully matched), the | ||
//! walker can be converted into a [`PersistentHugr`] instance using | ||
//! [`Walker::into_hugr`]. The matched nodes and ports can then be used to | ||
//! create a [`SimpleReplacement`](crate::SimpleReplacement) object, which |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll suspend disbelief here - the SimpleReplacement is the combination of all of the selected patches?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, you've done well to highlight this point. What I intended to say is that the pinned nodes can be used to specify a subgraph of the current PersistentHugr
, which in turn can be used to define a new SimpleReplacement
.
hugr-core/tests/walker.rs
Outdated
.contains(&pinned_node.1), | ||
"pinned node is deleted" | ||
); | ||
for walker in walker.expand(&wire, None) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for walker in walker.expand(&wire, None) { | |
for subwalker in walker.expand(&wire, None) { |
hugr-core/tests/walker.rs
Outdated
|
||
// enqueue new wires added by the replacement | ||
// (this will also add a lot of already visited wires, but they will | ||
// be deduplicated) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC, if you moved the outermost loop in enqueue_all
to the first callsite, then you could skip that loop here because you are adding only a single replacement? Would that address this comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no -- you'd need to consider all commits that could be neighbours (but disjoint) with the newly added commit. It's a bit iffy, another area where the API will probably have to improve in the future.
hugr-core/tests/walker.rs
Outdated
state_space | ||
} | ||
|
||
fn create_replacement(wire: PinnedWire, walker: &Walker) -> Result<PersistentReplacement, ()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Result -> Option
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
absolutely!
} | ||
|
||
/// Get all pinned ports of the wire. | ||
pub fn all_ports(&self) -> impl Iterator<Item = (PatchNode, Port)> + '_ { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider calling these pinned_outport
, pinned_inports
and all_pinned_ports
...reading the client code it's easy to miss that you have a PinnedWire not a Wire
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good names!
hugr-core/tests/walker.rs
Outdated
@@ -0,0 +1,406 @@ | |||
//! A test of the walker as it would typically be used by a user in practice. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fab**, although I wonder if it should be in persistent/tests.rs
or persistent/walker_example.rs
** and seeing usage examples has lead to several suggestions for API improvements above and below ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure thing, I'll put it within a persistent
subfolder.
Strangely, cargo
doesn't find the test file if I put it within a subfolder. I've called it persistent_walker_example.rs
instead. (We can go for a more nested structure once there are more than two files in the directory)
08e3eb0
to
7cd85d7
Compare
Closes #2074
Closes #2190