code wiki / (root) / nx_caplab_quality.nx

nx_caplab_quality.nx source

↩ module page · 84 lines · 3200 B

1// nx_caplab_quality.nx -- Capitalism Lab R4: demand driven by PRICE + QUALITY + 2// BRAND (the heart of Capitalism Lab -- customers don't just buy the cheapest; 3// a higher-quality, better-branded product wins share even at a higher price). 4// Generalizes R1's price-only competition: each firm's "appeal" is a weighted 5// sum of price-value, quality, and brand; the market splits by appeal 6// (largest-remainder, conserved). 7// 8// MODEL: 9// appeal = max(0, w_price*max(0,choke-price) + w_qual*quality + w_brand*brand) 10// share = market_m * appeal / sum(appeal) (largest-remainder) 11// 12// nx_safety_envelope: 13// intended_use: capitalism-lab demand model (pure functions, no I/O) 14// sil_target: SIL1 15// verdict: NOT_YET_EVALUATED 16// 17// genealogy_id: capitalism_lab_quality_brand_canon 18// lineage_id: nx_caplab_quality_v1 19 20import "nx_syscalls.nx" 21import "nx_tier.nx" 22 23// Generic largest-remainder apportionment of `total` among n shares by weight. 24// (Shared engine for any appeal model; conserves the total exactly.) 25func nx_clab_apportion(n: nx_int, weights: *i64, total: nx_int, out_q: *i64) { 26 var sumw: nx_int = 0 27 var i: nx_int = 0 28 while i < n { sumw = sumw + weights[i]; i = i + 1 } 29 if sumw <= 0 { 30 i = 0 31 while i < n { out_q[i] = 0; i = i + 1 } 32 return 33 } 34 let rem: *i64 = (sys_mmap(n * NX_SIZEOF_NX_INT)) as *i64 35 let got: *i64 = (sys_mmap(n * NX_SIZEOF_NX_INT)) as *i64 36 var alloc: nx_int = 0 37 i = 0 38 while i < n { 39 let num: nx_int = total * weights[i] 40 out_q[i] = num / sumw 41 rem[i] = num % sumw 42 got[i] = 0 43 alloc = alloc + out_q[i] 44 i = i + 1 45 } 46 var leftover: nx_int = total - alloc 47 while leftover > 0 { 48 var best: nx_int = 0 - 1 49 var best_rem: nx_int = 0 - 1 50 var j: nx_int = 0 51 while j < n { 52 if got[j] == 0 { if rem[j] > best_rem { best_rem = rem[j]; best = j } } 53 j = j + 1 54 } 55 out_q[best] = out_q[best] + 1 56 got[best] = 1 57 leftover = leftover - 1 58 } 59} 60 61// A product's appeal to customers: undercutting the choke price helps, and so 62// do quality and brand (each weighted). Priced at/above choke contributes 0 63// price-value, but quality/brand still pull brand-loyal buyers. 64func nx_clab_appeal_qb(choke: nx_int, price: nx_int, quality: nx_int, brand: nx_int, 65 w_price: nx_int, w_qual: nx_int, w_brand: nx_int) -> nx_int { 66 var pv: nx_int = choke - price 67 if pv < 0 { pv = 0 } 68 let a: nx_int = w_price * pv + w_qual * quality + w_brand * brand 69 if a < 0 { return 0 } 70 return a 71} 72 73// Split the market among n firms by price/quality/brand appeal. 74func nx_clab_split_qb(n: nx_int, prices: *i64, qualities: *i64, brands: *i64, 75 choke: nx_int, w_price: nx_int, w_qual: nx_int, w_brand: nx_int, 76 market_m: nx_int, out_q: *i64) { 77 let w: *i64 = (sys_mmap(n * NX_SIZEOF_NX_INT)) as *i64 78 var i: nx_int = 0 79 while i < n { 80 w[i] = nx_clab_appeal_qb(choke, prices[i], qualities[i], brands[i], w_price, w_qual, w_brand) 81 i = i + 1 82 } 83 nx_clab_apportion(n, w, market_m, out_q) 84}