OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-atomspace commits / 9ecfc92

Use Trigger and test PureLink function
9ecfc92415e87f83b56a1c2c76edc8419c560e47
by Linas Vepštas <linasvepstas@gmail.com> · 2026-01-22T03:41:09.000Z

Changed files (1) +113 -8

tests/atoms/flow/count-pipeline-test.scm +113 -8
……@@ -6,6 +6,7 @@
66;
77(use-modules (opencog))
88(use-modules (opencog test-runner))
9(use-modules (srfi srfi-1)) ; for fold
910
1011(opencog-test-runner)
1112(define tname "count-pipeline-test")
……@@ -44,7 +45,7 @@
4445
4546; Run the counting pipeline for the first time.
4647; At this point, relatively few atoms exist in the AtomSpace.
47(cog-execute! (Name "count-types"))
48(Trigger (Name "count-types"))
4849
4950; ------------------------------------------------------------
5051; Pipeline Stage 4: De-duplicate types
……@@ -115,7 +116,7 @@
115116; Some TypeNodes created after count-types ran won't have counts.
116117
117118(reset-counters)
118(define first-result (cog-execute! guarded-counter))
119(define first-result (Trigger guarded-counter))
119120
120121; The result should be a LinkValue containing TypeNodes
121122(test-assert "first-result-is-link-value"
……@@ -139,10 +140,10 @@
139140; TEST 3: Run count-types again - this will add to existing counts
140141; and count new types that were created (like AndLink from the guard)
141142
142(cog-execute! (Name "count-types"))
143(Trigger (Name "count-types"))
143144
144145(reset-counters)
145(cog-execute! guarded-counter)
146(Trigger guarded-counter)
146147
147148(format #t "Second run: ~A types, total count ~A\n"
148149 *type-count* *total-count*)
……@@ -164,10 +165,10 @@
164165; ------------------------------------------------------------
165166; TEST 5: Run count-types a third time and verify continued accumulation
166167
167(cog-execute! (Name "count-types"))
168(Trigger (Name "count-types"))
168169
169170(reset-counters)
170(cog-execute! guarded-counter)
171(Trigger guarded-counter)
171172
172173(format #t "Third run: ~A types, total count ~A\n"
173174 *type-count* *total-count*)
……@@ -205,7 +206,7 @@
205206 (Number 0 0 1)))
206207 (Name "unique-types")))
207208
208(cog-execute! (Name "grand-total"))
209(Trigger (Name "grand-total"))
209210
210211(define tot-types (cog-value-ref (Any "totals") (Predicate "tot-types") 2))
211212(test-assert "tot-types" (= 27 tot-types))
……@@ -245,7 +246,7 @@
245246;;; what lies down that path. I have no desire to create a Sinclair
246247;;; Z80 in Minecraft. We're not emulating to emulate badly and
247248;;; inefficiently. ... at least not yet ... :-/
248;;; (cog-execute! (Name "deref grand-total"))
249;;; (Trigger (Name "deref grand-total"))
249250;;;
250251;;; (define tot-types (cog-value-ref (Any "deref totals") (Predicate "tot-types") 2))
251252;;; (test-assert "deref tot-types" (= 27 tot-types))
……@@ -253,6 +254,110 @@
253254;;; (define tot-counts (cog-value-ref (Any "deref totals") (Predicate "tot-counts") 2))
254255;;; (test-assert "deref tot-counts" (= 182 tot-counts))
255256
257; ------------------------------------------------------------
258; TEST 8: Verify PureExec prevents double-counting
259;
260; This tests the full type-counts pipeline from atomspace-viz.
261; The key feature is that it uses PureExec to run the counting in
262; a fresh (scratch) AtomSpace, which prevents double-counting.
263; Running the pipeline multiple times should produce identical results.
264
265; Define the comparison predicate for sorting types by count.
266(DefineLink
267 (DefinedPredicate "viz-count-order")
268 (Lambda
269 (VariableList (Variable "left") (Variable "right"))
270 (Not
271 (LessThan
272 (ElementOf (Number 2)
273 (ValueOf (Variable "left") (Predicate "vcnt")))
274 (ElementOf (Number 2)
275 (ValueOf (Variable "right") (Predicate "vcnt")))))))
276
277; The type-counting pipeline that uses PureExec to prevent double-counting.
278; This is a copy of the pipeline from atomspace-viz/analytics/count-types.scm
279(PipeLink
280 (Name "viz-type-counts")
281 (PureExec
282 (Filter
283 (Rule
284 (TypedVariable (Variable "$typ") (Type 'Type))
285 ; Guard: only accept types that have a count attached
286 (And
287 (Present (Variable "$typ"))
288 (Equal
289 (Type 'FloatValue)
290 (TypeOf (ValueOf (Variable "$typ") (Predicate "vcnt")))))
291 ; Output: table row with type and count
292 (LinkSignature (Type 'LinkValue)
293 (Variable "$typ")
294 (ValueOf (Variable "$typ") (Predicate "vcnt"))))
295 ; Input: sorted unique types
296 (LinkSignature
297 (TypeNode 'SortedValue)
298 (DefinedPredicate "viz-count-order")
299 ; Input: unique types (deduplicated)
300 (CollectionOf (TypeNode 'UnisetValue)
301 ; Input: types extracted from atoms, with counts attached
302 (Filter
303 (Rule
304 (TypedVariable (Variable "$typ") (Type 'Type))
305 (Variable "$typ")
306 ; Increment the count on this TypeNode, return TypeNode
307 (IncrementValueOn (Variable "$typ") (Predicate "vcnt") (Number 0 0 1)))
308 ; Input: types of all atoms
309 (Filter
310 (Rule
311 (TypedVariable (Variable "$atom") (Type 'Atom))
312 (Variable "$atom")
313 (TypeOf (DontExec (Variable "$atom"))))
314 ; Input: all atoms in the base AtomSpace
315 (PureExec
316 (AtomSpaceOf (Link))
317 (Meet
318 (Variable "$atom")
319 (Variable "$atom"))))))))))
320
321; Helper to sum all counts in the result
322(define (sum-counts result)
323 (fold (lambda (row acc)
324 (+ acc (inexact->exact (cog-value-ref (cog-value-ref row 1) 2))))
325 0
326 (cog-value->list result)))
327
328; Helper to count rows in result
329(define (count-rows result)
330 (length (cog-value->list result)))
331
332; Run the pipeline three times and collect results
333(define viz-result-1 (Trigger (Name "viz-type-counts")))
334(define viz-rows-1 (count-rows viz-result-1))
335(define viz-sum-1 (sum-counts viz-result-1))
336
337(format #t "PureExec run 1: ~A types, total ~A\n" viz-rows-1 viz-sum-1)
338
339(define viz-result-2 (Trigger (Name "viz-type-counts")))
340(define viz-rows-2 (count-rows viz-result-2))
341(define viz-sum-2 (sum-counts viz-result-2))
342
343(format #t "PureExec run 2: ~A types, total ~A\n" viz-rows-2 viz-sum-2)
344
345(define viz-result-3 (Trigger (Name "viz-type-counts")))
346(define viz-rows-3 (count-rows viz-result-3))
347(define viz-sum-3 (sum-counts viz-result-3))
348
349(format #t "PureExec run 3: ~A types, total ~A\n" viz-rows-3 viz-sum-3)
350
351; The key test: all three runs should produce identical counts
352; If double-counting occurs, the counts would increase each time
353(test-assert "pureexec-consistent-row-count-1-2" (= viz-rows-1 viz-rows-2))
354(test-assert "pureexec-consistent-row-count-2-3" (= viz-rows-2 viz-rows-3))
355(test-assert "pureexec-consistent-total-1-2" (= viz-sum-1 viz-sum-2))
356(test-assert "pureexec-consistent-total-2-3" (= viz-sum-2 viz-sum-3))
357
358(format #t "PureExec consistency verified: ~A types, ~A total (all 3 runs identical)\n"
359 viz-rows-1 viz-sum-1)
360
256361; ------------------------------------------------------------
257362(test-end tname)
258363(opencog-test-end)