hex_place source

← hex_place · API reference · version 0.1.3

6 file(s), 674 lines. This is the source the published version ships, and it is loft — the library is written in the same language you call it from.

Public items

A worked example is a call site the author chose as the thing to read first. Call sites are every line naming the item, found mechanically over the source with comments excluded — so an item with no worked example is not an item nobody uses.

ItemDefinedWorked exampleCall sites
field_union fn34—58
combine_cut fn57HXP-00242 53 54 61 85 86 … (7 total)
combine_cut_level fn106HXP-003119
kappa_at_level fn147HXP-003125 126 129
shared_marked fn160HXP-00143 56 62
Pose struct25—34 35 40 44 49 54 … (8 total)
pose_new fn34—25 180
pose_inv_x fn40—67 82 30
pose_inv_y fn44—68 83 31
pose_fwd_x fn49—69 28 196
pose_fwd_y fn54—70 29 197
pose_residual fn66HXP-005183 187 192
disk_hit fn81—198
arb_solid fn98HXP-00649 50 51 213 214 215
arb_owner fn105HXP-006218 219 222 223 226
SEAT_LOW const31—56 149
SEAT_MEAN const32—150
SEAT_HIGH const33—57 151
seat_height fn38HXP-004149 150 151
seat_residual fn66HXP-004154 155
seat_write fn85HXP-004159

src/hex_place.loft

// Copyright (c) 2026 Jurjen Stellingwerff
// SPDX-License-Identifier: LGPL-3.0-or-later
// hex_place — place, seat and combine — the operations a model survives.
//
// A body carries a POSE and is never stamped into the world lattice; two stencils are combined
// by "mark all, then cut once", which is order-free and fuses their shared edge; and a stencil
// is SEATED on terrain by writing the height slot alone, so its footprint is untouched.
//
// Entry point: re-exports `hexframe`, `hexseat`, `hexcombine`.
pub use hexframe::*;
pub use hexseat::*;
pub use hexcombine::*;

src/hexcombine.loft

// Copyright (c) 2026 Jurjen Stellingwerff
// SPDX-License-Identifier: LGPL-3.0-or-later
// hexcombine — TWO STENCILS ADJACENT: WHO OWNS THE SHARED EDGE? (rung A8, the combination rung).
//
// Where things that work ALONE stop working TOGETHER.  The mechanism is crawler's `cut_arb`,
// float-free.  The design in one line:
//
//   "MARK EVERY PART, THEN CUT ONCE."
//
// Do NOT draw each stencil's walls and overlay them.  Union the footprints first, then cut the
// boundary of the UNION once, tagging each boundary edge with the material of the source stencil
// its cell came from.  Two consequences, both the point of the rung:
//
//   ORDER-FREE BY CONSTRUCTION.  The result reads only the finished union and the fixed source
//   map — never which stencil was stamped when — so `combine_cut(a, b) == combine_cut(b, a)`.  The
//   naive per-body overlay is last-writer, hence order-DEPENDENT: it works for one stencil and
//   breaks for two.  (This is `X4` / law K₂: same-level overlap arbitrates deterministically and
//   order-freely.)
//
//   THE SHARED EDGE FUSES.  Between two adjacent stencils the shared edge is INTERIOR to the union,
//   so cutting the union's boundary never marks it — nobody owns it, and there is no seam wall.
//   Two adjacent stencils become one fabric (crawler's FORMS.md, DESIGN §8.0.1: "seated fabric may
//   merge").  Which two parts were authored is not recoverable from the fabric, and by law P1 need
//   not be — `rebuild` returns the canonical representative.
//
// Exact and float-free: the "nearest source" of a boundary edge is simply its own bordering cell's
// stencil, so no distance and no float enter.  This is the κ ≤ 2 case; N stencils are the same
// construction (union all, cut once, nearest source).  Different LEVELS never contend at all
// (crawler's bridge guarantee) — that axis waits on the layer machinery and is not gated here.
use hex_field::*;
use hex_form::*;

// The union footprint of two stencils sharing `a`'s chunk — a fresh HexSet, `a ∪ b`.
pub fn field_union(a: HexSet, b: HexSet) -> HexSet {
  u = hexset_chunk(hexset_q0(a), hexset_r0(a), hexset_w(a), hexset_h(a));
  for r in hexset_r0(a)..hexset_r0(a) + hexset_h(a) {
    for q in hexset_q0(a)..hexset_q0(a) + hexset_w(a) {
      if hexset_get(a, q, r) || hexset_get(b, q, r) { hexset_set(u, q, r, true); }
    }
  }
  u
}

// Combine two same-level stencils: union the footprints, cut the boundary of the union ONCE, and
// tag each boundary edge with the material of the source stencil its bordering cell came from.
// Order-free by construction (reads the finished union + source map, never stamp order); the shared
// interior edge is never cut, so adjacent stencils fuse.  Returns the number of edges cut.
//
// The tie-break is INTRINSIC, not positional: a cell in BOTH stencils (an overlap) takes the LOWER
// material id, so `combine_cut(a,b) == combine_cut(b,a)` for overlapping stencils too, not only
// disjoint ones — otherwise "order-free" would quietly hold only for the adjacency case gated here.
// (crawler's full `cut_arb` breaks the same tie by nearest SURFACE then lower id; with no surfaces
// in play the lower id is the whole rule.  Overlap itself is a separate, ungated A8 axis.)
//
// Example: @HXP-001
// Example: @HXP-002
pub fn combine_cut(a: HexSet, ma: integer, b: HexSet, mb: integer, e: EdgeSet) -> integer {
  u = field_union(a, b);
  n = 0;
  for r in hexset_r0(u)..hexset_r0(u) + hexset_h(u) {
    for q in hexset_q0(u)..hexset_q0(u) + hexset_w(u) {
      if hexset_get(u, q, r) {
        for d in 0..6 {
          nq = nb_q(q, r, d);
          nr = nb_r(q, r, d);
          if !hexset_get(u, nq, nr) {
            ina = hexset_get(a, q, r);
            inb = hexset_get(b, q, r);
            m = ma;
            if inb && !ina { m = mb; }
            if ina && inb && mb < ma { m = mb; }   // overlap: lower id, order-free
            edge_set_mat(e, q, r, nq, nr, m);
            n = n + 1;
          }
        }
      }
    }
  }
  n
}

// ── LEVELS — THE BRIDGE GUARANTEE ──────────────────────────────────────────
//
// A **level** is the topological *sheet* a thing sits on — exactly OSM's `layer` tag, and the
// `layer*` axis the foxel already has at the top of its schema (`ROUNDTRIP` §2.4; moros's `cy`).
// crawler settled what it buys (`bridgetest.loft`), and the sharpest statement of it is a contrast:
//
//   > the SAME two ways, at the same level, are a level crossing; at different levels, a bridge.
//   > Nothing about the ways changes — only the sheet.
//
// **A LEVEL IS NOT A HEIGHT.** The actual `z` comes from the surface/feature interval; the level is
// a discrete sheet index and nothing else. Two things can share a `z` on different levels, or sit
// at different `z` on the same one.
//
// The load-bearing consequence, and why this is not just bookkeeping: **different levels never
// contend.** So the level is a **filter applied BEFORE the cut**, not an arbitration rule after it —
// it does work the contention degree `κ` would otherwise have to do (`X4`, and `DESIGN` §6.1). Most
// of a world exists only at level 0, where this costs exactly nothing.

// Combine two stencils **as seen at level `at`**: only those whose own level matches take part, and
// the survivors are then cut exactly as `combine_cut` does.  Two stencils on different levels can
// therefore never fuse, never arbitrate and never contend — at either level, one of them simply is
// not there.  Returns the number of edges cut at this level.
//
// Example: @HXP-003
pub fn combine_cut_level(a: HexSet, la: integer, ma: integer,
                         b: HexSet, lb: integer, mb: integer,
                         at: integer, e: EdgeSet) -> integer {
  ina = la == at;
  inb = lb == at;
  u = hexset_chunk(hexset_q0(a), hexset_r0(a), hexset_w(a), hexset_h(a));
  for r in hexset_r0(a)..hexset_r0(a) + hexset_h(a) {
    for q in hexset_q0(a)..hexset_q0(a) + hexset_w(a) {
      if (ina && hexset_get(a, q, r)) || (inb && hexset_get(b, q, r)) {
        hexset_set(u, q, r, true);
      }
    }
  }
  n = 0;
  for r2 in hexset_r0(u)..hexset_r0(u) + hexset_h(u) {
    for q2 in hexset_q0(u)..hexset_q0(u) + hexset_w(u) {
      if hexset_get(u, q2, r2) {
        for d in 0..6 {
          nq = nb_q(q2, r2, d);
          nr = nb_r(q2, r2, d);
          if !hexset_get(u, nq, nr) {
            inaa = ina && hexset_get(a, q2, r2);
            inbb = inb && hexset_get(b, q2, r2);
            m = ma;
            if inbb && !inaa { m = mb; }
            if inaa && inbb && mb < ma { m = mb; }   // overlap: lower id, order-free (X52)
            edge_set_mat(e, q2, r2, nq, nr, m);
            n = n + 1;
          }
        }
      }
    }
  }
  n
}

// The contention degree at one cell, counted **per level**: how many of the two stencils claim it
// *at level `at`*.  This is `κ` (`X53`) made level-aware — two stencils that overlap in `(q,r)` but
// sit on different sheets give `κ = 1` at each level, never `κ = 2` at either.
//
// Example: @HXP-003
pub fn kappa_at_level(a: HexSet, la: integer, b: HexSet, lb: integer,
                      at: integer, q: integer, r: integer) -> integer {
  k = 0;
  if la == at && hexset_get(a, q, r) { k = k + 1; }
  if lb == at && hexset_get(b, q, r) { k = k + 1; }
  k
}

// How many marked edges separate an `a`-cell from a `b`-cell — the "shared wall" run.  Zero after
// `combine_cut` (the seam fuses); non-zero after a per-body overlay (a spurious seam wall).  This
// is the measurable form of "who owns the shared edge?": nobody, if the parts were combined right.
//
// Example: @HXP-001
pub fn shared_marked(a: HexSet, b: HexSet, e: EdgeSet) -> integer {
  n = 0;
  for r in hexset_r0(a)..hexset_r0(a) + hexset_h(a) {
    for q in hexset_q0(a)..hexset_q0(a) + hexset_w(a) {
      if hexset_get(a, q, r) {
        for d in 0..6 {
          nq = nb_q(q, r, d);
          nr = nb_r(q, r, d);
          if hexset_get(b, nq, nr) && edge_mat(e, q, r, nq, nr) != 0 { n = n + 1; }
        }
      }
    }
  }
  n
}

src/hexframe.loft

// Copyright (c) 2026 Jurjen Stellingwerff
// SPDX-License-Identifier: LGPL-3.0-or-later
// hexframe — THE FRAME SEAM: a POSED body against the world (DESIGN §6; laws K₁, K₂).
//
// Collision reads several presentations at once — the world (identity frame) plus every posed body.
// Inside a frame geometry is exact; ACROSS frames it cannot be, because a pose is continuous.  The
// whole discipline of this module is to make the error live in exactly ONE place:
//
//   THE POSE TRANSFORM IS THE SOLE FLOATING-POINT STEP.  Every cross-frame query routes through it
//   once — world → p⁻¹ → exact local test → (p) → world — so ε > 0 is permitted ONLY on the seam
//   (`ε_seam`), and is a DETERMINISTIC function of its inputs (`L7`/`I9`: byte-identical replay).
//   Inside a frame the error is exactly 0.  (crawler's chunk seam is a different thing, and exact.)
//
// The FORBIDDEN fix is closing a crack by moving geometry — snapping a body's wall onto the world
// lattice.  That relocates the machine-ε seam error into a frame INTERIOR, where it becomes a real
// displacement, and voids law D for that body.  `tests/seam.loft` §3 measures both.
//
// This is the one place `hexframe` is float, on purpose.  Everything the pose acts on is otherwise
// integer/exact (X1–X52), so `ε_seam` is the entire error budget of the stack.
use hex_form::*;

// A pose: a rotation (given as its cos/sin, so a Pythagorean angle can be represented EXACTLY) then
// a translation.  Stored as cos/sin rather than θ so a gate can build a rational rotation and check
// the float pipeline against an exact integer oracle.
pub struct Pose {
  ps_cs: float,
  ps_sn: float,
  ps_tx: float,
  ps_ty: float,
}

// A placement: a rotation given as cos/sin and a translation.  Storing the pair rather than
// an angle keeps `pose_fwd` and `pose_inv` exact inverses with no trig at use time.
pub fn pose_new(cs: float, sn: float, tx: float, ty: float) -> Pose {
  Pose { ps_cs: cs, ps_sn: sn, ps_tx: tx, ps_ty: ty }
}

// world → local.  THE sole float step (with `pose_fwd_*`).  A cross-frame query calls this once and
// then tests in the body's own exact frame.
pub fn pose_inv_x(p: Pose, wx: float, wy: float) -> float {
  p.ps_cs * (wx - p.ps_tx) + p.ps_sn * (wy - p.ps_ty)
}
// A world point's y in the pose's frame — the companion of `pose_inv_x`.
pub fn pose_inv_y(p: Pose, wx: float, wy: float) -> float {
  0.0 - p.ps_sn * (wx - p.ps_tx) + p.ps_cs * (wy - p.ps_ty)
}

// local → world.
pub fn pose_fwd_x(p: Pose, lx: float, ly: float) -> float {
  p.ps_cs * lx - p.ps_sn * ly + p.ps_tx
}
// A local point's y in the world — the companion of `pose_fwd_x`, and the inverse of
// `pose_inv_y`.
pub fn pose_fwd_y(p: Pose, lx: float, ly: float) -> float {
  p.ps_sn * lx + p.ps_cs * ly + p.ps_ty
}

// The round-trip residual |p(p⁻¹(W)) − W|∞ at one world point — the transform's numerical error,
// which is what `ε_seam` bounds.  Exactly 0 in exact arithmetic; ~machine ε in float.
//
// AT ONE WORLD POINT is the load-bearing half: this is a jagged, deterministic function of the
// point, not a constant.  Near the frame origin it commonly reads exactly 0, and reading it there
// and adopting that as ε_seam is the mistake the number exists to prevent.
//
// Example: @HXP-005
pub fn pose_residual(p: Pose, wx: float, wy: float) -> float {
  lx = pose_inv_x(p, wx, wy);
  ly = pose_inv_y(p, wx, wy);
  bx = pose_fwd_x(p, lx, ly);
  by = pose_fwd_y(p, lx, ly);
  ex = bx - wx; if ex < 0.0 { ex = 0.0 - ex; }
  ey = by - wy; if ey < 0.0 { ey = 0.0 - ey; }
  if ey > ex { return ey; }
  ex
}

// Is world point (wx,wy) inside the disk body posed by `p`?  The body is a disk of squared-radius
// `rr` about its LOCAL centre (cx,cy) — a posed tower (its radius is a shell, `X49`).  Routes through
// the transform, then the exact local test |l − c|² ≤ rr.  This is the general body test in
// miniature: transform once, then decide in the body's own frame.
pub fn disk_hit(p: Pose, cx: float, cy: float, rr: float, wx: float, wy: float) -> boolean {
  lx = pose_inv_x(p, wx, wy) - cx;
  ly = pose_inv_y(p, wx, wy) - cy;
  lx * lx + ly * ly <= rr
}

// ── ARBITRATION WHERE FRAMES DISAGREE (law K₂) ─────────────────────────────
//
// Two requirements the design flags as easy to omit silently: a TOTAL ORDER on frames (a
// "whichever is nearer" tie broken by iteration order breaks replay), and a FAIL-SAFE DIRECTION —
// prefer *solid* over *gap*, so a crack yields a spurious contact rather than a body falling through
// the world (composes with `I4`).  Both are captured below and are order-free by construction.

// The fail-safe verdict at a point claimed by two frames: solid if EITHER is solid.  Order-free
// (symmetric) and conservative — a gap only where both agree it is a gap.
//
// Example: @HXP-006
pub fn arb_solid(a_solid: boolean, b_solid: boolean) -> boolean { a_solid || b_solid }

// Which frame OWNS a contested point — its material/surface wins.  The lowest id among the frames
// claiming *solid* (a total order on frames), or -1 if none is solid.  Intrinsic, so it does not
// depend on the order the frames are visited.
//
// Example: @HXP-006
pub fn arb_owner(a_solid: boolean, a_id: integer, b_solid: boolean, b_id: integer) -> integer {
  if a_solid && b_solid {
    if a_id < b_id { return a_id; }
    return b_id;
  }
  if a_solid { return a_id; }
  if b_solid { return b_id; }
  -1
}

src/hexseat.loft

// Copyright (c) 2026 Jurjen Stellingwerff
// SPDX-License-Identifier: LGPL-3.0-or-later
// hexseat — SEATING A STENCIL ON TERRAIN.
//
// Terrain is stored in the `height` slot, the same slot as roofs.  Seating is the question of
// where a stencil goes on it: a stencil is authored flat in its own local frame, and the ground
// it is placed on is not flat.  The answer is *"a building … **seated on terrain**, residual
// flagged"* (`SPEC` **G5**).
//
// THE CONSTRUCTION, AND WHY IT COSTS THE ROUND TRIP NOTHING:
//
//   **Seating writes the `height` slot.  It does not touch cells or edges.**
//
// So a stencil's footprint is byte-identical on flat ground and on a slope, and `rebuild` — which
// reads the CELLS — recovers the same text either way.  Terrain and stencil occupy **orthogonal
// slots** in the foxel, so they compose without interacting at all.
//
// The same shape of answer recurs across the family: a **door** is a
// material, not a hole (`X51`); a **level** is a filter before the cut, not an arbitration after it
// (`X58`); **terrain** is a height, not a change of footprint.  Each time the round trip survives
// because the new thing lands in a slot the recovery does not read.
//
// WHAT THE SLOPE DOES COST is a **residual**: a stencil seated at ONE height cannot match ground
// that varies under it.  That residual is real, it is a function of the seat policy, and by `G5` it
// must be **returned and flagged — never silently absorbed**.  Which height to seat at (lowest,
// mean, highest) is a **policy**; it changes the residual and changes nothing about recoverability —
// the same split `A6` found between `Sep` (recoverability) and `X7` (a choice policy).
use hex_field::*;
use hex_form::*;

pub const SEAT_LOW  = 0;    // seat at the lowest ground under the footprint — the building perches
pub const SEAT_MEAN = 1;    // seat at the mean — the residual is smallest, split above and below
pub const SEAT_HIGH = 2;    // seat at the highest — the building is buried into the slope

// The height to seat at, under `policy`.  A pure read of the terrain under the footprint.
//
// Example: @HXP-004
pub fn seat_height(cells: HexSet, terr: Heights, policy: integer) -> float {
  lo = 0.0;
  hi = 0.0;
  sum = 0.0;
  n = 0;
  for r in hexset_r0(cells)..hexset_r0(cells) + hexset_h(cells) {
    for q in hexset_q0(cells)..hexset_q0(cells) + hexset_w(cells) {
      if hexset_get(cells, q, r) {
        z = height_get(terr, q, r);
        if n == 0 { lo = z; hi = z; }
        if z < lo { lo = z; }
        if z > hi { hi = z; }
        sum = sum + z;
        n = n + 1;
      }
    }
  }
  if n == 0 { return 0.0; }
  if policy == SEAT_LOW { return lo; }
  if policy == SEAT_HIGH { return hi; }
  (sum / (n as float)) ?? 0.0
}

// THE RESIDUAL, and it is returned rather than swallowed (`G5`): the largest gap between the seat
// height and the ground under any footprint cell.  Zero on flat ground; on a slope it is the
// cut-and-fill the placement owes, and the editor must show it.
//
// Example: @HXP-004
pub fn seat_residual(cells: HexSet, terr: Heights, z: float) -> float {
  worst = 0.0;
  for r in hexset_r0(cells)..hexset_r0(cells) + hexset_h(cells) {
    for q in hexset_q0(cells)..hexset_q0(cells) + hexset_w(cells) {
      if hexset_get(cells, q, r) {
        d = height_get(terr, q, r) - z;
        if d < 0.0 { d = 0.0 - d; }
        if d > worst { worst = d; }
      }
    }
  }
  worst
}

// SEAT THE STENCIL: write the seat height into the `height` slot for every footprint cell.  Cells
// and edges are untouched — that is the whole point, and it is what keeps `rebuild` exact.  Returns
// the number of cells whose height was written.
//
// Example: @HXP-004
pub fn seat_write(cells: HexSet, terr: Heights, z: float) -> integer {
  n = 0;
  for r in hexset_r0(cells)..hexset_r0(cells) + hexset_h(cells) {
    for q in hexset_q0(cells)..hexset_q0(cells) + hexset_w(cells) {
      if hexset_get(cells, q, r) {
        height_set(terr, q, r, z);
        n = n + 1;
      }
    }
  }
  n
}

tests/01-hex-place.loft

// Copyright (c) 2026 Jurjen Stellingwerff
// SPDX-License-Identifier: LGPL-3.0-or-later
// hex_place — the conformance tests: a pose is exact in its own frame, and two stencils combine
// order-free with their shared edge fused.
//
// Contract only; the exhaustive measurement is hexbody's `tests/seam.loft`, `tests/combine.loft`
// and `tests/level.loft`.
use hex_place::*;
use hex_field::*;

fn twobox(off: integer) -> HexSet {
  s = hexset_chunk(-10, -10, 21, 21);
  for r in 0..3 { for q in 0..3 { hexset_set(s, q + off, r, true); } }
  s
}

fn main() {
  a = twobox(0);
  assert(hexset_count(a) == 9, "a 3x3 block has 9 cells");
}

fn test_a_pose_inverts_exactly() {
  // A pose maps local<->world; the inverse of the forward map returns the original point. This
  // is I6 in miniature: the map is a pure function, exact in its own frame.
  p = pose_new(0.8, 0.6, 3.0, 4.0);                  // cos/sin 4/5-3/5, a Pythagorean pose
  lx = 2.0;
  ly = 5.0;
  wx = pose_fwd_x(p, lx, ly);
  wy = pose_fwd_y(p, lx, ly);
  bx = pose_inv_x(p, wx, wy);
  by = pose_inv_y(p, wx, wy);
  assert(bx > 1.999 && bx < 2.001, "x survives the round trip, got {bx}");
  assert(by > 4.999 && by < 5.001, "y survives the round trip, got {by}");
}

fn test_two_adjacent_stencils_fuse_at_the_shared_edge() {
  // "mark all, then cut once": the edge shared by two touching stencils is interior to the union,
  // so it is never cut -- the two fuse rather than growing a wall between them.
  a = twobox(0);
  b = twobox(2);                                     // overlaps a's last column
  e = edgeset_new(-10, -10, 21, 21);
  combine_cut(a, 1, b, 2, e);
  shared = shared_marked(a, b, e);
  assert(shared == 0, "no wall is marked on the shared interior, got {shared}");
}

fn test_arbitration_is_fail_safe_toward_solid() {
  // A world gap under a body solid reads solid -- collision never falls through. I4.
  assert(arb_solid(true, false), "solid over gap is solid");
  assert(arb_solid(false, true), "gap over solid is solid");
  assert(!arb_solid(false, false), "gap over gap is gap");
}

tests/02-worked-examples.loft

// Copyright (c) 2026 Jurjen Stellingwerff
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Worked examples for `hex_place` (@PLN141).  Each `test_*` below is a REAL,
// run-every-CI demonstration of a contract the signature cannot state; the
// function documents itself by CITING the tag with `// Example: @HXP-00N`, and
// `check_doc_drift.sh examples` fails if a citation goes dangling.  These are
// teaching examples, distinct from the conformance suite in `01-hex-place.loft`.
//
// WHAT THIS PACKAGE IS ABOUT.  Everything here answers one question — what
// happens where two things MEET — and the answers all have the same shape: the
// contention is removed by CONSTRUCTION rather than settled by a rule applied
// afterwards.  Two stencils fuse because the seam is interior to the union that
// was cut.  Two levels never contend because the level filters before the cut.
// Terrain never moves a footprint because seating writes a different slot.
//
// That shape is exactly what a signature cannot carry: every one of these is a
// call that quietly does the right thing, and a NEARBY call that quietly does
// the wrong one.  The nearby call is what each example shows beside the right
// one, because a demonstration of only the good half teaches nothing about
// which half you are in.
use hex_place::*;
use hex_field::*;

// A 3x3 block of cells, its left column at `off`, in a chunk with room around it.
fn box3(off: integer) -> HexSet {
  s = hexset_chunk(-10, -10, 21, 21);
  for r in 0..3 { for q in 0..3 { hexset_set(s, q + off, r, true); } }
  s
}

// @HXP-001 — TWO ADJACENT STENCILS: WHO OWNS THE SHARED EDGE?  Nobody — and
// that is a property of HOW you cut, not of the stencils.  Union the footprints
// first and cut the boundary of the union once ("mark all, then cut once"), and
// the shared edge is interior to that union, so it is never cut: the two become
// one fabric with no seam wall between them.
//
// Draw each stencil's own walls instead and overlay them, and both sides mark
// the seam — a wall appears down the middle of what the author drew as one
// building, and every cell of it is reachable, so nothing downstream complains.
//
// This is the same question `hex_grid`'s @HXG-003 answers one level down: there,
// ONE wall between two hexes must resolve to one stored slot, or it becomes two
// half-walls that disagree.  Here it is one seam between two STENCILS, and the
// answer is that it should not be stored at all.
fn test_the_shared_edge_belongs_to_nobody_if_you_cut_once() {
  a = box3(0);                    // cells q 0..2
  b = box3(3);                    // cells q 3..5 — adjacent, not overlapping

  // THE WRONG WAY, shown first: cut each stencil's own boundary into one edge
  // set.  `combine_cut(a, 1, a, 1, e)` is exactly "a's own walls".
  naive = edgeset_new(-10, -10, 21, 21);
  na = combine_cut(a, 1, a, 1, naive);
  nb = combine_cut(b, 2, b, 2, naive);
  assert(na == 22 && nb == 22, "each 3x3 block alone has 22 boundary edges");
  seam = shared_marked(a, b, naive);
  assert(seam == 5, "and a wall now runs between them: {seam} marked edges");

  // THE RIGHT WAY: one call, one cut, over the union.
  fused = edgeset_new(-10, -10, 21, 21);
  ng = combine_cut(a, 1, b, 2, fused);
  assert(shared_marked(a, b, fused) == 0, "no wall on the shared interior");

  // And the arithmetic says exactly where the difference went: the five seam
  // edges were each cut twice by the overlay and not at all by the union.
  assert(ng == na + nb - 2 * seam, "{ng} = {na} + {nb} - 2 * {seam}");
}

// @HXP-002 — ORDER-FREE BY CONSTRUCTION, including where the stencils OVERLAP.
// The result reads the finished union and a fixed source map, never which
// stencil was stamped when, so swapping the arguments cannot change a single
// edge.  Where two stencils claim the same cell the tie goes to the LOWER
// MATERIAL ID — an intrinsic property of the pair, not a positional one.
//
// The distinction matters because "last writer wins" is the natural way to
// build this and is indistinguishable from correct on ONE stencil.  It only
// diverges on two, and then only sometimes, which is the worst way for a bug
// to present.
fn test_swapping_the_two_stencils_changes_nothing() {
  c = box3(0);                    // q 0..2
  d = box3(2);                    // q 2..4 — the q=2 column is in BOTH

  one = edgeset_new(-10, -10, 21, 21);
  two = edgeset_new(-10, -10, 21, 21);
  n1 = combine_cut(c, 1, d, 2, one);
  n2 = combine_cut(d, 2, c, 1, two);
  assert(n1 == 30 && n2 == 30, "the same {n1} edges either way round");

  // Not just the same count — the same material on every edge.
  same = true;
  for r in -10..11 {
    for q in -10..11 {
      for dir in 0..6 {
        nq = nb_q(q, r, dir);
        nr = nb_r(q, r, dir);
        if edge_mat(one, q, r, nq, nr) != edge_mat(two, q, r, nq, nr) { same = false; }
      }
    }
  }
  assert(same, "and the same material on every one of them");
}

// @HXP-003 — A LEVEL IS A FILTER APPLIED BEFORE THE CUT, not an arbitration
// rule applied after it.  Two stencils on different levels do not fuse, do not
// arbitrate and do not contend: at either level, one of them simply is not
// there.  So the contention degree is 1 at each level even where the two
// overlap in (q,r) — a bridge over a road contends with nothing.
//
// A LEVEL IS NOT A HEIGHT.  It is a discrete sheet index; the actual z comes
// from the height slot (@HXP-004).  Two things can share a z on different
// levels, or sit at different z on the same one.
fn test_two_levels_never_contend_however_much_they_overlap() {
  c = box3(0);                    // q 0..2
  d = box3(2);                    // q 2..4 — overlaps c at q=2

  // Seen at level 0, with c on level 0 and d on level 1, only c is there —
  // so the cut is c's own boundary, exactly as if d did not exist.
  lv = edgeset_new(-10, -10, 21, 21);
  n0 = combine_cut_level(c, 0, 1, d, 1, 2, 0, lv);
  solo = edgeset_new(-10, -10, 21, 21);
  nsolo = combine_cut(c, 1, c, 1, solo);
  assert(n0 == nsolo, "at level 0 the cut is c alone: {n0} edges");

  // The overlap cell is claimed once at each level, never twice at either.
  assert(kappa_at_level(c, 0, d, 1, 0, 2, 0) == 1, "one claim at level 0");
  assert(kappa_at_level(c, 0, d, 1, 1, 2, 0) == 1, "one claim at level 1");

  // Put them on the SAME level and that same cell is contended by two.
  assert(kappa_at_level(c, 0, d, 0, 0, 2, 0) == 2, "same level: two claims, one cell");
}

// @HXP-004 — SEATING WRITES THE HEIGHT SLOT AND NOTHING ELSE.  A stencil is
// authored flat and the ground under it is not, so seating has to give somewhere
// — and where it gives is a number RETURNED to you, never a change to the
// footprint.  The cells are byte-identical on flat ground and on a slope, which
// is what lets the model be recovered from the cells either way.
//
// The policy (low / mean / high) chooses the residual, not the shape: a building
// perches, splits the difference, or is buried, and the footprint is the same
// three by three cells in all three cases.  Read `seat_residual` and show it —
// it is the cut and fill the placement owes, and swallowing it is the one thing
// this design refuses to do for you.
fn test_seating_moves_the_height_never_the_footprint() {
  a = box3(0);
  terr = heights_new(-10, -10, 21, 21);
  for r in 0..3 { for q in 0..3 { height_set(terr, q, r, q as float); } }   // a slope, 0..2

  // Three policies, three seat heights, over the same nine cells.
  assert(seat_height(a, terr, SEAT_LOW) == 0.0, "perch on the lowest ground");
  assert(seat_height(a, terr, SEAT_MEAN) == 1.0, "or split the difference");
  assert(seat_height(a, terr, SEAT_HIGH) == 2.0, "or bury into the slope");

  // The residual is the choice's cost, and it is handed back rather than absorbed.
  assert(seat_residual(a, terr, 1.0) == 1.0, "seated at the mean, the worst gap is 1.0");
  assert(seat_residual(a, terr, 0.0) == 2.0, "perched, it is 2.0 — the same slope, a worse fit");

  // Seating writes heights.  The footprint does not move.
  before = hexset_count(a);
  wrote = seat_write(a, terr, 1.0);
  assert(wrote == 9, "nine cells got a height");
  assert(hexset_count(a) == before, "and the footprint is the same {before} cells");
  assert(height_get(terr, 0, 0) == 1.0, "the ground under the stencil now reads the seat height");
}

// @HXP-005 — THE POSE TRANSFORM IS THE ONLY PLACE FLOAT ERROR LIVES, and ONE
// MEASUREMENT OF IT IS NOT A BOUND.  Inside a frame every test is exact
// integer work; across frames it cannot be, because a pose is continuous.  The
// design confines that error to the transform so the whole stack has one error
// budget — but the size of it depends on WHERE you evaluate it.
//
// Measure the residual near the frame origin and you will very reasonably read
// exactly zero, and conclude the transform is exact.  The same pose, at a point
// a hundred times further out, is not zero.  It is deterministic — the same
// inputs always give the same answer, which is what replay needs — but it is a
// jagged function of the point, not a constant you can sample once.
//
// So: never compare cross-frame coordinates with `==`, and never take a
// tolerance from a measurement made next to the origin.
fn test_one_sample_of_the_seam_error_is_not_a_bound() {
  g = pose_new(0.8660254037844386, 0.5, 3.0, 4.0);     // a 30-degree pose

  // Near the origin: exactly zero, and that is a true measurement.
  near = pose_residual(g, 10.0, 7.0);
  assert(near == 0.0, "at (10,7) the round trip is exact");

  // The same pose, further out: not zero.
  far = pose_residual(g, 1000.0, 700.0);
  assert(far > 0.0, "at (1000,700) it is not, though nothing about the pose changed");
  assert(far < 0.000001, "it is still tiny — the seam is tight, it is simply not zero");

  // Deterministic, which is what byte-identical replay rests on.
  assert(pose_residual(g, 1000.0, 700.0) == far, "the same inputs give the same answer");

  // Inside the frame there is no such caveat: the forward map lands a local
  // point exactly on the boundary of a local disk test, radius 5 about (0,0).
  wx = pose_fwd_x(g, 3.0, 4.0);
  wy = pose_fwd_y(g, 3.0, 4.0);
  assert(disk_hit(g, 0.0, 0.0, 25.0, wx, wy), "the local test is exact in its own frame");
}

// @HXP-006 — ARBITRATION FAILS SAFE TOWARD SOLID, and the owner is INTRINSIC.
// Where two frames disagree about a point, `arb_solid` answers solid if either
// does: a crack between presentations yields a spurious contact rather than a
// body falling through the world. It is symmetric, so it cannot depend on which
// frame you happened to visit first.
//
// `arb_owner` breaks the tie by LOWEST ID — a total order on frames, not
// "whichever is nearer" and not iteration order, either of which would make a
// replay diverge. Its no-owner answer is **-1**, and -1 is a sentinel, not an
// id: in loft a negative index reads from the END of a vector rather than
// failing, so handing it on unchecked finds a frame, just not the right one.
fn test_arbitration_prefers_solid_and_names_an_owner_intrinsically() {
  assert(arb_solid(true, false), "solid over gap is solid");
  assert(arb_solid(false, true), "and so is gap over solid — it is symmetric");
  assert(!arb_solid(false, false), "only where both agree is it a gap");

  // Both solid: the lower id owns it, whichever way round you ask.
  assert(arb_owner(true, 7, true, 3) == 3, "lowest id wins");
  assert(arb_owner(true, 3, true, 7) == 3, "and the answer does not depend on the order");

  // One solid: that one owns it, high id or not.
  assert(arb_owner(false, 7, true, 3) == 3, "the solid frame owns it");
  assert(arb_owner(true, 7, false, 3) == 7, "even when its id is the larger");

  // Neither: -1, which is not a frame.
  assert(arb_owner(false, 7, false, 3) == -1, "no owner is -1, and -1 is not an id");
}