Skip to content

Commit 930000b

Browse files
proof(Slice 3+4 Route A): (c) trichotomy + consumer-side first-eq derivation (#166)
## Summary Follow-on to PR #165's (b) primitive. Adds the **(c) trichotomy** data type and the **consumer-side first-eq derivation** tools the (a)+(b)+(c) assembly plan calls for, plus a named theorem fully closing the bpsi-source-at-equal-head sub-case at the rank-lex-jb level GIVEN only a tail-rank-equality discharge. Zero postulates, \`--safe --without-K\`, no funext. ## What lands ### Consumer-side first-eq derivation (2 primitives) The DEFINITIONAL fact underlying the closure: \`rank-pow (bplus x y) = rank-pow x ⊕ rank-pow y\` (\`RankPow.rank-pow-bplus\`, \`refl\`). So first-eq REDUCES to a conjunction of summand-equalities via \`cong₂ _⊕_\`. | Name | Role | |---|---| | \`rank-pow-bplus-eq-from-summands\` | Generic \`cong₂ _⊕_\` helper | | \`first-eq-from-bpsi-source-at-equal-head\` | Specialised: bpsi-source at equal head (left-rank-eq is \`refl\`); reduces consumer-side first-eq to **tail-rank-equality only** | ### (c) Trichotomy data type + dispatchers (5 primitives) Brouwer ordinals are NOT decidably ordered in general (\`Ord\` carries \`olim f\` over arbitrary ℕ → Ord functions), so a universal trichotomy on \`rank-pow (bplus _ _)\` is unattainable under \`--safe --without-K\` without postulates. The TRACTABLE narrowing is a STRUCTURAL trichotomy data type that records the strict / equal cases the consumer can derive. | Name | Role | |---|---| | \`BplusFirstTri x₁ x₂ y₁ y₂\` | Data type with two constructors: \`bplus-tri-strict\` (rank-strict) and \`bplus-tri-equal\` (rank-equal) | | \`bplus-tri-from-strict\` / \`bplus-tri-from-equal\` | Wrapper constructors lifting consumer-derived witnesses into the trichotomy | | \`dispatch-trichotomy-to-<lex\` | Assembly headline: consumes a trichotomy + leftmost-α strict witness, produces \`<lex\` at rank-lex-jb level. Strict → \`<lex-first\` via (b) primitive (#165); equal → \`<lex-second\` via (a) primitive (#147). | ### Named theorem: bpsi-source-at-equal-head fully discharged (1) | Name | Type | |---|---| | \`rank-lex-jb-bpsi-equal-head-from-tail-eq\` | \`rank-pow x₂ ≡ rank-pow y₂ → α <ᵇ⁰ β → rank-lex-jb (bplus (bpsi ν α) x₂) <lex rank-lex-jb (bplus (bpsi ν β) y₂)\` | The tail-rank-equality gate is **THE SAME structural obligation** that the ψ-rank-level closure (\`RankLexSlice3.rank-adm-bpsi-strict-at-equality\`) carries. Resolving that one structural blocker unblocks BOTH the ψ-rank-level and the bplus-chain-level closures mechanically. ## Honest scope - The Brouwer-arithmetic blocker (strict-left-mono of \`_⊕_\` + additive-principal closure on generic sums, both CHECKED-REFUTED in PR #146) means **strict-first via strict-left-rank** is structurally unreachable at the bplus-chain level. Strict-first via strict-head-Ω already lands in PR #141 / \`<ᵇ¹-+1-+\`. - Equal-first beyond the bpsi-source-at-equal-head case is open multi-PR research; the trichotomy data type leaves room for future dispatchers without committing to any specific closure path. - \`dispatch-trichotomy-to-<lex\` shows the assembly composes mechanically — the structural ordinal-arithmetic obligation is the SOLE remaining gating, and it's pushed to the precise consumer call site rather than scattered across the proof. ## (a)+(b)+(c) assembly status after this PR Per PR #147's preamble plan: | Leg | Status | |---|---| | (a) equal-first lex-second | CLOSED in #147 | | (b) strict-first lex-first primitive | CLOSED in #165 (one-liner via \`<lex-first\`) | | (c) first-component trichotomy | CLOSED HERE as a structural data type + dispatchers | | Consumer-side first-eq derivation | CLOSED HERE for the bpsi-source-at-equal-head case (parameterised on tail-rank-eq) | | Full assembly headline | \`rank-lex-jb-bpsi-equal-head-from-tail-eq\` named theorem closes the bpsi sub-case given **only** tail-rank-eq | The bplus-chain-level rank-mono umbrella over **all** 13 \`_<ᵇ_\` constructors is still gated on (i) tail-rank-equality discharge (structural ordinal-arithmetic work) AND (ii) the equal-first dispatch beyond the bpsi-source case (open research). Per the SLICE 4 narrowing (\`RankMonoUmbrellaSlice4\`), the \`<ᵇ⁻ⁿ-shortfall-equal-head\` matched-negative remains. ## Local verification - \`agda -i proofs/agda proofs/agda/Ordinal/Buchholz/RankLexJointBplus.agda\` — clean. - \`agda -i proofs/agda proofs/agda/Ordinal/Buchholz/Smoke.agda\` — clean, exit 0. - \`agda -i proofs/agda proofs/agda/Smoke.agda\` — clean, exit 0. - \`agda -i proofs/agda proofs/agda/All.agda\` — clean, exit 0. - \`bash tools/check-guardrails.sh proofs/agda\` — 160 modules pass. - \`sh scripts/kernel-guard.sh\` — PASS. All eleven new names pinned in \`Ordinal/Buchholz/Smoke.agda\`. ## Test plan - [x] All Agda lanes typecheck locally. - [x] New names pinned in Buchholz Smoke. - [x] Foundation guardrail + kernel-guard pass. - [ ] 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 f21c62f commit 930000b

2 files changed

Lines changed: 177 additions & 2 deletions

File tree

proofs/agda/Ordinal/Buchholz/RankLexJointBplus.agda

Lines changed: 168 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@
114114

115115
module Ordinal.Buchholz.RankLexJointBplus where
116116

117-
open import Relation.Binary.PropositionalEquality using (_≡_; refl; subst)
117+
open import Relation.Binary.PropositionalEquality using (_≡_; refl; subst; cong; cong₂)
118118

119119
open import Ordinal.Brouwer using (Ord; oz)
120120
open import Ordinal.Brouwer.Phase13 using (_<′_)
@@ -125,7 +125,8 @@ open import Ordinal.Buchholz.Syntax using
125125
; bplus
126126
; bpsi
127127
)
128-
open import Ordinal.Buchholz.RankPow using (rank-pow)
128+
open import Ordinal.Brouwer.Arithmetic using (_⊕_)
129+
open import Ordinal.Buchholz.RankPow using (rank-pow; rank-pow-bplus; ω-rank-pow)
129130
open import Ordinal.Buchholz.RankLex using
130131
( RankLex
131132
; mkLex
@@ -372,3 +373,168 @@ rank-lex-jb-bpsi-at-equality {ν} {α} {β} {x₂} {y₂} first-eq α<β =
372373
{x₁ = bpsi ν α} {x₂ = x₂} {y₁ = bpsi ν β} {y₂ = y₂}
373374
first-eq
374375
(leftmost-α-strict-from-bpsi-source {ν = ν} {α = α} {β = β} {x₂ = x₂} {y₂ = y₂} α<β)
376+
377+
----------------------------------------------------------------------
378+
-- Consumer-side first-eq derivation
379+
----------------------------------------------------------------------
380+
381+
-- The HARD half of the (a) primitive's consumer plumbing: deriving
382+
-- the `first-eq : rank-pow (bplus x₁ x₂) ≡ rank-pow (bplus y₁ y₂)`
383+
-- hypothesis at the bplus-chain rank-pow level.
384+
--
385+
-- The DEFINITIONAL fact underlying the closure: `rank-pow (bplus
386+
-- x y) = rank-pow x ⊕ rank-pow y` (`RankPow.rank-pow-bplus`,
387+
-- definitional `refl`). So first-eq REDUCES to a conjunction of
388+
-- summand-level equalities via `cong₂ _⊕_`:
389+
--
390+
-- rank-pow x₁ ≡ rank-pow y₁ ∧ rank-pow x₂ ≡ rank-pow y₂
391+
-- ⇒ rank-pow (bplus x₁ x₂) ≡ rank-pow (bplus y₁ y₂)
392+
--
393+
-- The bpsi-source-at-equal-head sub-case has `x₁ = bpsi ν α` and
394+
-- `y₁ = bpsi ν β` (same ν). At the rank-pow level both reduce
395+
-- DEFINITIONALLY to `ω-rank-pow ν`, so the left summand's equality
396+
-- is `refl` and the consumer's residual obligation collapses to
397+
-- `rank-pow x₂ ≡ rank-pow y₂` on the right summand. Under WfCNF
398+
-- this is the same `rank-pow x₂ ≡ rank-pow y₂` discharge that
399+
-- already gates the lex-rank-level discharge of the same sub-case
400+
-- via `RankLexSlice3.rank-adm-bpsi-strict-at-equality`; the rank-
401+
-- pow-level closure has the same shape modulo the consumer-side
402+
-- ordinal-arithmetic gating, which means the bpsi sub-case at the
403+
-- bplus-chain level FOLLOWS the same closure ladder as the ψ-rank
404+
-- level once that ladder closes.
405+
406+
-- Generic summand-equalities composer: bplus-first-eq from summand-
407+
-- first-eqs.
408+
rank-pow-bplus-eq-from-summands :
409+
{x₁ x₂ y₁ y₂}
410+
rank-pow x₁ ≡ rank-pow y₁
411+
rank-pow x₂ ≡ rank-pow y₂
412+
rank-pow (bplus x₁ x₂) ≡ rank-pow (bplus y₁ y₂)
413+
rank-pow-bplus-eq-from-summands eq1 eq2 = cong₂ _⊕_ eq1 eq2
414+
415+
-- Specialised first-eq derivation for the bpsi-source-at-equal-head
416+
-- sub-case: left summands are `bpsi ν α` and `bpsi ν β` (same ν, ANY
417+
-- α and β); left-rank equality is definitional (`refl` since both
418+
-- evaluate to `ω-rank-pow ν`). Reduces consumer-side first-eq to
419+
-- the tail-rank-equality `rank-pow x₂ ≡ rank-pow y₂`.
420+
first-eq-from-bpsi-source-at-equal-head :
421+
{ν α β x₂ y₂}
422+
rank-pow x₂ ≡ rank-pow y₂
423+
rank-pow (bplus (bpsi ν α) x₂) ≡ rank-pow (bplus (bpsi ν β) y₂)
424+
first-eq-from-bpsi-source-at-equal-head {ν} {α} {β} {x₂} {y₂} tail-eq =
425+
rank-pow-bplus-eq-from-summands {x₁ = bpsi ν α} {x₂ = x₂}
426+
{y₁ = bpsi ν β} {y₂ = y₂}
427+
refl tail-eq
428+
429+
----------------------------------------------------------------------
430+
-- (c) Trichotomy data type for the bplus-chain first-component
431+
----------------------------------------------------------------------
432+
433+
-- Brouwer ordinals are NOT decidably ordered in general (`Ord`
434+
-- includes `olim f` carrying arbitrary functions ℕ → Ord), so a
435+
-- universal trichotomy on `rank-pow (bplus _ _)` values is
436+
-- unattainable under `--safe --without-K` without postulates.
437+
-- The TRACTABLE narrowing is a STRUCTURAL trichotomy: a data type
438+
-- that records which of the strict / equal cases applies WHEN the
439+
-- consumer has discharged the corresponding rank-arithmetic
440+
-- obligation. Dispatchers below populate the strict / equal
441+
-- constructors from rank-evidence the consumer derives via the
442+
-- closed `<ᵇ⁰` / `<ᵇ¹` / `<ᵇ⁻ⁿ` umbrellas or the bpsi-source
443+
-- definitional collapse.
444+
445+
data BplusFirstTri (x₁ x₂ y₁ y₂ : BT) : Set where
446+
bplus-tri-strict :
447+
rank-pow (bplus x₁ x₂) <′ rank-pow (bplus y₁ y₂)
448+
BplusFirstTri x₁ x₂ y₁ y₂
449+
bplus-tri-equal :
450+
rank-pow (bplus x₁ x₂) ≡ rank-pow (bplus y₁ y₂)
451+
BplusFirstTri x₁ x₂ y₁ y₂
452+
453+
-- Strict dispatcher: any consumer-derived strict witness on the
454+
-- bplus-chain rank-pow lifts into `bplus-tri-strict`. The closed
455+
-- `<ᵇ⁰` umbrella's `rank-pow-mono-<ᵇ⁰` and the `<ᵇ¹` umbrella's
456+
-- `rank-pow-mono-<ᵇ¹` (which dispatches the strict-head-Ω joint-
457+
-- bplus case `<ᵇ¹-+1-+`) are the canonical producers of this
458+
-- witness; see also `RankMonoUmbrellaSlice4.rank-pow-mono-<ᵇ⁻ⁿ`
459+
-- for the WfCNF-bundled form.
460+
461+
bplus-tri-from-strict :
462+
{x₁ x₂ y₁ y₂}
463+
rank-pow (bplus x₁ x₂) <′ rank-pow (bplus y₁ y₂)
464+
BplusFirstTri x₁ x₂ y₁ y₂
465+
bplus-tri-from-strict strict = bplus-tri-strict strict
466+
467+
-- Equal dispatcher: any consumer-derived first-eq lifts into
468+
-- `bplus-tri-equal`. The bpsi-source-at-equal-head derivation
469+
-- `first-eq-from-bpsi-source-at-equal-head` is the canonical
470+
-- producer of this witness; the rank-equal closure under more
471+
-- general bplus shapes is the multi-PR ordinal-arithmetic
472+
-- challenge documented in this module's preamble.
473+
474+
bplus-tri-from-equal :
475+
{x₁ x₂ y₁ y₂}
476+
rank-pow (bplus x₁ x₂) ≡ rank-pow (bplus y₁ y₂)
477+
BplusFirstTri x₁ x₂ y₁ y₂
478+
bplus-tri-from-equal eq = bplus-tri-equal eq
479+
480+
-- Trichotomy → rank-lex-jb dispatcher: the assembly that consumes
481+
-- whichever case the trichotomy yields and discharges to a `<lex`
482+
-- judgment at rank-lex-jb level. The strict case fires `<lex-first`
483+
-- via `rank-lex-jb-strict-first`; the equal case fires `<lex-second`
484+
-- via `rank-lex-jb-strict-second-at-equal-first` provided the
485+
-- consumer can supply the leftmost-α strict witness.
486+
--
487+
-- This is the (a)+(b)+(c) assembly's RECIPE at the rank-lex-jb
488+
-- level: every reachable case dispatches mechanically given the
489+
-- consumer-side strict-or-equal-first witness. The remaining
490+
-- gating obligation across the whole assembly is the
491+
-- consumer-side derivation of the leftmost-α strict witness in
492+
-- the equal case (when the consumer cannot supply it, the equal
493+
-- case is structurally dischargeable only if the rank-lex-jb is
494+
-- LITERALLY EQUAL on both sides — which by `<lex` irreflexivity
495+
-- contradicts a source-level strict inequality).
496+
497+
dispatch-trichotomy-to-<lex :
498+
{x₁ x₂ y₁ y₂}
499+
BplusFirstTri x₁ x₂ y₁ y₂
500+
leftmost-α (bplus x₁ x₂) <′ leftmost-α (bplus y₁ y₂)
501+
rank-lex-jb (bplus x₁ x₂) <lex rank-lex-jb (bplus y₁ y₂)
502+
dispatch-trichotomy-to-<lex {x₁} {x₂} {y₁} {y₂} (bplus-tri-strict strict) _ =
503+
rank-lex-jb-strict-first {x₁ = x₁} {x₂ = x₂} {y₁ = y₁} {y₂ = y₂} strict
504+
dispatch-trichotomy-to-<lex {x₁} {x₂} {y₁} {y₂} (bplus-tri-equal eq) l-strict =
505+
rank-lex-jb-strict-second-at-equal-first {x₁ = x₁} {x₂ = x₂} {y₁ = y₁} {y₂ = y₂} eq l-strict
506+
507+
----------------------------------------------------------------------
508+
-- Named theorem: bpsi-source-at-equal-head fully closed at rank-lex-jb
509+
----------------------------------------------------------------------
510+
511+
-- The composition of the trichotomy with the bpsi-source first-eq
512+
-- derivation and the leftmost-α strict witness from PR #147's (a)
513+
-- machinery. Inputs:
514+
--
515+
-- * `tail-eq : rank-pow x₂ ≡ rank-pow y₂` — the consumer's
516+
-- RESIDUAL rank-arithmetic obligation; gating depends on the
517+
-- source-level relationship between x₂ and y₂ under WfCNF.
518+
-- * `α <ᵇ⁰ β` — the source-side
519+
-- strict inequality on the ψ-arguments, supplied by the
520+
-- consumer via the 10-constructor `_<ᵇ⁰_` umbrella.
521+
--
522+
-- Output: `<lex` discharge at rank-lex-jb level for the bpsi-source
523+
-- bplus chain. This closes the bpsi-source-at-equal-head sub-case
524+
-- at the bplus-chain rank-lex-jb level GIVEN the consumer's
525+
-- tail-rank-equality discharge — which is the SAME gating
526+
-- obligation that the ψ-rank-level closure (`rank-adm-bpsi-strict-
527+
-- at-equality`) carries. Resolving the structural blocker on
528+
-- tail-rank-equality unblocks BOTH levels mechanically.
529+
530+
rank-lex-jb-bpsi-equal-head-from-tail-eq :
531+
{ν α β x₂ y₂}
532+
rank-pow x₂ ≡ rank-pow y₂
533+
α <ᵇ⁰ β
534+
rank-lex-jb (bplus (bpsi ν α) x₂) <lex rank-lex-jb (bplus (bpsi ν β) y₂)
535+
rank-lex-jb-bpsi-equal-head-from-tail-eq {ν} {α} {β} {x₂} {y₂} tail-eq α<β =
536+
rank-lex-jb-bpsi-at-equality
537+
= ν} {α = α} {β = β} {x₂ = x₂} {y₂ = y₂}
538+
(first-eq-from-bpsi-source-at-equal-head
539+
= ν} {α = α} {β = β} {x₂ = x₂} {y₂ = y₂} tail-eq)
540+
α<β

proofs/agda/Ordinal/Buchholz/Smoke.agda

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,15 @@ open import Ordinal.Buchholz.RankLexJointBplus using
539539
; rank-lex-jb-strict-first
540540
; leftmost-α-strict-from-bpsi-source
541541
; rank-lex-jb-bpsi-at-equality
542+
; rank-pow-bplus-eq-from-summands
543+
; first-eq-from-bpsi-source-at-equal-head
544+
; BplusFirstTri
545+
; bplus-tri-strict
546+
; bplus-tri-equal
547+
; bplus-tri-from-strict
548+
; bplus-tri-from-equal
549+
; dispatch-trichotomy-to-<lex
550+
; rank-lex-jb-bpsi-equal-head-from-tail-eq
542551
)
543552

544553
-- Slice 4 narrowing 2026-05-28 (own block per CLAUDE.md Working

0 commit comments

Comments
 (0)