hexagram.go raw

   1  // Package hexagram implements the 64 dynamical states as transition rules.
   2  //
   3  // Each hexagram (inner trigram + outer trigram) defines what operation
   4  // applies to a lattice node given its internal state and its environment.
   5  // The hexagrams are not descriptions — they are instructions. The lattice
   6  // executes itself.
   7  package hexagram
   8  
   9  import (
  10  	"git.mleku.dev/mleku/dendrite/pkg/state"
  11  )
  12  
  13  // Op is an operation the lattice performs on a node.
  14  type Op uint8
  15  
  16  const (
  17  	OpNone      Op = iota // no action — stable equilibrium
  18  	OpAccrete             // attempt to bond an element from solution
  19  	OpDissolve            // release the occupant back to solution
  20  	OpNucleate            // create new constraint sites around this node
  21  	OpPrune               // remove connections to weak neighbors
  22  	OpStrengthen          // deepen lock-in by adding constraints from neighbors
  23  	OpExplore             // extend the lattice topology with new vacant sites
  24  	OpCollapse            // resolve ambiguity — select one candidate
  25  	OpRecycle             // dissolve and immediately re-offer to solution
  26  )
  27  
  28  // Priority determines how much resource (computational attention) a node
  29  // in this state receives. Higher = more goroutines directed here.
  30  type Priority uint8
  31  
  32  const (
  33  	PriorityIdle   Priority = 0
  34  	PriorityLow    Priority = 1
  35  	PriorityMedium Priority = 2
  36  	PriorityHigh   Priority = 3
  37  )
  38  
  39  // Rule is the transition rule for one hexagram state.
  40  type Rule struct {
  41  	Op       Op
  42  	Priority Priority
  43  }
  44  
  45  // table maps each of the 64 hexagram encodings to a rule.
  46  // Inner trigram (low 3 bits) = site state.
  47  // Outer trigram (high 3 bits) = environment state.
  48  var table [64]Rule
  49  
  50  func init() {
  51  	// Build the table from first principles.
  52  	// The logic: what should happen at a site given its state and
  53  	// its environment?
  54  	for i := range 64 {
  55  		h := state.Hexagram(i)
  56  		table[i] = derive(h.Inner(), h.Outer())
  57  	}
  58  }
  59  
  60  // derive computes the rule for a given inner/outer trigram pair.
  61  // This is the core logic — the seed's instruction set made operational.
  62  func derive(inner, outer state.Trigram) Rule {
  63  	ib := inner.Bonding()
  64  	ic := inner.Constraint()
  65  	ie := inner.Energy()
  66  	ob := outer.Bonding()
  67  	oc := outer.Constraint()
  68  	oe := outer.Energy()
  69  
  70  	switch {
  71  
  72  	// === EARTH INNER (000): vacant, free, depleted ===
  73  
  74  	// Vacant site in dead environment — nothing to do.
  75  	case !ib && !ic && !ie && !ob && !oc && !oe:
  76  		return Rule{OpNone, PriorityIdle} // ☷/☷
  77  
  78  	// Vacant site, dead inside, but environment is nucleating.
  79  	case !ib && !ic && !ie && ob && !oc && !oe:
  80  		return Rule{OpNucleate, PriorityMedium} // ☷/☳
  81  
  82  	// Vacant site, environment has energy — attempt accretion.
  83  	case !ib && !ic && !ie && oe:
  84  		return Rule{OpAccrete, PriorityHigh} // ☷/anything-energized
  85  
  86  	// Vacant site, environment is structured but depleted — explore outward.
  87  	case !ib && !ic && !ie && oc && !oe:
  88  		return Rule{OpExplore, PriorityLow} // ☷/structured-depleted
  89  
  90  	// === THUNDER INNER (001): accreting, free, depleted — nucleation ===
  91  
  92  	// Nucleation happening — high priority regardless of environment.
  93  	case ib && !ic && !ie:
  94  		if oe {
  95  			return Rule{OpAccrete, PriorityHigh} // nucleation + energy = grow
  96  		}
  97  		return Rule{OpNucleate, PriorityMedium} // nucleation, build structure
  98  
  99  	// === WATER INNER (010): dissolving, bound, depleted — frozen defect ===
 100  
 101  	// Frozen defect in energized environment — can anneal.
 102  	case !ib && ic && !ie && oe:
 103  		return Rule{OpRecycle, PriorityHigh} // dissolve and re-offer
 104  
 105  	// Frozen defect in dead environment — just dissolve.
 106  	case !ib && ic && !ie && !oe:
 107  		return Rule{OpDissolve, PriorityMedium}
 108  
 109  	// === LAKE INNER (011): accreting, bound, depleted — ambiguity ===
 110  
 111  	// Ambiguity zone in structured environment — collapse.
 112  	case ib && ic && !ie && oc:
 113  		return Rule{OpCollapse, PriorityMedium}
 114  
 115  	// Ambiguity zone in energized environment — strengthen.
 116  	case ib && ic && !ie && oe:
 117  		return Rule{OpStrengthen, PriorityLow}
 118  
 119  	// Ambiguity zone, unstructured environment — hold.
 120  	case ib && ic && !ie:
 121  		return Rule{OpNone, PriorityLow}
 122  
 123  	// === FIRE INNER (100): dissolving, free, energized — noisy growth ===
 124  
 125  	// Noisy growth — energy without constraint. Prune.
 126  	case !ib && !ic && ie && oc:
 127  		return Rule{OpPrune, PriorityHigh} // coherence field says prune
 128  
 129  	// Noisy growth, no external constraint — dissolve the mess.
 130  	case !ib && !ic && ie:
 131  		return Rule{OpDissolve, PriorityMedium}
 132  
 133  	// === HEAVEN INNER (101): accreting, free, energized — ideal growth ===
 134  
 135  	// Ideal growth state — accrete with highest priority.
 136  	case ib && !ic && ie:
 137  		return Rule{OpAccrete, PriorityHigh}
 138  
 139  	// === WIND INNER (110): dissolving, bound, energized — coherence pruning ===
 140  
 141  	// The coherence field at work — pruning incompatible bonds.
 142  	case !ib && ic && ie:
 143  		if ob {
 144  			return Rule{OpPrune, PriorityHigh} // active growth nearby, prune hard
 145  		}
 146  		return Rule{OpDissolve, PriorityMedium} // gentle dissolution
 147  
 148  	// === MOUNTAIN INNER (111): accreting, bound, energized — equilibrium ===
 149  
 150  	// Full equilibrium — everything present. Explore to extend lattice.
 151  	case ib && ic && ie && oe:
 152  		return Rule{OpExplore, PriorityLow} // extend from stable base
 153  
 154  	// Equilibrium but environment is depleted — strengthen locally.
 155  	case ib && ic && ie:
 156  		return Rule{OpStrengthen, PriorityLow}
 157  	}
 158  
 159  	// Fallback: do nothing.
 160  	return Rule{OpNone, PriorityIdle}
 161  }
 162  
 163  // Lookup returns the rule for a given hexagram.
 164  func Lookup(h state.Hexagram) Rule {
 165  	return table[uint8(h)]
 166  }
 167  
 168  // Table returns the full 64-entry rule table. The caller must not modify it.
 169  func Table() *[64]Rule {
 170  	return &table
 171  }
 172  
 173  // ADSRPhase names the four age-based dynamical phases of a lattice node,
 174  // modeled after the envelope of a musical note.
 175  type ADSRPhase uint8
 176  
 177  const (
 178  	Attack  ADSRPhase = 0 // freshly bonded: high-energy accretion
 179  	Decay   ADSRPhase = 1 // settling: actively growing and bonding
 180  	Sustain ADSRPhase = 2 // durable: locked in, stable attractor
 181  	Release ADSRPhase = 3 // dissolving: returning to solution
 182  )
 183