aboutsummaryrefslogtreecommitdiff
path: root/lib/kernel/precedence.mli
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel/precedence.mli')
-rw-r--r--lib/kernel/precedence.mli44
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/kernel/precedence.mli b/lib/kernel/precedence.mli
index a0b4b1a..05022c5 100644
--- a/lib/kernel/precedence.mli
+++ b/lib/kernel/precedence.mli
@@ -145,3 +145,47 @@ type 'r resolution = {
val resolve :
('s, 'r) rules -> 's context -> temporal:'r candidate ->
sanctoral:'r candidate list -> 'r resolution
+
+(** RG 111(a) (EF; docs/research/rules-register.md; LT.txt, grep "Ratio
+ admittendi commemorationes"): {i "in diebus liturgicis I classis et in
+ Missis in cantu non conventualibus, nulla admittitur commemoratio,
+ praeter unam privilegiatam"} -- on a liturgical day of the first class,
+ AND at any non-conventual SUNG Mass regardless of the day's own class,
+ at most ONE commemoration is admitted, and only if it is privileged.
+ (b)/(c)/(d), immediately following in the same rubric, give the wider
+ caps -- two ordinary/privileged commemorations depending on class --
+ that apply everywhere else; {!rules.admit} already computes exactly
+ that wider set, which is why this function's own INPUT is the admitted
+ LOW-MASS list, not a fresh resolution: (a) is not a distinct admission
+ RULE with its own candidate-ranking logic, it is a narrower CAP applied
+ afterwards to the identical admitted, precedence-ordered list -- "at
+ most one, and it must be privileged" is exactly "keep the first
+ admitted entry, if any, that is privileged", nothing else in the list
+ can ever outrank it (RG 113: admission order already follows the
+ rite's own table of precedence, {!rules.admit}'s own citation).
+
+ Deliberately a pure post-hoc DERIVATION over
+ {!Liturgical_day.t.commemorations}, not a second stored field: the
+ input list is already validated (privilege-tagged, admission-capped);
+ this function adds no new information and can regress in no way the
+ input list itself could not already regress, so a second field would
+ only create a second place for the same fact to drift out of sync with
+ the first -- the identical reasoning {!Liturgical_day.t.temporal}'s own
+ "embedded, not flattened" comment gives for a different field. Exposed
+ here, at the kernel level, rather than left for an output layer to
+ reimplement: the filter is small but the RULE it encodes (RG 111(a))
+ is not obvious from the type alone, and a caller (the [rubrics] CLI
+ column, a future template, a differential test) should name the
+ rubric, not re-derive "privileged commemorations, capped at one" for
+ itself.
+
+ SCOPE: "non conventualibus" is read literally -- this models the
+ ordinary (non-conventual) sung Mass only. RG 111(a)'s own text implies
+ a CONVENTUAL sung Mass keeps the wider (b)/(c)/(d) caps even when sung
+ (a choir-obligation distinction), but this engine has no concept of
+ "conventual" at all (no community/choir dimension anywhere in
+ {!Celebration.t} or {!Liturgical_day.t}), so this function's result
+ should be read as "what a normal parish/private Low OR sung Mass
+ admits", never "what every sung Mass, everywhere, admits" -- a
+ documented scope limit, not an oversight. *)
+val sung_mass_commemorations : ('a * privilege) list -> ('a * privilege) list