Exact constructions: split and move
The current Python construction layer has two material operations:
Construction.split(piece, planes)extracts the intersection of a piece with all selected halfspaces and retains its entire remainder.Construction.move(piece, motion)applies one checked proper rigid motion to the whole piece, including every internal convex cell.
Planes are ThreePointPlane((a,b,c)), with three ordered, noncollinear algebraic
points. Both split children must be positive-volume and face-connected. Nonconvex
pieces and cavities are supported; disconnected children are rejected. Handles
are consumed by splits or moves, and the operation returns current handles.
See the design and Hafner verification and English recipe guide.
Start with Hafner step 1: split and move.
Then continue through step 2: pentagonal pyramids.
Its recipe starts with augmented_icosidodecahedron, dodecahedron and contains
only the twelve pentagonal transfers. stages.py verifies the step-1 recipe,
preserves its constituent pieces and history, and supplies the assembly input.
The composed certificate still certifies both rhombic endpoint assemblies.
The current recipe starts both solids centered, cycles through 19 splits and
immediate moves, then explicitly moves the last residual. The shared Polycone subroutine
rotates through base vertices to define the wedge sides.
steps executes valid operations and returns the live pieces without issuing a
certificate. Face-based moves do check their contacts locally. Finish closes
the construction; Finish augmented_icosidodecahedron by icosidodecahedron, tetrahedra names its
step-1 target and live constituents. Step 2 declares two targets on consecutive
Finish ... by ... lines. Fixed piece arrays and assemblies expand to their
members, and every live piece must occur exactly once in its correct target
assembly. This does not fuse material or replace the geometric proof. Indentation closes Cycle blocks. The proof
runner then certifies and independently replays the final assembly against the
Hafner target. Each moved handle is written back into its fixed array slot.
python3 -m construction.language steps construction/examples/hafner_nineteen_splits.geom
python3 -m construction.language transpile construction/examples/hafner_nineteen_splits.geom --operations-only
python3 -m construction.language run construction/examples/split_move_brick.geom
python3 -m construction.examples.split_move_hafner --output-dir /tmp/split-move-hafner
python3 -m unittest tests.test_split_move tests.test_split_move_hafner -v
Run from the repository root with Python 3.11 or later. Only the standard library and the existing pure-Python exact kernel are required. No Rust, NumPy, or SciPy.
library/geometry.geom defines Polycone in the recipe language. subroutines.py
reads Define blocks; the ordinary compiler translates them into Python functions
with local variables and explicit returned outputs. Polycone is not a new kernel
primitive or a text alias. Both Hafner stages call the same definition. Its fixed
halfspace array is sized with size(base) at allocation. User definitions precede
Start and can call earlier routines, with no recursion. definitions.py parses
core expressions and inline comments; vocabulary.py lists the data operations.
The current Hafner recipe explains each operation with comments and
uses Let base_faces[20] be face of icosahedron, Cycle 19 into i:, and bracket indexing.
Cycle triangle by j into a, b, c: visits cyclic vertex triples.
Let sides[3] be halfspace allocates typed slots and Bound space by sides into wedge
intersects the filled array. cycle_syntax.py handles indentation and source lines.
Bound space by ab, bc, ca into wedge constructs an immutable Region of three halfspaces; Plane and Half define their geometry separately.
Let triangular_faces[20] be face[3] of icosidodecahedron reads candidate faces;
Match triangular_faces by base_faces, outward_docking into receiving_faces
reorders all faces by exact outward direction and congruence, preserving their vertex order.
Move tetrahedron by triangle, receiving_faces[i] into tetrahedron docks them
and checks full face equality, opposite sides, and overlap with placed pieces.
space is a constant, and face values have their own read-only Face type;
Split residual by wedge ... changes the material. Fixed-size arrays live in
arrays.py, and Region is defined in pieces.py.
history.py records and replays contact histories as scissors-split-move-v2,
while preserving v1 replay; contact.py checks exposed supporting convex polygons.
pieces.py implements
the nonconvex intersection/remainder and connectivity rules.
goals.py defines initial assemblies and independent target regions.
The Hafner example now uses 19 binary splits and 20 proper moves, retaining a
stationary icosidodecahedron. The generic verifier checks all final physical-piece
pairs and exact target coverage. It does not invoke a fan-specific proof rule.
The step 2 example adds 12 pentagonal transfers to its verified prerequisite: 31 total splits, 32 moves,
34 physical pieces in two separately checked rhombic assemblies.
Let pentagonal_faces[12] be face[5] of icosidodecahedron filters by vertex count;
Let vertices[12] be point of icosahedron reads canonical reference coordinates
without introducing additional material;
Match vertices by pentagonal_faces, outward_ray into apices reorders them in face order
on the outward-normal rays from their centroid. The dodecahedron uses the dual
orientation of the icosahedron, scaled to the same edge length.
relations.py defines typed immutable relations separately from the generic
Match T[n] by U[n], relation(T,U) into T[n] permutation operation. same_position also
supports exact point-to-point matching. Missing or ambiguous matches, duplicate
candidates, and candidate reuse fail. Both inputs must be fixed arrays of equal length; every candidate is used once.
Subset selection will use Select if needed; that keyword is not implemented yet.
Move chooses the vertex correspondence and records it for exact replay.
python3 -m construction.examples.hafner_pentagonal_transfer --output-dir /tmp/hafner-step2
python3 -m unittest tests.test_hafner_pentagonal_transfer -v
Continuous collision-free paths and fabrication are separate obligations.
The earlier Dissection, PartitionConstruction, and special transfer APIs are
retained for historical reproduction. Old .geom examples use
python3 -m construction.legacy_language, with legacy_aliases.json. Their
special certificate formats retain their original checkers. Existing saved-eight
and search workflows are unchanged. New work should use Construction,
PhysicalPiece, ThreePointPlane, Motion, and verify_history.