package hexagram import ( "testing" "git.mleku.dev/mleku/dendrite/pkg/permutation" "git.mleku.dev/mleku/dendrite/pkg/state" ) func TestVariantIdentityMatchesCanonical(t *testing.T) { for h := range uint8(64) { got := LookupVariant(state.Hexagram(h), permutation.Identity) want := Lookup(state.Hexagram(h)) if got != want { t.Errorf("LookupVariant(%d, Identity) = %v, want %v", h, got, want) } } } func TestVariantTablesOperationDistribution(t *testing.T) { // Each variant table should have the same multiset of operations // as the canonical table, since permutation is a bijection on // the 64 hexagrams. canonicalDist := opDistribution(table) for _, p := range permutation.All() { dist := opDistribution(variantTables[p]) for op, count := range canonicalDist { if dist[op] != count { t.Errorf("variant %v: Op %d appears %d times, want %d", p, op, dist[op], count) } } } } func TestVariantTablesPriorityDistribution(t *testing.T) { // Same check for priority distribution. canonicalDist := priorityDistribution(table) for _, p := range permutation.All() { dist := priorityDistribution(variantTables[p]) for pri, count := range canonicalDist { if dist[pri] != count { t.Errorf("variant %v: Priority %d appears %d times, want %d", p, pri, dist[pri], count) } } } } func TestVariantHeavenAccretes(t *testing.T) { // Heaven (101) is ideal growth under Identity. Under any permutation, // the permuted Heaven should still map to OpAccrete because the // variant table compensates. for _, p := range permutation.All() { permutedHeaven := p.ApplyTrigram(state.Heaven) h := state.Hex(permutedHeaven, state.Earth) rule := LookupVariant(h, p) if rule.Op != OpAccrete { t.Errorf("variant %v: permuted Heaven (%03b) / Earth should accrete, got Op %d", p, uint8(permutedHeaven), rule.Op) } } } func opDistribution(tbl [64]Rule) map[Op]int { dist := map[Op]int{} for _, r := range tbl { dist[r.Op]++ } return dist } func priorityDistribution(tbl [64]Rule) map[Priority]int { dist := map[Priority]int{} for _, r := range tbl { dist[r.Priority]++ } return dist }