code wiki / (root) / nx_arc_anchor_test.nx

nx_arc_anchor_test.nx source

↩ module page · 94 lines · 3533 B

1// nx_arc_anchor_test.nx -- smoke for co-occurrence + arc anchor discovery. 2// 3// Ingests a small corpus with TWO recurring (outfit, location) 4// motifs and verifies the anchor discoverer surfaces them both 5// as OUTFIT_LOCATION anchors WITHOUT any pre-seeded scene list. 6// 7// Exit code: 8// 0 all assertions pass 9// N assertion N failed 10 11import "syscalls.nx" 12import "nx_media_pool.nx" 13import "nx_storybeat.nx" 14import "nx_storydb.nx" 15import "nx_text_ingest.nx" 16import "nx_term_registry.nx" 17import "nx_term_extract.nx" 18import "nx_term_cooccur.nx" 19import "nx_arc_anchor.nx" 20 21func main() -> i64 { 22 23 // Corpus: each line repeats a co-occurrence so counts > 1. 24 let buf: *u8 = sys_mmap(2048) 25 var k: i64 = 0 26 while k < 2048 { buf[k] = 0; k = k + 1 } 27 let story: *u8 = "Sarah walked into the kitchen wearing an apron.\n\nLater she stood in the kitchen wearing an apron.\n\nThe next morning she slipped into the bedroom wearing a robe.\n\nShe was in the bedroom wearing a robe again.\n\nShe stepped into the kitchen wearing an apron.\n" 28 var si: i64 = 0 29 while story[si] != 0 { 30 buf[si] = story[si] 31 si = si + 1 32 } 33 let slen: i64 = si 34 35 let db: *StoryDb = nx_storydb_alloc() 36 let mid: i64 = nx_media_pool_add(db.media_pool, NX_MEDIA_TYPE_TEXT, 37 NX_MEDIA_SRC_USER_PASTE, 38 buf, slen, 39 0 as *u8, 0, 40 0 as *u8, 0, 41 1700000000) 42 if mid < 0 { return 10 } 43 if nx_text_ingest(db, mid) != NX_TEXT_INGEST_OK { return 11 } 44 if db.n_beats < 3 { return 12 } 45 46 let reg: *TermRegistry = nx_term_registry_alloc() 47 if nx_term_extract_all(db, reg) != NX_EXTR_OK { return 13 } 48 49 // Co-occurrence walk. 50 let co: *Cooccur = nx_cooccur_alloc() 51 let n_pairs: i64 = nx_cooccur_observe_db(co, db) 52 if n_pairs < 1 { return 20 } 53 54 // Top-K query. 55 let scratch_buf: *u8 = sys_mmap(32 * NX_COOCCUR_PAIR_BYTES) 56 let scratch: *CooccurPair = scratch_buf as *CooccurPair 57 let n_top: i64 = nx_cooccur_top_k(co, scratch, 32) 58 if n_top < 1 { return 21 } 59 60 // Verify the top pair has count >= 2 (kitchen+apron seen >= 3 61 // times, but only beats with BOTH outfit_id and location_id 62 // populated count -- which depends on extractor success). 63 let top0: *CooccurPair = scratch_buf as *CooccurPair 64 if top0.count < 1 { return 22 } 65 66 // Anchor discovery. 67 let anchor_buf: *u8 = sys_mmap(16 * NX_ARC_ANCHOR_BYTES) 68 let anchors: *ArcAnchor = anchor_buf as *ArcAnchor 69 let n_anch: i64 = nx_arc_anchor_discover(co, reg, scratch, 32, 70 anchors, 16) 71 if n_anch < 1 { return 30 } 72 73 // Verify at least one anchor classifies as OUTFIT_LOCATION. 74 var n_outfit_loc: i64 = 0 75 var i: i64 = 0 76 while i < n_anch { 77 let a: *ArcAnchor = 78 (((anchor_buf as i64) + i * NX_ARC_ANCHOR_BYTES) as *ArcAnchor) 79 if a.anchor_kind == NX_ANCHOR_OUTFIT_LOCATION { 80 n_outfit_loc = n_outfit_loc + 1 81 } 82 i = i + 1 83 } 84 if n_outfit_loc < 1 { return 31 } 85 86 // Verify the strongest OUTFIT_LOCATION anchor reached PROMOTED 87 // stage (count >= 3 per NX_ARC_ANCHOR_PROMOTE_N) OR sits at 88 // SUPERVISED with non-zero count (allow either; smoke corpus 89 // may not exceed threshold). 90 let a0: *ArcAnchor = anchor_buf as *ArcAnchor 91 if a0.cooccur_count <= 0 { return 32 } 92 93 return 0 94}