feat(axiom5): toward = fold direction + paper-incidence filter (v0.19-dev) #70

Closed
toph wants to merge 10 commits from toward-direction into main
Owner

Implements notes/2026-07-05-toward-direction-semantics.md and notes/2026-07-05-axiom5-paper-incidence.md: axiom-5 toward stops being a sector selector and becomes a fold direction, and omitted toward now runs a paper-incidence filter before erroring.

Semantics for map --l1 onto --l2:

  • toward X present — a bisector is selected iff reflecting the swinging material of --l1 across it lands on X's side of --l1. X on --l2 is now legal; X on --l1 errors (toward names where the fold goes, not where it comes from). The residual straddle case (hinge interior to the material) resolves via moving, otherwise errors with a fix-it hint.
  • toward omitted — candidates that crease no face (corner/edge grazers) are filtered out first; only a genuine two-way tie still asks for toward .p.
  • moving is now optional on @map … onto … — derived as the side carrying --l1's material, analogous to axiom 2's implied moving point. up to still needs moving.

Binds use the same material rule; center-cross binds (both halves swing either way) are honest ambiguity errors now, so bisect-a/b were rewritten as hinge-at-endpoint programs and bisect-intermediate (sector-semantics demo) became bisect-straddle.

The payoff example — the kite base drops from 9 statements (helper constructions, toward on helper points, explicit moving) to 4, with no selector at all:

paper square

--ac = --(.a .c)
@map --(.d .a) onto --ac
@map --(.b .a) onto --ac

toward as a direction, one token apart:

--v = map .a onto .b
map --v onto --(.a .b) toward .a    ; vs. toward .b — .b lies ON --l2, legal now

Enabling work that rode along: the golden/e2e harness now scans examples/ recursively (the reorg into syntax//bases/ had detached it); Geom.clip_line_to_convex (exact Cyrus–Beck) + strict-interior line_cuts_polygon; and a real pre-existing bug found by the new tests — table_polygon returns CW polygons for reflected faces, which silently disabled the taco-tortilla check on folded states (c284075).

Spec §4.5 rewritten accordingly (error strings byte-matched against the evaluator); axioms 6/7 toward (metric landing pick) are untouched — separate pass, per the note.

Note for the future: the bind straddle error suggests at-selection of the swinging segment; once pinch (#50 slice 2) lands, that hint gets a second natural resolution.

Implements `notes/2026-07-05-toward-direction-semantics.md` and `notes/2026-07-05-axiom5-paper-incidence.md`: axiom-5 `toward` stops being a sector selector and becomes a fold direction, and omitted `toward` now runs a paper-incidence filter before erroring. Semantics for `map --l1 onto --l2`: - `toward X` present — a bisector is selected iff reflecting the swinging *material* of `--l1` across it lands on X's side of `--l1`. `X` on `--l2` is now legal; `X` on `--l1` errors (`toward` names where the fold goes, not where it comes from). The residual straddle case (hinge interior to the material) resolves via `moving`, otherwise errors with a fix-it hint. - `toward` omitted — candidates that crease no face (corner/edge grazers) are filtered out first; only a genuine two-way tie still asks for `toward .p`. - `moving` is now optional on `@map … onto …` — derived as the side carrying `--l1`'s material, analogous to axiom 2's implied moving point. `up to` still needs `moving`. Binds use the same material rule; center-cross binds (both halves swing either way) are honest ambiguity errors now, so `bisect-a/b` were rewritten as hinge-at-endpoint programs and `bisect-intermediate` (sector-semantics demo) became `bisect-straddle`. The payoff example — the kite base drops from 9 statements (helper constructions, `toward` on helper points, explicit `moving`) to 4, with no selector at all: ``` paper square --ac = --(.a .c) @map --(.d .a) onto --ac @map --(.b .a) onto --ac ``` <img src="https://git.toph.so/attachments/5ea283ae-b30b-4705-b46b-c61b5607e280" width="49%"> <img src="https://git.toph.so/attachments/e8ad15a5-8c88-4a28-9067-edf1d23bc5c7" width="49%"> `toward` as a direction, one token apart: ``` --v = map .a onto .b map --v onto --(.a .b) toward .a ; vs. toward .b — .b lies ON --l2, legal now ``` <img src="https://git.toph.so/attachments/78fba66b-5f81-482f-95ee-62a462d102d9" width="49%"> <img src="https://git.toph.so/attachments/ee445dc8-3057-4b4d-92ec-9b0c0c53ed81" width="49%"> Enabling work that rode along: the golden/e2e harness now scans `examples/` recursively (the reorg into `syntax/`/`bases/` had detached it); `Geom.clip_line_to_convex` (exact Cyrus–Beck) + strict-interior `line_cuts_polygon`; and a real pre-existing bug found by the new tests — `table_polygon` returns CW polygons for reflected faces, which silently disabled the taco-tortilla check on folded states (`c284075`). Spec §4.5 rewritten accordingly (error strings byte-matched against the evaluator); axioms 6/7 `toward` (metric landing pick) are untouched — separate pass, per the note. Note for the future: the bind straddle error suggests `at`-selection of the swinging segment; once `pinch` (#50 slice 2) lands, that hint gets a second natural resolution.
toph added 10 commits 2026-07-05 19:09:08 +00:00
Golden and e2e harnesses only scanned examples/ non-recursively, so the
syntax/ and bases/ reorg left e2e reading stale paths and golden blind
to the moved/new .bel files. Walk recursively, mirror the golden path
to the subdirectory (needed since two examples share the name
multiple-folds.bel), and keep the basename as the span name passed to
fold_string so existing golden bytes don't drift. Move existing goldens
into tests/golden/{syntax,bases}/ and regen the ones with no prior
golden (bases/kite.fold, syntax/multiple-folds.fold,
syntax/crease-flap-restrict.fold — the last one wasn't called out in
the brief but has no predecessor golden either).
Cyrus-Beck exact clip of a line against a convex CCW polygon
(clip_line_to_convex), and a strict interior-cut test on top of it
(line_cuts_polygon) that treats an edge-collinear line as not folding
anything, per ADR 0014.
taco_tortilla_error fed segment_crosses_interior (which assumes CCW
input) the un-normalized table_poly_of, so a reflected face (det -1,
CW table winding) silently never registered as crossing a crease
interior — the same defect table_polygon_ccw already fixed for the
clip/cut helpers. Route the check through table_polygon_ccw instead;
moved that function (and table_polygon) earlier in the file so it's
in scope at the call site.
Kite filter, toward/moving agreement, straddle disambiguation (E5/E6),
no-viable (E4), bind on-l2/off-l1 legality, centre ambiguity, and the
E1 toward-on-l1 case. Retarget the bisect-errors case-3 grep to the new
E1 message.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S9YotFCnyosmMHEtF6r7ei
Replace the sector-based bisector pick with direction semantics. `axis_of`
now returns `axis_result`: intersecting `map --l1 onto --l2` yields an
`Ax5` deferred selection resolved against the fold state, everything else
a resolved `Axis`.

Selection shares one viability core (swing-rep sign trick) between bind and
fold. Omitted `toward` filters candidates by paper incidence; `toward x`
keeps the bisector whose swinging material lands on x's side of l1, using
the explicit `moving` anchor when present or a derived move-side override
otherwise. `toward` on l1 is E1; on l2 is legal (old on-l2 check removed).

Split `side_of_flap_arg` into a non-raising `_res` variant so candidate
rejection (on-axis/straddle) doesn't leak resolution errors, and thread
`~side_override` through `run_fold_checked` (with an E8 up-to guard).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S9YotFCnyosmMHEtF6r7ei
- drop broken reorg imports: examples/syntax/{crease-flap-restrict,multiple-folds}.bel + their goldens (the working top-level multiple-folds.bel stays)
- fix stale examples/ paths after the syntax/ reorg: README.md landing images, tools/README.md, editors/vscode/README.md, bibliography.md
- spec/SPECIFICATION.md §4.5: reword the paper-incidence filter to say it keeps candidates cutting a face's interior, not just "a positive-length segment"
- tests/test_eval.ml: add E8 (`up to` without `moving`, no implied anchor) via the kite fold; extend the E3/E7 NOTE to also cover the toward-without-moving empty-viables branch, unreachable on the flat sheet (confirmed by CLI sweep)
- notes/2026-07-05-toward-direction-semantics.md: mark the §4.5 rewrite bullet done
Author
Owner

Moved to GitHub: https://github.com/tophcodes/beloch/pull/16 (repo migrated 2026-07-05, GitHub is the source of truth now).

Moved to GitHub: https://github.com/tophcodes/beloch/pull/16 (repo migrated 2026-07-05, GitHub is the source of truth now).
toph closed this pull request 2026-07-05 19:15:05 +00:00

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
toph/beloch!70
No description provided.