|
| 1 | +{-# OPTIONS --safe --without-K #-} |
| 2 | + |
| 3 | +-- AntiEcho — the Σ-dual of Echo. |
| 4 | +-- |
| 5 | +-- Given `Echo f y := Σ (x : A) , (f x ≡ y)` from `Echo.agda`, the |
| 6 | +-- minimal-edit-distance dual is `AntiEcho f y := Σ A (λ x → f x ≢ y)`: |
| 7 | +-- a domain element together with a constructive proof that `f x` does |
| 8 | +-- NOT hit `y`. Same Σ-shape, same universe `a ⊔ b`, same |
| 9 | +-- proof-relevance posture; `--safe --without-K`-clean. |
| 10 | +-- |
| 11 | +-- Naming. The name `CoEcho` is ALREADY taken in |
| 12 | +-- `EchoFiberTriangulation.agda` for the trivial opposite-orientation |
| 13 | +-- fibre `∃ x . y ≡ f x` (Echo composed with `sym`). That construction |
| 14 | +-- is a reorientation, not a dual. The negative dual lives here under |
| 15 | +-- the distinct name `AntiEcho`. Cf. design note: `coecho.md` §6. |
| 16 | +-- |
| 17 | +-- This thin slice lands obligations 1–4 from `coecho.md` §5 (renamed |
| 18 | +-- `antiecho-*`): the carrier, per-element disjointness against Echo, |
| 19 | +-- 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. |
| 23 | + |
| 24 | +module AntiEcho where |
| 25 | + |
| 26 | +open import Level using (Level; _⊔_) |
| 27 | +open import Data.Empty using (⊥) |
| 28 | +open import Data.Product.Base using (Σ; _,_) |
| 29 | +open import Function.Base using (_∘_) |
| 30 | +open import Relation.Binary.PropositionalEquality using (_≡_; _≢_) |
| 31 | + |
| 32 | +---------------------------------------------------------------------- |
| 33 | +-- antiecho-def — the carrier. |
| 34 | +-- |
| 35 | +-- Same Σ-shape as `Echo`; only `≡` flips to `≢ := · ≡ y → ⊥`. |
| 36 | +-- Universe `a ⊔ b`, matching Echo exactly. |
| 37 | + |
| 38 | +AntiEcho : |
| 39 | + ∀ {a b} {A : Set a} {B : Set b} (f : A → B) → B → Set (a ⊔ b) |
| 40 | +AntiEcho {A = A} f y = Σ A (λ x → f x ≢ y) |
| 41 | + |
| 42 | +---------------------------------------------------------------------- |
| 43 | +-- antiecho-intro — introduction from a constructive miss. |
| 44 | +-- |
| 45 | +-- Trivial: an inhabitant is exactly a pair of a domain element and a |
| 46 | +-- miss-proof. Mirrors `Echo.echo-intro` modulo the flip. |
| 47 | + |
| 48 | +antiecho-intro : |
| 49 | + ∀ {a b} {A : Set a} {B : Set b} {f : A → B} {y : B} |
| 50 | + (x : A) → f x ≢ y → AntiEcho f y |
| 51 | +antiecho-intro x np = x , np |
| 52 | + |
| 53 | +---------------------------------------------------------------------- |
| 54 | +-- antiecho-disjoint — per-element disjointness against Echo. |
| 55 | +-- |
| 56 | +-- A single `x : A` cannot witness both `f x ≡ y` and `f x ≢ y`; apply |
| 57 | +-- the negation to the equation. Note this is the PER-ELEMENT form, |
| 58 | +-- per `coecho.md` §2: the joint statement `Echo f y → AntiEcho f y → ⊥` |
| 59 | +-- with possibly distinct witnesses requires decidability on the |
| 60 | +-- codomain and lives in the deferred partition lemma. Here the witness |
| 61 | +-- is shared explicitly. |
| 62 | + |
| 63 | +antiecho-disjoint : |
| 64 | + ∀ {a b} {A : Set a} {B : Set b} {f : A → B} {y : B} |
| 65 | + (x : A) → f x ≡ y → f x ≢ y → ⊥ |
| 66 | +antiecho-disjoint x p np = np p |
| 67 | + |
| 68 | +-- The asymmetric joint form `Echo f y → AntiEcho f y → ⊥` (where the |
| 69 | +-- two sides may carry different domain witnesses) is intentionally |
| 70 | +-- absent: it requires injectivity / decidability on the codomain to |
| 71 | +-- collapse the two witnesses, and lives in the deferred partition |
| 72 | +-- lemma (`coecho.md` §5 obligation 5). The per-element form above is |
| 73 | +-- the postulate-free, K-free primitive. |
| 74 | + |
| 75 | +---------------------------------------------------------------------- |
| 76 | +-- antiecho-map-over — covariance along the source. |
| 77 | +-- |
| 78 | +-- Given `g : A' → A`, an AntiEcho for the composite `f ∘ g` yields an |
| 79 | +-- AntiEcho for `f` by re-applying `g` to the source witness. The miss |
| 80 | +-- proof carries over unchanged: `f (g x) ≡ y` IS the proposition |
| 81 | +-- `(f ∘ g) x ≡ y`, so the same negation discharges both. |
| 82 | +-- |
| 83 | +-- This is the SOURCE-side `map-over`: misses propagate from the |
| 84 | +-- composite back to the outer leg. Cf. `coecho.md` §4 design note 3 |
| 85 | +-- ("contravariant MapOver"): the MapOver-style version (over a fixed |
| 86 | +-- codomain) is a follow-up; this slice ships the simpler composition- |
| 87 | +-- along-the-source form. |
| 88 | + |
| 89 | +antiecho-map-over : |
| 90 | + ∀ {a a' b} {A : Set a} {A' : Set a'} {B : Set b} |
| 91 | + {f : A → B} {y : B} |
| 92 | + (g : A' → A) → AntiEcho (f ∘ g) y → AntiEcho f y |
| 93 | +antiecho-map-over g (x , np) = g x , np |
0 commit comments