Zigzag engine (6802 lines, 184 tests): - Construction 17 normalisation: working through dimension 3+ - Import from homotopy-rs JSON: working (scalar, two_scalars, half_braid) - Piece extraction via Embedding/restrict_diagram: working - Type checking pipeline: working (Eckmann-Hilton half_braid passes) - Essential identity detection: validated with full 2-diagram test Bugs found and fixed: - assemble_factorisations losing cospan legs during reassembly - RewriteN::slice() using source offsets instead of target indices - singular_preimage() not handling passthrough heights - restrict_rewrite() not accounting for accumulated cone offsets - Embedding::preimage() using regular_preimage for Singular case Added vis-engine-spec.md: visualization engine specification - 6-layer architecture from math primitives to scene graph - SVG renderer for 2D, WebGL2 for 3D, custom hit testing - Spring constraint integration point for semiotic rendering - No external dependencies - game engine approach Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
94 lines
3.5 KiB
Rust
94 lines
3.5 KiB
Rust
//! Inspect the categorical structure of half_braid.json
|
|
//!
|
|
//! Run with: cargo run --example inspect_half_braid
|
|
|
|
use std::fs;
|
|
use zigzag_engine::diagram::Diagram;
|
|
use zigzag_engine::import::load_homotopy_diagram_n;
|
|
|
|
fn describe_diagram(d: &Diagram, indent: usize) -> String {
|
|
let prefix = " ".repeat(indent);
|
|
match d {
|
|
Diagram::Diagram0(g) => {
|
|
format!("{}0-diagram: generator id={}, dim={}", prefix, g.id, g.dimension)
|
|
}
|
|
Diagram::DiagramN(dn) => {
|
|
let dim = d.dimension();
|
|
let mut lines = vec![format!(
|
|
"{}{}-diagram with {} cospans:",
|
|
prefix,
|
|
dim,
|
|
dn.cospans.len()
|
|
)];
|
|
lines.push(format!("{} source:", prefix));
|
|
lines.push(describe_diagram(dn.source(), indent + 2));
|
|
if !dn.cospans.is_empty() {
|
|
lines.push(format!("{} target:", prefix));
|
|
lines.push(describe_diagram(&dn.target(), indent + 2));
|
|
}
|
|
lines.join("\n")
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let json = fs::read_to_string("fixtures/half_braid.json")
|
|
.expect("Failed to read half_braid.json");
|
|
let half_braid = load_homotopy_diagram_n(&json)
|
|
.expect("Failed to parse");
|
|
|
|
let half_braid_d = Diagram::DiagramN(half_braid.clone());
|
|
|
|
println!("=== HALF_BRAID CATEGORICAL STRUCTURE ===\n");
|
|
|
|
// The half_braid itself is a 3-diagram
|
|
println!("half_braid is a {}-diagram with {} cospans\n",
|
|
half_braid_d.dimension(), half_braid.cospans.len());
|
|
|
|
// Its source (a 2-diagram)
|
|
let source_2d = half_braid.source();
|
|
println!("SOURCE of half_braid (the 2-diagram it transforms FROM):");
|
|
println!("{}\n", describe_diagram(source_2d, 1));
|
|
|
|
// Its target (a 2-diagram)
|
|
let target_2d = half_braid.target();
|
|
println!("TARGET of half_braid (the 2-diagram it transforms TO):");
|
|
println!("{}\n", describe_diagram(&target_2d, 1));
|
|
|
|
// Are source and target the same?
|
|
println!("Are source and target equal? {}\n", source_2d == &target_2d);
|
|
|
|
// Look at the source 2-diagram structure
|
|
if let Diagram::DiagramN(src) = source_2d {
|
|
println!("=== SOURCE 2-DIAGRAM SLICES ===");
|
|
println!("This 2-diagram has {} cospans (singular heights)\n", src.cospans.len());
|
|
|
|
// Regular slices
|
|
for i in 0..=src.cospans.len() {
|
|
if let Some(slice) = src.regular_slice(i) {
|
|
println!("Regular slice r{}: {}", i, describe_diagram(&slice, 0));
|
|
}
|
|
}
|
|
println!();
|
|
|
|
// Singular slices
|
|
for i in 0..src.cospans.len() {
|
|
if let Some(slice) = src.singular_slice(i) {
|
|
println!("Singular slice s{}: {}", i, describe_diagram(&slice, 0));
|
|
}
|
|
}
|
|
}
|
|
|
|
println!("\n=== INTERPRETATION ===");
|
|
println!("Generator 0 (dim=0): The base object x");
|
|
println!("Generator 1 (dim=2): The scalar s (a 2-cell: id_x → id_x)");
|
|
println!();
|
|
println!("The SOURCE 2-diagram is 'two scalars stacked':");
|
|
println!(" - 2 cospans means 2 singular heights (s0, s1)");
|
|
println!(" - Each singular height is where a scalar (2-cell) lives");
|
|
println!();
|
|
println!("The half_braid 3-diagram is the Eckmann-Hilton homotopy:");
|
|
println!(" - It shows the two scalars 'sliding past' each other");
|
|
println!(" - Source = target (as 2-diagrams, they're the same configuration)");
|
|
println!(" - But the 3-diagram is NON-trivial: it's the braiding coherence");
|
|
}
|