Skip to content

Commit a94ee81

Browse files
feat(abi): close TacticRecord round-trip lemmas (closes #152) (#166)
## Summary - Discharges the two round-trip lemmas deferred in `src/abi/EchidnaABI/TacticRecord.idr`: - `natToFinToNat : (n : Nat) -> (0 _ : LT n (S MaxConfidence)) -> finToNat (natToFinLT n) = n` - `clampRoundtripInRange: (n : Nat) -> (prf : LT n (S MaxConfidence)) -> finToNat (clampConfidence n) = n` - Polymorphic helper `finToNatNatToFinLT` sidesteps the unification trap the original deferral comment misidentified as missing weakening: with `m` left implicit the recursive call's upper bound shrinks structurally and the `LTESucc` pattern unpacks without `lteSuccRight` glue. The specific-`S MaxConfidence` instance specialises in one line. `clampRoundtripInRange` `with`-abstracts on the same `isLT n (S MaxConfidence)` that `clampConfidence` inspects: `Yes` reduces and discharges via `natToFinToNat`; `No` is contradicted by the hypothesis via `absurd`. - Constraint preserved: zero `believe_me`, zero `postulate`, zero `admit`, zero `assert_total`. All three new lemmas verified `total` by Idris2 0.8.0 REPL `:total`. ## Test plan - [x] `idris2 --check EchidnaABI/TacticRecord.idr` → `1/1: Building EchidnaABI.TacticRecord` (clean, zero warnings) - [x] `:total natToFinToNat` → total - [x] `:total clampRoundtripInRange` → total - [x] `:total finToNatNatToFinLT` → total - [x] Pre-existing comparison-order lemmas (`compareByConfidenceRefl`, `compareByConfidenceAntiSym`) still total — no regression - [x] `grep -nE 'believe_me|assert_total|postulate|admit|sorry|Admitted'` against the file returns only doc-comment occurrences (`||| NO ...`) Closes #152.
1 parent 598487c commit a94ee81

1 file changed

Lines changed: 44 additions & 12 deletions

File tree

src/abi/EchidnaABI/TacticRecord.idr

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,38 @@ clampConfidence n = case isLT n (S MaxConfidence) of
8585
Yes prf => natToFinLT n
8686
No _ => last -- saturate to MaxConfidence
8787

88-
-- Round-trip lemma `natToFinToNat` is desirable but requires careful
89-
-- LTE-weakening that has not yet been spelled out structurally. The
90-
-- absence of this lemma here is INTENTIONAL: the file ships with the
91-
-- comparison total order proven and the round-trip property captured
92-
-- as a Wave-3 sub-issue rather than a believe-me hole. See issue
93-
-- breadcrumb at the top of this file.
88+
------------------------------------------------------------------------
89+
-- natToFinLT / finToNat Round-Trip
90+
------------------------------------------------------------------------
91+
92+
-- The LTE-weakening worry recorded in the original deferral comment was
93+
-- a unification trap, not a missing lemma. Specialising on
94+
-- `S MaxConfidence` directly forces the recursive call to see
95+
-- `LTE (S k) MaxConfidence`, but the recursive obligation needs
96+
-- `LTE (S k) (S MaxConfidence)` — the same proposition off-by-one.
97+
-- The polymorphic helper sidesteps the trap: with `m` implicit the
98+
-- recursive `m` is inferred to the structural predecessor, so the
99+
-- LTESucc pattern matches without explicit weakening. The
100+
-- `S MaxConfidence` instance is then a one-line specialisation.
101+
102+
||| Generic round-trip: every nat strictly below `m` is faithfully
103+
||| recovered by `finToNat . natToFinLT`. Polymorphic in `m` so the
104+
||| recursion's implicit upper bound shrinks structurally and the
105+
||| LTESucc pattern can be unpacked without `lteSuccRight` glue.
106+
public export
107+
finToNatNatToFinLT :
108+
(n : Nat) -> {m : Nat} -> (0 prf : LT n m) ->
109+
finToNat (natToFinLT n {prf}) = n
110+
finToNatNatToFinLT 0 (LTESucc _) = Refl
111+
finToNatNatToFinLT (S k) (LTESucc lt) = cong S (finToNatNatToFinLT k lt)
112+
113+
||| In-range nat ↔ ConfidenceFP round-trip. Discharges the round-trip
114+
||| obligation flagged at lines 88-93 of the original file.
115+
public export
116+
natToFinToNat :
117+
(n : Nat) -> (0 prf : LT n (S MaxConfidence)) ->
118+
finToNat (natToFinLT n {prf}) = n
119+
natToFinToNat n prf = finToNatNatToFinLT n prf
94120

95121
------------------------------------------------------------------------
96122
-- Comparison: by confidence, descending
@@ -188,9 +214,15 @@ confidenceFloatZero = Refl
188214
-- ABI Roundtrip Invariant
189215
------------------------------------------------------------------------
190216

191-
-- clampRoundtripInRange is deferred along with natToFinToNat above;
192-
-- the constructive round-trip proof requires the in-range
193-
-- nat-fin-nat lemma which is the Wave-3 sub-issue. The clamp
194-
-- operation itself is total and that totality is verified by
195-
-- Idris2's pattern-matching exhaustiveness on the `with` of
196-
-- `isLT n (S MaxConfidence)`.
217+
||| Clamp is the identity on in-range inputs. The `with`-abstraction
218+
||| pivots on the very `isLT n (S MaxConfidence)` that `clampConfidence`
219+
||| inspects, so the `Yes` branch reduces the case and we discharge it
220+
||| via the round-trip lemma; the `No` branch is contradicted by the
221+
||| in-range hypothesis, closed by `absurd`. Total, no admits.
222+
public export
223+
clampRoundtripInRange :
224+
(n : Nat) -> (prf : LT n (S MaxConfidence)) ->
225+
finToNat (clampConfidence n) = n
226+
clampRoundtripInRange n prf with (isLT n (S MaxConfidence))
227+
_ | Yes prf' = natToFinToNat n prf'
228+
_ | No nlt = absurd (nlt prf)

0 commit comments

Comments
 (0)