aboutsummaryrefslogtreecommitdiff
path: root/lib/rites/rite_ef/precedence_ef.ml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rites/rite_ef/precedence_ef.ml')
-rw-r--r--lib/rites/rite_ef/precedence_ef.ml109
1 files changed, 76 insertions, 33 deletions
diff --git a/lib/rites/rite_ef/precedence_ef.ml b/lib/rites/rite_ef/precedence_ef.ml
index 50da4a7..0716177 100644
--- a/lib/rites/rite_ef/precedence_ef.ml
+++ b/lib/rites/rite_ef/precedence_ef.ml
@@ -9,22 +9,27 @@
without a separate exclusion for every later entry it pre-empts.
Two kinds of evidence decide an entry:
- - The temporal cycle's own office (Nativity, a Sunday, a feria, a vigil of
- the Lord) is identified structurally, from the context's date/season/
- weekday and the day's Easter offset -- never from its slug, which is
- just a label. [origin = Temporal] gates every such entry so a sanctoral
- candidate that happens to share a date (Immaculate Conception can never
- coincide with the movable cycle, but nothing stops a future rite bug
- from producing one) cannot be mistaken for the office itself.
- - A sanctoral feast's entry (11-13 I class, 14/16/19/20 II class, 23/24
- III class) is decided by its [rank] plus, per the brief's structural
- insight, its {!Celebration.t}.layer: a celebration whose layer is not
- the universal base is an overlay, hence "proper" or "indult" rather
- than the universal entry (see precedence_ef.mli). [origin = Sanctoral]
- gates these for the same reason: temporal-origin celebrations carry the
- literal layer id "temporal" (rite_ef/temporal_ef.ml's [build]), which is
- not [universal_layer] either, and would otherwise be misread as
- "proper" by the layer test alone.
+ - The temporal cycle's own office (Nativity, a Sunday, a feria, All Souls)
+ is identified structurally, from the context's date/season/weekday and
+ the day's Easter offset -- never from its slug, which is just a label.
+ [origin = Temporal] gates every such entry so a sanctoral candidate that
+ happens to share a date (Immaculate Conception can never coincide with
+ the movable cycle, but nothing stops a future rite bug from producing
+ one) cannot be mistaken for the office itself. All Souls (entry 8, the
+ one non-temporal-origin member of this group) additionally reads the
+ context's weekday for its own register-stated exception -- see entry 8
+ below.
+ - A sanctoral feast's entry is decided by its [rank], and -- except at
+ entry 14 (see its own comment below, where the register draws no such
+ line) -- per the brief's structural insight, also by its
+ {!Celebration.t}.layer: a celebration whose layer is not the universal
+ base is an overlay, hence "proper" or "indult" rather than the
+ universal entry (11-13 I class; 16/19/20 II class; 23/24 III class; see
+ precedence_ef.mli). [origin = Sanctoral] gates these for the same
+ reason: temporal-origin celebrations carry the literal layer id
+ "temporal" (rite_ef/temporal_ef.ml's [build]), which is not
+ [universal_layer] either, and would otherwise be misread as "proper" by
+ the layer test alone.
Vigils (21, 26) are the one shape neither of those two kinds fully
describes on their own: a II/III-class vigil can be temporal-origin (the
@@ -46,19 +51,33 @@ let unclassified = max_int
let is_indult layer = String.starts_with ~prefix:indult_prefix layer
let is_universal layer = String.equal layer universal_layer
-(* Ember days are identified by the temporal cycle's own slug convention
- (rite_ef/temporal_ef.ml's [ember]: "ef-<set>-ember-<day>"), not
- re-derived here: the September anchor in particular is one of the more
- contested dates in the 1962 calendar (temporal_ef.ml's own comment on
+(* Not an RG citation either -- see [universal_layer] above. Nothing in
+ {!Celebration.t} otherwise marks "this is a vigil, not an ordinary office
+ of the same rank" (see the file's top comment), so entries 21/26 read it
+ off the temporal cycle's own slug suffix (rite_ef/temporal_ef.ml's
+ [named], e.g. "ef-ascension-vigil"). Exposed so a future task naming a
+ sanctoral vigil (Task 10: Assumption, John Baptist, Peter & Paul,
+ Lawrence -- only Ascension exists today) uses the same suffix; a
+ differently-named vigil would band 16/24 instead of 21/26, silently. *)
+let vigil_suffix = "-vigil"
+
+let is_vigil slug = String.ends_with ~suffix:vigil_suffix slug
+
+(* Not an RG citation -- see [universal_layer]. Entry 18's Ember days are
+ identified by the temporal cycle's own slug convention (rite_ef/
+ temporal_ef.ml's [ember]: "ef-<set>-ember-<day>"), not re-derived here:
+ the September anchor in particular is one of the more contested dates in
+ the 1962 calendar (temporal_ef.ml's own comment on
[third_sunday_of_september]), and re-deriving it a second time would only
create a second place for that same uncertainty to drift. Only the
Advent, Lent and September sets are listed: RG 91 entry 18 names exactly
those three; the Whitsun (Pentecost) set is I class and falls inside the
- Pentecost octave, entry 10, matched below before this is ever reached. *)
-let is_ember_18 slug =
- String.starts_with ~prefix:"ef-advent-ember-" slug
- || String.starts_with ~prefix:"ef-lent-ember-" slug
- || String.starts_with ~prefix:"ef-september-ember-" slug
+ Pentecost octave, entry 10, matched below before this is ever reached.
+ Exposed for the same reason as [vigil_suffix]: a rename of temporal_ef's
+ format has somewhere to be caught other than a silently-wrong entry 18. *)
+let ember_prefixes = [ "ef-advent-ember-"; "ef-lent-ember-"; "ef-september-ember-" ]
+
+let is_ember_18 slug = List.exists (fun prefix -> String.starts_with ~prefix slug) ember_prefixes
let band (ctx : Vocab_ef.season Precedence.context) (c : Vocab_ef.rank Precedence.candidate) :
int =
@@ -68,7 +87,7 @@ let band (ctx : Vocab_ef.season Precedence.context) (c : Vocab_ef.rank Precedenc
let layer = cel.Celebration.layer in
let slug = Slug.to_string cel.Celebration.slug in
let is_temporal = c.Precedence.origin = Precedence.Temporal in
- let is_vigil = String.ends_with ~suffix:"-vigil" slug in
+ let is_vigil = is_vigil slug in
let date = ctx.Precedence.date in
let season = ctx.Precedence.season in
let weekday = ctx.Precedence.weekday in
@@ -77,6 +96,11 @@ let band (ctx : Vocab_ef.season Precedence.context) (c : Vocab_ef.rank Precedenc
(* Easter offset, the same convention as temporal_ef.ml's [days_between
easter d]: 0 is Easter itself, negative before, positive after. *)
let off = Date.to_rata date - Date.to_rata (Computus.gregorian_easter (Date.year date)) in
+ (* 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
let open Vocab_ef in
(* 1: Nativity, Easter Sunday, Pentecost Sunday (I class w/ octave). *)
if is_temporal && rank = Class1 && ((m = 12 && d = 25) || off = 0 || off = 49) then 1
@@ -101,8 +125,23 @@ let band (ctx : Vocab_ef.season Precedence.context) (c : Vocab_ef.rank Precedenc
(* 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
- (* 8: All Souls. *)
- else if (not is_temporal) && rank = Class1 && m = 11 && d = 2 then 8
+ (* 8: All Souls -- register line 334's own text 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
+ 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
+ otherwise not a citation to any other RG 91 row -- nothing else can
+ ever occur on 2 November to be confused with it. Entry 8's own [rank]
+ is untouched by this, so Task 8's disposition (RG 95: only I-class
+ 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
(* 9: Vigil of Pentecost. *)
else if is_temporal && rank = Class1 && off = 48 then 9
(* 10: Days within the Octaves of Easter and Pentecost. *)
@@ -116,12 +155,16 @@ let band (ctx : Vocab_ef.season Precedence.context) (c : Vocab_ef.rank Precedenc
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. *)
- else if (not is_temporal) && (not is_vigil) && rank = Class2 && is_universal layer
- && subject = Subject.Lord
- then 14
+ (* 14: Feasts of the Lord, II class -- register line 341, deliberately
+ UNQUALIFIED (contrast entry 16 at line 342, which explicitly says "not
+ of the Lord"; RG 37c, register line 393, 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
(* 15: Sundays, II class (every Sunday not already named at 6). *)
- else if is_temporal && rank = Class2 && is_sunday then 15
+ 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
(* 17: Days within the Octave of the Nativity (26-28 Dec are Stephen,