code wiki / (root) / nx_scene_index_test.nx

nx_scene_index_test.nx source

↩ module page · 116 lines · 4352 B

1// nx_scene_index_test.nx -- end-to-end smoke for the full ingestion stack. 2// 3// Verifies the FULL Tier 0 -> Tier 4 chain end-to-end: 4// 1. ingest text (nx_text_ingest) 5// 2. extract terms (nx_term_extract -> nx_term_registry) 6// 3. co-occurrence (nx_term_cooccur) 7// 4. anchor discovery (nx_arc_anchor) 8// 5. scene-candidate build (nx_scene_index) 9// 10// Then queries the index for an OUTFIT_LOCATION candidate and 11// verifies the companion can recover the source byte span. 12// 13// Exit code: 14// 0 all assertions pass 15// N assertion N failed 16 17import "syscalls.nx" 18import "nx_media_pool.nx" 19import "nx_storybeat.nx" 20import "nx_storydb.nx" 21import "nx_text_ingest.nx" 22import "nx_term_registry.nx" 23import "nx_term_extract.nx" 24import "nx_term_cooccur.nx" 25import "nx_arc_anchor.nx" 26import "nx_scene_index.nx" 27 28func main() -> i64 { 29 30 let buf: *u8 = sys_mmap(2048) 31 var k: i64 = 0 32 while k < 2048 { buf[k] = 0; k = k + 1 } 33 let story: *u8 = "Sarah walked into the kitchen wearing an apron.\n\nLater she stood in the kitchen wearing an apron.\n\nShe 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" 34 var si: i64 = 0 35 while story[si] != 0 { 36 buf[si] = story[si] 37 si = si + 1 38 } 39 let slen: i64 = si 40 41 let db: *StoryDb = nx_storydb_alloc() 42 let mid: i64 = nx_media_pool_add(db.media_pool, NX_MEDIA_TYPE_TEXT, 43 NX_MEDIA_SRC_USER_PASTE, 44 buf, slen, 45 0 as *u8, 0, 46 0 as *u8, 0, 47 1700000000) 48 if mid < 0 { return 10 } 49 if nx_text_ingest(db, mid) != NX_TEXT_INGEST_OK { return 11 } 50 51 let reg: *TermRegistry = nx_term_registry_alloc() 52 if nx_term_extract_all(db, reg) != NX_EXTR_OK { return 12 } 53 54 let co: *Cooccur = nx_cooccur_alloc() 55 let n_pairs: i64 = nx_cooccur_observe_db(co, db) 56 if n_pairs < 1 { return 13 } 57 58 // Anchor discovery. 59 let scratch_buf: *u8 = sys_mmap(32 * NX_COOCCUR_PAIR_BYTES) 60 let scratch: *CooccurPair = scratch_buf as *CooccurPair 61 let anchor_buf: *u8 = sys_mmap(16 * NX_ARC_ANCHOR_BYTES) 62 let anchors: *ArcAnchor = anchor_buf as *ArcAnchor 63 let n_anch: i64 = nx_arc_anchor_discover(co, reg, scratch, 32, 64 anchors, 16) 65 if n_anch < 1 { return 14 } 66 67 // Scene-index build. 68 let idx: *SceneIndex = nx_scene_index_alloc() 69 let n_built: i64 = nx_scene_index_build(idx, db, anchors, n_anch) 70 if n_built < 1 { return 20 } 71 if idx.n_candidates < 1 { return 21 } 72 73 // Query: first OUTFIT_LOCATION candidate. 74 let cid: i64 = nx_scene_index_first_of_kind(idx, 75 NX_ANCHOR_OUTFIT_LOCATION) 76 if cid < 0 { return 22 } 77 let c: *SceneCandidate = nx_scene_candidate_at(idx, cid) 78 if c.anchor_kind != NX_ANCHOR_OUTFIT_LOCATION { return 23 } 79 if c.best_beat_id < 0 { return 24 } 80 if c.best_beat_id >= db.n_beats { return 25 } 81 if c.source_start < 0 { return 26 } 82 if c.source_end <= c.source_start { return 27 } 83 if c.sighting_count <= 0 { return 28 } 84 85 // Verify source-span query works. 86 var media: i64 = -1 87 var start: i64 = -1 88 var end: i64 = -1 89 if nx_scene_index_source_span(idx, cid, &media, &start, &end) != 0 { 90 return 30 91 } 92 if media != mid { return 31 } 93 if start != c.source_start { return 32 } 94 if end != c.source_end { return 33 } 95 96 // Verify the source-bytes can be looked up via MediaPool. 97 var bytes: *u8 = 0 as *u8 98 var n: i64 = 0 99 if nx_media_pool_get(db.media_pool, media, &bytes, &n) != 0 { return 40 } 100 if n <= 0 { return 41 } 101 if start >= n { return 42 } 102 if end > n { return 43 } 103 // First byte of the span must be non-zero (the source paragraph 104 // is non-empty ASCII). 105 let first_byte: i64 = bytes[start] 106 if first_byte == 0 { return 44 } 107 108 // Verify user-pin promotes stage. 109 let pin_rc: i64 = nx_scene_index_pin(idx, cid) 110 if pin_rc != 0 { return 50 } 111 let c_after: *SceneCandidate = nx_scene_candidate_at(idx, cid) 112 if (c_after.flags & NX_SCENE_FLAG_USER_PINNED) == 0 { return 51 } 113 if c_after.stage != 3 { return 52 } 114 115 return 0 116}