diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/test_golden.ml | 16 | ||||
| -rw-r--r-- | test/test_oracle.ml | 81 | ||||
| -rw-r--r-- | test/test_precedence_ef.ml | 68 |
3 files changed, 137 insertions, 28 deletions
diff --git a/test/test_golden.ml b/test/test_golden.ml index c5aa65a..80e2c9d 100644 --- a/test/test_golden.ml +++ b/test/test_golden.ml @@ -434,11 +434,21 @@ let test_ember_ferias_commemorated_when_impeded () = comms=[ef-advent-ember-fri:privileged] in=- out=[]"; (* 1902-02-22: Lent Ember Saturday (RG91 entry 18, II class) impeded by the Chair of St Peter (II class, universal, entry 16). Same RG24/ - RG109(e) mandate. *) - check ~msg:"1902-02-22: Lent Ember Saturday, impeded, MUST be commemorated (RG24) and is privileged (RG109e)" + RG109(e) mandate. ALSO, ef-holyname-rg110 task: RG 110's own + inseparable Peter/Paul commemoration -- "in Officio ... S. Petri semper + fit commemoratio S. Pauli" -- fires unconditionally whenever + [chair-of-st-peter] is observed, uncapped by RG 111's own admission + count, so `+paul` now rides alongside the Ember feria's own + commemoration rather than being displaced by it (precedence_ef.ml's own + [rg110_additions]). This pin's own [ef-lent-ember-sat:privileged] half + is UNCHANGED from before this task -- only [paul:ordinary] is new, + confirming RG 110 adds a genuinely SEPARATE, uncapped slot rather than + competing for the Ember feria's own privileged one. *) + check ~msg:"1902-02-22: Lent Ember Saturday, impeded, MUST be commemorated (RG24) and is privileged (RG109e) -- \ + AND RG110's Paul companion rides alongside it, uncapped" 1902 2 22 "1902-02-22 saturday season=lent week=1 slug=chair-of-st-peter rank=class-2 colour=white subject=saint \ - comms=[ef-lent-ember-sat:privileged] in=- out=[]" + comms=[ef-lent-ember-sat:privileged,paul:ordinary] in=- out=[]" let test_iv_class_ferias_never_commemorated () = (* 2026-07-22: an ordinary Time-after-Pentecost feria (Class4, RG91 entry diff --git a/test/test_oracle.ml b/test/test_oracle.ml index 35d4501..370eec0 100644 --- a/test/test_oracle.ml +++ b/test/test_oracle.ml @@ -599,23 +599,23 @@ let m10_dates = [ "2026-11-30"; "2027-11-30"; "2026-12-08"; "2027-12-08" ] own full note and the task report. *) let m11_dates = [ "2026-12-26"; "2026-12-28"; "2027-12-27"; "2027-12-28" ] -(* M12 -- RG 110, primary text: "In Officio et Missa S. Petri semper fit - commemoratio S. Pauli, et vicissim" -- in the Office and Mass of EITHER - Peter or Paul, a commemoration of the OTHER is ALWAYS made (the - "inseparable commemoration"), uncapped by RG 111's ordinary admission - count ("in numero orationum computando, pro unica habeantur" -- counted - as one for counting purposes, i.e. it rides alongside whatever RG 111 - already admits). Unimplemented in this codebase -- confirmed by the one - row in this window where it is visible: 22 February 2027 (Chair of - St Peter) shows only the privileged Lent feria commemorated in colitur, - while missalemeum shows that AND "St. Paul". A genuine, primary-cited - feature gap -- verdict missalemeum, register §6 open item. Real but - NARROW: every other Peter/Paul office in this window (29 June, both - years; 1 August M4-adjacent dates were checked and found clean) either - had no room for the extra commemoration to become visible against this - comparator's axes, or fell on a day this predicate does not otherwise - touch -- see the task report for the specific check. *) -let m12_dates = [ "2027-02-22" ] +(* M12 -- CLOSED (ef-holyname-rg110 task): RG 110 is now built + (precedence_ef.ml's own [rg110_additions]/[rg110_companion_slug]), and + this window's one visible instance -- 22 February 2027 -- no longer + diverges from missalemeum on [Comm_count] at all: colitur now shows the + privileged Lent feria's own commemoration AND "St. Paul", same COUNT + (two) as missalemeum. Removed rather than kept as a dead 0-row citation, + the SAME shape M17's own removal already established (this file's own + header): the count pin now enforces that this exact divergence cannot + silently reappear. NOT closed with zero remaining difference, though -- + see M15's own widened date list immediately below: once count agrees, + IDENTITY comparison is reached for the first time on this date, and + trips a SEPARATE, pre-existing, unrelated comparator limit (one of + colitur's two admitted commemorations, [ef-lent-2-monday], is + TEMPORAL-origin and carries no English name) -- a newly-exposed + instance of M15's own gap, not a new one, folded into M15's date list + rather than kept here under RG 110's own citation, which no longer + explains ANY part of this row's remaining diff. *) (* M13 -- OPEN, NOT adjudicated (the brief's own explicit permission, "say so as an open item rather than absorbing it"). 19 March 2027: St @@ -647,13 +647,13 @@ let m13_dates = [ "2027-03-19" ] either engine is wrong about: a genuine LIMIT of this comparator, honestly counted rather than silently passed (the brief's own explicit instruction: "a day whose commemoration cannot be matched must be - visibly counted and reported, not quietly passed"). On each of these 19 + visibly counted and reported, not quietly passed"). On 19 of these 20 rows, colitur's own admitted commemoration is TEMPORAL-origin (an impeded Advent/Lent feria) -- Rite_ef.Temporal_ef's own [build] (temporal_ef.ml) never sets a celebration's [names] field, so there is no English string on colitur's side to compare against missalemeum's title text at all (this file's own header, "THE MAPPING, AND EXACTLY WHAT IT - CANNOT RESOLVE"). Every one of these 19 oracle titles reads as a plain + CANNOT RESOLVE"). Every one of those 19 oracle titles reads as a plain prose description of the SAME temporal ferial slot colitur independently computes for that date (e.g. 2 Dec 2026: oracle "Feria IV after I Sunday of Advent" against colitur's own [ef-advent-1-wednesday]; 4 Dec 2027: @@ -664,12 +664,25 @@ let m13_dates = [ "2027-03-19" ] unresolved. Fixing this at the ROOT (giving every temporal-cycle candidate an English name) is a data/lectionary-bootstrap task, not something this comparator can do for itself -- register §6, "RG 113 - tie-break" section's own neighbour, records it as an open item. *) + tie-break" section's own neighbour, records it as an open item. + + ADDED, ef-holyname-rg110 task: 2027-02-22 -- the closed M12's own date, + above. NOT the same shape as the other 19 (colitur admits TWO + commemorations there, not one -- [paul], sanctoral-origin and + resolvable, and [ef-lent-2-monday], temporal-origin and not): the + comparator's own [identity_diff] bails out to [Comm_identity_unresolved] + the moment ANY admitted commemoration is unresolvable, regardless of how + many others resolve cleanly (test_oracle.ml's own [identity_diff], + "[List.exists] ... name = None"), so this row reaches the identical + diagnosis for the identical structural reason, once RG 110 stopped + [Comm_count] from masking it. Genuinely newly-EXPOSED by this task's own + fix, not newly-CAUSED by it: the underlying gap (no English name for a + temporal-cycle candidate) is exactly M15's own pre-existing one. *) let m15_dates = [ "2026-02-24"; "2026-03-19"; "2026-03-25"; "2026-12-02"; "2026-12-03"; "2026-12-04"; - "2026-12-07"; "2026-12-11"; "2026-12-21"; "2027-02-24"; "2027-12-02"; "2027-12-03"; - "2027-12-04"; "2027-12-06"; "2027-12-07"; "2027-12-11"; "2027-12-13"; "2027-12-16"; - "2027-12-21" ] + "2026-12-07"; "2026-12-11"; "2026-12-21"; "2027-02-22"; "2027-02-24"; "2027-12-02"; + "2027-12-03"; "2027-12-04"; "2027-12-06"; "2027-12-07"; "2027-12-11"; "2027-12-13"; + "2027-12-16"; "2027-12-21" ] (* M16 -- Task B: a genuine IDENTITY mismatch, both sides otherwise agreeing on rank/colour/count/presence. 27 March 2026 (Friday of Passion Week): @@ -766,6 +779,26 @@ let m16_dates = [ "2026-03-27" ] bootstrap task (Plan 4), not something this comparator can do for itself -- register §6 tracks it, the same open item [M15]'s own note already points to. *) +(* M19 -- ef-holyname-rg110 task: RG 110's OTHER direction, 30 June (this + window's two instances -- both years -- of + [in-commemoratione-sancti-pauli-apostoli], data/ef/adjustments.sexp's + own `Add commemoration-of-st-peter` directive; see that file's own + citation for the full scan quote). Unlike 22 February above, + missalemeum's own row for both dates shows an EMPTY commemorations array + ("St. Peter" absent, and not even listed as "displaced" -- nothing + competes for the slot on either side, so there is no candidate for + missalemeum's own engine to have rejected, only one it never + constructed): missalemeum has the SAME gap this task's own scan found in + lectio's source data (`~/git/projects/lectio/internal/caldata/ + tridentine-calendar.ini` has no 06-30 companion entry either) -- a + genuine feature gap, verdict colitur, the SAME shape as M1/M3/M8/M10 + above (each already "missalemeum does not implement X"), not a + citation-count coincidence: RG 110's own text is unconditional ("in + Officio et Missa S. Petri semper fit commemoratio S. Pauli, ET + VICISSIM"), and the calendarium's own June table states the SAME + pattern already built for the other two pairs, word for word. *) +let m19_dates = [ "2026-06-30"; "2027-06-30" ] + let layer_m_reason (c : colitur_row) (o : oracle_row) diffs = if diffs = [] then None (* M1's own subset widened (this task): colitur's observed day on both @@ -795,7 +828,6 @@ let layer_m_reason (c : colitur_row) (o : oracle_row) diffs = else if List.mem c.c_date m8_dates && diffs = [ Comm_presence ] then Some "M8" else if List.mem c.c_date m10_dates && diffs = [ Comm_presence ] then Some "M10" else if List.mem c.c_date m11_dates && diffs = [ Comm_presence ] then Some "M11" - else if List.mem c.c_date m12_dates && diffs = [ Comm_count ] then Some "M12" (* M13's own subset widened AGAIN (this task, following the SAME pattern Task B's own widening comment below records): colitur's observed celebration here is Joseph, SANCTORAL-origin, so its name IS @@ -818,6 +850,7 @@ let layer_m_reason (c : colitur_row) (o : oracle_row) diffs = && subset diffs [ Comm_identity_mismatch; Observed_identity_unresolved ] then Some "M16" else if diffs = [ Observed_identity_unresolved ] then Some "M18" + else if List.mem c.c_date m19_dates && diffs = [ Comm_presence ] then Some "M19" else None (* ---------------------------------------------------------------------- *) diff --git a/test/test_precedence_ef.ml b/test/test_precedence_ef.ml index d873e34..af7f65e 100644 --- a/test/test_precedence_ef.ml +++ b/test/test_precedence_ef.ml @@ -1016,6 +1016,33 @@ let sixtus = UNIVERSALLY), so the two values coinciding is the faithful shape, not a simplification that dodges the new parameter. The last two rows are where they genuinely differ -- see their own comment. *) +(* RG 110 (§4, Caput XIV): candidates built with the REAL trigger/companion + slugs {!PE.rg110_companion_slug} matches on -- unlike every other + [admit_cases] candidate above, which is deliberately built with a + SYNTHETIC slug {!PE.band}'s 28 branches (and this file's own RG 110 + lookup) cannot recognise, these three rows need [PE.admit] to recognise + the slug itself, so the real ones are used directly. [~status: + Cel.Commemoration_only] on the companions matches the real data shape + (data/ef/sanctoral.sexp's own [peter]/[paul]; + data/ef/adjustments.sexp's own [commemoration-of-st-peter]) even though + [admit] itself never reads [status] -- only [Precedence.resolve]'s own + partition does, upstream of [admit] -- kept for a reader's sake, not a + test requirement. *) +let chair_of_st_peter_synth = cand ~rank:V.Class2 "chair-of-st-peter" +let paul_companion_synth = cand ~rank:V.Class3 ~status:Cel.Commemoration_only "paul" + +(* Any real Lent/Ember feria's own shape (a Class3, PRIVILEGED, temporal- + origin candidate) -- {!PE.rg110_companion_slug} does not match this slug, + so it is a neutral bystander in [admit]'s own normal (pre-RG110) contest, + exactly like [privileged_lo] elsewhere in this table, just kept + separately named so this block's own rows are self-contained and do not + depend on a binding declared for an unrelated purpose above. Given the + WORSE (higher) precedence int than [paul_companion_synth] would need to + win the day's one "other II class" slot on its own dignity ALONE -- the + whole point of the row below is that RG 110 does not care who wins that + contest; it adds Paul regardless. *) +let lent_feria_synth = (cand ~origin:P.Temporal ~rank:V.Class3 "ef-lent-2-monday-synth", P.Privileged, 180) + let admit_cases = [ (* RG 111 (§4): "I class: none save one privileged." *) ( "I-class day, only an ordinary commemoration due -> none admitted", @@ -1109,7 +1136,46 @@ let admit_cases = admitted", lord_winner, lord_winner, [ po sixtus P.Ordinary ], - [ "pope-sixtus-ii-felicissimus-and-agapitus-martyrs" ] ) + [ "pope-sixtus-ii-felicissimus-and-agapitus-martyrs" ] ); + (* RG 110, shape (a)/(b): [chair-of-st-peter] observed, a competing + PRIVILEGED Lent feria also due for the day's single "other II class" + slot (RG 111(c) itself has no privilege-override clause -- unlike the + Sunday branch above -- so pure precedence order decides that slot on + its own, and [lent_feria_synth]'s own 180 beats + [paul_companion_synth]'s 999). Without RG 110, this is exactly + precedence_ef.ml's own measured defect (3,533 of 8,417 domain-wide + years, this task's own report): Paul loses the slot outright and is + never admitted at all. With RG 110, Paul is added ADDITIONALLY, + PREPENDED ahead of the feria per RG 110(c)'s own "ante omnes alias + commemorationes" -- both admitted, not one displacing the other. *) + ( "RG110 (a)/(b): chair-of-st-peter observed, Paul rides alongside a \ + competing privileged Lent feria, uncapped and prepended", + chair_of_st_peter_synth, chair_of_st_peter_synth, + [ (paul_companion_synth, P.Ordinary, 999); lent_feria_synth ], + [ "paul"; "ef-lent-2-monday-synth" ] ); + (* RG 110, shape (c): [chair-of-st-peter] itself LOSES the day outright + (observed is some unrelated II-class Sunday) but is admitted, on its + OWN Class2 dignity, as RG 111(b)'s single ordinary commemoration -- + exactly the domain-wide 593-year pattern this task's own report + measures. RG 110(c)'s own text ("quoties vero oratio unius Apostoli + addenda est ad modum commemorationis...") governs precisely this: the + companion (Paul, Class3, no standing of its OWN for this Sunday's + rank-floored slot) rides along anyway, uncapped. *) + ( "RG110 (c): chair-of-st-peter admitted merely AS a commemoration \ + (loses the day to an ordinary II-class Sunday), Paul still rides \ + along", + cand ~rank:V.Class2 "ef-some-other-sunday", cand ~rank:V.Class2 "ef-some-other-sunday", + [ po chair_of_st_peter_synth P.Ordinary; (paul_companion_synth, P.Ordinary, 999) ], + [ "paul"; "chair-of-st-peter" ] ); + (* Defensive: a trigger slug is [observed], but its companion is simply + not present among [comms] at all (a data gap, or -- as this exact + shape was for 30 June before this task's own [Add + commemoration-of-st-peter] directive -- an upstream omission). + {!PE.rg110_find_companion} must return [None] gracefully, not raise; + the day's own (empty, here) normal result is unaffected. *) + ( "RG110 defensive: chair-of-st-peter observed, no companion present in \ + comms at all -> no crash, nothing added", + chair_of_st_peter_synth, chair_of_st_peter_synth, [], [] ) ] (* Order independence (brief: "the admitted set must not depend on input |
