Skip to content

Reproducible word counts and account selection

Corpus counts describe a selected text view and population. They do not establish that a lemma, restored reading, or accounting interpretation is correct.

frequencies = corpus.word_frequencies(view="normalized")
print(frequencies[:10])             # ordinary (word, count) pairs
print(frequencies.metadata)         # normalization, denominator, exclusions
print(frequencies.cite())           # source plus counting choices

lemmas = corpus.word_frequencies(view="lemma", statuses=["certain"])
documents = corpus.word_frequencies(view="lemma", count_unit="document")

The existing methods accept these choices:

Option Meaning
view="surface" Exact Token.text; case and canonical Unicode spelling remain distinct.
view="normalized" NFC, lowercase, final-sigma folding, then NFC. Accents, breathings, and iota subscript remain distinct. This is a comparison key, not the token's editorial form_state.normalized.
view="lemma" Apply the same normalization to the existing annotations["lemma"]. Missing, null, empty, and nonstring lemmas are excluded. No analyzer runs and no surface-form fallback is invented.
count_unit="token" Every qualifying lexical token occurrence.
count_unit="document" Each document once per word, irrespective of repetition within it.
statuses=["certain"] Include a whole token only if its reading and every typed editorial segment are certain. Omitted means all statuses. Use combinations such as ["certain", "restored"] for a sensitivity analysis.

Only TokenKind.WORD enters lexical counts. Punctuation, numerals, foreign UNKNOWN tokens, and structured speaker-label tokens are excluded. Selection does not remove the excluded evidence from the corpus. Legacy datasets that mark a speaker label as WORD still count it; audit the source's classification.

word_frequencies() remains a list-compatible result, with the original defaults of exact surface spelling and token frequency. Its metadata states the denominator: represented word tokens for token frequency, or all documents in the selected corpus for document frequency (including empty documents and documents with no lemma-bearing tokens). It separately reports selected and represented word tokens, status exclusions, missing lemmas, and recorded lemma-source labels. Source labels are provenance, not accuracy measurements. Treat unspecified provenance as unknown.

from aegean.analysis import FilterRow

result = corpus.query(
    [FilterRow("site-is", "Athens"), FilterRow("word-prefix", "λόγ")],
    output="words", view="normalized", count_unit="token", statuses=["certain"],
)
print(result.words, result.metadata, result.cite())

Compound queries keep their original default of document frequency. Their denominator covers the population matching the inscription-scope filters, before word-scope predicates narrow the listed words. result.metadata records that scope. Explicit views share the frequency-table keys and uncertainty rules. Omitting view preserves legacy uppercase text predicates, literal ins-contains-word and cooccurrence predicates, and separate surface keys; the metadata records that legacy predicate normalization. Script-specific sign-label and wildcard predicates retain their established rules. Cooccurrence predicates use the selected lexical view across the source corpus, before inscription filters; query metadata records this scope when applicable.

SQLite aegean.db.search(path, text, view="normalized") shares the explicit lexical views and status selection. It returns the original surface text in its hit tuples, including when matching a lemma. Missing lemmas cannot match. Explicit exact searches can use an explicitly built lexical index: aegean.db.build_lexical_index(path). An absent or stale index falls back to the token-table scan; building again refreshes it. Token edits invalidate the index, and neither search nor status inspection writes to the database. Substring queries retain their scan behavior. Omitting both view and status selection retains the existing indexed, case-insensitive search across all token kinds. This legacy path preserves diacritics but does not equate NFC/NFD variants. Token search is literal equality; mode="substring" is explicit.

CLI examples:

aegean stats corpus.json --view lemma --statuses certain --details --json
aegean stats corpus.json --count-unit document --details --json
aegean query corpus.json --view normalized --output-kind words --count-unit token --json
aegean db index corpus.db
aegean db search corpus.db λόγος --view lemma --statuses certain --json
aegean balance lineara HT13 --exact --strict --json

The default stats --json keeps its original row-list shape. --details or a nondefault view/count/status selection emits an envelope containing the rows, population metadata, and citation. Query JSON and MCP query_corpus always include metadata. MCP accepts the same view, count-unit, and status choices.

Exact arithmetic and eligibility

balance_check(document) retains the legacy arithmetic cutoff of an absolute floating-point difference below 1e-6. Every check now also exposes exact_difference as a fractions.Fraction and exact_balances. Written integer and fraction values are summed rationally, including subtotal/grand-total sections. balance_check(document, exact=True) uses rational equality for balances. Approximate quantities are still read at the edition's face value; rational arithmetic does not turn an approximate reading into a certain one.

is_checkable_account and checkable_accounts retain the exploratory teaching rule: intact text and at least one total within max(1, tolerance * abs(stated_total)). tolerance=0 therefore retains the legacy absolute-one allowance. Use exact=True for no allowance. Typed noncertain segments also make a document ineligible, even if its overall token status is certain.

HT13 has stated 130½, computed 131, and rational discrepancy 1/2. It remains tolerance-eligible but is not exactly eligible. The shared CLI/MCP/TUI balance rows display the discrepancy and expose both eligibility states; account eligibility does not mean that every total balances. --strict --exact exits unsuccessfully when a checked total lacks rational equality. None of these labels validates section boundaries, disputed signs, the edition's reading, or metrology.

Evidence still needed for scholarly validation

The constructed reference corpus in tests/test_research_semantics.py is hand counted to test these contracts: canonical/case/diacritic variants, missing lemmas, partial uncertain and restored forms, repeated tokens versus document frequency, empty documents, and exact fractional accounting. It is not ancient-text gold and does not measure lemma-search precision or philological correctness.

Further research validation requires independent material and specialist labor:

  • Statistics: select a small published corpus claim and its editions; annotate the relevant lemma hits and omissions; report precision/recall and uncertainty sensitivity. Audit duplicate editions and author/work sampling. Existing document bootstrap helpers can resample supplied author/work clusters through their sequence interface, but no default automatically supplies author balance, clustered inference, or a multiple-comparison correction.
  • Geography/chronology: the current gazetteer uses approximate WGS84 site points, and missing sites are omitted. Audit omitted sites and findspot versus origin before interpreting a map. Date ranges, coordinate uncertainty distributions, spatial sampling bias, and uncertainty-aware cluster sensitivity require curated source data and additional analysis; current maps do not model them.
  • Aegean and undeciphered scripts: audit tablet editions for sign readings, fractions, subtotal boundaries, and damaged/restored quantities, including negative cases and competing readings. Rational arithmetic can test an entered interpretation reproducibly; it cannot adjudicate that interpretation. Linear B dossiers, Cypriot analyses, allograph assumptions, and phonetic-comparison bias need specialists and independent edition-linked annotations.

These are feasible study designs, not completed expert audits or new gold scores.