- vfl-journal-reset-lauf ans Funktionsanfang verschoben (Modus 1/2/3,
Lisp/vf_linienzug.lsp): stand bisher nach der Startpunkt/Hoehe/AS-
Praeambel und loeschte diese beim Reset selbst wieder - Journal begann
mit dem ersten STEP-Marker statt PT, betraf jede Kette.
- Spec-Grammatik erweitert (Lisp/vf_spec.lsp, lib/vf_linienzug_grammatik.py,
lib/vf_spec_export.py): "auf-ab" bei bereits flach ankommender Kette
(Richtungswahl statt Zielhoehe) und neue Linie-GF-Fragereihenfolge
(Kettenende direkt nach laenge_modus, inkl. vorgezogenem ES). Tests in
tests/test_vf_spec.lsp/.py angepasst.
- lib/vf_linienzug_grammatik.py: _linie("kettenende_ziel") erwartete
faelschlich ein hz-REAL nach der Distanz - der reale Bauablauf
(vfl-body-abschluss) leitet die Richtung dort aus dem Frame ab und
fragt sie nie. Fuehrte zu einem Token-Desync beim Dekodieren echter
Kettenende-Journale.
- tests/testdata/hundm05.json (VF_hundm05_LZ_01): 5 ueberfluessige
hz-Felder entfernt. vsp-linie injiziert bei JEDEM vorhandenen hz-Feld
einen Richtungs-Token, unabhaengig vom tatsaechlichen Bauablauf - die
Felder desyncten den Replay und liessen die Kette stumm mit der
falschen (verkuerzten) Geometrie fertig bauen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Lisp (vf_linienzug.lsp/vf_spec.lsp):
- vsp-eingang-hoehe unterstuetzt jetzt "auto" (NIL-Token statt REAL) -
bewusst keine Zahl vorgeben, der Bauablauf berechnet seinen eigenen
Vorschlag, wie bei leerer Konsoleneingabe
- vfl-journal-reset-lauf: internes Reset innerhalb von vf-linienzug-modus/
-modus2 loescht *vfl-replay-queue*/*vflw-pending* nicht mehr mit (Bug:
REPLAY-getriebener Bau (vsp-bau-aus-spec) brach mitten in der Kette ab,
weil eine noch unverbrauchte Queue verworfen wurde)
Python-Gegenstueck nachgezogen (lib/vf_linienzug_grammatik.py,
lib/vf_spec_export.py, lib/vf_journal_export.py):
- NIL-Token-Unterstuetzung fuer eingang_hoehe="auto" im gemeinsamen
Parser-Kern, im Schreiber (SpecSchreiber) und in der Protokoll-Annotation
- gf_verteilung ist im Schreiber jetzt an der Feldpraesenz in der Spec
festgemacht statt an einem Grammatik-Flag (selbstbeschreibend, deckt
Specs mit und ohne diese Frage ab, ohne dass der Aufrufer die Grammatik
kennen muss)
- Rundlauf-Pruefung (main(), test_verlustfrei) toleriert jetzt die bekannte,
schon dokumentierte Erweiterung um drei neue Linie-GF-Pflichtfragen
(ist_teilfolge statt exakter Gleichheit)
- test_gleiche_journale_wie_protokoll: alle 5 Ketten in hundm05.json weichen
inzwischen vom Rohprotokoll ab (Kette 1 bewusst wegen eingang_hoehe,
Ketten 2-5 schon laenger wegen Handkorrektur gegen echte DXF-Positionen)
- expliziter Skip mit Begruendung statt leerem Loop
tests/testdata/hundm05.json:
- mm-Werte (dl, Start-/Stuetzpunkte, Koordinaten der Nachtrag-Objekte) auf
eine Nachkommastelle gerundet
- nicht abgefragte Kopf-Metadaten entfernt (beschreibung, sivas_id,
sivas_bezeichnung, planquadrat, block, dxf_handle) - nur quelle bleibt
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
vf-linienzug-modus fragt bei einem mit "Horizontal-VF" eroeffneten
Kettenanfang eine Ziel-Hoehe fuer den GF1-Einlauf ab (vfl-prompt-hoehe-
eingang-gf1) und laesst dort die GF-Verteilungsfrage weg (fest "alles am
Einlauf") - vsp-journal/vsp-vf-einheit kannten das noch nicht. Ausserdem
werden ES-Winkel/-Seite beim kettenende-sub jetzt an der richtigen
Journal-Position (inkl. eigenem STEP-Marker) emittiert.
tests/testdata/hundm05.json: VF_hundm05_LZ_02..05 (die vier baugleichen
Schleifen, Block VF_1) aus tests/testdata/linienzug_tests.json neu
abgeleitet, mit den realen Startkoordinaten aus results/test_hundM05.dxf
statt der alten "sub":"auf-ab"-Behelfsloesung. VF_hundm05_LZ_01 und alle
Kreisel-/Separator-/Scanner-/BTMT-Objekte unveraendert.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Lisp/vf_standard.lsp: berechne-alle-winkel um Parameter schon-flach
erweitert (Fussabdruck-Korrektur, wenn ein Frame flach statt bei 3 Grad
ankommt) - vf_linienzug.lsp rief die Funktion bereits mit diesem 5.
Argument auf, dieser Commit fehlte im letzten Commit und liess den
Zwischenstand mit Argumentzahl-Mismatch zurueck. tests/test_foerderer.lsp
und tests/test_mubea.lsp ziehen dieselbe Signatur nach (inkl.
berechne-horizontale-mitte, das schon-flach bereits erwartete).
tests/testdata/linienzug_tests*.json aktualisiert passend zum echten
Bau-Ablauf. menu/SSG_LIB.mnu/.cui: TEST_LINIENZUG_STUFE2 im Testmenue
ergaenzt.
Lisp/vf_spec.lsp + lib/vf_spec_export.py: *vsp-menu-start* auf die aktuelle
6-Optionen-Kettenanfang-Zuordnung umgestellt (vorher noch 4 Optionen) -
vsp-journal replayt gegen den LEBENDEN vf-linienzug-modus. Python-Tabelle
bewusst NICHT umgestellt (dekodiert eine eingefrorene Alt-Aufzeichnung).
TEST_HUNDM05 schlaegt trotzdem weiterhin fehl (separates, ungeloestes
Problem - siehe naechster Absatz).
Bekannter offener Fehler: TEST_HUNDM05 baut nach wie vor nicht korrekt -
der Menu-Code-Fix allein reicht nicht. Root Cause nicht abschliessend
geklaert, Uebergabe an Kollegen fuer Logik-Review vorgesehen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Restauriert alles aus e76e24e, das nach dem Reset auf master fehlte oder nur
teilweise wiederhergestellt war, und mit dem Kollegen-Umbau abgeglichen:
- vf_core.lsp: Radio-Button-Dialoge fuer Anlagen-Typ/Linienzug-Modus
(vfc-dialog-typ-waehlen/-linienzug-modus-waehlen) + Zurueck-Schleife im
c:VarioFoerderer-Dispatcher
- Vario-Kurve/GF-Bogen-Erkennung am Kettenanfang: vfl-eingang-modus-bestimmen
threaded durch vfl-vf-eingang-bauen/vfl-vf-einheit/vfl-vf-einheit-abschluss,
inkl. Punkt-7-Winkel/Hoehen-Tabelle fuer reduzierten Eingang
- Modus 2: Lauf-Anfang/Lauf-Abschluss (offener Anfang/Ende, GF-Verteilung
"alles Auslauf", Kletter-zu-kurz-Fallback) + Separator VOR/NACH bei
GF-Geraden
- Systemischer Bug behoben: mehrere Wizard-Dialogfunktionen nutzten noch
start_list/add_list (Dropdown) gegen laengst auf boxed_radio_column
umgestellte DCL-Dialoge (vflw-gruppe-as/-gefaelle/-variokurve/
-winkel-seite-impl, vflw-seg-linie-m2/-m3/-bogen-impl,
vfl-glied-gf-bogen/-vario/-as-es-dialog)
- Zentraler Abbruch-Trigger in vfl-in-value/-value-p wiederhergestellt (ohne
ihn wirkte der Zurueck/Abbrechen-Button in keinem Wizard-Dialog)
- vfl-frage-ist-endpunkt/-ist-kettenende als eigene Funktionen mit
Wizard-Dialog extrahiert (vorher Konsolen-Duplikate ohne Dialog-Hookup)
- 3 vfs-vf-entry-Aufrufe mit falscher Argumentzahl gefixt (akute
Absturz-Bugs in Modus 2/3)
- Tote Funktion vflw-gruppe-horizontal-impl entfernt (Tiles nicht mehr im
DCL vorhanden)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Spiegelt die drei neuen Felder (laenge_modus/sep_vor/sep_nach/steigend_modus)
aus Lisp/vf_spec.lsp im Python-Pendant (SpecSchreiber.sektion) - haelt die
"zwei unabhaengige Implementierungen pruefen sich" Architektur des Kollegen
fuer den Schreib-Pfad synchron. tests/test_vf_spec.py: LISP_FAELLE um die
2 neuen Testfaelle ergaenzt, Faelle-Zaehler 7 -> 9.
Bewusst NICHT angefasst: der Rueckwaerts-Decoder (SpecLeser, spec_aus_journal)
- die 5 echten HundM-Ketten (hm_recformat.json) wurden vor dieser Erweiterung
aufgezeichnet und haben daher keine Separator-Antworten fuer ihre Linie-GF-
Sektionen. Der Rundlauf-Test TestRundlauf.test_verlustfrei wird fuer Ketten
mit Linie-GF dadurch rot - eine inhaerente, bewusst in Kauf genommene Folge
der neuen Pflichtfragen im interaktiven Ablauf, kein Fehler im Schreiber
(ausfuehrlich kommentiert direkt an der Aenderung in vf_spec_export.py).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Auf der neuen Kollegen-Architektur (Stufe 0-2: Spec/Journal/Replay-System
in vf_spec.lsp, Frage-Schale/Bauteil-Trennung) neu aufgebaut, nachdem der
urspruengliche Stand (Commit e76e24e) auf einer aelteren Basis beruhte und
per Rebase-Analyse als eigenstaendige, unabhaengige Erweiterung erkannt
wurde (der Kollege hat nichts entfernt - diese Features existierten vorher
nur lokal uncommitted).
Drei Erweiterungen fuer "Neue Linie: GF" in vf-linienzug-modus:
- Separator VOR/NACH direkt vor bzw. nach der Gefaellestrecke einfuegbar.
- Aeussere Vorwahl "Wie soll die Laenge bestimmt werden?": Endpunkt waehlen
(bisheriges Verhalten) oder Zielhoehe zuerst festlegen (Winkel wird
daraus berechnet).
- Dritte Option "Steigende GF" (Sonderfall, 0 bis 3 Grad): erlaubt eine GF,
die statt zu fallen steigt. Neuer Helfer vfl-bogen-uebergang erkennt
anhand der tatsaechlichen Frame-Neigung, ob 0/1/2 Uebergangsboegen
(Vario_Bogen_auf_3/ab_3) noetig sind, und baut sie automatisch - im
Normalfall (fallend->fallend) ein No-Op.
Lisp/vf_spec.lsp (Kollegen-Spec/Headless-Bau-System) um die drei neuen
Felder (laenge_modus/sep_vor/sep_nach/steigend_modus) erweitert, mit
Defaults, die alte Specs unveraendert lassen - haelt die "Spec-Pfad ==
interaktiver Pfad"-Invariante seines Systems (TEST_HUNDM05/VF_SPEC_BAU)
intakt. tests/test_vf_spec.lsp entsprechend mit neuen Testfaellen ergaenzt.
Neuer Regressionstest TEST_LINIENZUG_STUFE2 (linienzug_tests_stufe2.json)
sowie Anleitung doc/vf_linienzug_modus1_anleitung.md aus dem urspruenglichen
Commit uebernommen; die Gefaelle-Hoehe/Winkel-Optionsreihenfolge im
Testdatensatz an die jetzt geltende (Kollegen-)Konvention angepasst.
Offen (bewusst zurueckgestellt): lib/vf_spec_export.py (Python-Vorwaerts-
Emitter, Pendant zu vf_spec.lsp) noch nicht nachgezogen - siehe Folge-Commit.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
export_graph.py behandelte BTMT-Stationen bisher wie ein generisches
Durchlaufelement mit zwei Achs-Enden - dadurch entstanden mehrere,
teils widerspruechliche Kanten und die Rolle blieb "Element" statt
"Eingang"/"Ausgang". BTMT hat aber physisch nur EINEN Anschluss zum
Foerdersystem (sitzt als dritter Zweig einer Weiche auf der Kreisel-
Durchgangsbahn, der Kreisel bleibt dabei ein einzelner Verteiler-Knoten):
Beladung speist fest Material ein (kein Vorgaenger im Fluss), Entladung
nimmt es fest raus (kein Nachfolger).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
write_separatorliste_merkmale liess bisher nur "SEP"-Eintraege der
sepliste in die "TrackIds"-Spalte einfliessen; die AS-/ES-Ausschleus-
/Einschleuselemente an Anfang und Ende der Kette fehlten dadurch,
obwohl sie beim Kreisel (compute_kreisel_umlauf) bereits Teil von
dessen TrackIds sind. Jetzt werden alle sepliste-Eintraege (AS, SEP,
ES) in Baureihenfolge aufgeloest.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Statt eines JSON-Merkmals bekommen VF_n/GF_n/Kreisel jetzt eine eigene
CSV-Spalte "TrackIds" (nach "Nachbarn", vor "Fehler") mit der Reihenfolge
der Separator-/BTMT-/AS-ES-/Weichen-TeileIds entlang der Strecke bzw. um
den Kreisel - analog zur bestehenden "Nachbarn"-Spalte statt versteckt im
Merkmale-JSON. Referenz-CSV fuer den Omniflo-Test an den neuen Header
angepasst.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Die Spalte "Bezeichnung" verwendet jetzt das in BricsCAD frei editierbare
Attribut "Bezeichnung" des Blocks, falls gesetzt - sonst wie bisher die
generierte Standardbezeichnung ("VarioFoerderer :3" usw.). Damit laesst
sich ein in der Zeichnung umbenanntes Element im CSV-Export wiedererkennen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Kreisel bekommen wie VF_n/GF_n ein Merkmal mit der Reihenfolge aller
Separator-/BTMT-Beladung-/BTMT-Entladung-TeileIds entlang der Bahn,
sortiert nach Winkel um die Kreiselachse (Start bei 0 Grad in
Drehrichtung DREHRICHTUNG) - nutzt dieselbe Umlauf-Logik, die bisher
nur die "Nachbarn"-Spalte gespeist hat. Merkmal-Schluessel einheitlich
auf "list_trackids" umbenannt (vorher "Separatorlist" bei VF/GF).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
TEST_HUNDM05 baute bisher keine BTMT-Beladung/SC_Entladung-Stationen,
weil hundm05.json anders als mubea.json nie Eintraege dafuer hatte -
dadurch fehlten sie im CSV-Export der Testanlage. Koordinaten/Rotation
aus dem Insertpoint/K1-KOS-String der realen Referenz-CSV
(hundmM05_1.csv) dekodiert und als "block"-Eintraege ergaenzt; der
bestehende generische _.INSERT-Pfad in hundm05:bau-sensor baut sie ohne
weitere Code-Aenderung. Kommentare/Doku (test_hundm05.lsp,
object_data.md Abschnitt 5) an die jetzt nicht mehr auf Separator/
Scanner beschraenkte Nutzung angepasst.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Kreisel-Kreisel-Weichen fehlten bisher im Kreisel-Umlauf (compute_kreisel_umlauf),
wodurch angrenzende Separatoren auf falsche/fehlende Nachbarn zeigten. Die
kreisel_bounds-Matching-Box ignorierte ausserdem die tatsaechliche Kreiseldrehung
(faelschlich als achsparallel angenommen), was bei gedrehten langen Kreiseln
(Mubea Kreisel 0002) zu falschen Nachbarschaften fuehrte.
Die sepliste-XDATA (AS/SEP/ES-Reihenfolge je VF_n/GF_n) wurde nie ans Python-Item
durchgereicht - die gesamte Ketten-Nachbarschaftserkennung lief dadurch ins Leere.
Nach dem Beheben entstand eine Doppelzaehlung: die in einer Kette verpackten
Separatoren existieren bereits als echte Proxy-INSERTs (csv:sep-proxies-erzeugen);
build_separator_kette_items erzeugte zusaetzlich eigene Zeilen aus der sepliste.
Umgebaut zu map_separator_kette_items: ordnet die sepliste-Reihenfolge den
vorhandenen Proxy-Items zu (Match ueber Wrapper-ID + INSERT-Punkt) statt neue
Zeilen zu erzeugen - keine Doppelzaehlung mehr, Nachbarn korrekt gesetzt.
Ausserdem: vla-getboundingbox scheiterte in einem realen Export bei ALLEN
Bloecken (fehlende bbox ueberall), der Fehler wurde bisher still verschluckt.
REGENALL vor der Export-Schleife behebt das; eine neue Diagnose (exp-bbox-fail)
meldet kuenftige Ausfaelle statt sie zu verschlucken. Freie/eingebettete
Separatoren ohne bbox bekommen zusaetzlich einen Fallback aus einer konfigurierbaren
Symbol-Groesse (cfg/export.cfg [Boundingbox] separator_box_*).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sammelt beim Bau von VF_n/GF_n-Ketten die Baureihenfolge der Separator-/
AS-/ES-Sub-Bloecke vor dem Block-Sweep und schreibt sie als XDATA auf den
fertigen Wrapper (ssg_ks_insert.lsp); export.lsp liest sie fuer das neue
"sepliste"-Feld im CSV-Export, export_neighbors.py nutzt es als Fallback
zur BBox-Kollisionspruefung. Dazu Unit-Tests fuer die reinen Serialisierungs-
funktionen (Chunking, Roundtrip) in test_unit.lsp.
Ausserdem: makunbound (existiert nicht in BricsCAD-AutoLISP) aus
test_run_all.lsp entfernt - verursachte Laufzeitfehler bei
SSG_RUN_ALL_TESTS_EXPORT/_OFFEN.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
9 reale Separator/Scanner-Koordinaten aus der Anlage in hundm05.json
ergaenzt. hundm05:bau-zusatzobjekte (test_hundm05.lsp) baute bisher nur
Kreisel-Zusatzobjekte - neue hundm05:bau-sensor-Funktion (analog zu
mubea:build-separator-one in test_mubea.lsp) faengt jetzt auch
"block"-Eintraege (Separator/Scanner) ab und fuegt sie per _.INSERT ein.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ILS_EINGANG_INSERT/ILS_AUSGANG_INSERT (Menue SPS > Connections) setzen
das Eingang-/Ausgang-Symbol automatisch lotrecht ueber eine gewaehlte
BTMT-Beladung/-Entladung-Instanz statt per freiem Einfuegepunkt.
Blockdateien Eingang_2D/3D.dwg und Ausgang_2D/3D.dwg ins Flach-Schema
von data/ils kopiert (Quellen in data/ils/2D|3D bleiben unangetastet).
Mubea-Testdaten um ein Eingang-Symbol ueber der Beladung und je ein
Ausgang-Symbol ueber beiden Entladungen erweitert.
Zusaetzlich: BTMT-Drehung im CSV-Export (export_csv.py) auf ganze
Grad gerundet (90/180/... statt z.B. 90.4078), da Kommastellen dort
keine Bedeutung haben.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Benannte Zeichnungen exportieren jetzt nach <name>_export.csv bzw.
<name>_sivas.csv statt der festen Namen export.csv/export_sivas.csv,
damit sich Ergebnisse mehrerer Zeichnungen nicht mehr gegenseitig
ueberschreiben. Unbenannte Zeichnungen (DWGTITLED=0) behalten die
alten Standardnamen. test_export_all.lsp verlaesst sich jetzt auf
diese automatische Praefixierung statt *export-filenames* manuell
zu ueberschreiben.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Konvention: Eine Referenz traegt IMMER denselben Dateinamen wie das Ist-
Ergebnis in output/ (nur anderes Verzeichnis). Referenz festlegen = Datei aus
output/ unter gleichem Namen nach reference/ kopieren.
- tests/README.md: neuer Abschnitt "Referenz-Namenskonvention (vereinheitlicht)"
mit Regel/Tabelle/copy-Beispiel; Namenskonventions-Tabelle, Fixture-Vorlage
(<modul>_tests.dxf statt <modul>_ref.dxf) und die Workflow-Referenzabschnitte
angeglichen.
- tests/conftest.py: kreisel_ref_dxf laedt reference/kreisel_tests.dxf
(vorher kreisel_ref.dxf).
- tests/test_omniflo.py: Referenz reference/omniflo_export.csv
(vorher omniflo_export_reference.csv).
- Referenzen abgenommen und in Git aufgenommen:
reference/kreisel_tests.dxf (Umbenennung des Tippfehlers Kresel_ref.dxf),
reference/omniflo_export.csv (aus geprueftem output/omniflo_export.csv).
Der Batch-Vergleich --diff_references matchte schon immer ueber identische
Basisnamen und bleibt unveraendert. Der Kreisel-Referenztest laeuft dadurch
jetzt statt zu skippen.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Erwartete Drehung fuer den Separator in Kreisel_rechts korrigiert
(entdeckt beim Nachverfolgen der Separator-Rotation im GF-Export).
gf.dxf/test.dxf sind Testzeichnungen aus der Fehlersuche.
Commit e2f0384 (vor dieser Session) liess EXPORTCSV/EXPORTSIVAS auch die in
VF_n-Blockdefinitionen verpackten Separator_SP-Sensoren als eigene Zeile
exportieren (TeileArt "ILS 2.0 Separator"). tests/test_foerderer.py wurde
seitdem nicht angepasst und nahm weiter an, JEDE Zeile sei eine Vario-
Strecke - drei Tests schlugen daher fehl, sobald die CSV tatsaechlich
vorlag (39 statt 13 Zeilen: 13 Vario- + 26 Separator-Zeilen).
Neu NEBEN_TEILEARTEN = {"ILS 2.0 Separator"} plus zwei Filter-Helfer
(_vario_rows/_separator_rows). test_vario_teileart, test_merkmale_felder
und test_anzahl_csv_zeilen_entspricht_gebaut pruefen jetzt nur noch die
Vario-Zeilen (verifiziert: 13 Vario- + 26 Separator-Zeilen in der aktuellen
CSV, Summe stimmt).
Statt die Separator-Zeilen nur zu ignorieren, zwei neue, eigenstaendige
Tests:
- test_teileart_bekannt: jede Zeile ist Vario-Strecke ODER eine bekannte
Neben-TeileArt - faengt eine dritte, unerwartete Art, die die beiden
Filter sonst stillschweigend durchliessen.
- test_separator_merkmale_felder: die Separator-Merkmale haben ihr eigenes,
kleineres Pflichtfeld-Schema (Zuordnung, ARTINR) statt der Vario-Felder.
- test_separator_zuordnung_konsistent: der eigentliche Beweis, dass
csv:sep-proxies-erzeugen die Sensoren dem RICHTIGEN Wrapper zuordnet -
jede Separator-Zuordnung zeigt auf eine Vario-TeileId derselben Datei,
und je Vario-Zeile stimmt die Anzahl ihrer Separatoren mit dem eigenen
Merkmal Anzahl_Separator ueberein (test_export_ids.py prueft nur, dass
die Zuordnung ueberhaupt auf eine bekannte ID zeigt, nicht auf die
richtige). Gegengeprobt: eine verfaelschte Zuordnung wird erkannt.
Verifiziert: alle 27 Tests in test_foerderer.py gruen (vorher 3 FAILED),
Gesamtsuite 188 passed / 0 failed / 19 skipped.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
TEST_GEFAELLESTRECKE brach mit "too few / too many arguments at
[GF-BLOCK-ERSTELLEN]" ab, kurz vor Ende des letzten Testfalls - darum blieb
gefaellestrecke_results.json unbeschrieben (die Variable, aus der die Datei
geschrieben wird, wird erst in der letzten Zeile der Funktion gesetzt).
Ursache: ddb5dfa ("WINKEL_AS und WINKEL_ES hinzugefügt") erweiterte
gf-block-erstellen um die Parameter as-winkel/es-winkel (25 -> 27 Pflicht-
parameter) und aktualisierte die zwei Aufrufstellen in Gefaellestrecke.lsp,
uebersah aber die vierte Aufrufstelle in tests/test_gefaellestrecke.lsp
(gefaellestrecke:modus3-einfuegen) - blieb bei 25 Argumenten.
Fix: "90" "90" ergaenzt. Kein geratener Wert - die Funktion baut bereits
durchgaengig mit AS_Element_90_*/ES_Element_90_* (as-block/es-block weiter
oben in derselben Funktion), sie ruft anders als der interaktive Modus 3
nie vf-frage-element-winkel auf. "90" ist also deckungsgleich mit dem Rest
der Funktion.
Verifiziert: mechanischer Arity-Check aller 18 Aufrufe von 11
Gefaellestrecke.lsp-Funktionen in test_gefaellestrecke.lsp - alle
Pflichtparameterzahlen stimmen jetzt. TEST_GEFAELLESTRECKE lief
durch (8/8 GEBAUT), die 13 zuvor uebersprungenen pytest-Tests in
tests/test_gefaellestrecke.py sind gruen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
tests/testdata/hundm05.json enthaelt jetzt neben den 5 Spec-Ketten auch
andere Objekte der Anlage - erkennbar am Feld "function", im Format der
jeweiligen Einzel-Testdaten (ein Kreisel also wie in kreisel_tests.json).
Damit beschreibt EINE Datei die ganze Anlage.
- tests/test_hundm05.lsp: hundm05:bau-zusatzobjekte sammelt alle Objekte mit
"function" und baut sie; hundm05:bau-kreisel ruft kreisel-insert-script
(wie tests/test_kreisel.lsp) und liefert einen Ergebnis-Record in derselben
Form wie die Ketten. Eigener ssg-start-Rahmen mit ATTREQ/ATTDIA 0, weil
vsp-bau-datei seinen schon geschlossen hat und (command "_.INSERT" ...)
sonst nach Attributwerten fragt. Je Objekt gefangen, damit ein Fehler die
restlichen nicht mitnimmt.
- Lisp/vf_spec.lsp: "kind" ist jetzt ein Record-Feld (Default "linienzug")
statt eines Literals in vsp-result-json - so schreibt vsp-results-schreiben
beide Objektarten in EINE Ergebnisdatei.
- lib/vf_spec_export.py: Objekte der Ziel-Datei, die keine Kette beschreiben,
werden beim Neuschreiben unveraendert ans Dateiende uebernommen. Ohne das
waere jeder von Hand ergaenzte Eintrag beim naechsten Generatorlauf weg -
die Datei ist erzeugt UND handgepflegt. spec_aus_flachen_objekten
ueberspringt sie jetzt statt zu werfen, genau wie vsp-gruppieren in LISP.
- tests/test_hundm05.py: die Ketten-Tests filtern auf kind "linienzug"
(Records ohne das Feld stammen aus aelteren Laeufen und waren nur Ketten);
neue Klasse TestZusatzobjekte prueft Status, expect_block_prefix,
expect_hoehe (Attribut HOEHE), expect_kreiselart (KREISELART) und den
Einfuegepunkt - dieselben Erwartungsfelder wie tests/test_kreisel.py.
- tests/test_vf_spec.py: neuer Test, dass die Zusatzobjekte die
Ketten-Zerlegung nicht beeinflussen - auch nicht, wenn sie mitten zwischen
den Sektionen stehen (der eingetragene Kreisel stand zunaechst inmitten
der Sub-Knoten von Kette 5; nach dem Regenerieren steht er am Dateiende).
Verifiziert: 118 pytest-Tests gruen, Spec-Regenerierung uebernimmt das
Zusatzobjekt (58 Objekte), beide .lsp lint-sauber. Die Kreisel-Tests warten
auf den naechsten TEST_HUNDM05-Lauf.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Der CAD-Lauf belegt die Schritte 0-4 jetzt auch EMPIRISCH:
results/test_hundm05.dxf entstand nach dem Umbau, das Ergebnis-JSON von
11:18 davor - fuer alle 5 Ketten sind ALLE 37 Attribute identisch,
inklusive der reihenfolgeabhaengigen Komma-Listen L_VF_m, L_GF_m, GF_WINKEL
und ANTRIEBFAHRTRICHTUNG. TEST_VF_SPEC: 28 PASS / 0 FAIL.
results/test_linienzug.dxf zeigt eine vollstaendige Kette (AS+ES, Motor,
Umlenkung, 2 Vario-Kurven, 22 Bausteine, HOEHE_VON = HOEHE_BIS = 4500 bei
DELTA_H 0).
Schritt 5a/5b - vfl-vf-eingang-bauen und vfl-vf-ausgang-bauen: beide Bloecke
(GF1 + Einlauf-Separator + Umlenkstation bzw. Motorstation + GF2) enthalten
keine Frage und sind zusammenhaengend, der Umzug ist wortwoertlich
(Zeilenvergleich: 0 Zeilen entfernt, nur zwei Koepfe, zwei Aufrufe und zwei
"frame)" neu). Die Auswahl gf2-eff (ziel-gf2 im Kettenende-Modus, sonst
L_GF2-bau) bleibt BEWUSST an der Aufrufstelle - genau dort entsteht sonst
still die falsche GF2 hinter dem Motor. Der Separator-Zaehler und die
vfl-acc-*-Aufrufe bleiben an derselben Stelle in derselben Reihenfolge.
Regressionsnetz, damit die restlichen Schritte nicht blind gemacht werden
muessen:
- lib/dxf_vf_abbild.py (neu): liest eine Testzeichnung streamend und bildet
je Kette Attribute, Bausteinzusammensetzung und Einfuegepunkt ab. Ketten
werden ueber den EINFUEGEPUNKT der Spec zugeordnet, nicht ueber den
Blocknamen - die VF-Nummer beginnt in jeder neuen Zeichnung wieder bei 1.
ID und Bezeichnung sind aus dem Vergleich heraus (pro Zeichnung neu).
--referenz vergleicht (Exit 1 bei Abweichung), --schreibe-referenz frischt
die Referenz nach einem GEPRUEFTEN Lauf auf.
- tests/reference/hundm05_attribute.json (neu): die Referenz, erzeugt aus dem
geprueften Lauf - also dem Stand, der attributgleich mit dem Zustand VOR
dem Umbau ist.
- tests/test_vf_geometrie.py (neu, 8 Tests): vergleicht automatisch, mit
einem eigenen Test nur fuer die Komma-Listen (das einzige, was eine
vertauschte vfl-acc-*-Reihenfolge sichtbar macht) und einer Gegenprobe,
dass eine verfaelschte Referenz auch erkannt wird.
Das faengt, was der Ergebnis-Record NICHT sieht: er sagt "executed, kein
Prompt, Journal aufgegangen", aber nichts darueber, ob dieselbe Geometrie
herauskam. Ablauf ab jetzt pro Schritt: umbauen -> TEST_HUNDM05 (save dxf)
-> pytest tests/test_vf_geometrie.py.
Offen bleiben 5c, 6, 8, 9, 10 (Schleifenrumpf der VF-Einheit, Daten-Executor,
Einheit-Abschluss, Kettenebene je Glied, vfl-spec-ausfuehren). Die vier
haengen zusammen: 6 und 10 brauchen den aufgeteilten Schleifenrumpf. Halb
umgebaut waere der Code schlechter dran als vor oder nach dem Umbau, darum
als ein Schritt mit CAD-Lauf davor und danach.
Verifiziert: 117 pytest-Tests gruen, vf_linienzug.lsp lint-sauber.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Alle Aenderungen sind verhaltensgleich: die Frage-Schalen behalten ihre
Namen, keine Aufrufstelle in Modus 1/2/3 wurde angefasst.
Schritt 0 - vfl-ziel-report: der Soll-Ist-Vergleich am Kettenende stand
zweimal WORTGLEICH in vfl-vf-einheit-abschluss (einmal fuer "Kettenende ohne
ES", einmal "mit ES"); die Faelle unterscheiden sich nur darin, wann sie
melden, nicht was.
Schritt 1 - Winkelwahl aufgeteilt: vfl-winkel-gueltige (Kandidaten filtern)
und vfl-winkel-nach-index (Kandidat waehlen) sind rein; die Frage-Schale
vfl-waehle-winkel setzt sie zusammen. Neuer Vorgabe-Kanal
*vfl-winkel-idx-vorgabe*: ist er gesetzt, wird nicht gefragt. Kanal statt
Parameter, weil vfl-waehle-winkel aus vier Solvern gerufen wird
(vfl-vf-winkel, vfl-vf-entscheidung, vfl-body-zerlegung,
vfl-segment-entscheidung) - ein Parameter wuerde vier Signaturen und alle
deren Aufrufer aendern. Default nil, also heute ohne Wirkung.
Schritt 2 - vfl-es-masse-setzen: reines Globals-Setzen (ES-Winkel merken +
vf-set-es-masse) aus vfl-frage-es-seite gezogen. *vfl-es-winkel* wird LAZY
von den Blocknamen-Bauern gelesen und muss vor dem ersten ES-Insert stehen.
Schritt 3 - vfl-hor-koerper-bauen: die drei Fragen (Separator vor/nach,
Endpunkt) haengen an keinem berechneten Wert und stehen jetzt alle vor dem
Bau. Journal-Reihenfolge UND Entity-Reihenfolge bleiben identisch; nur
interaktiv erscheint der auf_3-Uebergangsblock erst nach den drei Fragen
statt zwischen Frage 1 und 2. Die dL-Subtraktionskette wurde Zeile fuer Zeile
uebernommen - jeder Schritt ist mit (max *vfk-restlaenge-min-clamp* ...)
geklammert, also nicht kommutativ, und der auf_3-Insert sitzt bewusst
zwischen Subtraktion 1 und 2 (sein Fussabdruck wird GEMESSEN). Nachweis:
Zeilenvergleich alt/neu, dieselben 15 geometrie-relevanten Zeilen in
derselben Reihenfolge.
Schritt 4 - vfl-body-abschluss-bauen: hier laesst sich NICHT alles vorab
fragen (vfl-neue-linie-messen braucht den Frame nach vfl-nach-3grad, die
Hoehenvorschlaege brauchen dL und die Kettenhoehe). Die Schale macht darum
3-Grad-Abschluss -> messen -> Vorschlaege -> Zielhoehe fragen, der reine Teil
beginnt bei der Zerlegung. Nachweis: Multiset-Vergleich der Zeilen, ausser
Kopf, Klammer und Aufruf ist keine Zeile veraendert.
Schritt 7 (Assertion-Teil) - vsp-journal-diff in Lisp/vf_spec.lsp: stellt das
aus der Spec erzeugte Journal Token fuer Token gegen das beim Bau neu
aufgezeichnete. Schaerfster Desync-Detektor - offene Queue-Werte und die
Glied-Folge zeigen nur grobe Abweichungen, ein einzelner Wert, der an der
falschen Stelle verbraucht wird, kann beide passieren lassen und trotzdem
andere Geometrie erzeugen. Neues Record-Feld journal_diff, neuer Test
test_journal_token_gleich.
Zwei bewusste Abweichungen von der Planung (begruendet in
doc/TODO-plan-vf-interactive.md, Abschnitt "Umsetzungsstand Stufe 2"):
vfl-hor-koerper-bauen behaelt ziel-modus als eigenen Parameter neben
ende-code (ende-code darf nil sein, die Separator-Subtraktionen haengen aber
allein am Ziel-Modus); vfl-body-abschluss-bauen braucht letzt-hz und
es-gewuenscht nicht.
Offen: Schritte 5, 6, 8, 9, 10. Das sind die, bei denen die Reihenfolge
selbst Geometrie ist - der Fahrplan verlangt nach jedem einen CAD-Lauf
(TEST_HUNDM05 + TEST_VF_SPEC + TEST_LINIENZUG), nach den Geometrie-Schritten
zusaetzlich DXF-Diff und Sivas-Export-Vergleich. Ohne Lauf zwischen den
Schritten waere ein Fehler nicht mehr einem Schritt zuzuordnen. Sie bringen
keine neue Faehigkeit: der Bau aus Daten laeuft seit Stufe 1 und ist mit
VF_SPEC_BAU belegt (5 OK, 0 Fehler).
Verifiziert: 109 pytest-Tests gruen, beide .lsp lint-sauber, kein neuer
alert/get*/ssget im Bau-Pfad (statischer Waechter).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ergebnis des EXPORTCSV/EXPORTSIVAS-Laufs auf der Mubea-Zeichnung NACH dem
ID-/ZUORDNUNG-Fix (2168410), abgelegt nach der Konvention von
tests/reference/ (<basis>_export.csv + <basis>_sivas.csv, wie
foerderer_tests/gefaellestrecke_tests/kreisel_tests/omniflo_tests).
mubea_export.csv belegt beide reparierten Punkte:
- 119 Zeilen mit 119 unterschiedlichen TeileIds, lueckenlos 0001-0119.
Vorher teilten sich Gefaellestrecke/VF/Kreisel und die aus ihnen
erzeugten Separator-Kopien 26 IDs (0001-0026).
- Jeder der 20 Gefaellestrecken ist genau ein Separator zugeordnet
(0016-0035), den VF-Strecken 0013/0014/0015 sind es 2/5/4. Nur die 7
tatsaechlich freistehenden Separatoren haengen noch an einer
Kreiselhaelfte (0001-R, 0002-L, 0010-R). Vorher landeten 26 in VF/GF
VERPACKTE Separatoren bei einer Kreiselhaelfte, weil die Python-seitige
Boundingbox-Suche die bekannte Wrapper-Zuordnung ueberschrieb.
tests/test_export_ids.py laeuft gegen diese Datei gruen (gegen die alte,
fehlerhafte CSV meldete er alle 26 Dubletten).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Beim CSV-Export von Mubea trugen Gefaellestrecke/VF/Kreisel und die aus
ihnen erzeugten Separator-Kopien dieselbe ID (26 Dubletten 0001-0026), und
die ZUORDNUNG der Separatoren zeigte auf den falschen Carrier.
ssg-id-check-all: neue Phase 0 ermittelt das globale Maximum der bereits
vergebenen IDs, BEVOR die erste neue ID vergeben wird (ausgelagert nach
ssg-id-max-in-ss, das auch ssg-id-max nutzt). Bisher wurde max-id erst
waehrend Phase 1 mitgezogen (Start 0); da (ssget "X" ...) in BricsCAD die
zuletzt erzeugten Entities zuerst liefert, standen die noch ID-losen
Separator-Kopien ganz vorne und bekamen 0001, 0002, ... - genau die IDs der
weiter hinten liegenden Wrapper-Bloecke. Phase 2 konnte das nicht heilen,
weil frisch vergebene IDs nicht in id-map landen.
ssg-collect-nested-inserts: fuehrt Position, Z-Drehung und Skalierung jetzt
ueber alle Verschachtelungsebenen mit (Records statt nackter Entity-Namen).
Vorher gab die Rekursion Entities tieferer Ebenen mit ihrer ROH-Position aus
der Zwischen-Blockdefinition zurueck - zwei Separatoren an derselben lokalen
Stelle in zwei verschieden platzierten Zwischenbloecken landeten dadurch auf
exakt derselben Weltposition.
csv:sep-proxies-erzeugen: die Kopie steht jetzt exakt auf Position/Drehung/
Skalierung ihres verpackten Vorbilds; der kosmetische Versatz von 500 mm ist
weg (er kippte Separatoren am Kettenende in die Boundingbox des Nachbar-
Carriers). Der vla-InsertBlock-Aufruf ist gekapselt, damit ein Sonderfall
nur diese eine Kopie ausfallen laesst statt den ganzen Export abzubrechen.
csv:sep-proxies-zuordnung-setzen (neu, laeuft NACH ssg-id-check-all, da ein
frisch gebauter Wrapper vorher keine ID hat): fuer einen VERPACKTEN Separator
ist der Carrier bekannt - es ist der Wrapper, in dem er steckt. ZUORDNUNG
wird daher auf die Wrapper-ID gesetzt (Separator in VF 0010 -> ZUORDNUNG
0010) und ueber *cs-sep-fix-by-handle* festgenagelt: cs-zuordnung-lauf
uebernimmt sie unveraendert statt sie geometrisch neu zu raten, und
csv:block-to-json reicht sie als "zuordnung_fix" an export_csv.py durch.
Ohne das ueberschrieb compute_sensor_zuordnung (Prioritaet GF > Foerderer >
Kreiselhaelfte) den bekannten Wert - in der Mubea-Zeichnung landeten 26 in
VF/GF verpackte Separatoren so bei einer Kreiselhaelfte.
export_csv.py: respektiert "zuordnung_fix" und ersetzt eine vorhandene
ZUORDNUNG nicht mehr durch "nicht zugeordnet" - nur ein echter Treffer
ueberschreibt, wie im Docstring von compute_sensor_zuordnung beschrieben.
tests/test_export_ids.py (neu): prueft je tests/output/*_export.csv, dass
jede TeileId hoechstens einmal vorkommt und jede Sensor-Zuordnung auf eine
existierende TeileId zeigt. Gegen die fehlerhafte Mubea-CSV schlaegt der
Test mit allen 26 Dubletten an.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Nach dem gruenen VF_SPEC_BAU-Lauf bauten zwei Tests dieselben 5 Ketten. Der
Spec-Pfad ist jetzt der routinemaessige Bau-Test, der Aufzeichnungs-Pfad der
abgeschaltete Regressionstest fuer das Journal-Format.
Umbenennungen:
- tests/testdata/vf_spec_hundm05.json -> tests/testdata/hundm05.json
Die Spec ist das Eingabeformat und die Datei, in der weitere Ketten der
Anlage nachgetragen werden. spec_ids jetzt VF_hundm05_LZ_* (wie im
Aufzeichnungs-Protokoll), damit sich die Ergebnisse beider Laeufe paaren
lassen.
- tests/testdata/hundm05.json -> tests/testdata/hm_recformat.json
tests/test_hundm05.lsp -> tests/test_hm_recformat.lsp (TEST_HM_RECFORMAT,
Praefix hmrec:, Export hm_recformat:export-results)
tests/test_hundm05.py -> tests/test_hm_recformat.py
In alltests.json auf "disabled": true.
Neu: tests/test_hundm05.lsp (TEST_HUNDM05) baut die Spec - OHNE eigene
Bau-Logik, es ruft vsp-bau-datei aus Lisp/vf_spec.lsp. Damit gibt es genau
einen Code-Pfad, der aus einer Spec Geometrie erzeugt; c:VF_SPEC_BAU nutzt
denselben. tests/test_hundm05.py prueft das Ergebnis (die 9 Tests, die
vorher in test_vf_spec.py standen); test_vf_spec.py ist jetzt reiner
Uebersetzer-Test ohne CAD.
Warum das Aufzeichnungsformat bleibt (Details in
doc/TODO-plan-vf-interactive.md Abschnitt 4.7):
- hm_recformat.json ist die EINZIGE eingecheckte Kopie der Originaldaten
(data/polylines.dxf ist mit 124 MB per .gitignore ausgeschlossen). Die Spec
ist daraus abgeleitet; ohne die Aufzeichnung faellt die rechte Seite des
Rundlauf-Beweises weg.
- Es prueft eine ANDERE Invariante: das Journal kommt roh aus der XDATA einer
Kundenzeichnung. TEST_HM_RECFORMAT ist damit der einzige Test dafuer, dass
ein BESTEHENDER VF_n-Block weiter abspielbar ist - also dass
Doppelklick-Edit und 2D/3D-Konvertierung an Altbestand funktionieren. Ein
spec-gebautes Journal kann das nicht zeigen, es kommt aus dem Uebersetzer.
- Es dokumentiert die Frage-Reihenfolge (kommentar je Eintrag); die Spec
verbirgt den Dialog, das ist ihr Zweck.
Weitere Anpassungen:
- Ergebnisdatei heisst nach der Spec-Datei (<basisname>_results.json), damit
Befehl und Testrunner in dieselbe Datei schreiben. Verzeichnis: tests/output
(Override DXFM_VF_SPEC_OUT); NICHT DXFM_RESULTS - das sind die Sivas-/
CSV-Exporte, dort landete die Datei ausserhalb des Testbaums.
- Neu *vsp-dim-override* fuer TEST_HUNDM05_2D/_3D: wird je Kette angewandt,
weil der Abbruch-Handler in vf-linienzug-modus *ssg-ils-dim* zurueck setzt.
- Das Anlagenkuerzel der test_id in lib/vf_journal_export.py kam aus dem
Namen der Ziel-JSON. Nach der Umbenennung haette eine Regenerierung die ids
stillschweigend auf VF_hm_recformat_LZ_* geaendert und die Paarung der
beiden Laeufe zerlegt - jetzt feste Konstante TEST_ID_ANLAGE.
- conftest: hundm05_* Fixtures -> hmrec_* (die Spec-Fixtures stehen in
tests/test_hundm05.py).
Verifiziert: 98 pytest-Tests gruen (die 9 Ergebnis-Tests warten auf einen
neuen TEST_HUNDM05-Lauf), alle .lsp lint-sauber, Spec-Regenerierung
idempotent, TEST_VF_SPEC in BricsCAD 28 PASS / 0 FAIL.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Stufe 1 des Fahrplans in doc/TODO-plan-vf-interactive.md, fertig fuer
Modus 1. Eine SPEC beschreibt eine Kette in Domaenenwerten ("links",
"winkel", "aussen", ja/nein) statt in Menue-Codes; vsp-journal uebersetzt sie
in ein Eingabe-Journal, vsp-bau-aus-spec spielt es per
vfl-journal-replay-start durch den UNVERAENDERTEN vf-linienzug-modus. Der
fertige Block traegt damit dasselbe SSG_VF_EDIT-Journal wie eine handgebaute
Kette und bleibt per Doppelklick editier- und 2D/3D-konvertierbar - kein
Journal-Konsument muss etwas von Specs wissen.
CAD-Lauf VF_SPEC_BAU: 5 OK, 0 Fehler. Je Kette status "executed",
prompts 0 (keine Live-Eingabe erreicht), eingaben_offen 0, keine
Spec-Fehler, keine Bau-Meldungen, glieder_ist == glieder_soll,
Einfuegepunkt gleich dem Kettenstart der Spec.
Neu:
- Lisp/vf_spec.lsp: Code-Tabellen, Emitter vsp-journal, Validierung
vsp-pruefen, flacher JSON-Loader, Headless-Rahmen vsp-headless-an/-aus,
Ergebnis-Record, vsp-bau-aus-spec/-liste, c:VF_SPEC_BAU. Von vf_core.lsp
NACH vf_linienzug.lsp geladen - damit sind beide Ladewege abgedeckt (Menue
und der .scr-Loader), das MNL bleibt unveraendert.
- lib/vf_spec_export.py: derselbe Emitter in Python PLUS die Umkehrung
(spec_aus_journal), erzeugt die Spec-Testdaten.
- tests/testdata/vf_spec_hundm05.json: die 5 echten Ketten als Spec,
erzeugt statt handgeschrieben.
- tests/test_vf_spec.lsp (C:TEST_VF_SPEC, in alltests.json): 7 Faelle je
Glied-Typ, 7 Validierungsfaelle, Gruppieren, und die 5 echten Ketten gegen
ihr aufgezeichnetes Journal.
- tests/test_vf_spec.py: 36 Tests (Rundlauf, Spec-Daten, Validierung,
Erwartungswert-Abgleich, Ergebnisse von VF_SPEC_BAU).
Drei Regeln, die der Uebersetzer besitzen muss - jede wuerde sonst die ganze
Replay-Queue verschieben:
- Der Menue-Code haengt am Frame: erste Sektion 4 Optionen (kein GF-Bogen,
es gibt noch keine Richtung), jede spaetere 5.
- hz steht genau EINMAL im Journal, beim ersten Segment (vfl-in-abstand
journalisiert die Richtung nur bei freier Richtungswahl).
- Nur ein HORIZONTALER Erstkoerper einer VF-Einheit stellt die Separator-/
Endpunktfragen vorab (winkel1=0 laeuft durch vfl-baue-horizontal-koerper);
ein gewinkelter wird ohne jede Frage gebaut.
Wie die Richtigkeit belegt ist - drei Implementierungen derselben Grammatik,
die einander pruefen:
- Rundlauf gegen echte Daten: journal_aus_spec(spec_aus_journal(tok)) == tok
fuer alle 5 HundM-Ketten, tokenweise numerisch verglichen. Damit ist
bewiesen, dass die Spec das Journal verlustfrei abbildet.
- Der Weg, den LISP nimmt (flaches JSON -> Spec -> Journal), ergibt separat
geprueft dieselben Journale wie das aufgezeichnete Protokoll.
- Der unabhaengige Dekoder aus lib/vf_journal_export.py verdaut alle 7
synthetischen Emitter-Ausgaben restlos, auch die zwei Zweige, die in den
echten Daten fehlen (Linie-VF, gewinkelter Erstkoerper).
- Die Erwartungswerte im LISP-Test kommen aus dem geprueften Python-Emitter;
TestLispErwartungen liest sie zurueck und vergleicht erneut. Ohne das
koennte ein Uebertragungsfehler einen falschen Erwartungswert
festschreiben und der CAD-Lauf waere gruen, obwohl der Emitter falsch
liegt.
Abweichungen von der Planung (Begruendungen in doc/TODO-plan-vf-interactive.md
Abschnitt 4.6): vsp-pruefen ruft den Emitter statt eine zweite Regelmenge zu
pflegen; das vollstaendige Journal steht nicht im Record (statt dessen
glieder_soll/glieder_ist als Desync-Detektor); Zusatzfeld segment_typ am
Glied "Linie", weil dort vfl-segment-entscheidung selbst zwischen GF und VF
waehlt; vf_ende-Werte "automatisch"/"zielpunkt-ohne-es" fuer die Faelle ohne
Frage; Praefix vsp- statt vfs- (das gehoert vf_standard.lsp).
Zusaetzlich:
- tests/test_vf_headless_statisch.py prueft jetzt auch, dass
Lisp/vf_spec.lsp UEBERHAUPT keine Eingabe-/Dialogfunktion aufruft - beim
Daten-Pfad ist die Null die Vorgabe.
- tests/testdata/mubea.json: die drei einzeln eingefuegten S-LP-Separatoren
entfernt (Fortsetzung von 699744e - die Separatoren stecken jetzt in den
Staustreckenbloecken).
Noch offen: die Uebersetzer fuer Modus 2 und 3. Modus 2 braucht laut
Fahrplan erst 2-3 echte "linienzug2"-Journale als Referenz -
tests/testdata/hundm05.json enthaelt ausschliesslich Modus-1-Ketten.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>