aboutsummaryrefslogtreecommitdiff
path: root/lib/rites/rite_ef/lectionary_ef.ml
blob: 02c3c64d4de6903d20e7362834b8ec56a7e057b8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
open Colitur_kernel

(* Step 1: the observed celebration's own proper.
   Step 2: the day's own temporal slug.
   Step 3: a weekday whose own slug has no entry says the preceding Sunday's
   Mass -- see the implementation comment on that branch in [readings] for
   the termination argument and why it is the Sunday's TEMPORAL, not
   observed, identity.

   Nothing here encodes "Lent has daily propers": the presence of an entry in
   [lectionary] is the sole discriminator -- this function does not branch on
   season, rank, or any other field to decide whether a temporal slug "ought"
   to have its own Mass.

   The WARRANT for that shape is lectio's own observed behaviour only, not a
   confirmed Missal citation: Lent 1 Monday returns its own Ezech 34:11-16,
   while Advent, Christmas and post-Pentecost Mondays return their Sunday's
   Mass, in both streams. docs/research/rules-register.md records this
   openly as unconfirmed against the primary source ("EF reading-selection
   rules ... Have lectio's behaviour; confirm against the Missal's
   ferial-Mass rubrics when coding") -- that confirmation has not been done;
   do not read this comment as citing RG/the Missal for the SELECTION rule
   itself, only [Lectionary.find]'s presence-or-absence as the mechanism. *)
(* Days from a given weekday back to the preceding Sunday. Sunday itself
   yields 0, which is why step 3 must guard on it -- see [readings] below. *)
let days_since_sunday : Date.weekday -> int = function
  | Date.Sun -> 0
  | Date.Mon -> 1
  | Date.Tue -> 2
  | Date.Wed -> 3
  | Date.Thu -> 4
  | Date.Fri -> 5
  | Date.Sat -> 6

let readings ~lectionary ~observed ~temporal ~date ~temporal_at =
  match observed.Celebration.citations with
  | _ :: _ as cs -> cs
  | [] -> (
      match Lectionary.find lectionary temporal.Temporal.office.Celebration.slug with
      | Some cs -> cs
      | None -> (
          (* Step 3: a feria with no proper of its own says the preceding
             Sunday's Mass. WARRANT is the same as step 2's -- lectio's own
             observed behaviour, not a confirmed Missal citation: this is the
             rule lectio hard-codes as data on the four Advent ferias
             (Advent II's readings copied verbatim onto the following
             Monday-Saturday) and leaves absent on the other slugs this step
             now also reaches; docs/research/rules-register.md already
             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.

             The preceding Sunday's TEMPORAL slug, never its observed one:
             the rubric is the preceding Sunday's Mass even in a year when a
             feast displaced that Sunday from being observed (see
             test_step3_uses_temporal_not_observed). [temporal_at] gives the
             temporal identity of any date, so the Sunday is reached by date
             arithmetic and a fresh call to the temporal cycle -- never by
             string surgery on [own_slug]: the slug shapes are genuinely
             inconsistent across seasons (e.g. [ef-advent-sunday-1] versus
             [ef-advent-1-monday], the week number on opposite sides of the
             season name), so deriving one from the other textually would be
             a latent bug the moment a season's naming convention differs. *)
          let offset = days_since_sunday temporal.Temporal.weekday in
          if offset = 0 then []
          else
            let sunday = Date.add_days date (-offset) in
            let sunday_temporal = temporal_at sunday in
            match
              Lectionary.find lectionary sunday_temporal.Temporal.office.Celebration.slug
            with
            | Some cs -> cs
            | None -> []))