Skip to main content

nexcore_helix/
lib.rs

1//! # nexcore-helix — Conservation Law as Computable Geometry
2//!
3//! The conservation law `∃ = ∂(×(ς, ∅))` encodes a helix:
4//! - It **advances** (→) — each turn raises resolution
5//! - It **returns** (κ) — same angular truth at every altitude
6//! - It **bounds** (∂) — radius separates inside from outside
7//!
8//! Five turns at increasing altitude, same truth at higher resolution:
9//!
10//! | Turn | Name               | What         | Encoding                    |
11//! |------|--------------------|-------------|-----------------------------|
12//! | 0    | Primitives         | The alphabet | 15 symbols                  |
13//! | 1    | Conservation       | The grammar  | ∃ = ∂(×(ς, ∅))              |
14//! | 2    | Crystalbook        | The laws     | 8 constraints               |
15//! | 3    | Derivative Identity| The calculus | How the grammar changes     |
16//! | 4    | Mutualism          | The point    | Why the grammar exists      |
17//!
18//! By Matthew A. Campion, PharmD.
19
20#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
21#![forbid(unsafe_code)]
22
23pub mod dna;
24pub mod engine;
25
26use serde::{Deserialize, Serialize};
27
28// ---- Core Types ----
29
30/// A point on the knowledge helix.
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct HelixPosition {
33    pub turn: Turn,
34    pub theta: f64,
35    pub x: f64,
36    pub y: f64,
37    pub z: f64,
38}
39
40/// The five turns of the knowledge helix.
41#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
42pub enum Turn {
43    Primitives = 0,
44    Conservation = 1,
45    Crystalbook = 2,
46    DerivativeIdentity = 3,
47    Mutualism = 4,
48}
49
50impl Turn {
51    /// Human-readable name.
52    pub fn name(self) -> &'static str {
53        match self {
54            Self::Primitives => "Primitives",
55            Self::Conservation => "Conservation",
56            Self::Crystalbook => "Crystalbook",
57            Self::DerivativeIdentity => "Derivative Identity",
58            Self::Mutualism => "Mutualism",
59        }
60    }
61
62    /// What this turn represents.
63    pub fn what(self) -> &'static str {
64        match self {
65            Self::Primitives => "The alphabet",
66            Self::Conservation => "The grammar",
67            Self::Crystalbook => "The laws",
68            Self::DerivativeIdentity => "The calculus",
69            Self::Mutualism => "The point",
70        }
71    }
72
73    /// The encoding at this altitude.
74    pub fn encoding(self) -> &'static str {
75        match self {
76            Self::Primitives => "15 symbols (9 prime + 6 composite)",
77            Self::Conservation => "∃ = ∂(×(ς, ∅))",
78            Self::Crystalbook => "8 constraints on the grammar",
79            Self::DerivativeIdentity => "How the grammar changes (5 calculus rules hold)",
80            Self::Mutualism => "Refusal to produce ∃ for self at cost of another's ∃",
81        }
82    }
83
84    /// Next turn, if any.
85    pub fn next(self) -> Option<Self> {
86        match self {
87            Self::Primitives => Some(Self::Conservation),
88            Self::Conservation => Some(Self::Crystalbook),
89            Self::Crystalbook => Some(Self::DerivativeIdentity),
90            Self::DerivativeIdentity => Some(Self::Mutualism),
91            Self::Mutualism => None,
92        }
93    }
94
95    /// From integer.
96    pub fn from_index(i: usize) -> Option<Self> {
97        match i {
98            0 => Some(Self::Primitives),
99            1 => Some(Self::Conservation),
100            2 => Some(Self::Crystalbook),
101            3 => Some(Self::DerivativeIdentity),
102            4 => Some(Self::Mutualism),
103            _ => None,
104        }
105    }
106}
107
108// ---- Conservation Law ----
109
110/// The three inputs to the conservation law.
111#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
112pub struct ConservationInput {
113    /// ∂ — boundary sharpness [0,1]
114    pub boundary: f64,
115    /// ς — state richness [0,1]
116    pub state: f64,
117    /// ∅ — void clarity [0,1]
118    pub void: f64,
119}
120
121/// Result of computing ∃ = ∂(×(ς, ∅)).
122#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct ConservationResult {
124    pub existence: f64,
125    pub boundary: f64,
126    pub state: f64,
127    pub void: f64,
128    pub weakest: WeakestPrimitive,
129    pub classification: ExistenceClass,
130}
131
132#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
133pub enum WeakestPrimitive {
134    Boundary,
135    State,
136    Void,
137    None,
138}
139
140impl WeakestPrimitive {
141    pub fn symbol(self) -> &'static str {
142        match self {
143            Self::Boundary => "∂",
144            Self::State => "ς",
145            Self::Void => "∅",
146            Self::None => "—",
147        }
148    }
149}
150
151#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
152pub enum ExistenceClass {
153    Strong,
154    Moderate,
155    Weak,
156    Collapsing,
157}
158
159impl ExistenceClass {
160    pub fn label(self) -> &'static str {
161        match self {
162            Self::Strong => "strong",
163            Self::Moderate => "moderate",
164            Self::Weak => "weak",
165            Self::Collapsing => "collapsing",
166        }
167    }
168}
169
170/// Compute ∃ = ∂(×(ς, ∅)).
171pub fn conservation(input: ConservationInput) -> ConservationResult {
172    let b = input.boundary.clamp(0.0, 1.0);
173    let s = input.state.clamp(0.0, 1.0);
174    let v = input.void.clamp(0.0, 1.0);
175    let existence = b * s * v;
176
177    let weakest = if b <= s && b <= v {
178        WeakestPrimitive::Boundary
179    } else if s <= v {
180        WeakestPrimitive::State
181    } else {
182        WeakestPrimitive::Void
183    };
184
185    let classification = if existence >= 0.5 {
186        ExistenceClass::Strong
187    } else if existence >= 0.2 {
188        ExistenceClass::Moderate
189    } else if existence >= 0.05 {
190        ExistenceClass::Weak
191    } else {
192        ExistenceClass::Collapsing
193    };
194
195    ConservationResult {
196        existence,
197        boundary: b,
198        state: s,
199        void: v,
200        weakest,
201        classification,
202    }
203}
204
205// ---- Partial Derivatives ----
206
207/// Partial derivatives of ∃ with respect to each primitive.
208#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
209pub struct Derivatives {
210    /// ∂∃/∂∂ = ς × ∅
211    pub d_boundary: f64,
212    /// ∂∃/∂ς = ∂ × ∅
213    pub d_state: f64,
214    /// ∂∃/∂∅ = ∂ × ς
215    pub d_void: f64,
216    /// Which partial derivative is largest.
217    pub highest_leverage: WeakestPrimitive,
218}
219
220/// Compute partial derivatives of ∃ = ∂(×(ς, ∅)).
221pub fn derivatives(input: ConservationInput) -> Derivatives {
222    let b = input.boundary.clamp(0.0, 1.0);
223    let s = input.state.clamp(0.0, 1.0);
224    let v = input.void.clamp(0.0, 1.0);
225
226    let d_b = s * v;
227    let d_s = b * v;
228    let d_v = b * s;
229
230    let highest = if d_b >= d_s && d_b >= d_v {
231        WeakestPrimitive::Boundary
232    } else if d_s >= d_v {
233        WeakestPrimitive::State
234    } else {
235        WeakestPrimitive::Void
236    };
237
238    Derivatives {
239        d_boundary: d_b,
240        d_state: d_s,
241        d_void: d_v,
242        highest_leverage: highest,
243    }
244}
245
246// ---- Mutualism ----
247
248/// Result of a mutualism test.
249#[derive(Debug, Clone, Serialize, Deserialize)]
250pub struct MutualismResult {
251    pub mutualistic: bool,
252    pub delta_self: f64,
253    pub delta_other: f64,
254    pub net_existence: f64,
255    pub classification: MutualismClass,
256    pub conservation_holds: bool,
257}
258
259#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
260pub enum MutualismClass {
261    Mutualistic,
262    Sacrificial,
263    Parasitic,
264    ParasiticNetNegative,
265    Destructive,
266}
267
268impl MutualismClass {
269    pub fn label(self) -> &'static str {
270        match self {
271            Self::Mutualistic => "mutualistic",
272            Self::Sacrificial => "sacrificial",
273            Self::Parasitic => "parasitic",
274            Self::ParasiticNetNegative => "parasitic_net_negative",
275            Self::Destructive => "destructive",
276        }
277    }
278}
279
280/// Test whether an action serves mutualism.
281pub fn mutualism_test(
282    self_before: f64,
283    self_after: f64,
284    other_before: f64,
285    other_after: f64,
286) -> MutualismResult {
287    let delta_self = self_after - self_before;
288    let delta_other = other_after - other_before;
289    let net = delta_self + delta_other;
290
291    let (mutualistic, class) = if delta_self >= 0.0 && delta_other >= 0.0 {
292        (true, MutualismClass::Mutualistic)
293    } else if delta_self > 0.0 && delta_other < 0.0 {
294        if delta_self.abs() <= delta_other.abs() {
295            (false, MutualismClass::ParasiticNetNegative)
296        } else {
297            (false, MutualismClass::Parasitic)
298        }
299    } else if delta_self < 0.0 && delta_other > 0.0 {
300        (true, MutualismClass::Sacrificial)
301    } else {
302        (false, MutualismClass::Destructive)
303    };
304
305    MutualismResult {
306        mutualistic,
307        delta_self,
308        delta_other,
309        net_existence: net,
310        classification: class,
311        conservation_holds: net >= 0.0,
312    }
313}
314
315// ---- Helix Geometry ----
316
317/// Compute 3D position on the helix.
318pub fn helix_position(turn: Turn, theta: f64) -> HelixPosition {
319    let altitude = (turn as usize) as f64 + theta / (2.0 * std::f64::consts::PI);
320    HelixPosition {
321        turn,
322        theta,
323        x: theta.cos(),
324        y: theta.sin(),
325        z: altitude,
326    }
327}
328
329/// Check if a system can advance to the next helix turn.
330pub fn can_advance(turn: Turn, existence: f64) -> bool {
331    let threshold = match turn {
332        Turn::Primitives => 0.1,
333        Turn::Conservation => 0.2,
334        Turn::Crystalbook => 0.3,
335        Turn::DerivativeIdentity => 0.4,
336        Turn::Mutualism => f64::INFINITY, // already at top
337    };
338    existence >= threshold
339}
340
341// ---- Crystalbook Law Routing ----
342
343/// Which Crystalbook laws bind a system based on its weakest primitive.
344pub fn binding_laws(weakest: WeakestPrimitive) -> &'static [u8] {
345    match weakest {
346        WeakestPrimitive::Boundary => &[1, 3, 8],
347        WeakestPrimitive::State => &[2, 5, 7],
348        WeakestPrimitive::Void => &[4, 6],
349        WeakestPrimitive::None => &[1, 2, 3, 4, 5, 6, 7, 8],
350    }
351}
352
353/// Vice risk associated with the weakest primitive.
354pub fn vice_risk(weakest: WeakestPrimitive) -> &'static str {
355    match weakest {
356        WeakestPrimitive::Boundary => "Pride, Lust, Corruption",
357        WeakestPrimitive::State => "Greed, Gluttony, Sloth",
358        WeakestPrimitive::Void => "Envy, Wrath",
359        WeakestPrimitive::None => "Low — all primitives healthy",
360    }
361}
362
363#[cfg(test)]
364mod tests {
365    use super::*;
366
367    #[test]
368    fn conservation_strong() {
369        let r = conservation(ConservationInput {
370            boundary: 0.9,
371            state: 0.8,
372            void: 0.7,
373        });
374        assert_eq!(r.classification, ExistenceClass::Strong);
375        assert!((r.existence - 0.504).abs() < 0.001);
376    }
377
378    #[test]
379    fn conservation_collapsing_zero_boundary() {
380        let r = conservation(ConservationInput {
381            boundary: 0.0,
382            state: 1.0,
383            void: 1.0,
384        });
385        assert_eq!(r.classification, ExistenceClass::Collapsing);
386        assert_eq!(r.existence, 0.0);
387        assert_eq!(r.weakest, WeakestPrimitive::Boundary);
388    }
389
390    #[test]
391    fn conservation_weak_state() {
392        let r = conservation(ConservationInput {
393            boundary: 0.95,
394            state: 0.05,
395            void: 0.6,
396        });
397        assert_eq!(r.classification, ExistenceClass::Collapsing);
398        assert_eq!(r.weakest, WeakestPrimitive::State);
399    }
400
401    #[test]
402    fn derivatives_highest_leverage() {
403        let d = derivatives(ConservationInput {
404            boundary: 0.9,
405            state: 0.3,
406            void: 0.8,
407        });
408        // d_boundary = 0.3*0.8 = 0.24
409        // d_state = 0.9*0.8 = 0.72  <-- highest
410        // d_void = 0.9*0.3 = 0.27
411        assert_eq!(d.highest_leverage, WeakestPrimitive::State);
412    }
413
414    #[test]
415    fn mutualism_both_gain() {
416        let r = mutualism_test(0.5, 0.7, 0.5, 0.6);
417        assert!(r.mutualistic);
418        assert_eq!(r.classification, MutualismClass::Mutualistic);
419        assert!(r.conservation_holds);
420    }
421
422    #[test]
423    fn mutualism_parasitic() {
424        let r = mutualism_test(0.3, 0.8, 0.7, 0.4);
425        assert!(!r.mutualistic);
426        assert_eq!(r.classification, MutualismClass::Parasitic);
427    }
428
429    #[test]
430    fn mutualism_destructive() {
431        let r = mutualism_test(0.5, 0.3, 0.5, 0.2);
432        assert!(!r.mutualistic);
433        assert_eq!(r.classification, MutualismClass::Destructive);
434        assert!(!r.conservation_holds);
435    }
436
437    #[test]
438    fn helix_position_at_origin() {
439        let p = helix_position(Turn::Primitives, 0.0);
440        assert_eq!(p.x, 1.0);
441        assert!(p.y.abs() < 1e-10);
442        assert_eq!(p.z, 0.0);
443    }
444
445    #[test]
446    fn advance_gate() {
447        assert!(can_advance(Turn::Primitives, 0.15));
448        assert!(!can_advance(Turn::Primitives, 0.05));
449        assert!(!can_advance(Turn::Mutualism, 1.0)); // can't advance past top
450    }
451
452    #[test]
453    fn binding_laws_boundary_weak() {
454        assert_eq!(binding_laws(WeakestPrimitive::Boundary), &[1, 3, 8]);
455    }
456
457    #[test]
458    fn turn_traversal() {
459        let mut t = Turn::Primitives;
460        let mut count = 0;
461        while let Some(next) = t.next() {
462            t = next;
463            count += 1;
464        }
465        assert_eq!(count, 4);
466        assert_eq!(t, Turn::Mutualism);
467    }
468}