Skip to content

Commit 2b59685

Browse files
hyperpolymathclaude
andcommitted
proof(Slice 3+4 Route A): (c) trichotomy + consumer-side first-eq derivation
Follow-on to PR #165's (b) primitive. Adds the (c) trichotomy data type and the consumer-side first-eq derivation tools that 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. ## Two consumer-side first-eq derivation tools 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-level equalities via `cong₂ _⊕_`. 1. `rank-pow-bplus-eq-from-summands` — generic `cong₂ _⊕_` helper: from two summand-equalities derive bplus-eq. 2. `first-eq-from-bpsi-source-at-equal-head` — specialised for bpsi-source-at-equal-head: left summands are `bpsi ν α` and `bpsi ν β` (same ν, ANY α and β), so left-rank equality is DEFINITIONAL (`refl`). Reduces consumer-side first-eq to the tail-rank-equality `rank-pow x₂ ≡ rank-pow y₂`. ## (c) Trichotomy data type + dispatchers 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: * `BplusFirstTri x₁ x₂ y₁ y₂` — two constructors: - `bplus-tri-strict : rank-pow (bplus x₁ x₂) <′ rank-pow (bplus y₁ y₂)` - `bplus-tri-equal : rank-pow (bplus x₁ x₂) ≡ rank-pow (bplus y₁ y₂)` * `bplus-tri-from-strict` / `bplus-tri-from-equal` — wrapper constructors that lift consumer-derived witnesses into the trichotomy. * `dispatch-trichotomy-to-<lex` — the assembly headline: consumes a trichotomy + a leftmost-α strict witness and produces a `<lex` judgment at rank-lex-jb level. Strict case → `<lex-first` via `rank-lex-jb-strict-first` (PR #165); equal case → `<lex-second` via `rank-lex-jb-strict-second-at-equal-first` (PR #147). This IS the (a)+(b)+(c) assembly's RECIPE at the rank-lex-jb level: every reachable case dispatches mechanically given the consumer-side strict-or-equal-first witness. The residual gating across the assembly is the consumer-side derivation of the leftmost-α strict witness in the equal case AND tail-rank- equality discharge. ## Named theorem: bpsi-source-at-equal-head fully discharged `rank-lex-jb-bpsi-equal-head-from-tail-eq` composes the two consumer-side derivations into a closure: Inputs: * `rank-pow x₂ ≡ rank-pow y₂` (tail-rank-eq, consumer gate) * `α <ᵇ⁰ β` (source-side strict ψ-arg, 10-constructor umbrella) Output: 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 (preserved in module) - 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 the 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. ## 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` under the existing `RankLexJointBplus` `using` block. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f21c62f commit 2b59685

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)