|
CDT++ 1.0.0
Causal Dynamical Triangulations in C++
|
This directory is the bounded behavior-level oracle published for issue #94 and for the Rust causal-triangulations implementation. CDT++ is an independent implementation under comparison, not presumed ground truth. A discrepancy is an investigation target until the protocol or one of the implementations explains it.
The principal reason to preserve this implementation is its causality-filtering Delaunay construction path in Foliated_triangulation.hpp. find_invalid_timevalue_cells classifies cells from stored vertex time labels, has_valid_timevalues provides the predicate, find_bad_vertex selects a vertex responsible for an acausal local configuration, and fix_timevalues removes offending vertices through CGAL so the cavity is retriangulated until the foliation contract is satisfied.
The deterministic doctest scenario "Detecting and fixing problems with vertices and cells" in Foliated_triangulation_test.cpp exercises this path with fixed points and time labels. Its inputs, detected bad vertex, final initialization state, cell counts, and causal classification are the first comparison fixture for causal-triangulations; exact Monte Carlo trajectories are not required to match.
The package extends that construction case with the complete move set, action values, Metropolis-Hastings decisions, persistence records, and one bounded end-to-end run.
After building, run the construction fixture directly with:
Run the complete offline package validator with:
It applies the complete JSON Schema Draft 2020-12 contracts, then checks canonical identifiers and ordering, incidence, reciprocal adjacency, causal edge and simplex classification, f-vectors and Euler relations, all five move sites and deltas, raw proposal domains, independent closed-form actions and Metropolis-Hastings probabilities, deterministic decisions, persistence size and FNV-1a integrity, bounded-run command provenance and declared f-vector band, matched scaling parameters, raw sample counts, and manifest SHA-256 values.
Read fixtures/v1/protocol.json first. Entity arrays are canonical:
Compare topology, incidence, adjacency, foliation labels, simplex and edge types, f-vectors, move sites, integer deltas, and accept/reject decisions exactly. Compare coordinates, actions, deltas, and probabilities with the named quantity-specific absolute-plus-relative tolerance. Do not apply one repository-wide percentage.
Transition fixtures provide the raw proposal site and acceptance variate. They therefore test proposal preparation, action delta, Hastings factor, and commit/reject behavior without requiring the C++ and Rust implementations to share an RNG engine, allocation order, or container iteration order.
This complete command writes the same manifested pair consumed by the second command:
Despite the suffix, this is not generic mesh OFF. Plain geometry cannot carry the vertex time labels, causal cell types, artifact role, or stochastic provenance required to reconstruct a CDT state. The pair is the archival interchange boundary and remains coupled to the pinned CDT++/CGAL persistence contract documented in docs/reproducibility.md.
The successor workflow is:
The causal-triangulations side should own that importer: validate the complete pair at its input boundary, reconstruct its native invariant-bearing state, and then use its own serialization. CDT++ should not add a second lossy converter or pretend that the CGAL payload alone is portable. Direct Rust import is a downstream compatibility direction, not a capability claimed by the CDT++ v1.0.0 release.
For generating many separately seeded random starting states, invoke just initialize with a different seed in a dedicated directory for each run and preserve every payload/manifest pair together. The seed replays pre-CGAL random inputs; the persisted pair, not the seed alone, identifies the exact post-repair topology to import or evolve.
CDT++ checkpoints serve a different purpose from this interchange boundary. just resume CHECKPOINT.off can continue the identical CDT++ Markov chain after an interrupted Slurm/HPC job because the checkpoint sidecar records mutable PCG state and cumulative transition accounting. That restart contract is deliberately locked to the recorded CDT++ source revision and producer toolchain. A successor importer should consume initial-triangulation artifacts for independent evolution, not depend on CDT++'s private checkpoint engine state.
The repository's cdt-compare command copies this protocol, the canonical C++ result, the v1 result schema, and a selected run manifest into a local bundle before launching independent C++ and Rust producers. It anchors the live C++ payload to the committed result, retains both raw process records, anchors any live C++ transition observations to this protocol, and applies only the exact and named numerical rules declared here. just comparison-analyze PATH requires the complete canonical artifact inventory, verifies every retained digest, and reproduces the machine-readable summary without rerunning either implementation.
After building CDT++ and a compatible Rust fixture producer, run one bounded comparison and retain it locally:
Reproduce summary.json entirely from the stored raw artifacts, without running either executable:
The bundle under out/comparisons/run-1 is published atomically only after analysis and manifest creation finish. Preserve its inputs/, raw/, manifest.json, and summary.json together. Python validates the artifact inventory and its digests, validates schemas, constructs commands, classifies comparisons, and renders a small text table; it does not implement topology, action, move-legality, or acceptance rules. See the comparison-harness contract for producer configuration, placeholders, artifact layout, failure records, and the C++ reference/Rust result boundary.
The retained cdt-optimize-initialize command is also entirely local and dependency-free. It writes one directory per parameter pair under out/experiments/initialize, including configuration JSON, raw stdout, a tab-separated volume profile, metrics, artifact digests, and source/executable provenance. Each invocation requires a nonexistent output path. Seed 92 is the default; use --seed and --output-directory for another replayable record. Fresh CGAL triangulations remain subject to the reproducibility contract.
Inspect its command line with:
reference-fixtures is a quick diagnostic that builds and prints only cpp-reference.json:
The archival workflow is:
It refuses a dirty worktree, builds the sequential and parallel configurations, and regenerates all four artifact families before publishing them:
The generator updates both manifests, records the exact producer command for every file under raw/v1/, and refreshes all SHA-256 values. The recipe then runs the offline validator and reference-archive-check, which requires every raw record and manifest to name the same clean Git commit. The v1 manifest templates are macOS-arm64-specific, so regeneration refuses a different host instead of publishing records under a misleading platform name.
Regeneration is a review operation. Explain every exact-field change. A randomized CGAL f-vector, wall-clock sample, or benchmark checksum change is diagnostic data, not automatically a defect; deterministic minimal fixtures and transition results must remain exact.
The comprehensive just ci gate additionally rebuilds the C++ fixture executable and compares its canonical states and actions with the committed raw record. It reuses the offline validation performed by just check; the generated-only step compares exact topology and metadata while applying the protocol’s named tolerances to coordinates and action values. Host, compiler, and source-revision provenance are intentionally excluded from that equality check.
The committed macOS records retain the -dirty revision captured during the review for issue #94. Their scientific payload remains covered by just reference-check and just reference-generated-check, but they are not the final archival provenance record. Issue #97 must first commit the release metadata, run just reference-regenerate from that exact clean producer commit, and then review and commit the regenerated raw artifacts and manifests. The final merged release state is tagged; its files name the preceding producer commit because an artifact commit cannot record its own hash. Both just tag and just tag-check enforce the provenance-only archival check, which intentionally fails until that handoff is complete.
The package does not claim exact cross-language Monte Carlo trajectories, exact fresh topology for nested cospherical CGAL inputs, a general performance study, or a calibrated phase-distribution equivalence result. The spherical population value is explicitly a monotone construction heuristic; randomized post-repair simplex counts are implementation-specific. The rigorous quadratic tetrahedron bound is retained only for safety and preflight reasoning.