1#![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#[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#[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 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 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 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 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 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#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
112pub struct ConservationInput {
113 pub boundary: f64,
115 pub state: f64,
117 pub void: f64,
119}
120
121#[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
170pub 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#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
209pub struct Derivatives {
210 pub d_boundary: f64,
212 pub d_state: f64,
214 pub d_void: f64,
216 pub highest_leverage: WeakestPrimitive,
218}
219
220pub 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#[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
280pub 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
315pub 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
329pub 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, };
338 existence >= threshold
339}
340
341pub 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
353pub 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 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)); }
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}