Answer stability round 1: readsRow counts a selector, checkNameReads defers to refuseSingleRead, climbed names the child's row, and geo-se.py owns its big-city reading

This commit is contained in:
2026-10-07 01:12:54 +02:00
committed by Lillem4n
parent a7101394f5
commit ee25212618
4 changed files with 9 additions and 7 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ NVDB_PAGE = 50000
OUT = Path(__file__).resolve().parent.parent / "data" / "geo" / "SE" OUT = Path(__file__).resolve().parent.parent / "data" / "geo" / "SE"
CACHE = Path(__file__).resolve().parent / "cache" CACHE = Path(__file__).resolve().parent / "cache"
TIMEZONE = "Europe/Stockholm" TIMEZONE = "Europe/Stockholm"
# The big cities the delivery-digit rule excepts: docs/research/research-geo-se.md, postnummer Structure. # This script's reading of the "exceptions in big cities" in docs/research/research-geo-se.md, postnummer Structure.
ONE_POSITION = {"Stockholm", "Göteborg", "Malmö"} ONE_POSITION = {"Stockholm", "Göteborg", "Malmö"}
# A tätort's floor: "minst 200 invånare", docs/research/research-geo-se.md, Ortnamn. # A tätort's floor: "minst 200 invånare", docs/research/research-geo-se.md, Ortnamn.
UNMATCHED_POPULATION = 200 UNMATCHED_POPULATION = 200
+2 -2
View File
@@ -9,8 +9,8 @@ import (
"github.com/larvit/fejkdata/internal/invariant" "github.com/larvit/fejkdata/internal/invariant"
) )
// checkNameReads refuses each binding of t read only once, a read of a name inside the field bound // checkNameReads refuses each binding of t that refuseSingleRead refuses, a read of a name inside
// to it, and a read {n} beside {n.w} where n's pick renders w twice. // the field bound to it, and a read {n} beside {n.w} where n's pick renders w twice.
func checkNameReads(label string, t *template, names resolvedNames) error { func checkNameReads(label string, t *template, names resolvedNames) error {
for _, tok := range t.tokens { for _, tok := range t.tokens {
if tok.Kind != grammar.NameBind { if tok.Kind != grammar.NameBind {
+3 -2
View File
@@ -185,8 +185,9 @@ func probePath(n node, tail []string, steps []pathStep) ([]pathStep, error) {
// For a read through a name, memo keeps the variant drawn at each of levels, so paths sharing a // For a read through a name, memo keeps the variant drawn at each of levels, so paths sharing a
// prefix share it. It returns the leaf and the pins its row is in. // prefix share it. It returns the leaf and the pins its row is in.
func drawSteps(s *drawstate.State, n node, steps []pathStep, pins *pinSet, memo *drawMemo, levels []pickKey) (node, *pinSet) { func drawSteps(s *drawstate.State, n node, steps []pathStep, pins *pinSet, memo *drawMemo, levels []pickKey) (node, *pinSet) {
// climbed is the table a ".." stepped up to. The next step down from it draws its row afresh, // climbed is the table a ".." stepped up to. The next step down from it draws the child's row
// into pins of its own, which memo shares with every path of the pick stepping down there. // afresh, into pins holding only the rows from climbed up, which memo shares with every path
// of the pick stepping down there.
var climbed *rowsTable var climbed *rowsTable
for _, st := range steps { for _, st := range steps {
if c, ok := n.(*choice); ok { if c, ok := n.(*choice); ok {
+3 -2
View File
@@ -265,13 +265,14 @@ func (t *table) route(tail []string, descended bool) (tableRoute, error) {
if err != nil { if err != nil {
return tableRoute{}, err return tableRoute{}, err
} }
selected, readsRow := sel != "", descended || len(tail) > 0 selected := sel != ""
readsRow := selected || descended || len(tail) > 0
// A selector further down pins this table by ancestry; drawing first could draw a row the // A selector further down pins this table by ancestry; drawing first could draw a row the
// selector is not inside. // selector is not inside.
pinnedBelow := grammar.HasSelector(tail) pinnedBelow := grammar.HasSelector(tail)
r := tableRoute{sel: sel, draw: !selected && readsRow && !pinnedBelow} r := tableRoute{sel: sel, draw: !selected && readsRow && !pinnedBelow}
switch { switch {
case !selected && !readsRow: case !readsRow:
r.next = t r.next = t
case len(tail) == 0: case len(tail) == 0:
r.next = t.rowNode r.next = t.rowNode