diff options
| -rw-r--r-- | lib/rites/rite_ef/lectionary_ef.ml | 25 | ||||
| -rw-r--r-- | lib/rites/rite_ef/lectionary_ef.mli | 7 | ||||
| -rw-r--r-- | test/test_lectionary_ef.ml | 39 |
3 files changed, 52 insertions, 19 deletions
diff --git a/lib/rites/rite_ef/lectionary_ef.ml b/lib/rites/rite_ef/lectionary_ef.ml index 02c3c64..37ec1d8 100644 --- a/lib/rites/rite_ef/lectionary_ef.ml +++ b/lib/rites/rite_ef/lectionary_ef.ml @@ -49,12 +49,25 @@ let readings ~lectionary ~observed ~temporal ~date ~temporal_at = records the ferial-Mass selection rule itself as unconfirmed against the primary source. - Termination: guarded on weekday. A Sunday reaching this branch - would compute [days_since_sunday Sun = 0] and look up ITSELF, - looping forever -- every other step in the chain consults data - (a lectionary lookup), this is the only one that consults - another date, so this guard is the whole chain's termination - argument, not merely a special case. + Guarded on weekday, but NOT because a Sunday reaching this + branch would loop (fix round 1, coordinator review: the + original comment here claimed exactly that, and it was wrong). + [readings] is not recursive -- step 3's fallback is one flat + [Lectionary.find], never a re-entrant call into [readings] -- + so without the guard, [days_since_sunday Sun = 0] would just + repeat the SAME [Lectionary.find] step 2 already ran and + already got [None] from (same pure inputs, same date), and + return [] once, normally. The chain as a whole terminates + because every step either consults data (a lookup) or, here, + a strictly EARLIER date via [temporal_at] -- no step ever calls + back into [readings] itself, so there is no recursion anywhere + in this function for a cycle to form in the first place. The + real reason for the guard is simpler: a Sunday has no + PRECEDING Sunday to resume -- consulting itself would be + meaningless (it would re-ask the question step 2 just + answered), not dangerous, so the guard exists to make that + intent explicit rather than to prevent a runaway loop that was + never actually possible. The preceding Sunday's TEMPORAL slug, never its observed one: the rubric is the preceding Sunday's Mass even in a year when a diff --git a/lib/rites/rite_ef/lectionary_ef.mli b/lib/rites/rite_ef/lectionary_ef.mli index 159fd57..e54a0b1 100644 --- a/lib/rites/rite_ef/lectionary_ef.mli +++ b/lib/rites/rite_ef/lectionary_ef.mli @@ -23,9 +23,10 @@ open Colitur_kernel Steps 1-3 (Tasks 4-5): the observed celebration's own proper, else the day's own temporal slug in the lectionary, else -- for a weekday whose own slug has no entry -- the preceding Sunday's temporal slug (never its - observed one; a Sunday guards against consulting itself and looping, - see [readings]'s own implementation comment). A day matching none of the - three gets [] for now -- the Commons (Task 6) are not built here. *) + observed one; a Sunday is guarded out because it has no PRECEDING Sunday + to resume, not because consulting itself would loop -- [readings] is not + recursive, see its own implementation comment). A day matching none of + the three gets [] for now -- the Commons (Task 6) are not built here. *) val readings : lectionary:Lectionary.t -> observed:Vocab_ef.rank Celebration.t -> diff --git a/test/test_lectionary_ef.ml b/test/test_lectionary_ef.ml index 6d8f3fe..8af57f6 100644 --- a/test/test_lectionary_ef.ml +++ b/test/test_lectionary_ef.ml @@ -128,16 +128,35 @@ let test_step3_christmas_feria_resumes_sunday () = [ "Gal 4:1-7"; "Luke 2:33-40" ] (refs (day 2025 12 29)) -(* The distinction that matters: step 3 uses the preceding Sunday's TEMPORAL - slug, never the observed one. 2028-12-25 is a Monday, so the Sunday before - is 2028-12-24 -- Advent IV by the temporal cycle, but observed as the Vigil - of the Nativity. The feria must take Advent IV's Mass, not the Vigil's. *) +(* Fix round 1 (coordinator review, Important finding 1): the original test + here (2028-12-26) did not exercise step 3 at all -- 26 December is always + Stephen (Class2, a real sanctoral entry with its own citations, fixed + regardless of weekday), so that date resolves entirely at step 1 and never + reaches step 2 or 3. Its justifying comment was also factually wrong: 24 + December's TEMPORAL slug is [ef-nativity-vigil], identical to its OBSERVED + slug -- [Temporal_ef.named] hard-codes the Vigil for 24 December ahead of + any Sunday computation, so there is no temporal/observed split on that + date to exploit in the first place. + + 2025-02-03 genuinely discriminates, verified directly against the real + data (data/ef/sanctoral.sexp, data/ef/lectionary.sexp) and the real + resolver, not transcribed: 2025-02-02 (a Sunday) is observed as the + Purification of the BVM (RG 16(a): a Feast of the Lord takes the Sunday's + place outright), with its own citations Mal 3:1-4 / Luke 2:22-32 -- but + its TEMPORAL identity is [ef-time-after-epiphany-sunday-4], whose + lectionary entry is the different Rom 13:8-10 / Matt 8:23-27. 2025-02-03 + (Monday) has no sanctoral office of its own and no entry for its own + temporal slug ([ef-time-after-epiphany-4-monday], absent from + data/ef/lectionary.sexp), so it reaches step 3 and must return the + Sunday's TEMPORAL readings (Rom 13:8-10 / Matt 8:23-27). A "step 3 reads + the observed office instead of the temporal one" bug would instead return + the Purification's (Mal 3:1-4 / Luke 2:22-32) -- different, checkable + values, not a bare length check. *) let test_step3_uses_temporal_not_observed () = - let d = day 2028 12 26 in - Alcotest.(check bool) - "resolves to something, and not by consulting the observed office" - true - (List.length (refs d) = 2) + Alcotest.(check (list string)) + "3 February 2025 takes the preceding Sunday's TEMPORAL Mass (Time after Epiphany IV), not the Purification's" + [ "Rom 13:8-10"; "Matt 8:23-27" ] + (refs (day 2025 2 3)) (* Termination: a Sunday that reaches step 3 would consult itself. It must not: the guard is weekday <> Sun. *) @@ -156,7 +175,7 @@ let suite = test_step3_advent_feria_resumes_sunday); ("step 3: Christmas feria resumes the preceding Sunday", `Quick, test_step3_christmas_feria_resumes_sunday); - ("step 3: uses the Sunday's temporal slug, not its observed office", `Quick, + ("step 3: 3 Feb 2025 takes the Sunday's temporal Mass, not the Purification's", `Quick, test_step3_uses_temporal_not_observed); ("step 3: a Sunday does not recurse into itself", `Quick, test_step3_sunday_does_not_recurse) ] |
