feat: a small public node interface, and a node that no longer silently estimates nothing (#374) - #379
Closed
seabbs-bot wants to merge 1 commit into
Closed
Conversation
…ent-zero The composer-node extension contract is public (not exported) and minimal now: a downstream node implements node_children/node_rebuild/component_names (promoted from the private _node_children/_rebuild), and that alone is enough to compose, table (composed_to_table), and update. child_nleaves/ child_logpdf/child_rand! default generically off node_children for a plain "concatenating" node; a node with novel combination semantics still overrides them, as Choose does. Codec (flatten/unflatten/reconstruct/fit) support additionally needs the node's own child names and children's types as its first two type parameters, matching Sequential/Parallel/Choose/ Compete's existing shape -- documented as a deliberate choice, since a @generated function cannot call a method a downstream package defines (a measured Julia world-age hazard). composed_to_table, params, update, has_uncertain, has_varying and compose(...) nesting are now generic over any AbstractComposedDistribution subtype rather than closed to the five built-in node kinds; a node missing a required method now fails with a clear error naming the gap, rather than silently being treated as a leaf with zero estimated parameters (#374). TestUtils.test_estimation_dimension is a new conformance check (wired into both test_node_interface and test_interface) asserting flat_dimension(d) matches composed_to_table(d)'s estimated-row count, so a node that silently drops an uncertain leaf from the codec fails the harness instead of shipping green. docs/src/developer/interface-contracts.md and test/interfaces.jl are rewritten around a genuinely working Both node (subtyping AbstractComposedDistribution) that composes, tables, flattens and fits, replacing the old worked example that could not actually participate in composition. A dedicated negative-fixture testitem asserts an incomplete node fails loudly rather than silently.
Contributor
Try this Pull Request!Option 1: Julia Package ManagerOpen Julia and type: import Pkg
Pkg.activate(temp=true)
Pkg.add(url="https://github.com/EpiAware/ComposedDistributions.jl", rev="feat/374-node-interface")
using ComposedDistributionsOption 2: Local CheckoutIf you have the repo locally: git checkout feat/374-node-interface
julia --project=. -e "using Pkg; Pkg.instantiate()" |
Collaborator
Author
|
Superseded by #381, which folds this and seven other PRs into one branch off This branch is preserved and the PR body is kept for its rationale — the detail here is the record of why, which #381 summarises rather than repeats. Closing so it does not compete for review. This comment was posted by a bot. Please ping @seabbs for any questions. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements your steer: writing methods to add a node is fine, but they must be few, clean, public but not exported, and backed by a stated interface and developer docs. It also fixes the correctness bug underneath.
Stacked on #343 (
feat/227-single-table-slice-1, which already carries #362).The bug it closes
A fresh
AbstractComposedDistributionsubtype implementing all four documented methods, with an uncertain child, gotflat_dimension == 0where the answer is 1. A fit on that tree estimated nothing and reported no error, and the shippedtest_node_interfacepassed it 8/8.The cause was structural: the codec's
if T <: Sequential / elseif T <: Choose / else leafchains live inside@generatedbodies, so there was no method a downstream node could add — it fell into the leaf branch.Now
composed_to_table,params,update,has_uncertain,has_varyingandcompose(...)nesting are generic over anyAbstractComposedDistributionsubtype rather than closed to the five built-ins, and a node missing a required method fails with an error naming the gap instead of being silently treated as a leaf.The interface
A downstream node implements
node_children,node_rebuildandcomponent_names— promoted from the private_node_children/_rebuild— and that alone is enough to compose, table and update.child_nleaves,child_logpdfandchild_rand!now default generically offnode_childrenfor a plain concatenating node. A node with novel combination semantics still overrides them, asChoosedoes.One honest limitation, documented rather than hidden
Full codec support additionally requires the node to carry its own child names and children's types as its first two type parameters, matching the shape
Sequential/Parallel/Choose/Competealready have. That is a deliberate constraint, not an oversight: a@generatedfunction cannot call a method a downstream package defines — a measured Julia world-age hazard, the same one #189 documented.It is stated in the interface docs rather than left for someone to discover through a silent zero.
The conformance check that would have caught it
TestUtils.test_estimation_dimensionassertsflat_dimension(d)matchescomposed_to_table(d)'s estimated-row count, wired into bothtest_node_interfaceandtest_interface. A node that silently drops an uncertain leaf from the codec now fails the harness instead of shipping green. A dedicated negative-fixture testitem pins that an incomplete node fails loudly.Docs
docs/src/developer/interface-contracts.mdandtest/interfaces.jlare rewritten around aBothnode that genuinely composes, tables, flattens and fits. The previous worked example could not participate in composition at all — it was not anAbstractComposedDistributionsubtype, so the composability gate rejected it.Note for #365: that PR deletes these developer pages into
extending.md. Expect a delete/modify conflict, resolved in #365's favour by carrying this wording across.Assertions
None removed or weakened — verified by diff: zero removed
@testlines, 25 assertions added.Closes #374. Refs #332, #365.
This was opened by a bot. Please ping @seabbs for any questions.