Fix setof/3 duplicate grouping for variant witnesses (issue #3151) #3176
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.
Summary
Fixes #3151 -
setof/3was creating duplicate groups for variant witnessesProblem
When using
setof/3with witness variables, variants with the same structure were being grouped separately instead of together.Test case:
Expected:
3,2(3 clauses, 2 unique variant groups)Actual (before fix):
3,3(incorrectly counted 3 groups)Clauses 1 and 3 have the same variant structure
[X,X,Y]and should be grouped together, but were being counted as separate groups.Root Cause
The
group_by_variant/4predicate insrc/lib/builtins.plonly grouped consecutive variants after sorting with$keysort_with_constant_var_ordering/2.With
VarComparison::Indistinct, all variable terms compare as equal and the sort is stable (maintains original order). This means variants with the same structure like[X,X,Y]from clauses 1 and 3 can be separated by different structures like[X,Y,X]from clause 2 in the sorted list.The original implementation only checked the next element in the list, so it would miss variants that appeared later.
Solution
Modified
group_by_variant/4(src/lib/builtins.pl:993-1001) to recursively scan the ENTIRE list for ALL variants, not just consecutive elements.Tail-recursive implementation:
The key insight: in the else branch, we unify
Pairs0with[V2-S2 | RestPairs]before the recursive call, making it tail-recursive.Test Plan
3,2Commits
7de9d0d4Add failing test for setof/3 duplicate grouping bug5a204fe7Fix setof/3 duplicate grouping bug (issue setof/3 problem #3151)86ba395cMake group_by_variant/4 tail-recursive