Add match-count builtin: count matches without materializing results#166
Closed
Tsion-Teklay wants to merge 1 commit intotrueagi-io:mainfrom
Closed
Add match-count builtin: count matches without materializing results#166Tsion-Teklay wants to merge 1 commit intotrueagi-io:mainfrom
Tsion-Teklay wants to merge 1 commit intotrueagi-io:mainfrom
Conversation
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.
Summary
This PR adds a match-count builtin that efficiently counts the number of atoms matching a pattern without materializing the entire result set. It addresses a critical performance issue where counting matches using (length (collapse (match ...))) would cause stack overflow on large knowledge bases.
Problem
Counting how many atoms in a space match a pattern is currently done via (length (collapse (match ))), which builds a Prolog list of every match. On large in-RAM AtomSpaces this exhausts the stack long before the count is needed — the caller only wants a number, not the results themselves.
Solution
Implemented match-count using aggregate_all/3 which is failure-driven and keeps a single counter — no list is built. The new function:
Implementation
The function is added to src/spaces.pl and registered in src/metta.pl to enable MeTTa calls.
Testing
Added comprehensive tests in examples/match_count.metta covering:
Full pattern count: (match-count &self (parent $p $c)) => 5
Bound pattern count: (match-count &self (parent alice $c)) => 2
Zero matches: (match-count &self (parent zelda $c)) => 0
Test with:
sh run.sh ./examples/match_count.mettaExpect: three lines each ending in ✅
Files changed
src/spaces.pl — defines match-count/3 as a wrapper over aggregate_all(count, match(...), Count)
src/metta.pl — registers match-count in the function list
examples/match_count.metta — three test cases