code wiki / _hdl_build / nx_pkg_solve.nx
nx_pkg_solve.nx
buildroot/runtime/_hdl_build/nx_pkg_solve.nx
about
nx_pkg_solve.nx -- GATE: VERSION-CONSTRAINT DEPENDENCY SOLVING (closes the PACKAGE-MGMT census gap "version-
constraint solving"). Reworks nx_pkg (transitive-closure + topo + sha) with the piece it lacked: a real
BACKTRACKING resolver over a package UNIVERSE where each package has multiple VERSIONS and each (package,version)
declares dependency CONSTRAINTS (semver: exact / >= / caret ^ / tilde ~ / range). Grounded on the banked field
research (pp_semver/pp_dephell/pp_sat/pp_backtracking): pick a version of every needed package satisfying ALL
dependents' constraints jointly; backtrack on conflict; report unsatisfiable. Complete search, highest-version-
first => deterministic (lockfile-stable). Constraints held as inclusive [lo,hi] intervals over encoded versions.
T1 DIAMOND: App->B^1,C^1; B->D>=1.2; C->D in[1.5,2.0) -> D resolves to the HIGHEST feasible (1.9.0) via intersection.
T2 BACKTRACK: App->B(any),D=1.3.0; B2.0.0->D>=1.5.0 (fails D=1.3.0) -> solver BACKTRACKS to B1.0.0 (the lower ver).
T3 CONFLICT: B->D<2.0.0, C->D>=2.0.0 -> UNSATISFIABLE detected (no version of D satisfies both).
T4 teeth: the semver operators (exact/gte/caret/tilde) map to the correct intervals (KATs).
T5 determinism: the diamond solved twice -> identical selection (reproducible / lockfile-stable).
expect_exit: 0 Sovereign: nx_syscalls. NEVER-BRICK: pure resolution, writes 0 firmware.
dependencies 2 imports · 0 importers
imports: nx_syscalls.nxnx_itoa_lib.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| 31 | struct Univ |
consts
| 16 | const K_MAGIC_1000000: i64 = 1000000 |
| 26 | const MAXV: i64 = 4 |
| 27 | const BIG: i64 = 999999999 |
functions
| 18 | func g_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } |
| 23 | func g_pn(v: i64) -> i64 { nxi_out(v); return 0 } |
| 24 | func ck(name: *u8, c: i64) -> i64 { if c==1 { g_puts(" PASS " as *u8) } else { g_puts(" FAIL " as *u8) } g_puts(name); g_puts("\n" as *u8); return c } |
| 29 | func ver(maj: i64, min: i64, pat: i64) -> i64 { return maj*K_MAGIC_1000000 + min*1000 + pat } called by 1: main |
| 48 | func feasible(u: *Univ, sel: *i64) -> i64 called by 1: solve |
| 71 | func solve(u: *Univ, idx: i64, sel: *i64) -> i64 |
| 83 | func mk(np: i64, nver: *i64, vers: *i64, nreq: i64, rs: *i64, rsv: *i64, rd: *i64, rl: *i64, rh: *i64, nroot: i64, rod: *i64, rol: *i64, roh: *i64) -> *Univ |
| 88 | func chosen(u: *Univ, sel: *i64, p: i64) -> i64 { if sel[p]==(0-1) { return 0-1 } return u.vers[p*MAXV+sel[p]] } called by 1: main |
| 90 | func main() -> i64 |