walk_test.mx raw
1 package iskra
2
3 import "testing"
4
5 func TestBigramWeightBasic(t *testing.T) {
6 tr := NewInMemoryTree(100)
7 IngestBigram(tr, 0x01, 0, "the", "cat")
8 IngestBigram(tr, 0x01, 0, "the", "cat")
9 IngestBigram(tr, 0x01, 0, "the", "dog")
10
11 w := BigramWeight(tr, 0x01, 0, "the", "cat")
12 if w != 2 {
13 t.Fatal("expected weight 2, got " | fmt_int(int32(w)))
14 }
15 w = BigramWeight(tr, 0x01, 0, "the", "dog")
16 if w != 1 {
17 t.Fatal("expected weight 1, got " | fmt_int(int32(w)))
18 }
19 w = BigramWeight(tr, 0x01, 0, "the", "bird")
20 if w != 0 {
21 t.Fatal("expected weight 0, got " | fmt_int(int32(w)))
22 }
23 }
24
25 func TestBigramWeightRelaxedFallback(t *testing.T) {
26 tr := NewInMemoryTree(100)
27 coord := PackCoord(SemanticHumanSubj, 0, 0, 0, 0, 0, 0)
28 IngestBigram(tr, 0x01, 0, "sat", "on") // at coord 0 (base form)
29
30 // Lookup at a specific coord should fall through to coord 0
31 w, matched := BigramWeightRelaxed(tr, 0x01, coord, "sat", "on")
32 if w == 0 {
33 t.Fatal("expected non-zero weight from relaxation fallback")
34 }
35 if matched != 0 {
36 t.Fatal("expected matched coord to be 0 (base form)")
37 }
38 }
39
40 func TestIngestText(t *testing.T) {
41 tr := NewInMemoryTree(100)
42 tokens := []string{"the", "cat", "sat", "on", "the", "mat"}
43 IngestText(tr, 0x01, 0, tokens)
44
45 // "the" appears twice: "the|cat" and "the|mat"
46 w := BigramWeight(tr, 0x01, 0, "the", "cat")
47 if w != 1 {
48 t.Fatal("expected the|cat weight 1")
49 }
50 w = BigramWeight(tr, 0x01, 0, "the", "mat")
51 if w != 1 {
52 t.Fatal("expected the|mat weight 1")
53 }
54 w = BigramWeight(tr, 0x01, 0, "cat", "sat")
55 if w != 1 {
56 t.Fatal("expected cat|sat weight 1")
57 }
58 }
59
60 func TestWalkStepBasic(t *testing.T) {
61 tr := NewInMemoryTree(100)
62 IngestText(tr, 0x01, 0, []string{"the", "cat", "sat", "on", "the", "mat"})
63 IngestText(tr, 0x01, 0, []string{"the", "dog", "ran", "to", "the", "park"})
64
65 state := WalkState{
66 Domain: 0x01,
67 Coord: 0,
68 Word: "the",
69 Score: 0,
70 Depth: 0,
71 }
72 candidates := WalkStep(tr, state, 10)
73 if len(candidates) == 0 {
74 t.Fatal("expected candidates after 'the'")
75 }
76 // "the" should lead to cat, dog, mat, park (all observed continuations)
77 found := false
78 for _, c := range candidates {
79 if c.State.Word == "cat" || c.State.Word == "dog" ||
80 c.State.Word == "mat" || c.State.Word == "park" {
81 found = true
82 }
83 }
84 if !found {
85 t.Fatal("expected known continuations in candidates")
86 }
87 }
88
89 func TestBeamRun(t *testing.T) {
90 tr := NewInMemoryTree(200)
91 // Ingest enough to create a multi-step walk
92 for i := 0; i < 5; i++ {
93 IngestText(tr, 0x01, 0, []string{"the", "cat", "sat", "on", "the", "mat"})
94 }
95 for i := 0; i < 3; i++ {
96 IngestText(tr, 0x01, 0, []string{"the", "dog", "ran"})
97 }
98
99 initial := WalkState{
100 Domain: 0x01,
101 Coord: 0,
102 Word: "the",
103 Score: 0,
104 }
105 beam := NewBeam(initial, 3, WalkTranslate)
106 result := beam.Run(tr, 3)
107 if result.Depth == 0 {
108 t.Fatal("beam should have advanced at least one step")
109 }
110 if result.Score == 0 {
111 t.Fatal("beam result should have non-zero score")
112 }
113 }
114