blob: d281f9a120db2b5fc12919287035f718ff35bd13 (
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
|
(** The invariant harness -- validation layer 2. Checks run over a *liturgical*
year, not a civil year: a season that straddles January would otherwise look
as though it recurs. *)
type failure = { year : int; date : string; check : string; detail : string }
val failure_to_string : failure -> string
(** [run rite ~year] returns every invariant violation in the liturgical year
opening in civil year [year]. An empty list means the year is clean.
[rite.Rite.anchors y] is the rite's own independent restatement of its
fixed and Easter-derived named days for civil year [y], as (expected
slug, date) pairs -- not derived from [rite.Rite.temporal] itself, so a
drift between the two is caught rather than invisible. [run] consults
both [anchors year] and [anchors (year + 1)], since a liturgical year
straddles two civil years, and checks only the pairs whose date actually
falls within the year walked.
The season check compares the run-length-compressed season sequence
against [rite.Rite.season_runs], not [rite.Rite.vocab.seasons]: a rite may
have one season appear in two separate runs (the modern form's Ordinary
Time does), so the two are not necessarily the same list.
Total over the whole 1583..9999 domain, including [year] = 9999: the
liturgical year opening there continues into out-of-domain civil year
10000, so the walk is clamped to 31 December 9999 and the checks run
against that truncated final year rather than raising. *)
val run : ('s, 'r) Rite.t -> year:int -> failure list
|