code wiki / _hdl_build / nx_ecodesign.nx

nx_ecodesign.nx source

↩ module page · 206 lines · 12202 B

1// nx_ecodesign.nx -- LIB: the REGENERATIVE LANDSCAPE calculator (operator: "more than edibles -- medicinal + 2// wildlife in ALL our calculations; rainwater harvesting w/ 3D-printed concrete structures; climbing useful 3// plants (jasmine/grapes) on the concrete; share with wildlife while discouraging damage; optimal use of the 4// environment while improving it"). Every plant is valued on MULTIPLE axes (edible/medicinal/wildlife/climbing/ 5// water/deer-resistance), so the design optimizes total ecosystem value, not just food. Rainwater capture is 6// integer math (no float). Climbing multi-value plants go on the 3D-printed concrete cistern wall. "Share with 7// wildlife while discouraging damage" = high wildlife value AND high deer-resistance. Each plant CITEs a real 8// fetched research source. Plants live in the food store keyed eco:plant:<id>. 9// Schema: eco:plant:<id> -> name <t> edible(0/1) <t> medicinal(0-10) <t> wildlife(0-10) <t> climbing(0/1) <t> 10// water(1-5) <t> deer_resist(0-10) <t> nfix(0/1) <t> cite 11// license_tier: ORIGINAL 12import "nx_food_science.nx" 13import "nx_food_provenance.nx" 14import "nx_seg_store.nx" 15import "nx_syscalls.nx" 16 17func ec_money(dst: *u8, off: i64, cents: i64) -> i64 { 18 var o: i64 = off 19 dst[o] = 36 as u8; o = o + 1 20 o = fd_apnum(dst, o, cents / 100) 21 dst[o] = 46 as u8; o = o + 1 22 let r: i64 = cents % 100 23 dst[o] = (48 + (r / 10)) as u8; o = o + 1 24 dst[o] = (48 + (r % 10)) as u8; o = o + 1 25 return o 26} 27func ec_plant_key(id: *u8, out: *u8) -> i64 { 28 var o: i64 = 0 29 o = as_append(out, o, "eco:plant:" as *u8) 30 o = as_append(out, o, id) 31 out[o] = 0 as u8 32 return o 33} 34func ec_get(prefix: *u8, id: *u8, ptr: *i64, len: *i64) -> i64 { 35 let key: *u8 = sys_mmap(80) 36 ec_plant_key(id, key) 37 return ss_get(prefix, key, ptr, len) 38} 39func ec_field_int(prefix: *u8, id: *u8, f: i64) -> i64 { 40 let pq: *i64 = sys_mmap(16) as *i64 41 let lq: *i64 = sys_mmap(16) as *i64 42 if ec_get(prefix, id, pq, lq) != 1 { return 0 - 1 } 43 let buf: *u8 = sys_mmap(32) 44 let l: i64 = fd_field(pq[0] as *u8, lq[0], f, buf) 45 return fd_atoi(buf, l) 46} 47func ec_field_str(prefix: *u8, id: *u8, f: i64, out: *u8) -> i64 { 48 let pq: *i64 = sys_mmap(16) as *i64 49 let lq: *i64 = sys_mmap(16) as *i64 50 if ec_get(prefix, id, pq, lq) != 1 { out[0] = 0 as u8; return 0 } 51 return fd_field(pq[0] as *u8, lq[0], f, out) 52} 53func ec_edible(prefix: *u8, id: *u8) -> i64 { return ec_field_int(prefix, id, 1) } 54func ec_med(prefix: *u8, id: *u8) -> i64 { return ec_field_int(prefix, id, 2) } 55func ec_wild(prefix: *u8, id: *u8) -> i64 { return ec_field_int(prefix, id, 3) } 56func ec_climbing(prefix: *u8, id: *u8) -> i64 { return ec_field_int(prefix, id, 4) } 57func ec_deer(prefix: *u8, id: *u8) -> i64 { return ec_field_int(prefix, id, 6) } 58 59// TOTAL ECOSYSTEM VALUE -- the operator's "in all our calculations": food + medicine + wildlife together. 60func ec_value(prefix: *u8, id: *u8, wfood: i64, wmed: i64, wwild: i64) -> i64 { 61 let e: i64 = ec_edible(prefix, id) 62 let m: i64 = ec_med(prefix, id) 63 let wd: i64 = ec_wild(prefix, id) 64 var v: i64 = 0 65 if e > 0 { v = v + wfood } 66 v = v + wmed * m + wwild * wd 67 return v 68} 69// "share with wildlife while discouraging damage" = feeds wildlife (>=6) AND deer-resistant (>=6) 70func ec_share_safe(prefix: *u8, id: *u8) -> i64 { 71 if ec_wild(prefix, id) >= 6 { if ec_deer(prefix, id) >= 6 { return 1 } } 72 return 0 73} 74// rainwater capture (litres/year) = roof_area_m2 x rainfall_mm x runoff_pct/100 (1mm on 1m2 = 1 litre). Integer. 75func ec_capture(roof_m2: i64, rainfall_mm: i64, runoff_pct: i64) -> i64 { 76 return roof_m2 * rainfall_mm * runoff_pct / 100 77} 78 79// author the multi-value plant palette + ecosystem-value weights (idempotent). Cites landed perma_*.raw sources. 80func ec_seed(prefix: *u8) -> i64 { 81 let keys: *i64 = sys_mmap(8 * 24) as *i64 82 let vals: *i64 = sys_mmap(8 * 24) as *i64 83 var n: i64 = 0 84 keys[n] = "eco:weights" as *u8 as i64; vals[n] = "8\t2\t2" as *u8 as i64; n = n + 1 // wfood, wmed, wwild 85 keys[n] = "eco:plantids" as *u8 as i64 86 vals[n] = "grape\tjasmine\tlavender\techinacea\tyarrow\tmilkweed\tcomfrey\tclover\tgarlic\tbeebalm\thosta\telderberry" as *u8 as i64; n = n + 1 87 keys[n] = "eco:plant:grape" as *u8 as i64; vals[n] = "Grape\t1\t3\t7\t1\t3\t4\t0\tperma_a2_forest_gardening" as *u8 as i64; n = n + 1 88 keys[n] = "eco:plant:jasmine" as *u8 as i64; vals[n] = "Jasmine\t0\t6\t7\t1\t2\t6\t0\tperma_a2_forest_gardening" as *u8 as i64; n = n + 1 89 keys[n] = "eco:plant:lavender" as *u8 as i64; vals[n] = "Lavender\t0\t7\t9\t0\t1\t9\t0\tperma_a5_polyculture" as *u8 as i64; n = n + 1 90 keys[n] = "eco:plant:echinacea" as *u8 as i64; vals[n] = "Echinacea\t0\t9\t8\t0\t2\t7\t0\tperma_a5_polyculture" as *u8 as i64; n = n + 1 91 keys[n] = "eco:plant:yarrow" as *u8 as i64; vals[n] = "Yarrow\t0\t8\t8\t0\t1\t8\t0\tperma_a6_companion_planting" as *u8 as i64; n = n + 1 92 keys[n] = "eco:plant:milkweed" as *u8 as i64; vals[n] = "Milkweed\t0\t4\t10\t0\t2\t7\t0\tperma_a5_polyculture" as *u8 as i64; n = n + 1 93 keys[n] = "eco:plant:comfrey" as *u8 as i64; vals[n] = "Comfrey\t0\t8\t6\t0\t3\t6\t0\tperma_b6_humus" as *u8 as i64; n = n + 1 94 keys[n] = "eco:plant:clover" as *u8 as i64; vals[n] = "Clover\t0\t3\t7\t0\t3\t3\t1\tperma_b12_nitrogen_fixation" as *u8 as i64; n = n + 1 95 keys[n] = "eco:plant:garlic" as *u8 as i64; vals[n] = "Garlic\t1\t8\t3\t0\t2\t10\t0\tperma_a6_companion_planting" as *u8 as i64; n = n + 1 96 keys[n] = "eco:plant:beebalm" as *u8 as i64; vals[n] = "Bee Balm\t0\t6\t9\t0\t3\t7\t0\tperma_a5_polyculture" as *u8 as i64; n = n + 1 97 keys[n] = "eco:plant:hosta" as *u8 as i64; vals[n] = "Hosta\t0\t1\t5\t0\t4\t1\t0\tperma_a5_polyculture" as *u8 as i64; n = n + 1 98 keys[n] = "eco:plant:elderberry" as *u8 as i64; vals[n] = "Elderberry\t1\t9\t9\t0\t3\t6\t0\tperma_a2_forest_gardening" as *u8 as i64; n = n + 1 99 100 let w: *i64 = ss_begin() 101 var tw: i64 = 0 102 var i: i64 = 0 103 while i < n { 104 let k: *u8 = keys[i] as *u8 105 let v: *u8 = vals[i] as *u8 106 let vl: i64 = as_len(v) 107 if fd_streq_store(prefix, k, v, vl) == 0 { ss_add(w, 1, k, v, vl); tw = tw + 1 } 108 i = i + 1 109 } 110 if tw > 0 { let seg: i64 = fd_seg_next(prefix); ss_commit(prefix, w, seg) } 111 return tw 112} 113 114// walk eco:plantids; outids = ptrs to fresh id copies; returns count 115func ec_list(prefix: *u8, outids: *i64) -> i64 { 116 let pq: *i64 = sys_mmap(16) as *i64 117 let lq: *i64 = sys_mmap(16) as *i64 118 if ss_get(prefix, "eco:plantids" as *u8, pq, lq) != 1 { return 0 } 119 let buf: *u8 = pq[0] as *u8 120 let len: i64 = lq[0] 121 var c: i64 = 0 122 var i: i64 = 0 123 var ls: i64 = 0 124 while i <= len { 125 var sep: i64 = 0 126 if i == len { sep = 1 } else { if buf[i] == (9 as u8) { sep = 1 } } 127 if sep == 1 { 128 let tl: i64 = i - ls 129 if tl > 0 { 130 let tok: *u8 = sys_mmap(48) 131 var t: i64 = 0 132 while t < tl { tok[t] = buf[ls + t]; t = t + 1 } tok[tl] = 0 as u8 133 outids[c] = tok as i64; c = c + 1 134 } 135 ls = i + 1 136 } 137 i = i + 1 138 } 139 return c 140} 141 142// render the regenerative landscape design (NUL-terminated); returns length. 143func ec_render_design(prefix: *u8, roof_m2: i64, rainfall_mm: i64, out: *u8) -> i64 { 144 let pqw: *i64 = sys_mmap(16) as *i64; let lqw: *i64 = sys_mmap(16) as *i64 145 var wfood: i64 = 8; var wmed: i64 = 2; var wwild: i64 = 2 146 if ss_get(prefix, "eco:weights" as *u8, pqw, lqw) == 1 { 147 let f: *u8 = sys_mmap(16) 148 let l0: i64 = fd_field(pqw[0] as *u8, lqw[0], 0, f); wfood = fd_atoi(f, l0) 149 let l1: i64 = fd_field(pqw[0] as *u8, lqw[0], 1, f); wmed = fd_atoi(f, l1) 150 let l2: i64 = fd_field(pqw[0] as *u8, lqw[0], 2, f); wwild = fd_atoi(f, l2) 151 } 152 let cap: i64 = ec_capture(roof_m2, rainfall_mm, 80) 153 154 var o: i64 = 0 155 o = as_append(out, o, "<!doctype html><html lang='en'><head><meta charset='utf-8'><meta name='viewport' content='width=device-width,initial-scale=1'><title>Regenerative landscape</title><style>body{margin:0;font-family:system-ui,sans-serif;color:#1c2a1d;background:#eef4ea;line-height:1.55}header{background:#2e5b34;color:#fff;padding:26px 22px}header h1{margin:0;font-size:1.5rem}main{max-width:700px;margin:0 auto;padding:18px 18px 40px;display:grid;gap:14px}.tile{background:#fff;border-radius:12px;padding:16px 18px;box-shadow:0 1px 0 #d6e4cf}.tile h2{margin:0 0 8px;font-size:1.05rem;color:#2e5b34}.big{font-size:1.2rem;font-weight:700}table{border-collapse:collapse;width:100%;font-size:.92rem}th{text-align:left;background:#e6efe1;padding:6px 8px;color:#33503f}td{padding:6px 8px;border-top:1px solid #eef3ea}td.n{text-align:right;font-variant-numeric:tabular-nums}.muted{color:#5b6a52}</style></head><body><header><h1>Your regenerative landscape</h1></header><main>" as *u8) 156 157 // rainwater + 3D-printed concrete structure 158 o = as_append(out, o, "<div class='tile'><h2>Rainwater &rarr; 3D-printed concrete cistern</h2><div class='big'>" as *u8) 159 o = fd_apnum(out, o, cap); o = as_append(out, o, " litres / year</div><p class='muted'>captured from a " as *u8) 160 o = fd_apnum(out, o, roof_m2); o = as_append(out, o, " m&sup2; roof at " as *u8); o = fd_apnum(out, o, rainfall_mm) 161 o = as_append(out, o, " mm rainfall (80% runoff). Stored in a 3D-printed concrete cistern (&approx; " as *u8) 162 o = fd_apnum(out, o, cap / 1000); o = as_append(out, o, " m&sup3;) whose wall doubles as a climbing trellis.</p></div>" as *u8) 163 164 let ids: *i64 = sys_mmap(8 * 64) as *i64 165 let nids: i64 = ec_list(prefix, ids) 166 167 // climbers on the structure 168 o = as_append(out, o, "<div class='tile'><h2>On the concrete wall (climbing, useful)</h2><table><tr><th>Plant</th><th>Why</th><th>Value</th></tr>" as *u8) 169 var i: i64 = 0 170 while i < nids { 171 let id: *u8 = ids[i] as *u8 172 if ec_climbing(prefix, id) == 1 { 173 o = as_append(out, o, "<tr><td>" as *u8) 174 let nm: *u8 = sys_mmap(48); ec_field_str(prefix, id, 0, nm); o = as_append_escaped(out, o, nm, as_len(nm)) 175 o = as_append(out, o, "</td><td class='muted'>" as *u8) 176 if ec_edible(prefix, id) == 1 { o = as_append(out, o, "food " as *u8) } 177 if ec_med(prefix, id) >= 5 { o = as_append(out, o, "medicine " as *u8) } 178 if ec_wild(prefix, id) >= 6 { o = as_append(out, o, "wildlife" as *u8) } 179 o = as_append(out, o, "</td><td class='n'>" as *u8); o = fd_apnum(out, o, ec_value(prefix, id, wfood, wmed, wwild)) 180 o = as_append(out, o, "</td></tr>" as *u8) 181 } 182 i = i + 1 183 } 184 o = as_append(out, o, "</table></div>" as *u8) 185 186 // wildlife guild that resists damage 187 o = as_append(out, o, "<div class='tile'><h2>Shares with wildlife, resists damage</h2><table><tr><th>Plant</th><th>Wildlife</th><th>Deer-proof</th><th>Value</th></tr>" as *u8) 188 i = 0 189 while i < nids { 190 let id: *u8 = ids[i] as *u8 191 if ec_share_safe(prefix, id) == 1 { 192 o = as_append(out, o, "<tr><td>" as *u8) 193 let nm: *u8 = sys_mmap(48); ec_field_str(prefix, id, 0, nm); o = as_append_escaped(out, o, nm, as_len(nm)) 194 o = as_append(out, o, "</td><td class='n'>" as *u8); o = fd_apnum(out, o, ec_wild(prefix, id)) 195 o = as_append(out, o, "</td><td class='n'>" as *u8); o = fd_apnum(out, o, ec_deer(prefix, id)) 196 o = as_append(out, o, "</td><td class='n'>" as *u8); o = fd_apnum(out, o, ec_value(prefix, id, wfood, wmed, wwild)) 197 o = as_append(out, o, "</td></tr>" as *u8) 198 } 199 i = i + 1 200 } 201 o = as_append(out, o, "</table><p class='muted'>High wildlife value + deer-resistant: feed the pollinators and birds without feeding the deer.</p></div>" as *u8) 202 203 o = as_append(out, o, "<p class='muted' style='text-align:center'>Plants valued across food + medicine + wildlife. Grounded in the Nishi permaculture corpus. Optimal use of the environment, while improving it.</p></main></body></html>" as *u8) 204 out[o] = 0 as u8 205 return o 206}