code wiki / _hdl_build / nx_perma_mine.nx
nx_perma_mine.nx source
↩ module page · 89 lines · 3864 B
1// nx_perma_mine.nx -- LIB: GRIND the permaculture corpus into structured AFFORDABILITY facts (operator: "grind
2// this as part of our affordability improvement"). Two extractions over the license-clean perma_*.raw corpus:
3// 1. COMPANION PLANTING -- crop co-occurrence in the corpus = which crops to grow together for better yield
4// (more food per square foot = more affordability). Promoted to garden:companion:<a>:<b>.
5// 2. SOIL-IMPROVEMENT RANKING -- how often each cheap soil practice (compost, mulch, cover crop, ...) appears
6// = an evidence-ranked list of the cheapest ways to build fertility (free compost beats bought fertilizer).
7// FACTS-ONLY + LICENSE-GATED (reuses the recipe miner fm_* + the provenance gate). This GROWS the researcher
8// from a fetcher into a synthesizer (signal extraction), per the grow-the-researcher doctrine. license_tier: ORIGINAL
9import "nx_food_recipe_mine.nx"
10import "nx_garden.nx"
11import "nx_food_provenance.nx"
12import "nx_food_science.nx"
13import "nx_seg_store.nx"
14import "nx_syscalls.nx"
15
16// count boundary-anchored occurrences of a lowercased term in a lowercased corpus
17func pm_count_term(c: *u8, clen: i64, term: *u8, tl: i64) -> i64 {
18 if tl == 0 { return 0 }
19 var cnt: i64 = 0
20 var i: i64 = 0
21 while i + tl <= clen {
22 var bok: i64 = 1
23 if i > 0 { let pc: i64 = c[i - 1] as i64; if pc >= 97 { if pc <= 122 { bok = 0 } } }
24 var matched: i64 = 0
25 if bok == 1 {
26 var k: i64 = 0
27 var m: i64 = 1
28 while k < tl { if c[i + k] != term[k] { m = 0; k = tl } else { k = k + 1 } }
29 if m == 1 { matched = 1 }
30 }
31 if matched == 1 { cnt = cnt + 1; i = i + tl } else { i = i + 1 }
32 }
33 return cnt
34}
35
36// lowercase a term in place (small helper for caller-supplied literals)
37func pm_lower_term(t: *u8) -> i64 {
38 var i: i64 = 0
39 while t[i] != (0 as u8) { let c: i64 = t[i] as i64; if c >= 65 { if c <= 90 { t[i] = (c + 32) as u8 } } i = i + 1 }
40 return 0
41}
42
43// promote crop-co-occurrence into garden:companion:<a>:<b> = count, for GROWABLE pairs only (additive, idempotent)
44func pm_promote_companions(prefix: *u8, world: *i64, cooc: *i64) -> i64 {
45 let n: i64 = world[0]
46 let ids: *i64 = world[1] as *i64
47 let w: *i64 = ss_begin()
48 var cnt: i64 = 0
49 var i: i64 = 0
50 while i < n {
51 if gd_growable(prefix, ids[i] as *u8) == 1 {
52 var j: i64 = i + 1
53 while j < n {
54 let cv: i64 = cooc[i * n + j]
55 if cv > 0 { if gd_growable(prefix, ids[j] as *u8) == 1 {
56 let key: *u8 = sys_mmap(96)
57 var o: i64 = 0
58 o = as_append(key, o, "garden:companion:" as *u8)
59 o = as_append(key, o, ids[i] as *u8)
60 key[o] = 58 as u8; o = o + 1
61 o = as_append(key, o, ids[j] as *u8)
62 key[o] = 0 as u8
63 let val: *u8 = sys_mmap(24)
64 let vl: i64 = fd_apnum(val, 0, cv)
65 if fd_streq_store(prefix, key, val, vl) == 0 { ss_add(w, 1, key, val, vl); cnt = cnt + 1 }
66 } }
67 j = j + 1
68 }
69 }
70 i = i + 1
71 }
72 if cnt > 0 { let seg: i64 = fd_seg_next(prefix); ss_commit(prefix, w, seg) }
73 return cnt
74}
75
76// companion co-occurrence count between two crop ids (after promotion)
77func pm_companion(prefix: *u8, a: *u8, b: *u8) -> i64 {
78 let key: *u8 = sys_mmap(96)
79 var o: i64 = 0
80 o = as_append(key, o, "garden:companion:" as *u8)
81 o = as_append(key, o, a)
82 key[o] = 58 as u8; o = o + 1
83 o = as_append(key, o, b)
84 key[o] = 0 as u8
85 let pq: *i64 = sys_mmap(16) as *i64
86 let lq: *i64 = sys_mmap(16) as *i64
87 if ss_get(prefix, key, pq, lq) != 1 { return 0 }
88 return fd_atoi(pq[0] as *u8, lq[0])
89}