// Package hexagram implements the 64 dynamical states as transition rules. // // Each hexagram (inner trigram + outer trigram) defines what operation // applies to a lattice node given its internal state and its environment. // The hexagrams are not descriptions — they are instructions. The lattice // executes itself. package hexagram import ( "git.mleku.dev/mleku/dendrite/pkg/state" ) // Op is an operation the lattice performs on a node. type Op uint8 const ( OpNone Op = iota // no action — stable equilibrium OpAccrete // attempt to bond an element from solution OpDissolve // release the occupant back to solution OpNucleate // create new constraint sites around this node OpPrune // remove connections to weak neighbors OpStrengthen // deepen lock-in by adding constraints from neighbors OpExplore // extend the lattice topology with new vacant sites OpCollapse // resolve ambiguity — select one candidate OpRecycle // dissolve and immediately re-offer to solution ) // Priority determines how much resource (computational attention) a node // in this state receives. Higher = more goroutines directed here. type Priority uint8 const ( PriorityIdle Priority = 0 PriorityLow Priority = 1 PriorityMedium Priority = 2 PriorityHigh Priority = 3 ) // Rule is the transition rule for one hexagram state. type Rule struct { Op Op Priority Priority } // table maps each of the 64 hexagram encodings to a rule. // Inner trigram (low 3 bits) = site state. // Outer trigram (high 3 bits) = environment state. var table [64]Rule func init() { // Build the table from first principles. // The logic: what should happen at a site given its state and // its environment? for i := range 64 { h := state.Hexagram(i) table[i] = derive(h.Inner(), h.Outer()) } } // derive computes the rule for a given inner/outer trigram pair. // This is the core logic — the seed's instruction set made operational. func derive(inner, outer state.Trigram) Rule { ib := inner.Bonding() ic := inner.Constraint() ie := inner.Energy() ob := outer.Bonding() oc := outer.Constraint() oe := outer.Energy() switch { // === EARTH INNER (000): vacant, free, depleted === // Vacant site in dead environment — nothing to do. case !ib && !ic && !ie && !ob && !oc && !oe: return Rule{OpNone, PriorityIdle} // ☷/☷ // Vacant site, dead inside, but environment is nucleating. case !ib && !ic && !ie && ob && !oc && !oe: return Rule{OpNucleate, PriorityMedium} // ☷/☳ // Vacant site, environment has energy — attempt accretion. case !ib && !ic && !ie && oe: return Rule{OpAccrete, PriorityHigh} // ☷/anything-energized // Vacant site, environment is structured but depleted — explore outward. case !ib && !ic && !ie && oc && !oe: return Rule{OpExplore, PriorityLow} // ☷/structured-depleted // === THUNDER INNER (001): accreting, free, depleted — nucleation === // Nucleation happening — high priority regardless of environment. case ib && !ic && !ie: if oe { return Rule{OpAccrete, PriorityHigh} // nucleation + energy = grow } return Rule{OpNucleate, PriorityMedium} // nucleation, build structure // === WATER INNER (010): dissolving, bound, depleted — frozen defect === // Frozen defect in energized environment — can anneal. case !ib && ic && !ie && oe: return Rule{OpRecycle, PriorityHigh} // dissolve and re-offer // Frozen defect in dead environment — just dissolve. case !ib && ic && !ie && !oe: return Rule{OpDissolve, PriorityMedium} // === LAKE INNER (011): accreting, bound, depleted — ambiguity === // Ambiguity zone in structured environment — collapse. case ib && ic && !ie && oc: return Rule{OpCollapse, PriorityMedium} // Ambiguity zone in energized environment — strengthen. case ib && ic && !ie && oe: return Rule{OpStrengthen, PriorityLow} // Ambiguity zone, unstructured environment — hold. case ib && ic && !ie: return Rule{OpNone, PriorityLow} // === FIRE INNER (100): dissolving, free, energized — noisy growth === // Noisy growth — energy without constraint. Prune. case !ib && !ic && ie && oc: return Rule{OpPrune, PriorityHigh} // coherence field says prune // Noisy growth, no external constraint — dissolve the mess. case !ib && !ic && ie: return Rule{OpDissolve, PriorityMedium} // === HEAVEN INNER (101): accreting, free, energized — ideal growth === // Ideal growth state — accrete with highest priority. case ib && !ic && ie: return Rule{OpAccrete, PriorityHigh} // === WIND INNER (110): dissolving, bound, energized — coherence pruning === // The coherence field at work — pruning incompatible bonds. case !ib && ic && ie: if ob { return Rule{OpPrune, PriorityHigh} // active growth nearby, prune hard } return Rule{OpDissolve, PriorityMedium} // gentle dissolution // === MOUNTAIN INNER (111): accreting, bound, energized — equilibrium === // Full equilibrium — everything present. Explore to extend lattice. case ib && ic && ie && oe: return Rule{OpExplore, PriorityLow} // extend from stable base // Equilibrium but environment is depleted — strengthen locally. case ib && ic && ie: return Rule{OpStrengthen, PriorityLow} } // Fallback: do nothing. return Rule{OpNone, PriorityIdle} } // Lookup returns the rule for a given hexagram. func Lookup(h state.Hexagram) Rule { return table[uint8(h)] } // Table returns the full 64-entry rule table. The caller must not modify it. func Table() *[64]Rule { return &table } // ADSRPhase names the four age-based dynamical phases of a lattice node, // modeled after the envelope of a musical note. type ADSRPhase uint8 const ( Attack ADSRPhase = 0 // freshly bonded: high-energy accretion Decay ADSRPhase = 1 // settling: actively growing and bonding Sustain ADSRPhase = 2 // durable: locked in, stable attractor Release ADSRPhase = 3 // dissolving: returning to solution )