textmachine/eval/premise_review/premise_batch_test.go.txt

132 lines
4.1 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package terminology
import (
"encoding/json"
"fmt"
"os"
"sort"
"testing"
"textmachine/backend/internal/lang"
)
type pyDump struct {
Roster []struct {
Src string `json:"src"`
Type string `json:"type"`
Origin string `json:"origin"`
Freq int `json:"freq"`
Drafts [][]interface{} `json:"drafts"`
Ctx []string `json:"ctx"`
Evidence []string `json:"evidence"`
} `json:"roster"`
Blocks map[string]string `json:"blocks"`
Batches [][]string `json:"batches"`
Series map[string][]string `json:"series"`
BatchRunes int `json:"batch_runes"`
}
// TestPremisePythonRigMatchesEngine доказывает ИСПОЛНЕНИЕМ, что питон-риг пробы C
// (consilium_probe.block_of / batches_of) воспроизводит движковые RenderBatch/Batch.
func TestPremisePythonRigMatchesEngine(t *testing.T) {
raw, err := os.ReadFile("/home/ubuntu/projects/textmachine/eval/premise_review/py_batching.json")
if err != nil {
t.Fatal(err)
}
var d pyDump
if err := json.Unmarshal(raw, &d); err != nil {
t.Fatal(err)
}
cands := make([]Candidate, 0, len(d.Roster))
for _, r := range d.Roster {
c := Candidate{
Key: r.Src, Src: r.Src, Type: r.Type, Origin: Origin(r.Origin),
Freq: r.Freq, SinceCh: 0, Evidence: r.Evidence, KWIC: r.Ctx,
}
for _, v := range r.Drafts {
if len(v) != 2 {
t.Fatalf("draft shape %v", v)
}
c.Variants = append(c.Variants, Variant{
Dst: v[0].(string), Chunks: int(v[1].(float64)),
})
}
cands = append(cands, c)
}
// (1) поблочный рендер
blockMismatch := 0
for _, c := range cands {
got := RenderBatch([]Candidate{c})
want, ok := d.Blocks[c.Src]
if !ok {
t.Fatalf("нет питон-блока для %s", c.Src)
}
if got != want {
blockMismatch++
if blockMismatch <= 3 {
t.Errorf("БЛОК РАСХОДИТСЯ %s:\n--- go ---\n%s\n--- py ---\n%s", c.Src, got, want)
}
}
}
t.Logf("блоков сверено: %d, расхождений: %d", len(cands), blockMismatch)
// (2) движок ключ-сортирует кандидатов ДО Batch (terminology.go:212 Merge) — риг делает то же.
sort.Slice(cands, func(i, j int) bool { return cands[i].Key < cands[j].Key })
// (2а) серии движок выводит DetectSeries из язык-слоя, а риг задаёт руками. Сверяем группировки.
sEnabled, headFinal := lang.SeriesMorphology("zh")
auto := DetectSeries(cands, SeriesParams{Enabled: sEnabled, HeadFinal: headFinal})
hand := map[string]int{}
i := 0
for _, name := range []string{"zhuan", "deng", "dengzizhi", "jie"} {
i++
for _, m := range d.Series[name] {
hand[m] = i
}
}
groups := func(m map[string]int) map[int][]string {
g := map[int][]string{}
for _, c := range cands {
if id := m[c.Key]; id != 0 {
g[id] = append(g[id], c.Key)
}
}
return g
}
ga, gh := groups(auto), groups(hand)
t.Logf("DetectSeries(zh, enabled=%v headFinal=%v): %d серий", sEnabled, headFinal, len(ga))
for id, mem := range ga {
t.Logf(" движок серия %d: %v", id, mem)
}
for id, mem := range gh {
t.Logf(" риг серия %d: %v", id, mem)
}
got := Batch(cands, d.BatchRunes, auto)
gotComp := make([][]string, 0, len(got))
for _, b := range got {
row := make([]string, 0, len(b))
for _, c := range b {
row = append(row, c.Src)
}
gotComp = append(gotComp, row)
}
gj, _ := json.Marshal(gotComp)
pj, _ := json.Marshal(d.Batches)
if string(gj) != string(pj) {
t.Errorf("СОСТАВ БАТЧЕЙ РАСХОДИТСЯ:\n go=%s\n py=%s", gj, pj)
} else {
sizes := ""
for _, b := range gotComp {
sizes += fmt.Sprintf(" %d", len(b))
}
t.Logf("состав батчей совпал: %d батчей, размеры%s", len(gotComp), sizes)
}
// (3) рунный размер каждого батча против потолка
for k, b := range got {
t.Logf("батч %d: %d кандидатов, %d рун (потолок %d)", k, len(b), BatchRunes(b), d.BatchRunes)
}
}