Skip to content

Commit 7fc43dd

Browse files
hyperpolymathclaude
andcommitted
hygiene: per-lemma Smoke pins for EchoApprox via concrete instance module
Closes a silent violation of the CLAUDE.md "Working rules" invariant ("Every headline theorem must be pinned in Smoke.agda via using clause") for parameterised modules. EchoApprox.Approx lemmas could not be named in Smoke.agda until some PseudoMetric was supplied; PR #70 (Lane C of the multi-lane swarm) added the retract-direction lemmas but, following existing convention, left them unpinned for the same reason. This PR closes the gap with the smallest, most honest possible instance. Instance chosen: the trivial / collapse-to-strict pseudometric on the unit carrier ⊤. * Tol := ⊤, zero := tt, _+_ := λ _ _ → tt * _≤_ := λ _ _ → ⊤ * dist := λ _ _ → tt on B := ⊤ Every order / monotonicity / triangle obligation discharges to tt. Every approximate echo collapses to Σ A (λ _ → ⊤), so each pinned lemma is a proof-of-life sanity check that the parameterised module's term is well-typed at *some* instance — exactly the hygiene contract the invariant asks for. No new mathematical content. When a genuine metric instance lands in the repo, the per-lemma pins can be re-pointed at it. Headlines now pinned in Smoke.agda (9 names): * approx-EchoR (= EchoR) * approx-intro (= echo-approx-intro) * approx-strict→approx (= echo-strict→approx) * approx-relax (= echo-approx-relax) * approx-NonExpansive (= NonExpansive) * approx-compose (= echo-approx-compose) * approx-comp-sound (= echo-approx-comp-sound) * approx-comp-retract-to (= echo-approx-comp-retract-to) * approx-comp-retract-A (= echo-approx-comp-retract-A) Plus the instance constructors trivialTolerance, trivialPseudoMetric. Build verified in parent session (sandbox quirk denied positional- argument agda invocations in this worktree): $ LC_ALL=C.UTF-8 agda -i proofs/agda proofs/agda/All.agda exit: 0 $ LC_ALL=C.UTF-8 agda -i proofs/agda proofs/agda/Smoke.agda exit: 0 --safe --without-K invariants intact. No postulates, no funext, no path algebra — every field is tt or refl. Refs PR #70 (Lane C surfaced the gap). Refs CLAUDE.md "Working rules" invariant. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 35e1739 commit 7fc43dd

3 files changed

Lines changed: 116 additions & 0 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 EchoIntegration
1818
open import EchoCNOBridge
1919

2020
open import EchoApprox
21+
open import EchoApproxInstance
2122
open import EchoIndexed
2223
open import EchoDecidable
2324
open import EchoAccess
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
{-# OPTIONS --safe --without-K #-}
2+
3+
-- A concrete `Tolerance` + `PseudoMetric` instance for `EchoApprox.Approx`,
4+
-- whose sole purpose is to give `Smoke.agda` a typeable identifier per
5+
-- headline lemma of the parameterised `EchoApprox.Approx` module.
6+
--
7+
-- Repo invariant (`CLAUDE.md`, "Working rules"):
8+
--
9+
-- "Every headline theorem must be pinned in `Smoke.agda` via
10+
-- `using` clause."
11+
--
12+
-- Lemmas living inside the parameterised submodule `EchoApprox.Approx`
13+
-- cannot be named in `Smoke.agda` until *some* `PseudoMetric` is
14+
-- supplied, so the invariant is silently violated for every
15+
-- `echo-approx-*` and `echo-strict→approx` lemma. This module closes
16+
-- that gap.
17+
--
18+
-- Design call: the trivial / collapse-to-strict pseudometric on `⊤`.
19+
--
20+
-- * `Tol` := `⊤`, `zero` := `tt`, `_+_` := `λ _ _ → tt`
21+
-- * `_≤_` := `λ _ _ → ⊤`
22+
-- * `dist` := `λ _ _ → tt` on the carrier `B := ⊤`
23+
--
24+
-- Every order / monotonicity / triangle obligation discharges to `tt`.
25+
-- Every approximate echo `EchoR ε f y = Σ A (λ x → dist (f x) y ≤ ε)`
26+
-- collapses to `Σ A (λ _ → ⊤)`, so each pinned lemma here is a trivial
27+
-- sanity check that the parameterised module's term is well-typed at
28+
-- *some* instance. That is exactly the hygiene contract the invariant
29+
-- asks for — proof-of-life, not new content.
30+
--
31+
-- We choose `A := ⊤` and `B := ⊤` so each pinned name resolves to a
32+
-- single top-level identifier with no remaining type parameters, which
33+
-- lets `Smoke.agda` enumerate them in a `using` clause one-for-one.
34+
--
35+
-- A non-trivial pseudometric (e.g. the discrete metric over `Bool`)
36+
-- would also work, but adds nothing the trivial one does not give for
37+
-- the purposes of `Smoke.agda` pinning. When a genuine metric instance
38+
-- lands in the repo, the per-lemma pins below can be re-pointed at it.
39+
40+
module EchoApproxInstance where
41+
42+
open import Level using (Level)
43+
open import Data.Unit.Base using (⊤; tt)
44+
open import Relation.Binary.PropositionalEquality using (refl)
45+
46+
open import EchoApprox using (Tolerance; PseudoMetric; module Approx)
47+
48+
----------------------------------------------------------------------
49+
-- The trivial tolerance carrier
50+
----------------------------------------------------------------------
51+
52+
-- All fields are tt / Unit; every law obligation is met by `tt`.
53+
trivialTolerance : Tolerance Level.zero
54+
trivialTolerance = record
55+
{ Tol =
56+
; zero = tt
57+
; _+_ = λ _ _ tt
58+
; _≤_ = λ _ _
59+
; ≤-refl = tt
60+
; ≤-trans = λ _ _ tt
61+
; +-mono-≤ = λ _ _ tt
62+
}
63+
64+
----------------------------------------------------------------------
65+
-- The trivial pseudometric on the carrier `⊤`
66+
----------------------------------------------------------------------
67+
68+
-- Distance is constantly `tt`; self-distance is `refl`; triangle is `tt`.
69+
trivialPseudoMetric : PseudoMetric ⊤ trivialTolerance
70+
trivialPseudoMetric = record
71+
{ dist = λ _ _ tt
72+
; dist-self = λ _ refl
73+
; dist-tri = λ _ _ _ tt
74+
}
75+
76+
----------------------------------------------------------------------
77+
-- Per-lemma proof-of-life pins for `Approx` at the trivial instance.
78+
--
79+
-- Top-level identifiers, one per `EchoApprox.Approx` headline, with
80+
-- `A := ⊤` and `B := ⊤` so each is a closed term that `Smoke.agda`
81+
-- can enumerate in a `using` clause. Definitions use `=` (no explicit
82+
-- type signature) so the original term's type is inferred — which is
83+
-- exactly the typeability check the hygiene invariant asks for.
84+
----------------------------------------------------------------------
85+
86+
private
87+
open module ApproxT⊤ =
88+
Approx {A = ⊤} {B = ⊤} {T = trivialTolerance} trivialPseudoMetric
89+
90+
approx-EchoR = EchoR
91+
approx-intro = echo-approx-intro
92+
approx-strict→approx = echo-strict→approx
93+
approx-relax = echo-approx-relax
94+
approx-NonExpansive = NonExpansive
95+
approx-compose = echo-approx-compose
96+
approx-comp-sound = echo-approx-comp-sound
97+
approx-comp-retract-to = echo-approx-comp-retract-to
98+
approx-comp-retract-A = echo-approx-comp-retract-A

proofs/agda/Smoke.agda

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,23 @@ open import EchoApprox using
7575
; module Approx
7676
)
7777

78+
-- Per-lemma pins for the parameterised EchoApprox via EchoApproxInstance
79+
-- (hygiene; closes the CLAUDE.md "Working rules" invariant gap for
80+
-- parameterised modules — see follow-up to PR #70).
81+
open import EchoApproxInstance using
82+
( trivialTolerance
83+
; trivialPseudoMetric
84+
; approx-EchoR
85+
; approx-intro
86+
; approx-strict→approx
87+
; approx-relax
88+
; approx-NonExpansive
89+
; approx-compose
90+
; approx-comp-sound
91+
; approx-comp-retract-to
92+
; approx-comp-retract-A
93+
)
94+
7895
open import EchoIndexed using
7996
( Echoᵢ
8097
; echoᵢ-intro

0 commit comments

Comments
 (0)