Add method for removing redundant nodes#571
Conversation
4dab596 to
a8040b8
Compare
a8040b8 to
82cc356
Compare
56195c1 to
57638a8
Compare
In C++20 Node::operator==(const Node&) const is amibiguous because either order is valid.
39fb39d to
055fe62
Compare
ee71c02 to
770a9cb
Compare
This requires some fiddling, see https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members for the why.
261d2d6 to
98e4bd0
Compare
98e4bd0 to
47e1be7
Compare
90386b6 to
cd107a0
Compare
| virtual bool equal_to(const Derived& rhs) const = 0; | ||
| }; | ||
|
|
||
| /// Overload for EqualityMixin that does not require a class-specific equal_to() |
There was a problem hiding this comment.
A doubt I have is whether these two overloads are different enough that they should actually be given different names 🤔
42a0edd to
f7a75d1
Compare
4e887e4 to
f643bca
Compare
|
As a note: I didn't try to be inclusive about the |
212caf4 to
d0dd3d3
Compare
fastbodin
left a comment
There was a problem hiding this comment.
Managed to work through all files excluding the test files. Thought I would upload these comments before moving onto them.
| >>> model = Model() | ||
| ... | ||
| >>> x = model.integer(5) | ||
| ... |
There was a problem hiding this comment.
Nit: I find that the ... do not add much to the example. Additionally, most of the other examples do not include .... Am I missing something?
| if (not dropped(uptr)) continue; | ||
|
|
||
| // Remove the node from its predecessor's successor vectors. | ||
| // This very leaves the node in an invalid state, very briefly |
There was a problem hiding this comment.
| // This very leaves the node in an invalid state, very briefly | |
| // This leaves the node in an invalid state, very briefly |
|
|
||
| index -= 1; |
There was a problem hiding this comment.
// If we haven't found the Array* we want to replace, then "normalize"
// the index so that it looks like it would if `initial_` wasn't an array.
| bool UnaryOpNode<UnaryOp>::equal_to(const Node& rhs) const { | ||
| const auto* rhs_ptr = dynamic_cast<const UnaryOpNode*>(&rhs); | ||
| if (rhs_ptr == nullptr) return false; // not same type so not equal | ||
| return this->equal_to(*rhs_ptr); |
There was a problem hiding this comment.
Confirming that I am not sleeping at the wheel. I had to do a double take here 😆
There was a problem hiding this comment.
Probably should change 190 to
const UnaryOpNode* rhs_ptr = dynamic_cast<const UnaryOpNode*>(&rhs);to make it a little clearer what's happening.
There was a problem hiding this comment.
Usually I am fine with auto here, but, in this case, that would actually be helpful.
| } | ||
| } | ||
|
|
||
| SECTION("predecessor replacement") { |
There was a problem hiding this comment.
For some nodes that use the EqualityMixin without needing to implement another overload I stopped bothering to write separate tests for them, reasoning that it is already extremely well covered elsewhere.
There was a problem hiding this comment.
That is fine with me. 👍 You were correct in predicting that I would make such a comment 🤣
fastbodin
left a comment
There was a problem hiding this comment.
I have now gone through all the files. I would like to go through graph.cpp again.
The patience you had when writing these tests is a marvel.
| graph.emplace_node<ArrayValidationNode>(sets.at(i)); | ||
| } | ||
|
|
||
| THEN("node equality works as expected") { |
There was a problem hiding this comment.
Test for DisjointListNode too?
| Node* a_ptr = graph.emplace_node<BSplineNode>(x0_ptr, k, t0, c0); | ||
| Node* b_ptr = graph.emplace_node<BSplineNode>(x0_ptr, k, t0, c0); | ||
| Node* c_ptr = graph.emplace_node<BSplineNode>(x1_ptr, k, t1, c0); | ||
| Node* d_ptr = graph.emplace_node<BSplineNode>(x0_ptr, k, t0, c1); |
There was a problem hiding this comment.
Just because BSplineNode::equal_to() also checks k, I would add
Node* e_ptr = graph.emplace_node<BSplineNode>(x0_ptr, 3, t0, c0);and the corresponding checks like
CHECK(not a_ptr->equal_to(*e_ptr));| void ARangeNode::replace_predecessor_(ssize_t index, Node* node_ptr) { | ||
| Node::replace_predecessor_(index, node_ptr); | ||
|
|
||
| assert(0 <= index and static_cast<size_t>(index) < predecessors().size()); |
There was a problem hiding this comment.
This logic makes sense. Consider me convinced.
| """ | ||
| return self.num_nodes() | ||
|
|
||
| def remove_redundant_symbols(self, time_limit_s=None): |
There was a problem hiding this comment.
Worth adding a note in here that this is ineffective on named symbols?
| auto* c0_ptr = graph.emplace_node<ConstantNode>(std::vector{0, 1, 2, 3}); | ||
| auto* c1_ptr = graph.emplace_node<ConstantNode>(std::vector{7, 6, 5, 4}); | ||
|
|
||
| auto* argsort_ptr = graph.emplace_node<MeanNode>(c0_ptr); |
| auto* c0_ptr = graph.emplace_node<ConstantNode>(std::vector{0, 1, 2, 3}); | ||
| auto* c1_ptr = graph.emplace_node<ConstantNode>(std::vector{7, 6, 5, 4}); | ||
|
|
||
| auto* argsort_ptr = graph.emplace_node<UnaryOpNode<TestType>>(c0_ptr); |
| auto* y_ptr = graph.emplace_node<BinaryNode>(); | ||
|
|
||
| auto* left_x_plus_y = graph.emplace_node<AddNode>(x_ptr, y_ptr); | ||
| auto* right_x_plus_y = graph.emplace_node<AddNode>(x_ptr, y_ptr); |
There was a problem hiding this comment.
| auto* right_x_plus_y = graph.emplace_node<AddNode>(x_ptr, y_ptr); | |
| auto* right_x_plus_y = graph.emplace_node<AddNode>(y_ptr, x_ptr); |
As per the variable name?
Closes #563
AI Generation Disclosure
No AI used.