diff options
Diffstat (limited to 'lib/rites/rite_of/temporal_of.mli')
| -rw-r--r-- | lib/rites/rite_of/temporal_of.mli | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/lib/rites/rite_of/temporal_of.mli b/lib/rites/rite_of/temporal_of.mli new file mode 100644 index 0000000..982ff05 --- /dev/null +++ b/lib/rites/rite_of/temporal_of.mli @@ -0,0 +1,141 @@ +(** The OF (post-1970) temporal cycle, per the Missale Romanum editio typica + tertia (2002) "Normae universales de anno liturgico et de calendario" + ("Normae n. N") and the Institutio Generalis Missalis Romani ("IGMR + n. N") -- the same PDF carries both documents, independently numbered + from 1, so every citation in this rite module names which one it is. + + OPEN QUESTION, deliberately NOT settled here (design + 2026-08-24-colitur-of-rite-module-design.md ยง8.1): the OF calendar has + no meaning before 1970, but colitur's kernel domain is 1583..9999, and + this module is computable -- and computed -- across the WHOLE of it, + exactly as {!Rite_ef.Temporal_ef} is. Phase 1 takes no position on + whether a pre-1970 (or, symmetrically, a far-future) answer from this + module means anything liturgically; it only guarantees the arithmetic is + total and the properties below hold everywhere the kernel itself is + total. Refusing, extrapolating, or flagging pre-1970 output specially is + a decision for the phase that wires this module into a {!Colitur_kernel + .Rite.t} and a validation layer with a real oracle to check it + against -- not this one. *) + +open Colitur_kernel + +(** Normae n. 40: "Tempus Adventus incipit a I Vesperis dominicae quae + incidit in diem 30 novembris vel est huic vicinior" -- Advent begins with + First Vespers of the Sunday falling on 30 November or nearest to it. + Worded identically in substance to EF's own RG 20 ({!Rite_ef.Temporal_ef + .advent_start}), so the same closed-form identity applies: the Sunday + nearest 30 November is, equivalently, three weeks before the last Sunday + on or before 24 December -- see that function's own citation for why + that identity holds for every civil year with no case split. *) +val advent_start : int -> Date.t + +(** First day of the liturgical year opening in civil year [y]. Same as + {!advent_start}. *) +val year_start : int -> Date.t + +val season : Date.t -> Vocab_of.season + +(** Normae n. 38 and the Calendarium Romanum Generale's own January table + (extracted line ~4033: "Dominica post diem 6 ianuarii: In baptismate + Domini Festum"): the Sunday falling AFTER 6 January (never 6 January + itself, even in a year 6 January IS a Sunday -- "post", not "on or + after") carries the feast of the Baptism of the Lord. The January + table's own further note ("Ubi sollemnitas Epiphaniae ad dominicam + transfertur... festum Baptismatis Domini celebratur feria secunda + sequenti") only concerns places that exercise Normae n. 37's LOCAL + option to move Epiphany itself off 6 January -- inapplicable to the + universal calendar this module computes, which keeps Epiphany fixed at + 6 January (spec's own EF-precedented "universal calendar only" + discipline), so that Monday-shift clause is never reached here. *) +val baptism_of_the_lord : int -> Date.t + +(** Normae n. 35(a) and the December calendarium table's own closing line + (extracted line ~4459: "Dominica infra octavam Nativitatis, vel, ea + deficiente, die 30 decembris: Sanctae Familiae ... Festum"): the Sunday + falling within the Octave of the Nativity (26-31 December), or, that + lacking, 30 December. Movable-with-a-fixed-fallback, the same shape as + EF's own Holy Family/Holy Name ({!Rite_ef.Temporal_ef.holy_family_sunday} + /[holy_name_sunday]) -- CODE for that reason, not sanctoral DATA, unlike + the plain fixed-date entries this window also contains (Stephen 26 Dec, + John 27 Dec, the Holy Innocents 28 Dec), which carry no such fallback + logic and are deferred to Phase 3's calendar data instead (see this + file's own top-of-module comment for the full CODE-vs-DATA argument). + UNLIKE EF's 7-13 January window, which can never be empty of a Sunday, + this 6-day window (26-31 December) CAN be -- confirmed by the fallback + clause's own existence in the primary text, not merely inferred. *) +val holy_family : int -> Date.t + +(** Normae n. 36: "Dominica a die 2 ad diem 5 ianuarii occurrens est + Dominica II post Nativitatem" -- the Sunday falling 2-5 January, if any, + is the Second Sunday after the Nativity. [None] when no such Sunday + exists that year (the SAME 2-5 January window as EF's own Holy Name of + Jesus, {!Rite_ef.Temporal_ef.holy_name_sunday} -- a real structural + coincidence between the two rites' calendars, not a shared computation: + OF's Normae carries no "otherwise, on a fixed date" fallback for this + Sunday at all, unlike EF's RG 17(a) -- a year without one simply has no + "Second Sunday after the Nativity" office; {!temporal}'s own dispatch + falls through to an ordinary Christmas-time feria for every day of that + window in such a year). *) +val second_sunday_of_christmas : int -> Date.t option + +(** Normae n. 43-44 and the Missale's own "HEBDOMADA XXXIV 'PER ANNUM'" + heading (extracted line 13099: "Dominica ultima 'per annum' fit + sollemnitas ... universorum Regis"): the LAST Sunday before Advent I, + always the Solemnity of Christ the King, always week XXXIV. See + {!temporal}'s own citation on the two-block week arithmetic for the full + derivation this anchors. *) +val christ_the_king : int -> Date.t + +(** The named temporal days: the Nativity and its Vigil, Mary Mother of God + (the Nativity's own Octave Day, 1 January), Epiphany, Ash Wednesday, + Palm/Passion Sunday, Easter and the days of its Octave, Ascension, + Pentecost, Trinity Sunday, Corpus Christi, and Christ the King. Returns + (season, slug, colour, rank). Carries no week of its own, for the same + reason {!Rite_ef.Temporal_ef.named} does not: {!temporal} computes it + uniformly via {!week} for every day, named or not, so a named day inside + a numbered season run always carries that run's week. + + Deliberately EXCLUDES {!holy_family}, {!second_sunday_of_christmas} and + {!baptism_of_the_lord}: each needs a per-year conditional ([holy_family] + on whether 26-31 December has a Sunday at all; the other two on which + Sunday, if any, actually falls in their own window) that this function's + bare [Date.t -> ... option] shape has no way to express without + threading extra state through every other branch too -- the exact + reason EF's own [named] excludes its structurally identical Holy + Family/Holy Name. {!temporal} applies all three as its own targeted + dispatch instead. *) +val named : Date.t -> (Vocab_of.season * string * Colour.t * Vocab_of.rank) option + +(** Week within the season, 1-indexed, Sunday-aligned (constant across a + Sunday-to-Saturday span). [None] outside every numbered run -- Christmas + has none at all (Normae's own Christmas-season structure is date-keyed, + never week-keyed: contrast n. 36's "the Sunday falling 2-5 January", a + date range, against n. 30's own "Sundays I, II, III..." for Lent) -- and + Ordinary Time's own numbering is total over both of its runs (Normae + n. 43-44): see {!temporal}'s own citation for the two-block arithmetic + that makes the second run's numbers land correctly on 1..34 with the + final week always 34, INCLUDING the "in some years a week is skipped + entirely" case Normae n. 43's own "thirty-three OR thirty-four" already + names. *) +val week : Date.t -> int option + +(** The slug for a Sunday, or [None] if [d] is not a Sunday. *) +val sunday_slug : Date.t -> string option + +val id : string + +(** Total over 1583..9999: every date yields exactly one temporal identity + (subject to this file's own top-of-module note on what "yields" means + before 1970). *) +val temporal : Date.t -> (Vocab_of.season, Vocab_of.rank) Temporal.t + +(** Independent restatement of {!named}'s fixed and Easter-relative dates, + plus {!holy_family}, {!second_sunday_of_christmas} and + {!baptism_of_the_lord}, for civil year [y], paired with the slug each + should carry -- the same anchor-agreement discipline + {!Rite_ef.Temporal_ef.anchors} follows, for the same reason: catches an + accidental single-site drift in an offset rather than leaving it + invisible. Not wired into {!Colitur_kernel.Validate.run} in this phase + (that needs a full {!Colitur_kernel.Rite.t}, Phase 2's own deliverable), + but kept in the same shape so that wiring is a straight reuse. *) +val anchors : int -> (string * Date.t) list |
