diff options
Diffstat (limited to 'lib/rites/rite_ef/precedence_ef.ml')
| -rw-r--r-- | lib/rites/rite_ef/precedence_ef.ml | 252 |
1 files changed, 215 insertions, 37 deletions
diff --git a/lib/rites/rite_ef/precedence_ef.ml b/lib/rites/rite_ef/precedence_ef.ml index 750da8b..374e9a4 100644 --- a/lib/rites/rite_ef/precedence_ef.ml +++ b/lib/rites/rite_ef/precedence_ef.ml @@ -48,6 +48,82 @@ let universal_layer = "ef-universal" let indult_prefix = "indult:" let unclassified = max_int +(* CORRECTED, fix round 1 (coordinator finding 1) -- the ORIGINAL version of + this constant was [-14], justified only by "cannot collide with a real + table position (1..28) or [unclassified]". That is a COLLISION argument, + not an ORDERING one, and [band]'s own return value is compared by + {!Precedence.compare_by}/{!compare_precedence} as a plain [<] -- a + negative value is not merely "distinct from 1..28", it is LOWER than + every one of them, so a movable Class2 Lord feast (Holy Family) would + have beaten every I-class day (entries 1-13) outright, not merely the + fixed Baptism it was built to beat. Not live against the shipped + UNIVERSAL sanctoral data (no I-class universal feast falls 7-13 January), + which is why the original 1583-9999 blast radius (§6.2) showed only the + one intended shape -- but entries 12/13 admit PROPER and INDULT I-class + feasts too (patron/titular/dedication days, {!is_universal}/{!is_indult} + below), which arrive via `data/ef/adjustments.sexp`-style overlays, this + architecture's own advertised extension point -- a diocesan I-class + patronal feast landing 7-13 January would have made the inversion live + immediately, transferring the I-class feast as though a II-class Sunday + had impeded it. Demonstrated directly (fix round 1, reproduced then + reverted): a synthetic Class1 sanctoral candidate on 11 January was + OBSERVED as Holy Family (band -14) and the synthetic candidate itself + TRANSFERRED to the next day -- backwards on every count. + + FIXED: every {!band} branch now returns the real RG 91 entry number + TIMES TEN (entry 1 -> 10, entry 28 -> 280, {!unclassified} untouched at + [max_int]) instead of the bare 1..28 -- not an arbitrary rescale, a + deliberate one: RG 91's own text records a "primum mobilia, deinde + fixa" (movable-then-fixed) split at FIVE rows, not only this one -- + entry 13 ("Festa indulta I classis, primum mobilia, deinde fixa", its + own numbered row on both scans), entry 14 (this one), entry 20, entry + 23's third sub-item ("deinde festa indulta, primum mobilia, deinde + fixa"), and entry 24 ("Festa III classis, in calendario Ecclesiae + universae inscripta, primum mobilia, deinde fixa") -- and only entry 14 + has a live witness in this codebase's data today. NOTE, corrected by the + fix-round re-review: this comment previously said THREE rows and + attributed the first to "entry 12's own ninth sub-item". Both scans, and + the register's own §4 table, put that clause at entry 13; entry 12 has + eight sub-items and no such clause. Entry 24's split is the notable + omission -- it is the most-evaluated band in the whole domain and is + unsplit here, which is exactly the kind of sub-rank this headroom exists + for. The + ×10 scale reserves nine integers of genuine headroom immediately BEFORE + each real entry's own value for exactly this kind of sub-rank, without + requiring a second rescale if entry 12's or entry 20's own movable half + ever needs one too -- a value DERIVABLE from RG 91's own table structure, + not an arithmetic convenience chosen to dodge one collision. [band]'s own + entry-14 comments (below) restate this scale at each branch it touches. *) +let entry_14_fixed_band = 140 + +(* RG 91 entry 14's own text (scan-verified, docs/research/rules-register.md + §4): "14. Festa Domini II classis, PRIMUM MOBILIA, DEINDE FIXA" -- feasts + of the Lord, II class, MOVABLE FIRST, then fixed. Both halves are the + SAME numbered table row, but the primary text states a real priority + between them, not merely two disjoint categories -- [band]'s own + entry-14 branches below must not literally TIE at + {!entry_14_fixed_band}, because a tie would fall to + {!Precedence.resolve}'s own kernel-level fallback ([compare_by], + Slug.compare), which is deliberately NOT rubric-authoritative (the exact + anti-pattern RG 113's own fix already corrected once for commemoration + ordering, this file's own header) and would in fact pick the WRONG side + here: "commemoration-of-the-baptism-of-the-lord" sorts before + "ef-time-after-epiphany-sunday-1" alphabetically, backwards from "primum + mobilia". Derived from {!entry_14_fixed_band}, one better (lower) than + it, using the one integer of headroom the ×10 scale reserves immediately + before every real entry -- not a citation to some entry "13.5" that does + not exist in the primary text, just the ordering fact RG 91's own two + half-rows require, expressed the same way the whole table now is. The + one real witness today: Holy Family (RG 17(b), temporal_ef.ml's own + [holy_family_sunday]) against the fixed Commemoration of the Baptism of + the Lord (13 January) -- the only date they can ever coincide, since + Holy Family only ever falls 7-13 January and no OTHER fixed Class2-Lord + sanctoral entry shares that window (register §6.0's own subject audit: + Transfiguration 6 Aug, Exaltation of the Cross 14 Sep, Dedication of the + Archbasilica 9 Nov, the Purification 2 Feb, the Baptism 13 Jan -- the + Baptism alone falls in Holy Family's own window). *) +let entry_14_movable_band = entry_14_fixed_band - 1 + let is_indult layer = String.starts_with ~prefix:indult_prefix layer let is_universal layer = String.equal layer universal_layer @@ -127,8 +203,12 @@ let band (ctx : Vocab_ef.season Precedence.context) (c : Vocab_ef.rank Precedenc (* Named so entry 8's Sunday exception below can read "one worse than the Sunday it must yield to" rather than a bare integer that happens to equal entry 15's own value; entry 15's own branch returns this same - binding, not a second literal, so the two can never drift apart. *) - let entry_15_band = 15 in + binding, not a second literal, so the two can never drift apart. + CORRECTED, fix round 1 (coordinator finding 1): every branch below now + returns the real RG 91 entry number TIMES TEN, not the bare 1..28 -- + see {!entry_14_fixed_band}'s own comment for why (a genuine ordering + bug the bare scale could not express, not a cosmetic rename). *) + let entry_15_band = 150 in let open Vocab_ef in (* CORRECTED (Task B fix round 1, ef-rg16a): a [Commemoration_only] celebration has NO row in RG 91's table at all, checked FIRST, ahead of @@ -171,9 +251,9 @@ let band (ctx : Vocab_ef.season Precedence.context) (c : Vocab_ef.rank Precedenc ea22ad2. The guard is right; its former justification was not. *) if status = Celebration.Commemoration_only then unclassified (* 1: Nativity, Easter Sunday, Pentecost Sunday (I class w/ octave). *) - else if is_temporal && rank = Class1 && ((m = 12 && d = 25) || off = 0 || off = 49) then 1 + else if is_temporal && rank = Class1 && ((m = 12 && d = 25) || off = 0 || off = 49) then 10 (* 2: Sacred Triduum (Thu-Sat of Holy Week). *) - else if is_temporal && rank = Class1 && off >= -3 && off <= -1 then 2 + else if is_temporal && rank = Class1 && off >= -3 && off <= -1 then 20 (* 3: Epiphany, Ascension, Holy Trinity, Corpus Christi, Sacred Heart, Christ the King. *) else if is_temporal && rank = Class1 @@ -181,25 +261,25 @@ let band (ctx : Vocab_ef.season Precedence.context) (c : Vocab_ef.rank Precedenc || off = 39 (* Ascension *) || off = 56 (* Trinity *) || off = 60 (* Corpus Christi *) || off = 68 (* Sacred Heart *) || Date.compare date (Temporal_ef.christ_the_king (Date.year date)) = 0) - then 3 + then 30 (* 4: Immaculate Conception, Assumption BVM. *) - else if (not is_temporal) && rank = Class1 && ((m = 12 && d = 8) || (m = 8 && d = 15)) then 4 + else if (not is_temporal) && rank = Class1 && ((m = 12 && d = 8) || (m = 8 && d = 15)) then 40 (* 5: Vigil & Octave day of the Nativity. *) - else if is_temporal && rank = Class1 && ((m = 12 && d = 24) || (m = 1 && d = 1)) then 5 + else if is_temporal && rank = Class1 && ((m = 12 && d = 24) || (m = 1 && d = 1)) then 50 (* 6: Sundays of Advent, Lent, Passiontide, and Low Sunday. *) else if is_temporal && rank = Class1 && is_sunday && (season = Advent || season = Lent || season = Passiontide || off = 7) - then 6 + then 60 (* 7: I-class ferias not above -- Ash Wednesday; Mon/Tue/Wed of Holy Week. Thu-Sat of Holy Week are the Triduum, entry 2 above, not this entry. *) - else if is_temporal && rank = Class1 && (off = -46 || (off >= -6 && off <= -4)) then 7 + else if is_temporal && rank = Class1 && (off = -46 || (off >= -6 && off <= -4)) then 70 (* 8: All Souls -- RG 91 entry 8's own text (§4) carries a qualifier this transcription must honour: "yields to an occurring Sunday". 2 November is always Time_after_pentecost (well clear of Advent/Lent/Passiontide and of every other entry's own Easter-relative or fixed date), so a Sunday landing on it is always an ordinary entry-15 II-class Sunday -- the one and only rival this exception ever has to lose to. On such a - Sunday this returns [entry_15_band + 1]: strictly worse than 15 (an + Sunday this returns [entry_15_band + 1]: strictly worse than 150 (an exact tie would fall to Precedence.resolve's slug tie-break, which for "ef-all-souls" against a "ef-time-after-pentecost-sunday-*" slug would make All Souls WIN -- the precise bug this guards against), but @@ -209,50 +289,67 @@ let band (ctx : Vocab_ef.season Precedence.context) (c : Vocab_ef.rank Precedenc feasts transfer) still sees the true I-class candidate it needs to move to 3 November. *) else if (not is_temporal) && rank = Class1 && m = 11 && d = 2 then - if is_sunday then entry_15_band + 1 else 8 + if is_sunday then entry_15_band + 1 else 80 (* 9: Vigil of Pentecost. *) - else if is_temporal && rank = Class1 && off = 48 then 9 + else if is_temporal && rank = Class1 && off = 48 then 90 (* 10: Days within the Octaves of Easter and Pentecost. *) else if is_temporal && rank = Class1 && ((off >= 1 && off <= 6) || (off >= 50 && off <= 55)) - then 10 + then 100 (* 11: I-class feasts of the universal Church not above. *) - else if (not is_temporal) && (not is_vigil) && rank = Class1 && is_universal layer then 11 + else if (not is_temporal) && (not is_vigil) && rank = Class1 && is_universal layer then 110 (* 12: Proper I-class feasts. *) - else if (not is_temporal) && (not is_vigil) && rank = Class1 && not (is_indult layer) then 12 + else if (not is_temporal) && (not is_vigil) && rank = Class1 && not (is_indult layer) then 120 (* 13: Indult I-class feasts. By elimination once 11 and 12 have failed: not the universal layer (11), and marked as an indult overlay (12's "not indult" test having just failed). *) - else if (not is_temporal) && (not is_vigil) && rank = Class1 then 13 - (* 14: Feasts of the Lord, II class -- RG 91 entry 14, deliberately - UNQUALIFIED (contrast entry 16, which explicitly says "not - of the Lord"; RG 37c (§4, "Sundays") speaks of "II-class feasts of - the Lord" replacing an occurring II-class Sunday with no universal - qualifier either). No layer test here, unlike 11/12/13 and 16/19/20: - the register does not split this entry into universal/proper/indult, - so a proper or indult feast of the Lord still bands 14, not 19/20. *) - else if (not is_temporal) && (not is_vigil) && rank = Class2 && subject = Subject.Lord then 14 + else if (not is_temporal) && (not is_vigil) && rank = Class1 then 130 + (* 14, MOVABLE half -- RG 91 entry 14's own "primum mobilia, deinde + fixa" ({!entry_14_movable_band}'s own comment has the full citation + and reasoning). Checked before the FIXED half immediately below, + matching the primary text's own order, though [is_temporal] already + makes the two branches structurally disjoint on any one candidate + regardless of which is checked first -- the ordering here is for a + reader following RG 91's own prose, not for correctness. The only + witness this codebase currently constructs is Holy Family + (temporal_ef.ml's own [holy_family_sunday] branch, the one place + [subject] is ever [Lord] on a temporal-origin candidate); a + hypothetical movable Holy-Name-of-Jesus office (RG 17(a), still + unbuilt as its own named day, register §6) would reach this same + branch too, once built, since nothing here is keyed to Holy Family's + own slug. *) + else if is_temporal && rank = Class2 && subject = Subject.Lord then entry_14_movable_band + (* 14, FIXED half -- RG 91 entry 14, deliberately UNQUALIFIED (contrast + entry 16, which explicitly says "not of the Lord"; RG 37c (§4, + "Sundays") speaks of "II-class feasts of the Lord" replacing an + occurring II-class Sunday with no universal qualifier either). No + layer test here, unlike 11/12/13 and 16/19/20: the register does not + split this entry into universal/proper/indult, so a proper or + indult feast of the Lord still bands {!entry_14_fixed_band}, not + 19/20. *) + else if (not is_temporal) && (not is_vigil) && rank = Class2 && subject = Subject.Lord then + entry_14_fixed_band (* 15: Sundays, II class (every Sunday not already named at 6). *) else if is_temporal && rank = Class2 && is_sunday then entry_15_band (* 16: II-class feasts of the universal Church, not of the Lord. *) - else if (not is_temporal) && (not is_vigil) && rank = Class2 && is_universal layer then 16 + else if (not is_temporal) && (not is_vigil) && rank = Class2 && is_universal layer then 160 (* 17: Days within the Octave of the Nativity (26-28 Dec are Stephen, John, the Innocents -- sanctoral, not this entry). *) - else if is_temporal && rank = Class2 && m = 12 && (d = 29 || d = 30 || d = 31) then 17 + else if is_temporal && rank = Class2 && m = 12 && (d = 29 || d = 30 || d = 31) then 170 (* 18: II-class ferias -- Advent 17-23 Dec; Ember days of Advent, Lent, September. *) else if is_temporal && rank = Class2 && ((season = Advent && m = 12 && d >= 17 && d <= 23) || is_ember_18 slug) - then 18 + then 180 (* 19: Proper II-class feasts. *) - else if (not is_temporal) && (not is_vigil) && rank = Class2 && not (is_indult layer) then 19 + else if (not is_temporal) && (not is_vigil) && rank = Class2 && not (is_indult layer) then 190 (* 20: Indult II-class feasts. By elimination, as at 13. *) - else if (not is_temporal) && (not is_vigil) && rank = Class2 then 20 + else if (not is_temporal) && (not is_vigil) && rank = Class2 then 200 (* 21: II-class vigils (Ascension, Assumption, John Baptist, Peter & Paul -- can be temporal- or sanctoral-origin, see the file comment above). *) - else if rank = Class2 && is_vigil then 21 + else if rank = Class2 && is_vigil then 210 (* 22: Ferias of Lent and Passiontide (Thursday after Ash Wednesday to the Saturday before Palm Sunday), except the Ember days (18 above). *) - else if is_temporal && rank = Class3 && (season = Lent || season = Passiontide) then 22 + else if is_temporal && rank = Class3 && (season = Lent || season = Passiontide) then 220 (* 23: III-class feasts in particular calendars. Unlike 11/12 and 14/16 above, the universal entry (24) is the HIGHER number here -- RG 91's own table ranks a particular-calendar III-class feast ahead of a @@ -260,13 +357,13 @@ let band (ctx : Vocab_ef.season Precedence.context) (c : Vocab_ef.rank Precedenc the register states it, not "corrected" into the other classes' pattern. RG 91 has no indult sub-rank at III class, so every non-base layer lands here, not split further. *) - else if (not is_temporal) && (not is_vigil) && rank = Class3 && not (is_universal layer) then 23 + else if (not is_temporal) && (not is_vigil) && rank = Class3 && not (is_universal layer) then 230 (* 24: III-class feasts in the universal calendar. *) - else if (not is_temporal) && (not is_vigil) && rank = Class3 then 24 + else if (not is_temporal) && (not is_vigil) && rank = Class3 then 240 (* 25: Ferias of Advent to 16 Dec, except the Ember days (18 above). *) - else if is_temporal && rank = Class3 && season = Advent then 25 + else if is_temporal && rank = Class3 && season = Advent then 250 (* 26: III-class vigils (St Lawrence). *) - else if rank = Class3 && is_vigil then 26 + else if rank = Class3 && is_vigil then 260 (* 27: Office of the BVM on Saturday -- every otherwise-unoccupied IV-class Saturday, per the historical default that fills it; ordinary Mass propers still make Rogation Mon/Tue/Wed proper without changing the @@ -275,12 +372,12 @@ let band (ctx : Vocab_ef.season Precedence.context) (c : Vocab_ef.rank Precedenc vigils for the same reason 11-13/14/16/19/20/23/24 do: RG 91 has no IV-class vigil at all (RG 91's own vigil list, §4 "Vigils", stops at III class), so one would be an anomaly, not this entry. *) - else if is_temporal && (not is_vigil) && rank = Class4 && weekday = Date.Sat then 27 + else if is_temporal && (not is_vigil) && rank = Class4 && weekday = Date.Sat then 270 (* 28: IV-class ferias -- the unqualified catch-all (temporal_ef.ml's own comment on [ferial_rank] cites the same primary text, "Feriae IV classis"). Excludes vigils for the same reason as 27 above: a IV-class "feria" that is also a vigil is not a feria RG 91 describes. *) - else if (not is_vigil) && rank = Class4 then 28 + else if (not is_vigil) && rank = Class4 then 280 else unclassified (* Task 8: what happens to the day's LOSING candidate (docs/research/ @@ -732,6 +829,87 @@ let disposition ~(winner : Vocab_ef.rank Precedence.candidate) the RG26 branch above gives its own [not is_vigil] guard, rather than relying on that absence silently. *) Precedence.Omit + else if winner.Precedence.cel.Celebration.subject = Subject.Lord && cel.Celebration.subject = Subject.Lord + then + (* PRIMARY AUTHORITY -- CORRECTED, fix round 1 (coordinator finding 7): + RG 95's own SECOND paragraph (Caput XIII, "De dierum liturgicorum + occurrentia accidentali", immediately after the "only I-class feasts + translate" sentence {!disposition}'s own Transfer branch above + already cites), present verbatim in ALL THREE documents including + the electronic transcription -- an OCCURRENCE-level rule, closer to + this exact question than RG 112(a) below: "Si vero duo festa eiusdem + Divinae Personae aut duo festa eiusdem Sancti vel Beati simul + occurrunt, fit de festo, quod in tabella praecedentiae superiorem + obtinet locum et aliud omittitur" -- but if two feasts of the SAME + DIVINE PERSON, or two feasts of the same Saint or Blessed, occur + TOGETHER, [the Office] is made of the feast which holds the HIGHER + PLACE in the table of precedence, and the OTHER IS OMITTED. This is + the direct authority: two feasts of the same Divine Person + (RG 112(a)'s own vocabulary) occurring together, the higher-table one + kept, the other omitted -- exactly {!band}'s own + [entry_14_movable_band]/[entry_14_fixed_band] ordering plus this + branch's own [Omit], not [Commemorate]. + + CORROBORATION 1, RG 112(a) (docs/research/rules-register.md §4/§6.0, + primary text, verified against all three documents -- CORRECTED, fix + round 1 (coordinator finding 2): a previous version of this comment + claimed the electronic transcription drops this paragraph's own + worked example and the Mass-proper rubric below, "the transcription's + documented defect" -- WRONG on both counts, struck. RG 112 has NO + worked example in any of the three documents; there was nothing to + drop. The Mass-proper rubric's absence from the transcription is not + an instance of that document's documented defect either (dropped + CALENDARIUM commemoration lines) -- checked directly: that specific + transcription (1962-06-23,_SS_Ioannes_XXIII,_Missale_Romanum, + _LT.pdf, a 2006 web capture) contains almost no Mass-propers text of + any kind (5 "Introitus"/"Antiphona ad Introitum" occurrences in + 26,322 lines, against 61 and 402 in the two photographic scans); its + own "Proprium de Tempore" page is a TABLE OF CONTENTS linking to + separate PDF files the capture never pulled in. A coverage gap in a + partial web capture, not a silent drop from content it otherwise + has): "112. Ad commemorationes et orationes quod attinet, haec + insuper serventur: a) Officium, Missa aut commemoratio de aliquo + festo vel mysterio UNIUS DIVINAE PERSONAE excludit commemorationem + aut orationem de alio festo vel mysterio EIUSDEM DIVINAE PERSONAE" -- + the Office, Mass, or commemoration of some feast or MYSTERY of ONE + Divine Person excludes a commemoration or oration of ANOTHER feast + or mystery of the SAME Divine Person. + + {!Subject.t} has no finer split within [Lord] than "a mystery + touching the Divine Person of the Son" -- every real [subject = + Lord] entry this codebase's own data carries concerns Christ + specifically (register §6.0's subject audit: the Precious Blood, the + Transfiguration, the Exaltation of the Cross, the Dedication of the + Archbasilica, the Purification, the Baptism, and now Holy Family), + so reading "same Divine Person" as simply "both [Lord]" is safe at + today's data's own granularity -- a rite that ever needed to + distinguish, say, a Trinity-specific mystery from a Son-specific one + by Person would need a finer [Subject.t] first, not a special case + added here. + + CORROBORATION 2 -- the Holy Family Mass propers' own note, + immediately following the Postcommunion, word for word on BOTH + photographic scans (real, and settles 13 January on its own even + apart from RG 95/112(a) -- the quotation itself is not in dispute, + only its earlier mis-attribution above): "Si festum S. Familiae + occurrerit die 13 ianuarii, Missa dicitur de festo S. Familiae, SINE + COMMEMORATIONE BAPTISMATIS D.N.I.C., et sine commemoratione + dominicae" -- if the feast of the Holy Family occurs on 13 January, + the Mass is said of the Holy Family, WITHOUT commemoration of the + Baptism of Our Lord Jesus Christ, and without commemoration of the + Sunday (RG 17(b)'s own general rule, restated for this specific + date). Independently confirmed against missalemeum (register §6.0): + title "The Holy Family: Jesus, Mary & Joseph", commemorations [], + the Baptism listed only under "displaced", never commemorated. + + Checked after RG 16(a) above (so a genuine RG 16(a) Sunday- + suppression is never re-explained under this citation instead) and + before the final ordinary-commemoration catch-all below, since + without it a [Feast]-status loser of this shape would otherwise + reach RG 95's ordinary "commemorated or omitted" branch and be + admitted as an ordinary Class2 commemoration under RG 111(b) -- + confirmed wrong against all three primary sources above. *) + Precedence.Omit else (* RG 95's other branch: "aut commemorantur aut penitus omittuntur" -- commemorated or wholly omitted. Reached by every SANCTORAL loser |
