Skip to content

Commit 8cf7dc0

Browse files
committed
feat: bounded-search-is-decidable — EchoSearch decidability bridge
`EchoS enum f y n` is exactly the bounded existential `Σ k. (k < n) × (f (enum k) ≡ y)`, so under decidable equality on `B` it is decidable by structural recursion on the budget `n`: the `suc` step tests the new index `n` (via `_≟_`) and otherwise recurses, refuting every index below `suc n` in the negative case via `<-cmp` trichotomy (the index `n` itself by `¬eq`, indices below `n` by the recursive `¬below`, none strictly between). This is the concrete bridge from EchoSearch to `EchoDecidable` (axis 8(3)) that the module flagged under "where next". `--safe --without-K`, zero postulates, structural recursion (no TERMINATING). Added to `EchoSearch.agda`; pinned in `Smoke.agda`; the module's "where next" note marked LANDED. EchoSearch + Smoke.agda + All.agda exit 0; kernel-guard PASS (EchoSearch already classified — no new module). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018CaSgNjNURC7ocsyjYh9We
1 parent 7721c91 commit 8cf7dc0

2 files changed

Lines changed: 45 additions & 6 deletions

File tree

proofs/agda/EchoSearch.agda

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,23 @@
6767
-- ∧ trace.last ≡ x ∧ f x ≡ y`. The current `EchoS` projects from
6868
-- that by collapsing the trace to its terminal index.
6969
--
70-
-- * A *bounded-search-is-decidable* lemma in the presence of
71-
-- decidable equality on `B`: search up to `n` either yields an
70+
-- * (LANDED) A *bounded-search-is-decidable* lemma in the presence
71+
-- of decidable equality on `B`: search up to `n` either yields an
7272
-- `EchoS enum f y n` or proves `¬ EchoS enum f y n`. This is the
73-
-- concrete bridge to `EchoDecidable`, kept as a separate slice
74-
-- because it needs a `_≟_` on `B` and a finite-walk recursion.
73+
-- concrete bridge to `EchoDecidable`; it needs a `_≟_` on `B` and a
74+
-- finite-walk recursion on the budget. See `bounded-search-is-decidable`
75+
-- at the bottom of this module.
7576

7677
module EchoSearch where
7778

7879
open import Function.Base using (_∘_; id)
7980
open import Data.Nat.Base using (ℕ; zero; suc; _≤_; _<_; z≤n; s≤s)
80-
open import Data.Nat.Properties using (≤-<-trans; <-≤-trans)
81+
open import Data.Nat.Properties
82+
using (≤-<-trans; <-≤-trans; <-cmp; <-trans; ≤-trans; ≤-refl; <-irrefl)
8183
open import Data.Empty using (⊥; ⊥-elim)
8284
open import Data.Product.Base using (Σ; _,_; _×_; proj₁; proj₂)
83-
open import Relation.Nullary using (¬_)
85+
open import Relation.Nullary using (¬_; Dec; yes; no)
86+
open import Relation.Binary.Definitions using (Tri; tri<; tri≈; tri>)
8487
open import Relation.Binary.PropositionalEquality
8588
using (_≡_; refl; sym; trans; cong)
8689

@@ -156,3 +159,38 @@ echo-search-postcompose :
156159
EchoS enum f y n EchoS enum (g ∘ f) (g y) n
157160
echo-search-postcompose enum f g (k , k<n , eq) =
158161
k , k<n , cong g eq
162+
163+
----------------------------------------------------------------------
164+
-- Decidability bridge
165+
----------------------------------------------------------------------
166+
167+
-- Bounded search is decidable under decidable equality on the codomain.
168+
-- Because `EchoS enum f y n` is exactly the bounded existential
169+
-- `Σ k. (k < n) × (f (enum k) ≡ y)`, searching up to the budget `n`
170+
-- either produces a bound-`n` search echo or refutes one. This is the
171+
-- concrete bridge from EchoSearch to `EchoDecidable` (axis 8(3)): no
172+
-- machine model is required, only the step budget and a `_≟_` on `B`.
173+
-- Structural recursion on `n`; the `suc` step tests the new index `n`
174+
-- and otherwise recurses, using trichotomy to refute every index below
175+
-- `suc n` in the negative case.
176+
bounded-search-is-decidable :
177+
{a b} {A : Set a} {B : Set b}
178+
(_≟_ : (x y : B) Dec (x ≡ y))
179+
(enum : SearchStrategy A) (f : A B) (y : B) (n : ℕ)
180+
Dec (EchoS enum f y n)
181+
bounded-search-is-decidable _≟_ enum f y zero =
182+
no (echo-search-bound-zero enum f y)
183+
bounded-search-is-decidable _≟_ enum f y (suc n) with f (enum n) ≟ y
184+
... | yes eq = yes (n , ≤-refl , eq)
185+
... | no ¬eq with bounded-search-is-decidable _≟_ enum f y n
186+
... | yes (k , k<n , eqk) = yes (k , <-trans k<n ≤-refl , eqk)
187+
... | no ¬below = no λ { (k , k<1+n , eqk) contra k k<1+n eqk }
188+
where
189+
-- No index below `suc n` can witness `y`: indices below `n` are
190+
-- refuted by `¬below`, the index `n` itself by `¬eq`, and there is
191+
-- no index strictly between `n` and `suc n`.
192+
contra : k k < suc n f (enum k) ≡ y
193+
contra k (s≤s k≤n) eqk with <-cmp k n
194+
... | tri< k<n _ _ = ¬below (k , k<n , eqk)
195+
... | tri≈ _ k≡n _ = ¬eq (trans (sym (cong (λ j f (enum j)) k≡n)) eqk)
196+
... | tri> _ _ n<k = <-irrefl refl (≤-trans n<k k≤n)

proofs/agda/Smoke.agda

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ open import EchoSearch using
482482
; echo-search-forget
483483
; echo-search-bound-zero
484484
; echo-search-postcompose
485+
; bounded-search-is-decidable
485486
)
486487

487488
-- Per-lemma pins for the parameterised EchoSearch via

0 commit comments

Comments
 (0)