Skip to content

Enumerate finite intersections from a finite child; gather seeds from all children - #58

Merged
siddhss5 merged 1 commit into
mainfrom
fix/finite-intersection-members
Sep 17, 2026
Merged

siddhss5 merged 1 commit into
mainfrom
fix/finite-intersection-members

Conversation

@siddhss5

Copy link
Copy Markdown
Collaborator

Why

#55: members(AllOf) delegated to seeds(), 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 empty members and seeds.

What

  • members has 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 exhaustive members when 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.
  • Mixed finite/sampleable union behavior from Preserve explicit roots in mixed finite and sampleable unions #42 is unchanged.

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;

  • members configurations 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/AllOf trees of finite sets, predicates, and samplers: whenever is_finite(s), the set of members(s) configurations equals the membership filter of all leaf configurations, seeds(s) agrees, and otherwise members is empty and every seed is a member.

  • uv run pytest tests/: 261 passed, 1 skipped; ruff clean.

🤖 Generated with Claude Code

… 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.
@siddhss5
siddhss5 merged commit 2b8bb05 into main Sep 17, 2026
4 checks passed
@siddhss5
siddhss5 deleted the fix/finite-intersection-members branch September 17, 2026 13:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enumerate finite intersections from an exhaustive child

1 participant