Skip to content

Commit 0fb7587

Browse files
theory: AntiEchoTropicalGeneric — generic-codomain lift of the tropical decomposition (#91)
## Summary Lifts the concrete ℕ-scored tropical decomposition from `AntiEchoTropical.agda` to an arbitrary ordered codomain. Closes the "generic-codomain version is deferred (would need a \`≤\`-bearing ordered codomain)" remark that has lived in `AntiEchoTropical`'s preamble since #72. ## What lands ### `AntiEchoTropicalGeneric.agda` — new module ```agda record OrderedCodomain : Set₁ where field B : Set _≤_ : B → B → Set _<_ : B → B → Set ≤⇒¬< : ∀ {y n : B} → y ≤ n → n < y → ⊥ ¬<⇒≤ : ∀ {y n : B} → (n < y → ⊥) → y ≤ n ``` The first three fields are pure structure; the latter two are the order conversions. `≤⇒¬<` is always available; `¬<⇒≤` is the entire content of the "decidable order" hypothesis in the concrete ℕ case — factored out as a field rather than baked into the codomain. Three theorems in `module Generic (OC : OrderedCodomain)`: * **`antiecho-tropical-decompose-gen`** — pure Σ-reshape iso between `TropEchoG s y` and `Echo s y × (∀ z → y ≤ s z)`. `refl` round-trips, does NOT use the order at all (structural only). * **`optimality-as-antiecho-flavour-gen-to/from`** — `(∀ z → y ≤ s z)` ↔ `(∀ z → s z < y → ⊥)`. Uses `≤⇒¬<` / `¬<⇒≤` from the interface. * **`tropdecomp-antiecho-gen-to/from`** — composite `TropEchoG ↔ Echo × (Π-of-AntiEcho-flavoured-misses)`. Sanity instance `ℕ-ordered-codomain : OrderedCodomain` pinned in `Smoke.agda` so the interface is demonstrably inhabitable. ### Preamble updates (zero Agda content change) * `AntiEcho.agda` — obligation 6 line updated to point at both the concrete and generic landings * `AntiEchoTropical.agda` — "generic-codomain version is deferred" replaced by pointer to the new module ## Test plan * [x] `agda proofs/agda/AntiEchoTropicalGeneric.agda` exit 0 * [x] `agda proofs/agda/All.agda` exit 0 under `--safe --without-K` * [x] `agda proofs/agda/Smoke.agda` exit 0 under `--safe --without-K` * [x] `OrderedCodomain`, `ℕ-ordered-codomain`, `module Generic` pinned * [x] No postulates, no funext, no escape pragmas ## Scope The concrete `AntiEchoTropical.agda` module is **unchanged** (only its preamble comment updated). The two coexist: concrete remains the canonical landing for ℕ-scored tropical; generic is the abstract sibling for downstream users at other ordered codomains. ## Dependencies Depends on **#90** (antiecho-partition-dec). Branch based on `antiecho-partition-dec`; will rebase onto `main` once #90 lands. Disjoint from #88 (F3). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 56935f4 commit 0fb7587

5 files changed

Lines changed: 252 additions & 10 deletions

File tree

proofs/agda/All.agda

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ open import EchoLinear
1818
open import EchoGraded
1919
open import EchoTropical
2020
open import AntiEchoTropical
21+
open import AntiEchoTropicalGeneric
2122
open import EchoIntegration
2223
open import EchoCNOBridge
2324

proofs/agda/AntiEcho.agda

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,25 @@
1717
-- This thin slice lands obligations 1–4 from `coecho.md` §5 (renamed
1818
-- `antiecho-*`): the carrier, per-element disjointness against Echo,
1919
-- introduction from any witnessed miss, and contravariant `map-over`
20-
-- along the source. The partition-with-decidability lemma and the
21-
-- tropical decomposition (Echo × Π AntiEcho ≃ IsArgmin) are deferred
22-
-- to follow-up slices; see `coecho.md` §5 obligations 5–6.
20+
-- along the source. Obligation 5 (the partition-with-decidability
21+
-- lemma) lands below as `antiecho-partition-dec` and the
22+
-- codomain-decidability variant `antiecho-partition-codomain-dec`.
23+
-- Obligation 6 (the tropical decomposition `Echo × Π AntiEcho ≃
24+
-- IsArgmin`) lives in `AntiEchoTropical.agda` (concrete ℕ-scored
25+
-- form) and `AntiEchoTropicalGeneric.agda` (generic-codomain lift
26+
-- over an abstract `OrderedCodomain` interface).
2327

2428
module AntiEcho where
2529

2630
open import Level using (Level; _⊔_)
2731
open import Data.Empty using (⊥)
2832
open import Data.Product.Base using (Σ; _,_)
33+
open import Data.Sum.Base using (_⊎_; inj₁; inj₂)
2934
open import Function.Base using (_∘_)
3035
open import Relation.Binary.PropositionalEquality using (_≡_; _≢_)
36+
open import Relation.Nullary.Decidable.Core using (Dec; yes; no)
37+
38+
open import Echo using (Echo)
3139

3240
----------------------------------------------------------------------
3341
-- antiecho-def — the carrier.
@@ -91,3 +99,38 @@ antiecho-map-over :
9199
{f : A B} {y : B}
92100
(g : A' A) AntiEcho (f ∘ g) y AntiEcho f y
93101
antiecho-map-over g (x , np) = g x , np
102+
103+
----------------------------------------------------------------------
104+
-- antiecho-partition-dec — every source element classifies to one
105+
-- side, given decidability of `f x ≡ y`.
106+
--
107+
-- The companion to `antiecho-disjoint`. Disjointness ruled out
108+
-- `Echo` and `AntiEcho` *coinciding* on a shared `x`; this lemma
109+
-- says that for *any* `x`, decidability of `f x ≡ y` gives an actual
110+
-- classification of `x` into one side or the other. Together they
111+
-- exhibit `A` as the disjoint union of the Echo-side and the
112+
-- AntiEcho-side parameterised by `y`.
113+
--
114+
-- The asymmetric joint statement `Echo f y → AntiEcho f y → ⊥`
115+
-- (where the two sides carry *different* domain witnesses) is
116+
-- genuinely *not* a theorem and is not what is landed here:
117+
-- consider `f : Bool → Bool` with `f true = true` and
118+
-- `f false = false`; both `Echo f true` (via `(true, refl)`) and
119+
-- `AntiEcho f true` (via `(false, false≢true)`) are inhabited, so
120+
-- the joint statement is refuted by the model. The correct content
121+
-- of "obligation 5" is the per-element classification below.
122+
123+
antiecho-partition-dec :
124+
{a b} {A : Set a} {B : Set b} {f : A B} {y : B}
125+
(x : A) Dec (f x ≡ y) Echo f y ⊎ AntiEcho f y
126+
antiecho-partition-dec x (yes p) = inj₁ (x , p)
127+
antiecho-partition-dec x (no np) = inj₂ (x , np)
128+
129+
-- Codomain-decidability variant: when *every* `b ≡ y` is decidable
130+
-- (typically because `B` has decidable equality), the classification
131+
-- closes uniformly over `f x`.
132+
133+
antiecho-partition-codomain-dec :
134+
{a b} {A : Set a} {B : Set b} {f : A B} {y : B}
135+
( b Dec (b ≡ y)) (x : A) Echo f y ⊎ AntiEcho f y
136+
antiecho-partition-codomain-dec dec? x = antiecho-partition-dec x (dec? _)

proofs/agda/AntiEchoTropical.agda

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@
3333
--
3434
-- Scope. New module, neither `AntiEcho.agda` nor `EchoTropical.agda`
3535
-- is modified. Specialised to the concrete `Candidate → ℕ` setting
36-
-- of `EchoTropical.agda`; a generic-codomain version is deferred
37-
-- (would need a `≤`-bearing ordered codomain).
36+
-- of `EchoTropical.agda`; the generic-codomain version lives in
37+
-- `AntiEchoTropicalGeneric.agda`, parameterised by an abstract
38+
-- `OrderedCodomain` interface (carrier `B`, `_≤_`, `_<_`, `≤⇒¬<`,
39+
-- `¬<⇒≤`).
3840

3941
module AntiEchoTropical where
4042

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
{-# OPTIONS --safe --without-K #-}
2+
3+
-- AntiEchoTropicalGeneric — generic-codomain lift of
4+
-- `AntiEchoTropical.agda`'s tropical decomposition.
5+
--
6+
-- The concrete module `AntiEchoTropical.agda` works on the specific
7+
-- candidate scoring `score : Candidate → ℕ`. This module lifts the
8+
-- same decomposition to *any* ordered codomain interface — a carrier
9+
-- `B`, an order `_≤_`, a strict order `_<_`, the bound-against-strict
10+
-- conversion `≤⇒¬<` (always available), and the not-strict-below
11+
-- conversion `¬<⇒≤` (the decidability content; concretely
12+
-- `Data.Nat.Properties.¬<⇒≥`-shape, but ANY witness suffices).
13+
--
14+
-- Three theorems land over the interface:
15+
-- * `antiecho-tropical-decompose-gen` — Σ-reshape iso; structural,
16+
-- `refl` round-trips, does *not* need the order at all.
17+
-- * `optimality-iso-gen` — `(∀ z → y ≤ s z)` ↔ `(∀ z → s z < y → ⊥)`,
18+
-- using `≤⇒¬<` / `¬<⇒≤` from the interface.
19+
-- * `tropdecomp-antiecho-to-gen` / `-from-gen` — the composite
20+
-- `TropEcho-like ↔ Echo × Π-of-AntiEcho-flavoured-misses`.
21+
--
22+
-- Scope. The Σ-shapes for `IsArgmin-like` and `TropEcho-like` are
23+
-- replayed locally over the interface (`IsArgminG` and `TropEchoG`)
24+
-- because the concrete `IsArgmin` / `TropEcho` in `EchoTropical.agda`
25+
-- are pinned to `Candidate → ℕ`. The concrete module is *unchanged*
26+
-- and remains the canonical landing for the ℕ-scored case; this
27+
-- module is the abstract sibling, not a replacement.
28+
--
29+
-- The original concrete module discharged the obligation comment
30+
-- "a generic-codomain version is deferred (would need a `≤`-bearing
31+
-- ordered codomain)" — that obligation is now landed here.
32+
33+
module AntiEchoTropicalGeneric where
34+
35+
open import Data.Empty using (⊥)
36+
open import Data.Product.Base using (Σ; _×_; _,_; proj₁; proj₂)
37+
open import Function.Bundles using (_↔_; mk↔ₛ′)
38+
open import Relation.Binary.PropositionalEquality using (_≡_; refl)
39+
40+
open import Echo using (Echo)
41+
42+
----------------------------------------------------------------------
43+
-- Ordered codomain interface.
44+
--
45+
-- The minimum structure needed to land the tropical decomposition at
46+
-- a generic codomain. `B` is the codomain carrier; `_≤_` is the bound
47+
-- relation used on the optimality side; `_<_` is the strict order
48+
-- used in the AntiEcho-flavoured restatement; `≤⇒¬<` and `¬<⇒≤` are
49+
-- the two order conversions. Note that `¬<⇒≤` is the entire content
50+
-- of the "decidable order" hypothesis in the concrete ℕ case —
51+
-- factored out here as a field rather than baked into the codomain.
52+
53+
record OrderedCodomain : Set₁ where
54+
field
55+
B : Set
56+
_≤_ : B B Set
57+
_<_ : B B Set
58+
≤⇒¬< : {y n : B} y ≤ n n < y
59+
¬<⇒≤ : {y n : B} (n < y ⊥) y ≤ n
60+
61+
----------------------------------------------------------------------
62+
-- The generic decomposition, parameterised by `OrderedCodomain` and
63+
-- an abstract scoring function `s : C → B` from any candidate set to
64+
-- the ordered codomain.
65+
66+
module Generic (OC : OrderedCodomain) where
67+
open OrderedCodomain OC
68+
69+
-- Re-introduce the Σ-shapes locally over the abstract codomain.
70+
-- These mirror `EchoTropical.IsArgmin` / `TropEcho` exactly, with
71+
-- `Candidate → ℕ` replaced by an arbitrary `s : C B`.
72+
73+
IsArgminG : {C : Set} (s : C B) C B Set
74+
IsArgminG s x y = s x ≡ y × ( z y ≤ s z)
75+
76+
TropEchoG : {C : Set} (s : C B) B Set
77+
TropEchoG {C = C} s y = Σ C (λ x IsArgminG s x y)
78+
79+
------------------------------------------------------------------
80+
-- The structural decomposition. Pure Σ-reshape; the order is not
81+
-- used. Both round-trips `refl`.
82+
83+
antiecho-tropical-decompose-gen-to :
84+
{C : Set} {s : C B} {y : B}
85+
TropEchoG s y Echo s y × ( z y ≤ s z)
86+
antiecho-tropical-decompose-gen-to (x , p , bnd) = (x , p) , bnd
87+
88+
antiecho-tropical-decompose-gen-from :
89+
{C : Set} {s : C B} {y : B}
90+
Echo s y × ( z y ≤ s z) TropEchoG s y
91+
antiecho-tropical-decompose-gen-from ((x , p) , bnd) = x , p , bnd
92+
93+
antiecho-tropical-decompose-gen-to-from :
94+
{C : Set} {s : C B} {y : B}
95+
(r : Echo s y × ( z y ≤ s z))
96+
antiecho-tropical-decompose-gen-to
97+
(antiecho-tropical-decompose-gen-from r) ≡ r
98+
antiecho-tropical-decompose-gen-to-from ((x , p) , bnd) = refl
99+
100+
antiecho-tropical-decompose-gen-from-to :
101+
{C : Set} {s : C B} {y : B}
102+
(t : TropEchoG s y)
103+
antiecho-tropical-decompose-gen-from
104+
(antiecho-tropical-decompose-gen-to t) ≡ t
105+
antiecho-tropical-decompose-gen-from-to (x , p , bnd) = refl
106+
107+
antiecho-tropical-decompose-gen :
108+
{C : Set} (s : C B) (y : B)
109+
TropEchoG s y ↔ (Echo s y × ( z y ≤ s z))
110+
antiecho-tropical-decompose-gen s y =
111+
mk↔ₛ′
112+
(λ t antiecho-tropical-decompose-gen-to {s = s} {y = y} t)
113+
(λ r antiecho-tropical-decompose-gen-from {s = s} {y = y} r)
114+
(λ r antiecho-tropical-decompose-gen-to-from {s = s} {y = y} r)
115+
(λ t antiecho-tropical-decompose-gen-from-to {s = s} {y = y} t)
116+
117+
------------------------------------------------------------------
118+
-- AntiEcho-flavoured restatement of the optimality factor. The
119+
-- forward direction uses `≤⇒¬<` (always available); the backward
120+
-- uses `¬<⇒≤` (the decidability content of the interface).
121+
122+
optimality-as-antiecho-flavour-gen-to :
123+
{C : Set} {s : C B} {y : B}
124+
( z y ≤ s z) ( z s z < y ⊥)
125+
optimality-as-antiecho-flavour-gen-to bnd z lt = ≤⇒¬< (bnd z) lt
126+
127+
optimality-as-antiecho-flavour-gen-from :
128+
{C : Set} {s : C B} {y : B}
129+
( z s z < y ⊥) ( z y ≤ s z)
130+
optimality-as-antiecho-flavour-gen-from no-miss z = ¬<⇒≤ (no-miss z)
131+
132+
------------------------------------------------------------------
133+
-- Composite: TropEchoG ↔ Echo × (Π-of-AntiEcho-flavoured-misses).
134+
-- Forward + backward only, no extensionality on the Π factor (the
135+
-- two Π-shaped sides are not propositionally equal in general
136+
-- without funext; we keep them as a section/retraction pair, which
137+
-- is what the concrete module already does).
138+
139+
tropdecomp-antiecho-gen-to :
140+
{C : Set} {s : C B} {y : B}
141+
TropEchoG s y Echo s y × ( z s z < y ⊥)
142+
tropdecomp-antiecho-gen-to t
143+
with antiecho-tropical-decompose-gen-to t
144+
... | (e , bnd) = e , optimality-as-antiecho-flavour-gen-to bnd
145+
146+
tropdecomp-antiecho-gen-from :
147+
{C : Set} {s : C B} {y : B}
148+
Echo s y × ( z s z < y ⊥) TropEchoG s y
149+
tropdecomp-antiecho-gen-from (e , no-miss) =
150+
antiecho-tropical-decompose-gen-from
151+
(e , optimality-as-antiecho-flavour-gen-from no-miss)
152+
153+
----------------------------------------------------------------------
154+
-- Sanity instance: the natural numbers. Builds an `OrderedCodomain`
155+
-- record at ℕ with the same `≤⇒¬<` / `¬<⇒≤` lemmas the concrete
156+
-- `AntiEchoTropical.agda` uses internally. Pinned so the interface
157+
-- is demonstrably inhabitable; downstream users can build their own
158+
-- instances at other ordered codomains (e.g. `Float`, integers,
159+
-- abstract semirings) without modifying this module.
160+
161+
open import Data.Nat.Base using (ℕ; zero; suc; _≤_; _<_; z≤n; s≤s)
162+
open import Data.Empty using (⊥-elim)
163+
164+
private
165+
ℕ-≤⇒¬< : {y n : ℕ} y ≤ n n < y
166+
ℕ-≤⇒¬< z≤n ()
167+
ℕ-≤⇒¬< (s≤s p) (s≤s q) = ℕ-≤⇒¬< p q
168+
169+
ℕ-¬<⇒≤ : {y n : ℕ} (n < y ⊥) y ≤ n
170+
ℕ-¬<⇒≤ {y = zero} _ = z≤n
171+
ℕ-¬<⇒≤ {y = suc _} {n = zero} ¬p = ⊥-elim (¬p (s≤s z≤n))
172+
ℕ-¬<⇒≤ {y = suc _} {n = suc _} ¬p = s≤s (ℕ-¬<⇒≤ (λ q ¬p (s≤s q)))
173+
174+
ℕ-ordered-codomain : OrderedCodomain
175+
ℕ-ordered-codomain = record
176+
{ B =
177+
; _≤_ = _≤_
178+
; _<_ = _<_
179+
; ≤⇒¬< = ℕ-≤⇒¬<
180+
; ¬<⇒≤ = ℕ-¬<⇒≤
181+
}

proofs/agda/Smoke.agda

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,20 @@ open import Echo using
3434
)
3535

3636
-- AntiEcho thin slice (theory/antiecho — Σ-dual of Echo). Lands the
37-
-- carrier, per-element disjointness, introduction, and source-side
38-
-- map-over. Distinct from `EchoFiberTriangulation.CoEcho` (which is
39-
-- the trivial opposite-orientation fibre `∃ x . y ≡ f x`); see
40-
-- `coecho.md` §6 for the naming rationale. Partition-with-decidability
41-
-- and tropical decomposition deferred to follow-up slices.
37+
-- carrier, per-element disjointness, introduction, source-side
38+
-- map-over, and per-element partition with decidability of `f x ≡ y`
39+
-- (obligation 5). Distinct from `EchoFiberTriangulation.CoEcho`
40+
-- (which is the trivial opposite-orientation fibre `∃ x . y ≡ f x`);
41+
-- see `coecho.md` §6 for the naming rationale. Tropical decomposition
42+
-- lives in `AntiEchoTropical.agda`; the generic-codomain lift of it
43+
-- remains deferred.
4244
open import AntiEcho using
4345
( AntiEcho
4446
; antiecho-intro
4547
; antiecho-disjoint
4648
; antiecho-map-over
49+
; antiecho-partition-dec
50+
; antiecho-partition-codomain-dec
4751
)
4852

4953
-- Pillar A of docs/echo-types/establishment-plan.adoc: the
@@ -522,6 +526,17 @@ open import AntiEchoTropical using
522526
; tropdecomp-antiecho-from
523527
)
524528

529+
-- Generic-codomain lift of the tropical decomposition. Same headline
530+
-- theorems as `AntiEchoTropical` above, but parameterised by an
531+
-- abstract `OrderedCodomain` interface (carrier B, ≤/<, ≤⇒¬<, ¬<⇒≤)
532+
-- rather than fixed to ℕ. Sanity instance `ℕ-ordered-codomain`
533+
-- pinned so the interface is demonstrably inhabitable.
534+
open import AntiEchoTropicalGeneric using
535+
( OrderedCodomain
536+
; ℕ-ordered-codomain
537+
; module Generic
538+
)
539+
525540
open import EchoIntegration using
526541
( knowledge-preserved-under-choreo
527542
; merged-at-residue

0 commit comments

Comments
 (0)