code wiki / _hdl_build / nx_semantic_retrieval.nx
nx_semantic_retrieval.nx source
↩ module page · 71 lines · 3597 B
1// nx_semantic_retrieval.nx -- SPEC A built bits-up: match a query BEYOND exact terms via co-occurrence.
2// Terms that appear together across the corpus are related; so a document can be relevant to a query
3// even when it never contains the query word, as long as it contains terms that CO-OCCUR with it. This
4// is the rung where retrieval can exceed BM25 (which scores 0 when the exact term is absent).
5// Built on Layer-8 integer ALU ops only (the spec's primitives): COUNT (term presence), IMUL+IADD
6// (vector dot product), ISQRT (cosine magnitude) -- no floats, no learned embeddings.
7// Honest boundary: co-occurrence over a small corpus is a weak proxy for true semantics; learned
8// embeddings (the EMBED_TRAIN primitive the Researcher flagged) are the LLM rung, not faked here.
9// license_tier: ORIGINAL Pairs with nx_research_extract (re_has/re_count) + nx_bm25 (exact baseline).
10
11import "nx_research_extract.nx" // re_has / re_count
12import "nx_syscalls.nx"
13
14// L8 integer sqrt (digit-by-digit, no multiply in the loop) -- the cosine magnitude primitive, bits-up.
15func sr_isqrt(x: i64) -> i64 {
16 if x < 2 { return x }
17 var num: i64 = x; var r: i64 = 0; var b: i64 = 1
18 while b * 4 <= num { b = b * 4 }
19 while b > 0 {
20 if num >= r + b { num = num - r - b; r = (r / 2) + b } else { r = r / 2 }
21 b = b / 4
22 }
23 return r
24}
25
26func sr_doc(ptrs: *i64, k: i64) -> *u8 { return ptrs[k] as *u8 }
27
28// co-occurrence: number of docs containing BOTH terms a and b -- the semantic link strength.
29func sr_cooc(ptrs: *i64, lens: *i64, N: i64, a: *u8, b: *u8) -> i64 {
30 var c: i64 = 0; var i: i64 = 0
31 while i < N { if re_has(sr_doc(ptrs, i), lens[i], a) == 1 { if re_has(sr_doc(ptrs, i), lens[i], b) == 1 { c = c + 1 } } i = i + 1 }
32 return c
33}
34
35// the query's co-occurrence VECTOR over the vocabulary: qvec[t] = cooc(query_term, vocab[t]).
36func sr_build_qvec(ptrs: *i64, lens: *i64, N: i64, qterm: *u8, vocab: *i64, V: i64, qvec: *i64) -> i64 {
37 var t: i64 = 0
38 while t < V { qvec[t] = sr_cooc(ptrs, lens, N, qterm, vocab[t] as *u8); t = t + 1 }
39 return 0
40}
41
42// semantic score of doc k = dot(qvec, doc-presence-vector) = sum of qvec[t] for vocab terms present.
43func sr_score(ptrs: *i64, lens: *i64, k: i64, qvec: *i64, vocab: *i64, V: i64) -> i64 {
44 var s: i64 = 0; var t: i64 = 0
45 while t < V { if re_has(sr_doc(ptrs, k), lens[k], vocab[t] as *u8) == 1 { s = s + qvec[t] } t = t + 1 }
46 return s
47}
48
49// the exact-match baseline (what BM25/substring sees): occurrences of the literal query term.
50func sr_exact(ptrs: *i64, lens: *i64, k: i64, qterm: *u8) -> i64 { return re_count(sr_doc(ptrs, k), lens[k], qterm) }
51
52func sr_best(ptrs: *i64, lens: *i64, N: i64, qvec: *i64, vocab: *i64, V: i64) -> i64 {
53 var best: i64 = 0 - 1; var bestscore: i64 = 0; var i: i64 = 0
54 while i < N { let sc: i64 = sr_score(ptrs, lens, i, qvec, vocab, V); if sc > bestscore { bestscore = sc; best = i } i = i + 1 }
55 return best
56}
57
58// integer cosine similarity x1000 between the query vector and doc k's presence vector (uses ISQRT).
59func sr_cosine_milli(ptrs: *i64, lens: *i64, k: i64, qvec: *i64, vocab: *i64, V: i64) -> i64 {
60 var dot: i64 = 0; var qmag2: i64 = 0; var dmag2: i64 = 0; var t: i64 = 0
61 while t < V {
62 let dv: i64 = re_has(sr_doc(ptrs, k), lens[k], vocab[t] as *u8) // 0/1
63 dot = dot + qvec[t] * dv
64 qmag2 = qmag2 + qvec[t] * qvec[t]
65 dmag2 = dmag2 + dv * dv
66 t = t + 1
67 }
68 let denom: i64 = sr_isqrt(qmag2) * sr_isqrt(dmag2)
69 if denom <= 0 { return 0 }
70 return (dot * 1000) / denom
71}