Skip to content

Commit 8eb08de

Browse files
proof(architecture): RankMonoUnion umbrella over source-rule extensions (#168)
## Summary Realises the **architectural recommendation** from PR #167's closing note: the future bplus-chain rank-mono umbrella shipped as a UNION OF SOURCE-RULE EXTENSIONS rather than a single enriched rank function. **Zero new proof obligations**; purely structural composition via Sum + \`[_,_]\` mediator. \`--safe --without-K\`, no postulates, no funext. ## What the union umbrella ships | Name | Type | Role | |---|---|---| | \`_<ᵇᵘ_\` | \`BT → BT → Set\` | Disjoint sum of \`_<ᵇ¹_\` (Slice 3) and \`_<ᵇ⁺²_\` (Path-3) | | \`rank-pow-mono-<ᵇᵘ\` | \`∀ {x y} → x <ᵇᵘ y → rank-pow x <′ rank-pow y\` | Coproduct mediator via \`[_,_]\` — **ONE LINE** | | \`<ᵇᵘ-from-<ᵇ¹\` / \`<ᵇᵘ-from-<ᵇ⁺²\` / \`<ᵇᵘ-from-<ᵇ⁰\` (+symmetric) | embeddings | Convenience injections | ## The architectural design PR #167's closing observation: > The future bplus-chain rank-mono umbrella may want to be designed as a UNION OF SOURCE-RULE EXTENSIONS (Path-3 style for cleanly-decomposable cases) rather than a single enriched rank function (rank-lex-jb style for cross-head cases). This PR mechanises that recommendation. Each contributing extension keeps its own proof obligation local; the union dispatches via case analysis on which extension witnesses the relation. The mediator is \`[ rank-pow-mono-<ᵇ¹ , rank-pow-mono-<ᵇ⁺² ]\` — a single \`[_,_]\` over the existing per-extension umbrellas. ## Why this architectural shape (three observations) 1. **Different sub-cases prefer different rank-mono machinery.** Strict-head joint-bplus closes via head-Ω + \`ω-rank-pow-succ\`; same-left closes via \`rank-pow-bplus-right-mono\`; cross-head rank-equal closes at LEX-RANK via rank-lex-jb. No single rank function dominates. 2. **Source-rule enrichment is structurally simpler than rank-function enrichment** (Path-3 verdict, PR #167). The consumer-side first-eq derivation that rank-lex-jb requires (PR #166 (c) trichotomy + first-eq) gets bypassed entirely when the source rule carries the discriminator. 3. **Union of extensions scales.** Every new sub-case ships as its own extension module with its own rank-mono theorem, then unions in mechanically. No interference between extensions; closure is local. ## Extension recipe (for future contributors) Documented in the module preamble. To add a new source-rule extension: 1. Define the relation + rank-pow-mono in its own module (use \`RankMonoSameLeft\` as canonical template). 2. Re-export through \`Ordinal/Buchholz/Smoke.agda\` with its own \`using\` block. 3. Update this module to extend \`_<ᵇᵘ_\` with the new disjunct and extend \`rank-pow-mono-<ᵇᵘ\` with the new case via \`[_,_]\`. Both edits mechanical; no new proof obligations. ## Honest scope (preserved in module preamble) - Does NOT wrap with WfCNF endpoints (à la \`RankMonoUmbrellaSlice4._<ᵇ⁻ⁿ_\`). - Does NOT include rank-lex-jb discharge — cross-head rank-equal case lives at LEX-RANK level, different rank-relation. Union is over \`rank-pow <′\` discharges only. - Does NOT prove well-foundedness of the union — orthogonal to rank-mono. ## Slice 3+4 Route A arc summary (4 PRs total) After this PR the session arc is closed: | PR | Role | |---|---| | #165 | (b) \`<lex-first\` primitive + bpsi sub-case discharge | | #166 | (c) trichotomy data type + first-eq derivation | | #167 | Path-3 prototype (same-left source-rule extension) | | **THIS PR** | **RankMonoUnion** (architectural realisation) | The full bplus-chain rank-mono umbrella over all 13 \`_<ᵇ_\` constructors is still gated on (i) tail-rank-equality discharge for the bpsi-source-at-equal-head case AND (ii) the cross-head rank-equal case via rank-lex-jb's structural research; **neither is closed by this PR**. The architecture is now in place for those closures to plug in mechanically. ## Local verification - All four Agda lanes typecheck clean, exit 0. - \`bash tools/check-guardrails.sh proofs/agda\` — **162 modules** pass. - \`sh scripts/kernel-guard.sh\` — PASS. Six new names pinned in \`Ordinal/Buchholz/Smoke.agda\`. ## Test plan - [x] All Agda lanes typecheck under \`--safe --without-K\` with zero postulates. - [x] Foundation guardrail + kernel-guard pass with 162 modules. - [ ] CI: \`check\` + \`cold-check\` + governance lanes green. - [ ] Auto-merge on green. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 390cebb commit 8eb08de

3 files changed

Lines changed: 180 additions & 0 deletions

File tree

proofs/agda/All.agda

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ open import Ordinal.Buchholz.RankMonoUmbrella
150150
open import Ordinal.Buchholz.RankMonoUmbrellaSlice3
151151
open import Ordinal.Buchholz.RankMonoUmbrellaSlice4
152152
open import Ordinal.Buchholz.RankMonoSameLeft
153+
open import Ordinal.Buchholz.RankMonoUnion
153154
open import Ordinal.Buchholz.RecursiveSurfaceOrder
154155
open import Ordinal.Buchholz.RecursiveSurfaceBudget
155156
open import Ordinal.Buchholz.SurfaceOrder
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
{-# OPTIONS --safe --without-K #-}
2+
-- SPDX-License-Identifier: MPL-2.0
3+
-- SPDX-FileCopyrightText: 2025-2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
4+
5+
-- Union umbrella over source-rule rank-mono extensions (2026-05-30).
6+
--
7+
-- ## The architectural recommendation realised
8+
--
9+
-- PR #167's closing observation: "the future bplus-chain rank-mono
10+
-- umbrella may want to be designed as a UNION OF SOURCE-RULE
11+
-- EXTENSIONS (Path-3 style for cleanly-decomposable cases) rather
12+
-- than a single enriched rank function (rank-lex-jb style for
13+
-- cross-head cases)".
14+
--
15+
-- This module mechanises that pattern. The UNION RELATION
16+
-- `_<ᵇᵘ_` combines:
17+
--
18+
-- 1. `_<ᵇ¹_` (Slice 3 extension, `RankMonoUmbrellaSlice3`) — 10
19+
-- inherited K-free cases via `<ᵇ¹-from-<ᵇ⁰` + the strict-head
20+
-- joint-bplus case `<ᵇ¹-+1-+` (`PR #142`).
21+
-- 2. `_<ᵇ⁺²_` (Path-3 extension, `RankMonoSameLeft`) — 10
22+
-- inherited K-free cases via `<ᵇ⁺²-from-<ᵇ⁰` + the same-left
23+
-- joint-bplus case `<ᵇ⁺²-same-left` (PR #167).
24+
--
25+
-- The union is the SUM of the two relations. Rank-pow monotonicity
26+
-- on the union dispatches by case-analysis: either the relation is
27+
-- witnessed by the `<ᵇ¹` umbrella (which `rank-pow-mono-<ᵇ¹`
28+
-- discharges) or by the `<ᵇ⁺²` umbrella (which `rank-pow-mono-<ᵇ⁺²`
29+
-- discharges). Zero new proof obligations: the union is purely
30+
-- structural.
31+
--
32+
-- ## Why this architectural shape
33+
--
34+
-- Three observations from the Slice 3+4 Route A session arc:
35+
--
36+
-- 1. Different sub-cases of `<ᵇ-+1`-style joint-bplus close at
37+
-- DIFFERENT rank-relation levels. The strict-head case
38+
-- (`<ᵇ¹-+1-+`) closes via head-Ω inversion + `ω-rank-pow-succ`.
39+
-- The same-left case (`<ᵇ⁺²-same-left`) closes via
40+
-- `rank-pow-bplus-right-mono` on the tail. The cross-head
41+
-- rank-equal case (`bpsi ν α` vs `bOmega ν`) closes at the
42+
-- LEX-RANK level via `rank-lex-jb`. Each sub-case prefers a
43+
-- DIFFERENT rank-mono machinery.
44+
--
45+
-- 2. A SINGLE enriched rank function (rank-lex-jb) tries to handle
46+
-- multiple sub-cases via a uniform second-component
47+
-- discriminator, but the consumer-side first-eq derivation is
48+
-- structurally simpler when the source rule itself carries the
49+
-- enrichment (Path-3 verdict, PR #167).
50+
--
51+
-- 3. UNION OF EXTENSIONS scales: every new sub-case added to the
52+
-- bplus-chain rank-mono programme can ship as a new extension
53+
-- `_<ᵇⁿ_` with its own `rank-pow-mono-<ᵇⁿ`, then be unioned
54+
-- in mechanically via Sum + `[_,_]`. No interference between
55+
-- extensions; the closure is local to each extension's
56+
-- structural recursion.
57+
--
58+
-- ## What this module does NOT do
59+
--
60+
-- * Does NOT wrap with WfCNF endpoints (à la
61+
-- `RankMonoUmbrellaSlice4._<ᵇ⁻ⁿ_`). Consumers needing WfCNF
62+
-- compose with the predicates separately, or extend this union
63+
-- with a WfCNF-bundled variant.
64+
-- * Does NOT include `rank-lex-jb` discharge — the cross-head
65+
-- rank-equal case discharges at LEX-RANK level, not at rank-pow
66+
-- level, so it lives in a different rank-relation. The union
67+
-- here is over `rank-pow <′` discharges only.
68+
-- * Does NOT prove well-foundedness of the union — orthogonal to
69+
-- rank-mono; would need a single Brouwer-rank embedding.
70+
-- `rank-pow` provides the seed.
71+
--
72+
-- ## Extension recipe (for future contributors)
73+
--
74+
-- To add a new source-rule extension `_<ᵇⁿ_` with `rank-pow-mono-<ᵇⁿ`:
75+
--
76+
-- 1. Define the relation + the rank-pow-mono theorem in its own
77+
-- module (use `RankMonoSameLeft` as the canonical template).
78+
-- 2. Re-export the headlines through `Ordinal/Buchholz/Smoke.agda`
79+
-- with their own `using` block.
80+
-- 3. Update this module to extend `_<ᵇᵘ_` with the new disjunct
81+
-- and extend `rank-pow-mono-<ᵇᵘ` with the new case via `[_,_]`.
82+
-- Both edits are mechanical; no new proof obligations.
83+
--
84+
-- The mechanical-ness of the union extension is the architectural
85+
-- payoff: per-extension proof work + structural composition, vs
86+
-- proof obligations multiplying as the rank function gains
87+
-- discriminators.
88+
89+
module Ordinal.Buchholz.RankMonoUnion where
90+
91+
open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_])
92+
93+
open import Ordinal.Brouwer.Phase13 using (_<′_)
94+
open import Ordinal.Buchholz.Syntax using (BT)
95+
open import Ordinal.Buchholz.RankPow using (rank-pow)
96+
open import Ordinal.Buchholz.RankMonoUmbrella using (_<ᵇ⁰_)
97+
open import Ordinal.Buchholz.RankMonoUmbrellaSlice3 using
98+
( _<ᵇ¹_
99+
; <ᵇ¹-from-<ᵇ⁰
100+
; rank-pow-mono-<ᵇ¹
101+
)
102+
open import Ordinal.Buchholz.RankMonoSameLeft using
103+
( _<ᵇ⁺²_
104+
; <ᵇ⁺²-from-<ᵇ⁰
105+
; rank-pow-mono-<ᵇ⁺²
106+
)
107+
108+
----------------------------------------------------------------------
109+
-- The union relation `_<ᵇᵘ_`
110+
----------------------------------------------------------------------
111+
112+
-- Disjoint sum of `_<ᵇ¹_` and `_<ᵇ⁺²_`. Either extension's witness
113+
-- is accepted; rank-pow-mono dispatches accordingly.
114+
115+
_<ᵇᵘ_ : BT BT Set
116+
x <ᵇᵘ y = (x <ᵇ¹ y) ⊎ (x <ᵇ⁺² y)
117+
118+
infix 4 _<ᵇᵘ_
119+
120+
----------------------------------------------------------------------
121+
-- Rank-pow monotonicity by case analysis
122+
----------------------------------------------------------------------
123+
124+
-- The union's rank-mono is the COPRODUCT MEDIATOR of the two
125+
-- per-extension umbrellas. Each disjunct's discharge is the
126+
-- existing rank-mono theorem for that extension — no new proof
127+
-- obligation. The mediator `[_,_]` is purely structural.
128+
129+
rank-pow-mono-<ᵇᵘ : {x y} x <ᵇᵘ y rank-pow x <′ rank-pow y
130+
rank-pow-mono-<ᵇᵘ = [ rank-pow-mono-<ᵇ¹ , rank-pow-mono-<ᵇ⁺² ]
131+
132+
----------------------------------------------------------------------
133+
-- Convenience embeddings
134+
----------------------------------------------------------------------
135+
136+
-- Direct embeddings from each contributing relation into the union.
137+
-- These are `inj₁` / `inj₂` specialised, but named for readability
138+
-- at consumer call sites.
139+
140+
<ᵇᵘ-from-<ᵇ¹ : {x y} x <ᵇ¹ y x <ᵇᵘ y
141+
<ᵇᵘ-from-<ᵇ¹ = inj₁
142+
143+
<ᵇᵘ-from-<ᵇ⁺² : {x y} x <ᵇ⁺² y x <ᵇᵘ y
144+
<ᵇᵘ-from-<ᵇ⁺² = inj₂
145+
146+
-- Transitive embedding from the 10-constructor closed umbrella
147+
-- via either path. The choice between `<ᵇ¹` and `<ᵇ⁺²` is
148+
-- definitionally irrelevant for `<ᵇ⁰` derivations (both embed
149+
-- the same witness); we choose `<ᵇ¹` as the canonical path so
150+
-- consumers reasoning about the strict-head joint-bplus case
151+
-- don't need to switch disjuncts mid-proof.
152+
153+
<ᵇᵘ-from-<ᵇ⁰ : {x y} x <ᵇ⁰ y x <ᵇᵘ y
154+
<ᵇᵘ-from-<ᵇ⁰ p = <ᵇᵘ-from-<ᵇ¹ (<ᵇ¹-from-<ᵇ⁰ p)
155+
156+
-- Symmetric alternative: embed via `<ᵇ⁺²` instead. Same content;
157+
-- offered for consumer call sites where the `<ᵇ⁺²` path is
158+
-- already in scope.
159+
160+
<ᵇᵘ-from-<ᵇ⁰-via-<ᵇ⁺² : {x y} x <ᵇ⁰ y x <ᵇᵘ y
161+
<ᵇᵘ-from-<ᵇ⁰-via-<ᵇ⁺² p = <ᵇᵘ-from-<ᵇ⁺² (<ᵇ⁺²-from-<ᵇ⁰ p)

proofs/agda/Ordinal/Buchholz/Smoke.agda

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,3 +585,21 @@ open import Ordinal.Buchholz.RankMonoSameLeft using
585585
; rank-pow-mono-<ᵇ⁺²
586586
; rank-pow-mono-same-left
587587
)
588+
589+
-- Union umbrella 2026-05-30 (own block per CLAUDE.md Working rules):
590+
-- realises the architectural recommendation from PR #167's closing
591+
-- note — bplus-chain rank-mono umbrella as a UNION OF SOURCE-RULE
592+
-- EXTENSIONS rather than a single enriched rank function. Combines
593+
-- `_<ᵇ¹_` (Slice 3 strict-head joint-bplus) with `_<ᵇ⁺²_` (Path-3
594+
-- same-left joint-bplus) via Sum + `[_,_]` mediator. Zero new
595+
-- proof obligations; the union is purely structural over the two
596+
-- per-extension umbrellas. Extension recipe (for new sub-cases)
597+
-- documented in the module preamble.
598+
open import Ordinal.Buchholz.RankMonoUnion using
599+
( _<ᵇᵘ_
600+
; rank-pow-mono-<ᵇᵘ
601+
; <ᵇᵘ-from-<ᵇ¹
602+
; <ᵇᵘ-from-<ᵇ⁺²
603+
; <ᵇᵘ-from-<ᵇ⁰
604+
; <ᵇᵘ-from-<ᵇ⁰-via-<ᵇ⁺²
605+
)

0 commit comments

Comments
 (0)