Files
glpi-neural-brain/internal/graph/semantic_cluster_test.go
2026-08-07 21:54:37 +02:00

55 lines
2.1 KiB
Go

package graph
import (
"fmt"
"testing"
"github.com/local/glpi-neural-brain/internal/model"
)
func newSemanticTestStore(t *testing.T, count int) *Store {
t.Helper()
s := &Store{nodes: map[string]model.Node{}, edges: map[string]model.Edge{}, vectors: map[string][]float32{}, dirtyNodes: map[string]uint64{}, dirtyEdges: map[string]uint64{}, dirtyVectors: map[string]uint64{}, deletedNodes: map[string]uint64{}, deletedEdges: map[string]uint64{}, deletedVectors: map[string]uint64{}}
for i := 0; i < count; i++ {
id := fmt.Sprintf("n-%03d", i)
v := make([]float64, 16)
v[i%16] = 1
v[(i*7+3)%16] += float64((i%5)+1) * .03
s.UpsertNode(model.Node{ID: id, Kind: "knowledge", Status: "production", Label: id})
s.SetVector(id, v)
}
return s
}
func TestClusteredPairSearchUsesFarFewerExactCosines(t *testing.T) {
s := newSemanticTestStore(t, 240)
s.SetVector("n-000", []float64{1, .02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
s.SetVector("n-001", []float64{1, .021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
_, _, sim, ok, stats := s.NextPairClusteredScopedDepth(.95, 12, NodeFilter{}, 2, 24, 2, 24)
if !ok || sim < .95 {
t.Fatalf("expected clustered candidate, ok=%v sim=%.4f stats=%+v", ok, sim, stats)
}
if stats.ExactComparisons <= 0 || stats.ExactComparisons > 12*24 {
t.Fatalf("unexpected exact work: %+v", stats)
}
if stats.CoarseComparisons < 2000 {
t.Fatalf("expected cheap coarse scan over corpus, got %+v", stats)
}
if stats.ExactComparisons*5 >= stats.CoarseComparisons {
t.Fatalf("cluster mode did not reduce expensive comparisons enough: %+v", stats)
}
}
func TestClusteredSimilarFindsNearDuplicate(t *testing.T) {
s := newSemanticTestStore(t, 160)
target := []float64{.91, .31, .12, .04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
s.SetVector("n-055", target)
hits, stats := s.SimilarClusteredFiltered(target, 8, 48, NodeFilter{}, 2, 24, 2)
if len(hits) == 0 || hits[0].NodeID != "n-055" || hits[0].Score < .999 {
t.Fatalf("near duplicate not ranked first: hits=%+v stats=%+v", hits, stats)
}
if stats.ExactComparisons > 48 {
t.Fatalf("too many exact comparisons: %+v", stats)
}
}