Ablauf der Filterung
Neun Stufen von der Frage zur Evidenzobjektmenge, und was sie am Kármán-Nachlass messen
Die Partitur famulus_constraint_raum_agent bestimmt den Evidenzraum, liest aus der DTD die möglichen Attribute, nimmt den Kontext als Teilbaum auf, klassifiziert die Frage, führt beides zum Suchbaum zusammen, kompiliert ihn zu einer DuckDB-Anweisung, führt sie aus, bewertet die Menge, fragt gegebenenfalls nach, und beweist, dass kein Brief ohne Grund fehlt.
Die Stufen
| Stufe | Operation | was sie liefert | |
|---|---|---|---|
| 1 | raum | famulus:evidenz_filter_raum |
Collection, Objektzahlen, Gate gate:fx, Lücken der Bereitschaft |
| 2 | schemabaum | …_filter_schemabaum |
die Blätter, die die Klassifikation verwenden darf |
| 3 | kontextbaum | …_filter_kontextbaum |
der Suchbaum der Vorfrage dieser Sitzung, der stehende Baum aus dem Gedächtnis der Collection |
| 4 | fragebaum | …_filter_fragebaum |
ein Modellaufruf über den Blättern, dann der Fast Index je Wert |
| 5 | merge | …_filter_merge |
Suchbaum; Ersetzungen, gestrichene Blätter, Widersprüche |
| 6 | sql | …_filter_sql |
eine Anweisung, ohne Semikolon |
| 7 | ausfuehren | …_filter_ausfuehren |
Briefe, Evidenzobjekte mit Text, Trichter, Verbuchung jedes Briefs, Projektion |
| 8 | bewerten | …_filter_bewerten |
brauchbar, zu groß, unspezifisch, leer oder widersprüchlich; die Rückfrage |
| 9 | beweis | …_filter_beweis |
Zertifikat famulus-raum/1 |
Die Evaluatoren der Partitur prüfen, dass jedes Textblatt die Unbekannt-Regel des Textes trägt und kein Kopf- oder Inhaltsblatt sie trägt, dass jeder Cluster ein positives Blatt hat, dass die Anweisung eine ist und dass der Trichter von Ebene zu Ebene nicht wächst.
Kontext: eine Frage, die an die vorige anschließt
Welche Briefe schrieb Ludwig Prandtl? Dann: Welches Thema hat ein Brief dieser Person an Theodor von Kármán? Die zweite Frage legt nur den Empfänger neu fest und fragt nach dem Thema; dass „diese Person“ Prandtl ist, steht im Kontextbaum, nicht in der Frage. Die Klassifikation meldet bezug_vorfrage, und der Merge nimmt das Blatt der Vorfrage auf:
| Frage | Kontext | Blätter (Quelle) | Briefe | häufigste Themen |
|---|---|---|---|---|
| Welche Briefe schrieb Ludwig Prandtl? | — | kopf/korrespondenz/absender = Ludwig Prandtl (frage) |
6.908 | — |
| Welches Thema hat ein Brief dieser Person an Theodor von Kármán? | sitzung | kopf/korrespondenz/absender = Ludwig Prandtl (kontext); kopf/korrespondenz/empfaenger = Theodor von Kármán (frage) |
6.873 | Aerodynamics and Fluid Mechanics (3), Turbulence (3), Boundary layers (2) |
| Welches Thema hat ein Brief dieser Person an Theodor von Kármán? (verfeinert: nur verzeichneter Absender) | — | — | 5 | Aerodynamics and Fluid Mechanics (3), Turbulence (3), Boundary layers (2) |
Bindet die neue Frage dasselbe Blatt neu (und von Einstein?), ersetzt ihr Wert den des Kontexts, und die Ersetzung steht im Ergebnis. Der Kontextbaum kommt aus dem Protokoll der Sitzung (~/Library/Application Support/famulus-proof/suchbaeume.jsonl) oder aus dem Schlüssel kontextbaum im agent_context.json der Collection. Die Textchronik der Anfragen von ai-query hält Fragen, keine Bäume, und ist keine Quelle.
Die Anweisung
Der Suchbaum wird eine einzige DuckDB-Anweisung (evidenzraum/theorie.py). Ihre CTEs folgen den Ebenen; hier für Kármán und Hitler:
WITH
b0 AS (...), -- Kopfblatt Absender: erfüllt / verletzt / unentschieden je Brief (fx_post)
o1_hit AS (...), -- Textblatt Nennung: Objekte mit P007304 (NER) oder einer Namensform (Wortform, Fußnote)
o1_ss AS (...), -- die Sätze dieser Treffer
o1_v AS (...), -- jedes Namensvorkommen mit seinen Faktoren und seiner Gebrauchsklasse
o1_k AS (...), -- je Satz: eine akzeptierte Klasse? nur offene? nur Eponym, Beiwort, Zitat?
o1 AS (...), -- Entscheidung je Objekt mit Grund („Gebrauch person: Handelnder“)
b1 AS (...), -- Entscheidung je Brief: Treffer, sonst verletzt, ohne Text unentschieden (fx_deck)
k0 AS (...), -- Briefe nach dem Kopf
i0 AS (...), -- davon nach dem Inhalt
t0 AS (...), -- davon nach dem Text
ob0 AS (...), -- die Evidenzobjekte in diesen Briefen (fx_enthalten)
raum, obj, entscheid, -- Vereinigung der Cluster, Objekte, alle Entscheidungen
zaehl, erste, buchung, -- Zählung je Blatt, erstes ausschließendes Blatt, Verbuchung jedes Briefs
trichter, objtext -- Briefe je Ebene, Texte der Objekte
SELECT briefe, n_objekte, tragend, objekte, zaehlung, trichter, gruende, buchung, projektion …WITH b0 AS MATERIALIZED (
SELECT l.traeger_id,
CASE WHEN h.traeger_id IS NOT NULL THEN 'erfuellt' WHEN k.traeger_id IS NULL THEN 'unentschieden'
ELSE 'verletzt' END AS e,
CASE WHEN h.traeger_id IS NOT NULL THEN 'verzeichnet: ' || 'Theodor von Kármán'
WHEN k.traeger_id IS NULL THEN 'nicht verzeichnet'
ELSE 'verzeichnet ist ein anderer Wert als ' || 'Theodor von Kármán' END AS w
FROM fx_traeger l LEFT JOIN (SELECT DISTINCT substr(obj_id, 3) AS traeger_id FROM fx_post WHERE attr = 'person' AND rolle = 'sender' AND art = 'brief' AND schluessel IN ('P000224')) h USING (traeger_id) LEFT JOIN (SELECT DISTINCT substr(obj_id, 3) AS traeger_id FROM fx_post WHERE attr = 'person' AND rolle = 'sender' AND art = 'brief') k USING (traeger_id)),
o1_hit AS MATERIALIZED (
SELECT obj_id, kanal FROM fx_post
WHERE attr = 'person' AND rolle = 'genannt' AND art IN ('satz', 'fussnote') AND schluessel IN ('P007304')
UNION ALL
SELECT obj_id, 'lemma' AS kanal FROM fx_post
WHERE attr = 'lemma' AND rolle = 'text' AND art IN ('satz', 'fussnote') AND schluessel IN ('Hitler|de', 'Hitler|en', 'HITLER|en')
UNION ALL
SELECT obj_id, art AS kanal FROM fx_post
WHERE attr = 'form' AND rolle = 'text' AND art IN ('fussnote') AND schluessel IN ('hitler')
),
o1_hh AS (SELECT obj_id, list(DISTINCT kanal ORDER BY kanal) AS kanaele FROM o1_hit GROUP BY obj_id),
o1_ss AS (SELECT split_part(substr(obj_id, 3), '#', 1) AS doc_id, CAST(split_part(split_part(substr(obj_id, 3), '#', 2), '.', 1) AS BIGINT) AS pidx, CAST(split_part(split_part(substr(obj_id, 3), '#', 2), '.', 2) AS BIGINT) AS sent_idx FROM o1_hh WHERE starts_with(obj_id, 'S:')),
o1_v AS (
SELECT 'S:' || doc_id || '#' || pidx || '.' || sent_idx AS obj_id,
CASE WHEN (FRE) THEN 'andere' WHEN (ZIT) OR (LIT) THEN 'zitat' WHEN (BEI) THEN 'beiwort' WHEN (KOM) OR (DOP) THEN 'eponym' WHEN (POS) THEN 'urheber' WHEN (ZIEL) OR (ARG) OR (NAM) OR (KOO) OR (NER) THEN 'person' ELSE 'offen' END AS klasse, CASE WHEN (FRE) THEN 'andere: Registerlink andere Person' WHEN (ZIT) THEN 'zitat: Zitatumgebung' WHEN (LIT) THEN 'zitat: Titelangabe' WHEN (BEI) THEN 'beiwort: Beiwort' WHEN (KOM) THEN 'eponym: Kompositumglied' WHEN (DOP) THEN 'eponym: Doppelname' WHEN (POS) THEN 'urheber: Urheber' WHEN (ZIEL) THEN 'person: Registerlink Ziel' WHEN (ARG) THEN 'person: Handelnder' WHEN (NAM) THEN 'person: Namensgefüge' WHEN (KOO) THEN 'person: Reihung' WHEN (NER) THEN 'person: Personenspanne' ELSE 'keine Bedingung trifft zu' END AS bedingung
FROM (WITH g_ks AS MATERIALIZED (SELECT DISTINCT doc_id, pidx, sent_idx FROM (SELECT * FROM o1_ss)),
g_tk AS MATERIALIZED (SELECT t.*, s.lang FROM stz.stz_tokens t JOIN g_ks USING (doc_id, pidx, sent_idx) JOIN stz.stz_sentences s USING (doc_id, pidx, sent_idx)),
g_fe AS MATERIALIZED (SELECT DISTINCT x.doc_id, x.pidx, x.sent_idx FROM stz.stz_feats x JOIN g_ks USING (doc_id, pidx, sent_idx)
WHERE x.feat = 'VerbForm' AND x.val = 'Fin'),
g_en AS MATERIALIZED (SELECT x.* FROM stz.stz_entities x JOIN g_ks USING (doc_id, pidx, sent_idx) WHERE x.ent_type IN ('PER', 'PERSON')),
g_m AS MATERIALIZED (
SELECT m.doc_id, m.pidx, m.sent_idx, e.ind_id, e.canonical
FROM fq_mentions m JOIN g_ks USING (doc_id, pidx, sent_idx) JOIN fq_entities e ON e.ent_id = m.ent_id
WHERE e.ind_id IS NOT NULL AND e.kind = 'person'),
g_nk AS MATERIALIZED (
SELECT DISTINCT x.canonical, f.lemma || '|' || f.lang AS lk
FROM (SELECT DISTINCT canonical FROM g_m) x
JOIN fx_lemma_form f ON strip_accents(f.form) = strip_accents(lower(trim(split_part(x.canonical, ',', 1))))),
g_reg AS (
SELECT m.doc_id, m.pidx, m.sent_idx, bool_or(list_contains(['P007304']::VARCHAR[], m.ind_id)) AS ziel,
list(DISTINCT nk.lk) FILTER (WHERE nk.lk IS NOT NULL AND NOT list_contains(['P007304']::VARCHAR[], m.ind_id))
AS andere_klassen
FROM g_m m LEFT JOIN g_nk nk USING (canonical) GROUP BY ALL)
SELECT t.doc_id, t.pidx, t.sent_idx, t.tid, t.form, t.lemma, t.lang, t.upos, t.deprel, h.lemma AS kopf,
coalesce(t.upos = 'PROPN', false) AS EIG,
coalesce((t.deprel = 'amod' OR t.upos = 'ADJ'), false) AS BEI,
coalesce((t.deprel = 'compound' AND (h.upos NOT IN ('PROPN', 'PRON') OR (h.upos = 'PROPN' AND h.deprel IN ('compound', 'flat', 'flat:name') AND hh.upos IN ('NOUN', 'VERB')))), false) AS KOM,
coalesce((regexp_matches(t.form, '^[[:upper:]][[:alpha:]]+-[[:upper:]]') OR regexp_matches(t.form, '-$') OR EXISTS (SELECT 1 FROM g_tk x JOIN g_tk y ON y.doc_id = x.doc_id AND y.pidx = x.pidx AND y.sent_idx = x.sent_idx WHERE x.doc_id = t.doc_id AND x.pidx = t.pidx AND x.sent_idx = t.sent_idx AND x.form IN ('-', '–') AND ((x.tid = t.tid + 1 AND y.tid = t.tid + 2) OR (x.tid = t.tid - 1 AND y.tid = t.tid - 2)) AND y.upos = 'PROPN')), false) AS DOP,
coalesce((t.deprel LIKE 'nmod%' AND h.upos = 'NOUN'), false) AS POS,
coalesce((h.upos IN ('VERB', 'AUX') AND (t.deprel LIKE 'nsubj%' OR t.deprel IN ('obj', 'iobj') OR t.deprel LIKE 'obl%')), false) AS ARG,
coalesce((t.deprel IN ('flat', 'flat:name', 'appos') OR EXISTS (SELECT 1 FROM g_tk x WHERE x.doc_id = t.doc_id AND x.pidx = t.pidx AND x.sent_idx = t.sent_idx AND x.head = t.tid AND x.deprel IN ('flat', 'flat:name', 'appos'))), false) AS NAM,
coalesce((t.deprel = 'conj' AND h.upos IN ('PROPN', 'PRON') OR EXISTS (SELECT 1 FROM g_tk x WHERE x.doc_id = t.doc_id AND x.pidx = t.pidx AND x.sent_idx = t.sent_idx AND x.head = t.tid AND x.deprel = 'conj' AND x.upos IN ('PROPN', 'PRON'))), false) AS KOO,
coalesce(EXISTS (SELECT 1 FROM g_en x WHERE x.doc_id = t.doc_id AND x.pidx = t.pidx AND x.sent_idx = t.sent_idx AND list_contains(string_split(trim(regexp_replace(lower(strip_accents(x.text)), '[^a-z0-9]+', ' ', 'g')), ' '), string_split(trim(regexp_replace(lower(strip_accents(t.form)), '[^a-z0-9]+', ' ', 'g')), ' ')[1])), false) AS NER,
coalesce((NOT EXISTS (SELECT 1 FROM g_fe x WHERE x.doc_id = t.doc_id AND x.pidx = t.pidx AND x.sent_idx = t.sent_idx) AND EXISTS (SELECT 1 FROM g_tk x WHERE x.doc_id = t.doc_id AND x.pidx = t.pidx AND x.sent_idx = t.sent_idx AND x.upos = 'NUM')), false) AS ZIT,
coalesce((NOT EXISTS (SELECT 1 FROM g_fe x WHERE x.doc_id = t.doc_id AND x.pidx = t.pidx AND x.sent_idx = t.sent_idx) AND EXISTS (SELECT 1 FROM g_tk x WHERE x.doc_id = t.doc_id AND x.pidx = t.pidx AND x.sent_idx = t.sent_idx AND x.upos = 'PUNCT' AND x.form = ':' AND x.tid > t.tid AND x.tid <= t.tid + 8)), false) AS LIT,
coalesce(coalesce(g_reg.ziel, false), false) AS ZIEL,
coalesce((NOT coalesce(g_reg.ziel, false) AND list_contains(coalesce(g_reg.andere_klassen, []), t.lemma || '|' || coalesce(t.lang, ''))), false) AS FRE,
coalesce(t.deprel = 'root', false) AS WUR
FROM g_tk t
LEFT JOIN g_tk h ON h.doc_id = t.doc_id AND h.pidx = t.pidx AND h.sent_idx = t.sent_idx AND h.tid = t.head
LEFT JOIN g_tk hh ON hh.doc_id = h.doc_id AND hh.pidx = h.pidx AND hh.sent_idx = h.sent_idx AND hh.tid = h.head
LEFT JOIN g_reg ON g_reg.doc_id = t.doc_id AND g_reg.pidx = t.pidx AND g_reg.sent_idx = t.sent_idx
WHERE list_contains(['Hitler|de', 'Hitler|en', 'HITLER|en']::VARCHAR[], t.lemma || '|' || coalesce(t.lang, '')))),
o1_k AS (
SELECT obj_id, bool_or(list_contains(['person', 'urheber']::VARCHAR[], klasse)) AS ok, bool_or(klasse = 'offen') AS offen,
string_agg(DISTINCT klasse, ', ' ORDER BY klasse) AS klassen,
min(bedingung) FILTER (WHERE list_contains(['person', 'urheber']::VARCHAR[], klasse)) AS bed
FROM o1_v GROUP BY obj_id),
o1 AS MATERIALIZED (
SELECT h.obj_id, h.kanaele,
CASE WHEN k.ok THEN 'erfuellt' WHEN k.offen THEN 'unentschieden'
WHEN k.obj_id IS NOT NULL THEN 'verletzt'
WHEN list_contains(h.kanaele, 'ner_linked') THEN 'erfuellt'
ELSE 'unentschieden' END AS e,
CASE WHEN k.ok THEN 'Gebrauch ' || k.bed
WHEN k.offen THEN 'Gebrauch nicht entschieden'
WHEN k.obj_id IS NOT NULL THEN 'Name nur als ' || k.klassen
WHEN list_contains(h.kanaele, 'ner_linked') THEN 'Registerverknüpfung ohne Wortvorkommen'
WHEN starts_with(h.obj_id, 'S:') THEN 'Lemmatreffer ohne lesbares Vorkommen'
ELSE 'Objekt ohne Satzanalyse' END AS w
FROM o1_hh h LEFT JOIN o1_k k USING (obj_id)),
b1 AS MATERIALIZED (
SELECT l.traeger_id,
CASE WHEN p.n_ok > 0 THEN 'erfuellt' WHEN p.n_uns > 0 THEN 'unentschieden'
WHEN d.traeger_id IS NULL THEN 'unentschieden' ELSE 'verletzt' END AS e,
CASE WHEN p.n_ok > 0 THEN 'Treffer in ' || p.n_ok || ' Objekt(en)'
WHEN p.n_uns > 0 THEN 'nur unsichere Lesung in ' || p.n_uns || ' Objekt(en)'
WHEN d.traeger_id IS NULL THEN 'kein Text der Objektarten ' || 'satz, fussnote'
WHEN p.n_aus > 0 THEN p.w_aus
ELSE 'kein Treffer im Text' END AS w
FROM fx_traeger l
LEFT JOIN (SELECT fb.traeger_id,
count(*) FILTER (WHERE o.e = 'erfuellt') AS n_ok,
count(*) FILTER (WHERE o.e = 'unentschieden') AS n_uns,
count(*) FILTER (WHERE o.e = 'verletzt') AS n_aus,
min(o.w) FILTER (WHERE o.e = 'verletzt') AS w_aus
FROM o1 o JOIN fx_enthalten fb USING (obj_id) GROUP BY fb.traeger_id) p USING (traeger_id)
LEFT JOIN (SELECT DISTINCT traeger_id FROM fx_deck WHERE art IN ('satz', 'fussnote')) d USING (traeger_id)),
k0 AS MATERIALIZED (SELECT traeger_id FROM fx_traeger JOIN b0 x0 USING (traeger_id) WHERE x0.e <> 'verletzt'),
i0 AS MATERIALIZED (SELECT traeger_id FROM k0),
t0 AS MATERIALIZED (SELECT traeger_id FROM i0 JOIN b1 x0 USING (traeger_id) WHERE x0.e <> 'verletzt'),
ob0 AS (
SELECT o.obj_id, fb.traeger_id, o.kanaele FROM (SELECT obj_id, kanaele FROM o1 WHERE e <> 'verletzt') o JOIN fx_enthalten fb USING (obj_id) JOIN t0 USING (traeger_id)),
raum AS MATERIALIZED (SELECT DISTINCT traeger_id FROM (SELECT traeger_id FROM t0)),
obj AS MATERIALIZED (SELECT obj_id, list(DISTINCT traeger_id ORDER BY traeger_id) AS traeger, list_distinct(flatten(list(kanaele))) AS kanaele, list(DISTINCT cluster) AS cluster FROM (SELECT obj_id, traeger_id, kanaele, 0 AS cluster FROM ob0) GROUP BY obj_id),
entscheid AS (SELECT traeger_id, 'b1' AS knoten, 'kopf' AS ebene, 0 AS rang, e, w, false AS negiert, false AS streng FROM b0 UNION ALL SELECT traeger_id, 'b2' AS knoten, 'text' AS ebene, 2001 AS rang, e, w, false AS negiert, false AS streng FROM b1),
zaehl AS (
SELECT knoten, any_value(ebene) AS ebene, min(rang) AS rang,
count(*) FILTER (WHERE e = 'erfuellt') AS erfuellt,
count(*) FILTER (WHERE e = 'unentschieden') AS unentschieden,
count(*) FILTER (WHERE e = 'verletzt') AS verletzt
FROM entscheid GROUP BY knoten),
erste AS (
SELECT traeger_id, arg_min(struct_pack(knoten := knoten, w := w), rang) AS erste
FROM entscheid WHERE (NOT negiert AND e = 'verletzt') OR (negiert AND e = 'erfuellt')
OR (streng AND e = 'unentschieden')
GROUP BY traeger_id),
buchung AS (
SELECT l.traeger_id,
CASE WHEN r.traeger_id IS NOT NULL THEN 'raum' ELSE 'aus' END AS raum,
CASE WHEN r.traeger_id IS NOT NULL THEN NULL
ELSE coalesce(e.erste.knoten, 'einheit') END AS ausgeschlossen_durch,
CASE WHEN r.traeger_id IS NOT NULL THEN NULL
ELSE coalesce(e.erste.w, 'kein Objekt erfüllt die Textblätter gemeinsam (Einheit Satz)') END AS grund
FROM fx_traeger l LEFT JOIN raum r USING (traeger_id) LEFT JOIN erste e USING (traeger_id)),
trichter AS (SELECT 0 AS cluster, (SELECT count(*) FROM fx_traeger) AS alle, (SELECT count(*) FROM k0) AS kopf,
(SELECT count(*) FROM i0) AS inhalt, (SELECT count(*) FROM t0) AS text,
(SELECT count(DISTINCT obj_id) FROM ob0) AS objekte),
objsel AS MATERIALIZED (SELECT * FROM obj ORDER BY obj_id LIMIT 300),
objtext AS (
SELECT o.obj_id, 'satz' AS art, o.traeger, o.kanaele, s.text
FROM (SELECT *, split_part(substr(obj_id, 3), '#', 1) AS doc_id, CAST(split_part(split_part(substr(obj_id, 3), '#', 2), '.', 1) AS BIGINT) AS pidx, CAST(split_part(split_part(substr(obj_id, 3), '#', 2), '.', 2) AS BIGINT) AS sent_idx FROM objsel WHERE starts_with(obj_id, 'S:')) o
JOIN stz.stz_sentences s ON s.doc_id = o.doc_id AND s.pidx = o.pidx AND s.sent_idx = o.sent_idx
UNION ALL
SELECT o.obj_id, 'absatz', o.traeger, o.kanaele, a.text
FROM (SELECT *, split_part(substr(obj_id, 3), '#', 1) AS doc_id, CAST(split_part(substr(obj_id, 3), '#', 2) AS BIGINT) AS pidx, CAST(split_part(substr(obj_id, 3), '#', 3) AS BIGINT) AS par_idx FROM objsel WHERE starts_with(obj_id, 'A:')) o
JOIN fq_paragraphs a ON a.doc_id = o.doc_id AND a.pidx = o.pidx AND a.par_idx = o.par_idx
UNION ALL
SELECT o.obj_id, 'fussnote', o.traeger, o.kanaele, f.text
FROM objsel o JOIN (SELECT obj_id, src_rowid FROM fx_objekt WHERE art = 'fussnote') x USING (obj_id)
JOIN fq_footnotes f ON f.rowid = x.src_rowid
UNION ALL
SELECT o.obj_id, x.art, o.traeger, o.kanaele, NULL
FROM objsel o JOIN (SELECT obj_id, art FROM fx_objekt WHERE art IN ('brief', 'seite', 'abbildung', 'dokument')) x
USING (obj_id))
SELECT
(SELECT list(traeger_id ORDER BY traeger_id) FROM raum) AS traeger_raum,
(SELECT count(*) FROM obj) AS n_objekte,
(SELECT list(DISTINCT l ORDER BY l) FROM (SELECT unnest(traeger) AS l FROM obj)) AS tragend,
(SELECT list(struct_pack(art := art, n := n) ORDER BY art)
FROM (SELECT x.art, count(*) AS n FROM obj JOIN fx_objekt x USING (obj_id) GROUP BY x.art)) AS objektarten,
(SELECT list(struct_pack(obj_id := obj_id, art := art, traeger := traeger, kanaele := kanaele, text := text)
ORDER BY obj_id) FROM objtext) AS objekte,
(SELECT list(struct_pack(knoten := knoten, ebene := ebene, erfuellt := erfuellt,
unentschieden := unentschieden, verletzt := verletzt) ORDER BY rang) FROM zaehl) AS zaehlung,
(SELECT list(struct_pack(cluster := cluster, alle := alle, kopf := kopf, inhalt := inhalt, text := text,
objekte := objekte) ORDER BY cluster) FROM trichter) AS trichter,
(SELECT list(struct_pack(traeger_id := traeger_id, knoten := knoten, e := e, w := w) ORDER BY traeger_id, rang)
FROM entscheid WHERE traeger_id IN (SELECT traeger_id FROM raum ORDER BY traeger_id LIMIT 2000)) AS gruende,
(SELECT list(struct_pack(traeger_id := traeger_id, raum := raum, ausgeschlossen_durch := ausgeschlossen_durch,
grund := grund) ORDER BY traeger_id) FROM buchung) AS buchung,
[] AS projektion_zaehlung,
[] AS projektionDie Entscheidungen jedes Blatts werden für alle Briefe gerechnet, weil der Raumbeweis jeden Brief verbuchen muss; die Einschränkung selbst geht Ebene für Ebene (k0 → i0 → t0), und die Evidenzobjekte werden nur in den verbliebenen Briefen gesucht.
Bewertung und Verfeinerung
Eine Menge ist zu groß, wenn sie mehr Objekte ihrer Art enthält als die Karte zulässt (Briefe 150, Dokumente 5, Sätze 400), unspezifisch, wenn ein positives Blatt weniger als 5 % der Träger ausschließt, leer ohne Träger oder ohne ein einziges Evidenzobjekt (dann bleiben nur unentschiedene Träger: Briefe an Maupertuis aus Berlin, 1754 oder 1755 hat 4 solche und kein Objekt), widersprüchlich, wenn der Merge einen Widerspruch fand. Die Rückfrage nennt dann den Hebel, der die Menge am stärksten teilt:
- Lässt ein Blatt mehr als die Hälfte der Menge nur als unentschieden stehen, fragt sie zuerst, ob diese Briefe bleiben sollen. Welche Briefe schrieb Prandtl an Kármán zwischen 1930 und 1933? behält 5.949 Briefe; 5.945 davon nur, weil ihr Absender nicht verzeichnet ist. Die Antwort „nur verzeichnete“ macht das Blatt streng: 4 Briefe, alle Goldbriefe darunter.
- Sonst schlägt sie das Unterattribut mit der größten Entropie über der Menge vor (Oberthema, Jahrzehnt, Sprache, Absendeort, Absender, Empfänger), mit den Zählungen je Wert aus derselben Anweisung. Ein Attribut, das nicht einschränken kann, wird nicht angeboten.
Die Antwort wird ein Blatt des Suchbaums (quelle: verfeinerung), und die Stufen 5 bis 9 laufen neu.
Der Raumbeweis
Das Zertifikat famulus-raum/1 sagt: jeder Träger des Körpers liegt im Raum, oder ein Blatt des Suchbaums hat ihn mit Grund ausgeschlossen (verletzt, bei einem negierten Blatt erfüllt, bei einem strengen unentschieden), oder kein Objekt erfüllt die Textblätter gemeinsam (Einheit Satz); die Facetten fx (Gate) und schemabaum (geprüfte Karte) gelten. Der Körper ist der Bau der Evidenztabellen (collection@fx-…, aus der Gate-Zeile). Der Prover (famulus_proof.entails) leitet daraus RaumVollstaendig(B@version, Frage) ab. Ein Brief, den nichts verbucht, wird genannt, und der Beweis hält nicht.
Ob die Blätter angemessen sind, zeigt der Beweis nicht. Das misst der Recall gegen Gold. Die Goldzeilen haben den Status vorgeschlagen und zählen erst, wenn der Eigentümer sie bestätigt.
Messung
Am 8. Oktober 2026 auf neun Collections, je Frage ein Kalt- und ein Warmlauf, berichtet der Warmlauf. Die Klassifikation ist als JSON vorgegeben, damit die Messung nicht vom Modell abhängt. „Objekte“ sind die Evidenzobjekte: in einer Textfrage die Sätze, Absätze und Fußnoten, die die Textblätter erfüllen; in einer Kopffrage die Träger, die jedes Blatt erfüllen. „tragend“ sind die Träger, die ein Evidenzobjekt enthalten; der Raum hält daneben die unentschiedenen. „Baum“ vergleicht die tragenden Briefe mit dem Raum des Entscheidungsbaums vom 4. Oktober (reports/data/e*-nachher.json). Recall gegen Gold gibt es nur im Kármán-Nachlass; die Goldzeilen von Hevelius, Euler und Pirckheimer sind leer (nicht_erntbar: es gibt keine Briefdatensätze, aus denen sie zu ernten wären), Wäfler, Kepler und Copernicus haben Probefragen ohne Gold.
Kármán-Nachlass — Träger: Briefe; Gold vorgeschlagen.
| Suchbaum | Träger: alle → Kopf → Inhalt → Text | Objekte | tragend | Baum | Recall Raum / tragend | SQL | Urteil | verfeinert |
|---|---|---|---|---|---|---|---|---|
| von Theodor von Kármán, nennt Adolf Hitler | 15.976 → 9.413 → 9.413 → 175 | 1 | 1 | 1, gleich | 1,0 / 1,0 | 151 ms | brauchbar | — |
| von Theodor von Kármán, nennt Alexander Weinstein | 15.976 → 9.413 → 9.413 → 176 | 2 | 2 | 6, verschieden | — | 134 ms | brauchbar | — |
| von Theodor von Kármán, nennt Albert Einstein | 15.976 → 9.413 → 9.413 → 208 | 40 | 34 | 44, verschieden | 0,793 / 0,793 | 152 ms | brauchbar | — |
| von Theodor von Kármán, nennt Ludwig Prandtl | 15.976 → 9.413 → 9.413 → 392 | 542 | 218 | 279, verschieden | 0,87 / 0,87 | 194 ms | zu groß | 156, Recall 0,864 |
| von Ludwig Prandtl, an Theodor von Kármán, 1930/1933 | 15.976 → 5.949 → 5.949 → 5.949 | 2 | 2 | — | 1,0 / 1,0 | 75 ms | zu groß | 4, Recall 1,0 |
| von Theodor von Kármán, deutsch, aus Pasadena | 15.976 → 1.809 → 1.809 → 1.809 | 18 | 18 | — | 1,0 / 1,0 | 81 ms | zu groß | 18, Recall 1,0 |
| von Theodor von Kármán, 1933 | 15.976 → 6.621 → 6.621 → 6.621 | 22 | 22 | — | 1,0 / 1,0 | 71 ms | zu groß | 48, Recall 1,0 |
| an Albert Einstein | 15.976 → 9.077 → 9.077 → 9.077 | 1 | 1 | — | 1,0 / 1,0 | 63 ms | zu groß | 1, Recall 1,0 |
Hevelius — Träger: Briefe; kein Gold (die Goldzeilen sind nicht erntbar).
| Suchbaum | Träger: alle → Kopf → Inhalt → Text | Objekte | tragend | Baum | Recall Raum / tragend | SQL | Urteil | verfeinert |
|---|---|---|---|---|---|---|---|---|
| von Johannes Hevelius, an Pierre Des Noyers | 2.970 → 494 → 494 → 494 | 101 | 101 | — | — | 44 ms | zu groß | 102 |
| von Pierre Des Noyers, an Johannes Hevelius, 1665 | 2.970 → 352 → 352 → 352 | 9 | 9 | — | — | 45 ms | zu groß | 10 |
| von Johannes Hevelius, fr | 2.970 → 1.193 → 1.193 → 1.193 | 76 | 76 | — | — | 46 ms | zu groß | 103 |
| an Ismaël Boulliau, la | 2.970 → 437 → 437 → 437 | 2 | 2 | — | — | 43 ms | zu groß | 40 |
| von Stanisław Lubieniecki, an Johannes Hevelius | 2.970 → 456 → 456 → 456 | 63 | 63 | — | — | 44 ms | zu groß | 63 |
| von Henry Oldenburg, an Johannes Hevelius, 1665/1666 | 2.970 → 359 → 359 → 359 | 6 | 6 | — | — | 44 ms | zu groß | 6 |
| an Johannes Hevelius, 1679 | 2.970 → 396 → 396 → 396 | 56 | 56 | — | — | 44 ms | zu groß | 57 |
Euler, Briefwechsel (IVA) — Träger: Briefe; kein Gold (die Goldzeilen sind nicht erntbar).
| Suchbaum | Träger: alle → Kopf → Inhalt → Text | Objekte | tragend | Baum | Recall Raum / tragend | SQL | Urteil | verfeinert |
|---|---|---|---|---|---|---|---|---|
| von Leonhard Euler, an Christian Goldbach | 3.393 → 123 → 123 → 123 | 114 | 114 | — | — | 44 ms | brauchbar | — |
| von Christian Goldbach, an Leonhard Euler | 3.393 → 105 → 105 → 105 | 100 | 100 | — | — | 44 ms | brauchbar | — |
| von Leonhard Euler, aus Berlin | 3.393 → 985 → 985 → 985 | 780 | 780 | — | — | 47 ms | zu groß | — |
| an Maupertuis, aus Berlin, 1754/1755 | 3.393 → 4 → 4 → 4 | 0 | 0 | — | — | 43 ms | leer | 1 |
| von Daniel Bernoulli, an Leonhard Euler | 3.393 → 99 → 99 → 99 | 94 | 94 | — | — | 44 ms | brauchbar | — |
| aus Petersburg, 1748 | 3.393 → 75 → 75 → 75 | 20 | 20 | — | — | 42 ms | brauchbar | — |
| von Leonhard Euler, an Friedrich II. | 3.393 → 67 → 67 → 67 | 50 | 50 | — | — | 43 ms | brauchbar | — |
Pirckheimer — Träger: Briefe; kein Gold (die Goldzeilen sind nicht erntbar).
| Suchbaum | Träger: alle → Kopf → Inhalt → Text | Objekte | tragend | Baum | Recall Raum / tragend | SQL | Urteil | verfeinert |
|---|---|---|---|---|---|---|---|---|
| von Desiderius Erasmus, an Willibald Pirckheimer | 354 → 18 → 18 → 18 | 18 | 18 | — | — | 38 ms | brauchbar | — |
| von Willibald Pirckheimer, an Desiderius Erasmus | 354 → 3 → 3 → 3 | 3 | 3 | — | — | 36 ms | brauchbar | — |
| aus Nürnberg, 1525 | 354 → 39 → 39 → 39 | 36 | 36 | — | — | 37 ms | brauchbar | — |
| von Klara Pirckheimer, an Willibald Pirckheimer | 354 → 20 → 20 → 20 | 20 | 20 | — | — | 38 ms | brauchbar | — |
| an Willibald Pirckheimer, aus Basel | 354 → 29 → 29 → 29 | 26 | 26 | — | — | 38 ms | brauchbar | — |
| an Willibald Pirckheimer, 1524/1526 (offen: absender) | 354 → 231 → 231 → 231 | 231 | 231 | — | — | 38 ms | zu groß | — |
Wäfler, Primärquellen — Träger: Dokumente; Probefragen, kein Gold.
| Suchbaum | Träger: alle → Kopf → Inhalt → Text | Objekte | tragend | Baum | Recall Raum / tragend | SQL | Urteil | verfeinert |
|---|---|---|---|---|---|---|---|---|
| von Markus Wäfler, book | 15 → 5 → 5 → 5 | 4 | 4 | — | — | 37 ms | brauchbar | — |
| nennt Hamidiya | 15 → 15 → 15 → 14 | 443 | 14 | — | — | 53 ms | zu groß | — |
| 1975, Wort Siegel | 15 → 10 → 10 → 4 | 210 | 4 | — | — | 51 ms | brauchbar | — |
| diaserie | 15 → 5 → 5 → 5 | 4 | 4 | — | — | 36 ms | brauchbar | — |
Wäfler, Sekundärliteratur — Träger: Dokumente; Probefragen, kein Gold.
| Suchbaum | Träger: alle → Kopf → Inhalt → Text | Objekte | tragend | Baum | Recall Raum / tragend | SQL | Urteil | verfeinert |
|---|---|---|---|---|---|---|---|---|
| nennt Markus Wäfler | 15 → 15 → 15 → 7 | 41 | 7 | — | — | 51 ms | brauchbar | — |
| von Mirjo Salvini, englisch | 15 → 1 → 1 → 1 | 1 | 1 | — | — | 44 ms | brauchbar | — |
Kepler, Gesammelte Werke — Träger: Dokumente; Probefragen, kein Gold.
| Suchbaum | Träger: alle → Kopf → Inhalt → Text | Objekte | tragend | Baum | Recall Raum / tragend | SQL | Urteil | verfeinert |
|---|---|---|---|---|---|---|---|---|
| von Johannes Kepler, Buch | 27 → 27 → 27 → 27 | 26 | 26 | — | — | 40 ms | zu groß | — |
| nennt Tycho Brahe | 27 → 27 → 27 → 25 | 1.415 | 25 | — | — | 70 ms | zu groß | — |
| Wort Mars | 27 → 27 → 27 → 26 | 3.101 | 26 | — | — | 65 ms | zu groß | — |
Kepler, Sekundärliteratur — Träger: Dokumente; Probefragen, kein Gold.
| Suchbaum | Träger: alle → Kopf → Inhalt → Text | Objekte | tragend | Baum | Recall Raum / tragend | SQL | Urteil | verfeinert |
|---|---|---|---|---|---|---|---|---|
| von Max Caspar, Buch | 18 → 1 → 1 → 1 | 1 | 1 | — | — | 36 ms | brauchbar | — |
| englisch | 18 → 11 → 11 → 11 | 11 | 11 | — | — | 36 ms | zu groß | — |
Copernicus, Primärquellen — Träger: Dokumente; Probefragen, kein Gold.
| Suchbaum | Träger: alle → Kopf → Inhalt → Text | Objekte | tragend | Baum | Recall Raum / tragend | SQL | Urteil | verfeinert |
|---|---|---|---|---|---|---|---|---|
| von Georg Joachim Rheticus | 10 → 1 → 1 → 1 | 1 | 1 | — | — | 36 ms | brauchbar | — |
| Wort revolutio | 10 → 10 → 10 → 10 | 417 | 10 | — | — | 52 ms | zu groß | — |
Die Klassifikation durch das Modell, gesondert geprüft:
Die Klassifikation durch das Modell wurde in dieser Messung nicht geprüft.
Die Partitur über den Orchestrator (ExecutionHarness), Hitler-Frage im Kármán-Nachlass:
Kein Lauf über den Orchestrator in der Messung.
Die Stufe fragebaum enthält die Bindung der Namen an das Register (Fast Index); ohne Vorgabe kommt die Antwortzeit des Modellaufrufs der Klassifikation hinzu.
Ausführen
cd development/famulus-proof
.venv/bin/python scripts/build_fq_index.py karman-nachlass hevelius eulerOO-IVA pirckheimer waefler-prim waefler-sec kepler-prim kepler-sec copernicus-prim
.venv/bin/python scripts/pilot_constraint.py # Messung, reports/data/filter-pilot.json
../famulus-notebook/.venv/bin/python scripts/pilot_constraint.py --modell --orchestrator
.venv/bin/python scripts/docs_evidenzobjekte.py # Tabellen dieser Seiten
.venv/bin/python -c "from famulus_proof.evidenzraum import lauf; \
st = lauf.filtern('In welchen Briefen erwähnt Theodor von Kármán die Person Adolf Hitler?', \
collections=['karman-nachlass']); print(st['filter_ausfuehren']['trichter'])"