package hexagram import ( "git.mleku.dev/mleku/dendrite/pkg/permutation" "git.mleku.dev/mleku/dendrite/pkg/state" ) // variantTables holds 6 lookup tables, one per S_3 permutation. // variantTables[Identity] is identical to the canonical table. // // To look up a rule for hexagram h under permutation p: the hexagram // bits encode state in p's frame, so we apply p^-1 to map back to the // canonical frame, then look up the canonical rule. var variantTables [permutation.Count][64]Rule func init() { for _, p := range permutation.All() { inv := p.Inverse() for h := range uint8(64) { canonical := inv.ApplyHexagram(state.Hexagram(h)) variantTables[p][h] = table[uint8(canonical)] } } } // LookupVariant returns the rule for hexagram h under permutation p. // When p is Identity, this is equivalent to Lookup(h). func LookupVariant(h state.Hexagram, p permutation.Perm) Rule { return variantTables[p][uint8(h)] } // keyToPerm maps a 3-bit projection key (0-7) to an S_3 permutation. // Keys 6 and 7 are collapse points that alias to existing permutations. var keyToPerm = [8]permutation.Perm{ permutation.Identity, // 000: face XY permutation.Swap12, // 001: face XZ permutation.Swap02, // 010: face YZ permutation.Swap01, // 011: edge bias permutation.Cycle012, // 100: vertex A permutation.Cycle021, // 101: vertex B permutation.Identity, // 110: collapse → Identity permutation.Swap12, // 111: collapse → Swap12 } // LookupProjected returns the rule for hexagram h given a 3-bit projection // key. The key determines the S_3 permutation applied to the hexagram // before rule lookup. Collapse keys (6, 7) reduce to their parent // permutations, which is the geometric meaning of projection collapse: // the rule table simplifies. func LookupProjected(h state.Hexagram, projKey uint8) Rule { p := keyToPerm[projKey&0b111] return variantTables[p][uint8(h)] } // LookupFull returns the rule for a hexagram given the full 6-bit // projection encoding (vertex in low 3 bits, key in high 3 bits). // The vertex contributes to the hexagram's inner trigram (it IS the // inner trigram). The key determines the projection permutation. func LookupFull(h state.Hexagram, proj6bit uint8) Rule { key := (proj6bit >> 3) & 0b111 return LookupProjected(h, key) }