Settle the seam a warichu's sublines meet at, and give a furawake its two ends - #28
Merged
Merged
Conversation
`reduction_sites` offered the ladder every interior boundary of a stacked structure. Two characters of one subline are one such boundary, and so is the SEAM where a note's two sublines meet -- the last character of the first and the first character of the second are adjacent in the text, so Table 1 states an amount between them like anywhere else. That amount stands nowhere. The character that ends a subline reports its body alone and the character that begins the next one begins it at its own row's origin, so the line was never composed from the seam and there is nothing there to give back. Offering it to the ladder divides the line's arrears over a site that cannot pay them: `※〈〉あ※` at a three-em measure needs 250 units back, has one boundary on the line that can give them and one seam that cannot, halves the debt between the two, recovers 125 and reports `layout.overfull` about a line it could have made fit. The expansion ladder already stopped at the block, through the same construct-interior test `boundary_expansion_site` runs; the reduction ladder now asks the same question of a warichu and a furawake. Neither public API nor any other engine changed, and no other census coordinate moves: this is the only shape where a boundary Table 1 names is not a boundary the line was composed from. Fixes #26 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N8KNy2ejPqy81P2hVcRUjs
… edge `compose.rkt` gathers a §3.7.2 furawake into ONE item of the line, where a §3.4.2 warichu's members stay items of their own. Two things followed from that and both were wrong. A column was measured from bare cluster advances, so a member standing before a Table 1 amount inside its own column -- `cl-02` then `cl-01`, half of the member's own em -- reported 1000 while the same engine placed the next member 1000 units on and charged the line 1500 for the step. That is the defect #24 fixed for a warichu, at the other structure the same reading is addressed to: a column is ordinary text of the structure, so a member's advance is its body plus the amount after it inside its row, and the member that ends a row reports its body alone. And the one item carried the class of its FIRST cluster, so the boundary AFTER the block was answered at the wrong end of it. A structure has two edges and they are two different characters: the amount before the block is Table 1's answer at the block's first character and the amount after it the answer at its last. The `item` struct now carries a `trailing` edge -- the occurrence a boundary after the item is read against, which is the item itself for anything one character wide -- and every reading of the before side of a boundary asks for it. A tate-chu-yoko run carries none: §3.2.5 makes it cl-30 at both of its edges however many characters it holds. The two errors are equal and opposite wherever the two amounts are, which is why `※〉〈日※` comes out 4500 wide either way and `※・・日※` does not. Both halves had to move together. Neither public API nor any other engine changed, and `across` in `furawake-item` -- computed and read by nobody since the block's depth moved to `block-room` -- goes with them. Fixes #27 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N8KNy2ejPqy81P2hVcRUjs
…t every class pair `engines/ocaml/probe/census.ml` gains three `constructs` variants. The first is the sixth shape PR #25 deliberately withheld: `warichu-pair-inside-reduced` stands the pair under test inside a note on a line that has to give space back, which is where the two answers to "does §3.8.3's ladder reach the seam" come apart in the line's own width. The other two are `furawake-pair-inside` and its vertical mirror, which stand the pair inside one of a furawake's columns and put an ordinary character in the other, so one request asks both what Table 1 does inside a column and which of the block's characters the boundary after it is read against. The `constructs` census is 20,102 requests and all ten are at zero differences across the three engines over 122,199. Against the previous engines the same census reports 15 differing responses for the Rust one and 434 for the Racket one. `docs/decisions/stacked-structure-geometry.md` states both readings, why they follow from the sentences already published there rather than from anything new, and what a revision would have to say to settle either one the other way. The seam is the only boundary of a block that is neither strictly inside a subline nor at the block's edge, which is how an engine can reach it by asking Table 1 about two adjacent characters without asking which object they are adjacent on. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N8KNy2ejPqy81P2hVcRUjs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two coordinates a block hides from the line, one at each end of the reading
docs/decisions/stacked-structure-geometry.mdpublishes. The first is the sixth
constructsvariant PR #25 deliberately withheld,because it was the first shape two of the three engines answered differently from each
other; the second is the furawake half of #24, which needed a structure to be able to say
what it is at each of its two ends.
Fixes #26
Fixes #27
The seam, and which engine was right (#26)
Where a note's two sublines meet, Table 1 states an amount between the character that ends
the first and the character that begins the second.
crates/jlreq/src/pipeline.rsofferedthat boundary to §3.8.3's ladder;
engines/ocaml/lib/pipeline.mlandengines/racket/compose.rktdid not. Nothing had adjudicated it.The decision already settles it, and it settles it against the ladder. The published
reading is not "Table 1 states nothing here" — Table 1 states plenty. It is that the line
was not composed from the boundary: the character that ends a subline reports its body
alone and the character after it begins its own row at that row's origin, so the amount at
the seam stands nowhere in any engine's answer. The reading's own sentence for the block's
interior — "a boundary the line was not composed from is not a boundary the line can
adjust, which is why the two of them read the line's geometry and stop at the block" — is
about which object a boundary belongs to, and the seam belongs to the same object the rest
of the block's interior does. §3.8.3 adjusts the spacing of a line; there was no spacing of
the line there to adjust.
The measurement is what makes it more than a preference. A ladder handed a site that cannot
pay divides the arrears over it anyway and recovers only the other share:
An engine that hands back half of what it needs and then reports the line overfull is
contradicting its own diagnostic, which is what tipped this from "two readings" to "one
reading and one defect". The expansion ladder already stopped at the block; the reduction
ladder now asks the same question.
The alternative is publishable and the decision says so: a revision of §3.8.3 that said
what a boundary of a line is, or an Appendix D note saying whether a stage may be offered
a coordinate no amount stands at, would settle it either way. Today the only argument is
the one above, and it is this project's.
A furawake's two ends (#27)
compose.rktgathers a furawake into one item of the line where a warichu's members stayitems of their own, and two things followed. A column was measured from bare cluster
advances, so a member before a Table 1 amount inside its own column reported 1000 while the
engine placed the next member 1000 units on and charged the line 1500 — the defect #24
fixed for a warichu, at the other structure the same reading is addressed to. And the one
item carried the class of its first cluster, so the boundary after the block was
answered at the wrong end of it, and the amount missing from the column reappeared beside
the structure.
The two are equal and opposite wherever the two amounts are equal, which is why the shape
had to be swept over all 529 class pairs before it could be seen at all:
Both halves had to move together.
itemnow carries atrailingedge — the occurrence aboundary after the item is read against, which is the item itself for everything one
character wide — and every reading of the before side of a boundary asks for it. A
tate-chu-yoko run carries none: §3.2.5 makes it cl-30 at both of its edges however many
characters it holds.
What changed
crates/jlreq/src/pipeline.rs:reduction_sitesskips a boundary strictly inside awarichu or a furawake, the way it already skipped one inside a jidori and the way
boundary_expansion_sitealready skipped all of them. Public API unchanged.crates/jlreq/tests/public_api.rs: the seam at three measures — the natural width, wherethe amount stands nowhere; the width that needs half of it; and the width that needs all
of it. It fails on the previous engine at 3,125 against 3,000.
engines/racket/compose.rktandspacing.rkt: a furawake's columns are laid out fromthe advances the structure was composed from, and the block carries the character its far
boundary is read against.
acrossinfurawake-item, computed and read by nobody sincethe block's depth moved to
block-room, goes with them.engines/racket/tests/test-compose.rkt: three cases computed by hand from §3.7.2 andTable 1 — the in-column amount and the advance that reaches it, the pair whose two errors
do not cancel, and the block's own two extents, which neither reading moves. Two of the
three fail on the previous engine.
engines/ocaml/probe/census.ml:warichu-pair-inside-reduced,furawake-pair-insideandits vertical mirror. Against the previous engines the
constructscensus reports 15differing responses for the Rust one and 434 for the Racket one; against these, none.
docs/decisions/stacked-structure-geometry.mdpublishes both readings, why each followsfrom sentences already there, and what a revision would have to say to settle either one
the other way.
engines/ocaml/README.md's census counts were three pull requests staleand are now current.
Measurements
The Rust sample engine,
just conform-ocamlandjust conform-racketeach answer alleighty-nine built-in cases at exit 0;
raco test engines/racket/testsis 10,196 passing;just check,just designandjust ciare green locally.No known disagreement between the three engines is left open.
🤖 Generated with Claude Code
https://claude.ai/code/session_01N8KNy2ejPqy81P2hVcRUjs