diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-11 21:03:00 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-11 21:03:00 +0200 |
| commit | f15e44dd4c1b871c2daeb952b1c8c848274ea1f1 (patch) | |
| tree | 2e2f73260780f43a9d9a3e38ed9c181f94c9d50b /lib/kernel/liturgical_day.ml | |
| parent | 953427d8d1e3a34994be53b60e18662ec26fef4e (diff) | |
| download | colitur-f15e44dd4c1b871c2daeb952b1c8c848274ea1f1.tar.gz colitur-f15e44dd4c1b871c2daeb952b1c8c848274ea1f1.zip | |
kernel(calendar): place transferred celebrations (RG 96-98)
Calendar.year now runs a placement pass after resolving every day: each
deferred candidate (RG 95's I-class-only right of translation, via
Precedence's Transfer disposition) is placed on the next day the rite's
new Rite.t.transfer_target names as admissible, transferred_in/out are
set on the two ends of the move, and the whole year is re-resolved to a
fixed point, bounded by a hard max_transfer_rounds = 64 guard.
transfer_target is rite-supplied rather than a generic search Calendar
drives itself: RG 96's 'not I or II class' is not derivable from band or
disposition alone (RG 91's own table lets a universal I-class feast
outrank an ordinary Sunday in a raw contest, yet RG 96 forbids landing a
translation there regardless), and the search's starting point is
rite-specific too (the Annunciation exception). It takes an occupant
callback exposing what Calendar currently resolves as observed on any
date, so the rite never has to re-implement occurrence resolution.
Two correctness properties drove most of the design:
- A candidate's permanent natural loss at its own origin (the layer entry
never moves) is rediscovered every round; left unfiltered this
oscillates a placed candidate between two dates forever, since its own
rank makes it look 'occupied' to a fresh search from its origin. Both
the round loop's gather and the final per-day omitted accounting filter
this out, keeping only sightings that are either brand new or losing at
a candidate's *current* target (a fresh RG 97-98 bump).
- RG 97-98's sort has to actually decide something, not just happen to
agree with Precedence.resolve's own tie-break next round: a
claimed-this-round overlay lets earlier-processed candidates in one
round block later ones in the same pass, so two coinciding I-class
feasts land on consecutive admissible days in the one round they
collide, in band order.
Also folds in Task 5's review finding: year_bounds clamps y to [1582,
9999] once, up front, rather than guarding start and stop independently
(each guard only ever covered one of the two rite.year_start calls,
leaving year 999 and year 100000 each able to call it out of domain
through the other branch).
Diffstat (limited to 'lib/kernel/liturgical_day.ml')
0 files changed, 0 insertions, 0 deletions
