Enumerate finite intersections from a finite child; gather seeds from all children - #58
Merged
Merged
Conversation
… all children members(AllOf) delegated to seeds(), which picked the first child with any explicit seed. A child can have seeds without being finite, so an intersection whose first seed-bearing child was a mixed union enumerated nothing even when a later child was finite, and a start or goal using it failed root collection. members() now has its own recursion: an AnyOf enumerates every child when all are finite; an AllOf enumerates a child that is itself finite and keeps the members every other child contains, so the resulting configurations do not depend on child order. seeds(AllOf) returns the exhaustive members when the intersection is finite; otherwise it collects the seeds of every seed-bearing child, keeps those the whole intersection contains, and deduplicates equal configurations by first occurrence in child order. Tests: the issue's reproduction as a tree root, child-order independence, multi-child seed collection, the dedup policy, and a hypothesis law that members(s) equals the membership filter of all leaf configurations whenever is_finite(s). Fixes #55. Refs #17, #42.
11 tasks
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.
Why
#55:
members(AllOf)delegated toseeds(), which selected the first child with any explicit seed. A child can carry seeds without being finite, so an intersection whose first seed-bearing child was a mixed union enumerated nothing even though a later child was finite. Reproduced on main: the issue's example is finite, contains[1, 0], and returned emptymembersandseeds.What
membershas its own recursion again. A union enumerates all children when every child is finite. An intersection enumerates a child that is itself finite (the first such) and keeps the members every other child contains; the configurations returned do not depend on child order, only their provenance does.seeds(AllOf)returns the exhaustivememberswhen the intersection is finite. Otherwise it collects seeds from every seed-bearing child, keeps those the whole intersection contains, and deduplicates equal configurations by first occurrence in child order. Documented as the policy.Fixes #55. Refs #17, #42.
Test plan
Six new tests in test_seeds.py:
the issue's reproduction enumerates
[1, 0]and it becomes a tree root;membersconfigurations are identical under three child orderings of an intersection;a non-finite intersection whose seed-bearing children have disjoint finite parts yields no seeds, and one with a shared configuration yields it once with the earliest provenance (first child bears no seeds);
the first-occurrence dedup policy;
hypothesis over random nested
AnyOf/AllOftrees of finite sets, predicates, and samplers: wheneveris_finite(s), the set ofmembers(s)configurations equals the membership filter of all leaf configurations,seeds(s)agrees, and otherwisemembersis empty and every seed is a member.uv run pytest tests/: 261 passed, 1 skipped; ruff clean.🤖 Generated with Claude Code