nx_chemotaxis.nx source
↩ module page · 82 lines · 2873 B
1// nx_chemotaxis.nx -- service discovery via signal gradient.
2//
3// Biology: chemotaxis is movement of cells along chemical gradients
4// (immune cells toward inflammation, bacteria toward nutrients).
5// Substrate: discover service location by following published signal
6// gradients (signal strength = quality of match).
7
8import "nx_syscalls.nx"
9import "nx_tier.nx"
10const NX_MAGIC_1024: i64 = 1024
11
12const NX_CT_V_FOUND: nx_int = 0
13const NX_CT_V_NOT_FOUND: nx_int = 1
14const NX_CT_V_GRADIENT_WEAK: nx_int = 2
15const NX_CT_V_NULL: nx_int = 3
16const NX_CT_V_N: nx_int = 4
17
18struct NxChemoTarget {
19 target_id: nx_int,
20 capability_hash: nx_size,
21 signal_strength_q10: nx_int, // 0-NX_MAGIC_1024
22 last_seen_us: nx_size,
23 distance_hops: nx_int,
24}
25
26const NX_CT_BYTES: nx_int = 40
27
28func nx_ct_v_is_valid(v: nx_int) -> nx_int {
29 if v < 0 { return 0 }
30 if v >= NX_CT_V_N { return 0 }
31 return 1
32}
33
34func nx_ct_target_new(target_id: nx_int,
35 capability_hash: nx_size,
36 signal_strength_q10: nx_int,
37 distance_hops: nx_int,
38 now_us: nx_size) -> *NxChemoTarget {
39 if signal_strength_q10 < 0 { return 0 as *NxChemoTarget }
40 if signal_strength_q10 > NX_MAGIC_1024 { return 0 as *NxChemoTarget }
41 if distance_hops < 0 { return 0 as *NxChemoTarget }
42 let raw: *u8 = sys_mmap(NX_CT_BYTES)
43 let t: *NxChemoTarget = raw as *NxChemoTarget
44 t.target_id = target_id
45 t.capability_hash = capability_hash
46 t.signal_strength_q10 = signal_strength_q10
47 t.last_seen_us = now_us
48 t.distance_hops = distance_hops
49 return t
50}
51
52func nx_ct_target_score_q10(t: *NxChemoTarget) -> nx_int {
53 if (t as i64) == 0 { return 0 }
54 // Score = signal_strength / (1 + hops) (closer + stronger = higher)
55 let denom: nx_int = 1 + t.distance_hops
56 return t.signal_strength_q10 / denom
57}
58
59func nx_ct_target_is_fresh(t: *NxChemoTarget, now_us: nx_size,
60 max_age_us: nx_size) -> nx_int {
61 if (t as i64) == 0 { return 0 }
62 let age_us: nx_size = now_us - t.last_seen_us
63 if age_us > max_age_us { return 0 }
64 return 1
65}
66
67func nx_ct_classify(t: *NxChemoTarget, threshold_q10: nx_int) -> nx_int {
68 if (t as i64) == 0 { return NX_CT_V_NULL }
69 let score: nx_int = nx_ct_target_score_q10(t)
70 if score >= threshold_q10 { return NX_CT_V_FOUND }
71 if score > 0 { return NX_CT_V_GRADIENT_WEAK }
72 return NX_CT_V_NOT_FOUND
73}
74
75func nx_ct_pick_strongest(a: *NxChemoTarget, b: *NxChemoTarget) -> *NxChemoTarget {
76 if (a as i64) == 0 { return b }
77 if (b as i64) == 0 { return a }
78 let score_a: nx_int = nx_ct_target_score_q10(a)
79 let score_b: nx_int = nx_ct_target_score_q10(b)
80 if score_a >= score_b { return a }
81 return b
82}