basis_test.go raw

   1  package crypto
   2  
   3  import (
   4  	"testing"
   5  
   6  	"git.mleku.dev/mleku/dendrite/pkg/axiom"
   7  	"git.mleku.dev/mleku/dendrite/pkg/lattice"
   8  	"git.mleku.dev/mleku/dendrite/pkg/ratio"
   9  	"git.mleku.dev/mleku/dendrite/pkg/spore"
  10  )
  11  
  12  type tagConstraint struct{ tag string }
  13  
  14  func (c tagConstraint) Tag() string                { return c.tag }
  15  func (c tagConstraint) Admits(e axiom.Element) bool { return e.Type() == c.tag }
  16  
  17  func buildTestLattice(wordNodes, punctNodes int) *lattice.Lattice {
  18  	l := lattice.New()
  19  	var words, puncts []*lattice.Node
  20  	for range wordNodes {
  21  		n := l.AddNode([]axiom.Constraint{tagConstraint{"word"}})
  22  		words = append(words, n)
  23  	}
  24  	for range punctNodes {
  25  		n := l.AddNode([]axiom.Constraint{tagConstraint{"punct"}})
  26  		puncts = append(puncts, n)
  27  	}
  28  	// Ring within each type.
  29  	for i := range words {
  30  		l.Connect(words[i], words[(i+1)%len(words)])
  31  	}
  32  	for i := range puncts {
  33  		l.Connect(puncts[i], puncts[(i+1)%len(puncts)])
  34  	}
  35  	// Cross-connect.
  36  	if len(words) > 0 && len(puncts) > 0 {
  37  		l.Connect(words[0], puncts[0])
  38  	}
  39  	return l
  40  }
  41  
  42  func TestFromLattice(t *testing.T) {
  43  	l := buildTestLattice(10, 5)
  44  	b := FromLattice(l, ratio.FromInt(127))
  45  
  46  	if b.Dimension != 15 {
  47  		t.Errorf("Dimension = %d, want 15", b.Dimension)
  48  	}
  49  	if len(b.Tags) != 2 {
  50  		t.Errorf("Tags count = %d, want 2", len(b.Tags))
  51  	}
  52  	if b.TagCount("word") != 10 {
  53  		t.Errorf("word count = %d, want 10", b.TagCount("word"))
  54  	}
  55  	if b.TagCount("punct") != 5 {
  56  		t.Errorf("punct count = %d, want 5", b.TagCount("punct"))
  57  	}
  58  }
  59  
  60  func TestFromSporeRoundTrip(t *testing.T) {
  61  	l := buildTestLattice(8, 4)
  62  	s := spore.Extract(l)
  63  
  64  	b1 := FromLattice(l, ratio.FromInt(127))
  65  	b2 := FromSpore(s, ratio.FromInt(127))
  66  
  67  	if !b1.Equal(b2) {
  68  		t.Error("FromLattice and FromSpore should produce equal bases")
  69  	}
  70  }
  71  
  72  func TestBasisEqual(t *testing.T) {
  73  	l := buildTestLattice(6, 3)
  74  	b1 := FromLattice(l, ratio.FromInt(127))
  75  	b2 := FromLattice(l, ratio.FromInt(127))
  76  
  77  	if !b1.Equal(b2) {
  78  		t.Error("identical lattice should produce equal bases")
  79  	}
  80  
  81  	// Different modulus.
  82  	b3 := FromLattice(l, ratio.FromInt(251))
  83  	if b1.Equal(b3) {
  84  		t.Error("different modulus should produce unequal bases")
  85  	}
  86  }
  87  
  88  func TestBasisTagsSorted(t *testing.T) {
  89  	l := buildTestLattice(5, 5)
  90  	b := FromLattice(l, ratio.FromInt(127))
  91  
  92  	for i := 1; i < len(b.Tags); i++ {
  93  		if b.Tags[i] < b.Tags[i-1] {
  94  			t.Errorf("tags not sorted: %q comes after %q", b.Tags[i], b.Tags[i-1])
  95  		}
  96  	}
  97  }
  98