diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-27 00:37:45 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-27 00:37:45 +0200 |
| commit | 6e62e499aed1c5a31a18bcf5e9eaa7f2b0c4ff2e (patch) | |
| tree | 9650e9b60ed2c4b178f80ed10f4e7ba9a9bf572d /test/test_precedence_of.ml | |
| parent | bf42e85ed622da5227a69c26ec801d32c767bb32 (diff) | |
| download | colitur-6e62e499aed1c5a31a18bcf5e9eaa7f2b0c4ff2e.tar.gz colitur-6e62e499aed1c5a31a18bcf5e9eaa7f2b0c4ff2e.zip | |
fix(of): break the movable-BVM-memorial tie per a CDWDS Notification
Mary, Mother of the Church (Easter+50) and the Immaculate Heart of Mary
(Easter+69) are both movable obligatory memorials that can land on a
FIXED obligatory memorial's own date -- e.g. 2011-06-13 and 2015-06-13,
both against Anthony of Padua. Both candidates banded identically at
Tabula III.10 (100, both universal Memoria_obligatoria), a tie band
could not break, so Precedence.resolve's kernel-level alphabetical
Slug.compare tie-break silently picked instead -- 892 days for Mater
Ecclesiae and 1109 for the Immaculate Heart across 1583-9999, all one
shape (measured against the pre-fix alphabetical order directly, zero
unexplained).
Searched the corpus rather than inventing a rule. colitur's two
previously-checked primary sources really are silent: the 2018 decree
(AAS 110, 437-438) never addresses universal-calendar coincidence, and
Normae n. 14's third clause resolves only two AD-LIBITUM memorials
colliding. A third source resolves it: the CDWDS's own "Notification on
the Memorial of the Blessed Virgin Mary, Mother of the Church" (24 March
2018 -- same dicastery and signatories as the decree; published only on
vatican.va, confirmed absent from the AAS 2018 combined index) states
that when this memorial "coincides with another Memorial of a Saint or
Blessed... the Memorial of the Blessed Virgin Mary is to prevail," and
extends the identical reasoning to the Immaculate Heart of Mary by name.
This is a rubric, not colitur's own reasoned choice.
Implemented as a sub-rank of 95, strictly between Tabula entries 9 and
10 -- the same "fits between neighbours" technique this module already
uses elsewhere -- scoped to the two named slugs rather than
[subject = Bvm], since the Notification's own reasoning is specifically
about a memorial's link to a movable solemnity of the Lord, not a
blanket Marian precedence.
Golden pin updated: test_rite_of.ml's 2011-06-13 tie now pins Mary,
Mother of the Church as observed (was Anthony of Padua, labelled "known
arbitrary"), with the header rewritten to state the outcome now rests on
the Notification, not a coin-flip. The litcal oracle allow-list gains
L10: litcal's own grade vocabulary has no representation for a 95
sub-rank (everything Memoria_obligatoria reads "Memorial"), a
representational gap in litcal, not a computational disagreement -- the
identity axis is untouched and needed no new entry.
Diffstat (limited to 'test/test_precedence_of.ml')
| -rw-r--r-- | test/test_precedence_of.ml | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/test/test_precedence_of.ml b/test/test_precedence_of.ml index 23c26c2..e2e8540 100644 --- a/test/test_precedence_of.ml +++ b/test/test_precedence_of.ml @@ -524,6 +524,60 @@ let test_all_souls_beats_an_ordinary_sunday () = Alcotest.(check bool) "All Souls, not the Sunday, is observed" true (resolution.Precedence.observed = all_souls_candidate) +(* W3 (of-known-wrongs, 2026-08-26). Mary, Mother of the Church (Easter+50) + and a fixed obligatory memorial (e.g. Anthony of Padua, 13 June) both + used to band at Tabula III.10 (100) whenever they coincide -- a tie + {!Rite_of.Precedence_of.band} could not break, silently resolved instead + by {!Colitur_kernel.Precedence.resolve}'s own generic alphabetical + tie-break. See {!Rite_of.Precedence_of.movable_bvm_memorials}'s own + comment for the primary source (the CDWDS's own 24 March 2018 + Notification) this fix cites: the Marian memorial now bands at 95 and + always prevails. This is the direct unit-level counterpart to + test_rite_of.ml's own end-to-end + [test_mater_ecclesiae_anthony_tie_2011_resolved] -- this one calls + {!Colitur_kernel.Precedence.resolve} directly, the same shape every + other test in this file uses, and checks BOTH real years the sweep in + this task's own report found (2011 for Mater Ecclesiae, 2015 for the + Immaculate Heart -- three years apart via the other offset, colliding + with the SAME rival, Anthony of Padua, both confirmed via + {!Colitur_kernel.Computus.gregorian_easter} rather than trusted). *) +let test_movable_bvm_memorial_beats_a_fixed_one () = + let anthony = + mk ~slug:"anthony-of-padua-priest-and-doctor" ~rank:Vocab_of.Memoria_obligatoria + ~origin:Precedence.Sanctoral () + in + List.iter + (fun (label, slug, easter_offset, year, expected_date) -> + let movable = + mk ~slug ~rank:Vocab_of.Memoria_obligatoria ~subject:Subject.Bvm + ~origin:Precedence.Sanctoral () + in + Alcotest.(check bool) + (Printf.sprintf "%s: alphabetically \"anthony-of-padua...\" sorts BEFORE %S -- confirms this \ + test exercises the tie-break the fix overrides, not a vacuous check" + label slug) + true (String.compare "anthony-of-padua-priest-and-doctor" slug < 0); + let easter = Computus.gregorian_easter year in + let d = Date.add_days easter easter_offset in + Alcotest.(check string) + (Printf.sprintf "%s: Easter+%d %d really is %s" label easter_offset year expected_date) + expected_date (Date.to_iso8601 d); + let temporal_c = + mk ~slug:"of-ordinary-time-feria" ~rank:Vocab_of.Feria ~origin:Precedence.Temporal () + in + let ctx = { Precedence.date = d; season = Vocab_of.Ordinary_time; weekday = Date.weekday d } in + let resolution = + Precedence.resolve Rite_of.Precedence_of.rules ctx ~temporal:temporal_c + ~sanctoral:[ anthony; movable ] + in + Alcotest.(check bool) + (Printf.sprintf "%s prevails over Anthony of Padua, not the alphabetical order" label) + true (resolution.Precedence.observed = movable)) + [ ("Mary, Mother of the Church vs Anthony of Padua", "mary-mother-of-the-church", 50, 2011, + "2011-06-13"); + ("Immaculate Heart of Mary vs Anthony of Padua", "immaculate-heart-of-mary", 69, 2015, + "2015-06-13") ] + let suite = ( "precedence-of", [ Alcotest.test_case "Tabula part I (entries 1-4)" `Quick test_part1; @@ -549,5 +603,9 @@ let suite = test_target_is_free_of_entries_1_to_8; Alcotest.test_case "fix round 2: shipped All Souls beats an ordinary per-annum Sunday (2025-11-02)" `Quick - test_all_souls_beats_an_ordinary_sunday ] + test_all_souls_beats_an_ordinary_sunday; + Alcotest.test_case + "W3: a movable BVM obligatory memorial beats a fixed one, per the CDWDS's 24 March 2018 \ + Notification" `Quick + test_movable_bvm_memorial_beats_a_fixed_one ] @ List.map QCheck_alcotest.to_alcotest [ prop_band_total ] ) |
