isomorphism_test.mx raw
1 package iskra
2
3 import (
4 "fmt"
5 "os"
6 "path/filepath"
7 "testing"
8 )
9
10 func TestCorpusIsomorphism(t *testing.T) {
11 corpora := []string{
12 "/tmp/iskra-corpus/utf8",
13 "/tmp/iskra-corpus/bytes",
14 }
15
16 totalFuncs := 0
17 selfIso := 0
18 totalPairs := 0
19 isoCollisions := 0
20 nonIsoCorrect := 0
21
22 type sigEntry struct {
23 name string
24 sig *BindingSignature
25 }
26
27 var allSigs []sigEntry
28
29 for _, corpusDir := range corpora {
30 segs, err := LoadManifest(filepath.Join(corpusDir, "manifest.csv"))
31 if err != nil {
32 t.Fatalf("LoadManifest %s: %s", corpusDir, err.Error())
33 }
34
35 corpusName := filepath.Base(corpusDir)
36
37 for _, seg := range segs {
38 if seg.Kind != "func" && seg.Kind != "method" {
39 continue
40 }
41 if seg.ASTDump == "" {
42 continue
43 }
44
45 astPath := filepath.Join(corpusDir, "ast", seg.ASTDump)
46 data, err := os.ReadFile(astPath)
47 if err != nil {
48 continue
49 }
50
51 st := ExtractSymbols(string(data))
52 bg := ExtractBindings(st)
53 sig := bg.Signature()
54 totalFuncs++
55
56 // Self-isomorphism: every signature must match itself.
57 if sig.IsIsomorphic(sig) {
58 selfIso++
59 } else {
60 t.Errorf("%s/%s: NOT self-isomorphic", corpusName, seg.Name)
61 }
62
63 allSigs = append(allSigs, sigEntry{
64 name: corpusName | "/" | seg.Name,
65 sig: sig,
66 })
67 }
68 }
69
70 // Selectivity: compare all pairs. Functions with different structure
71 // should NOT be isomorphic. Track collision rate.
72 for i := 0; i < len(allSigs); i++ {
73 for j := i + 1; j < len(allSigs); j++ {
74 totalPairs++
75 if allSigs[i].sig.IsIsomorphic(allSigs[j].sig) {
76 isoCollisions++
77 fmt.Printf(" ISO MATCH: %s ≡ %s\n", allSigs[i].name, allSigs[j].name)
78 } else {
79 nonIsoCorrect++
80 }
81 }
82 }
83
84 fmt.Printf("\n=== ISOMORPHISM AUDIT ===\n")
85 fmt.Printf("Functions analyzed: %d\n", totalFuncs)
86 fmt.Printf("Self-isomorphic: %d/%d (should be 100%%)\n", selfIso, totalFuncs)
87 fmt.Printf("Cross pairs checked: %d\n", totalPairs)
88 fmt.Printf("Isomorphic collisions: %d (structurally identical different functions)\n", isoCollisions)
89 fmt.Printf("Correctly distinct: %d\n", nonIsoCorrect)
90 if totalPairs > 0 {
91 selectivity := (nonIsoCorrect * 100) / totalPairs
92 fmt.Printf("Selectivity: %d%%\n", selectivity)
93 }
94
95 if selfIso != totalFuncs {
96 t.Errorf("self-isomorphism failed: %d/%d", selfIso, totalFuncs)
97 }
98 }
99
100 func TestCorpusBindingStats(t *testing.T) {
101 corpora := []string{
102 "/tmp/iskra-corpus/utf8",
103 "/tmp/iskra-corpus/bytes",
104 }
105
106 for _, corpusDir := range corpora {
107 segs, err := LoadManifest(filepath.Join(corpusDir, "manifest.csv"))
108 if err != nil {
109 t.Fatalf("LoadManifest %s: %s", corpusDir, err.Error())
110 }
111
112 corpusName := filepath.Base(corpusDir)
113 funcCount := 0
114 totalLocals := 0
115 totalExternals := 0
116 maxLocals := 0
117 maxExternals := 0
118 maxLocalName := ""
119 maxExternalName := ""
120
121 for _, seg := range segs {
122 if seg.Kind != "func" && seg.Kind != "method" {
123 continue
124 }
125 if seg.ASTDump == "" {
126 continue
127 }
128
129 astPath := filepath.Join(corpusDir, "ast", seg.ASTDump)
130 data, err := os.ReadFile(astPath)
131 if err != nil {
132 continue
133 }
134
135 st := ExtractSymbols(string(data))
136 bg := ExtractBindings(st)
137 funcCount++
138 totalLocals += len(bg.Bindings)
139 totalExternals += len(bg.Externals)
140 if len(bg.Bindings) > maxLocals {
141 maxLocals = len(bg.Bindings)
142 maxLocalName = seg.Name
143 }
144 if len(bg.Externals) > maxExternals {
145 maxExternals = len(bg.Externals)
146 maxExternalName = seg.Name
147 }
148 }
149
150 fmt.Printf("\n=== %s BINDING STATS ===\n", corpusName)
151 fmt.Printf("Functions: %d\n", funcCount)
152 fmt.Printf("Total locals: %d (avg %.1f/func)\n", totalLocals, float64(totalLocals)/float64(funcCount))
153 fmt.Printf("Total externals: %d (avg %.1f/func)\n", totalExternals, float64(totalExternals)/float64(funcCount))
154 fmt.Printf("Max locals: %d (%s)\n", maxLocals, maxLocalName)
155 fmt.Printf("Max externals: %d (%s)\n", maxExternals, maxExternalName)
156 }
157 }
158