Commit 94a8d71
proof(idris2): tighten Ephapax.IR.SExpr to %default total via fueled mutual parser (#89)
## Summary
First step of the
[hyperpolymath/standards#134](hyperpolymath/standards#134)
totality tightening campaign. `Ephapax.IR.SExpr` was one of 9 ephapax
Idris2 source files declared `%default partial`. This PR converts it to
**`%default total`** without any proof escapes.
## Root cause of the partiality
The mutual `parseExpr` / `parseList` (plus its `where`-bound `go`)
thread `List Char` through `dropWhile` and parser-returned remainders.
Idris2 0.8.0's structural termination checker cannot prove these
recursive arguments smaller.
## Resolution (no `assert_total`, no `assert_smaller`)
- Introduced explicit `Nat` fuel parameters: `parseExprFuel`,
`parseListFuel`, `listGo`. Each recursive call decrements `S k → k`,
giving Idris2 a structural decreasing measure.
- Lifted the original inner `go` to a top-level `listGo` in the same
mutual block, so its fuel can participate in mutual termination (an
inner `where` cannot).
- Public `parse` wrapper seeds fuel from `length (unpack input)`.
**Sound**: every successful primitive parser (`parseAtom`,
`parseString`, `'('` / `')'` tokens) consumes at least one character, so
the input-length bound cannot be exceeded by any valid parse.
## Verification
- `idris2 --check Ephapax/IR/SExpr.idr` from `idris2/src/` → **exit 0**
(Idris2 0.8.0).
- No remaining `partial` annotations, no `assert_smaller`, no
`assert_total`.
- `Show SExpr` retains its original `covering` annotation — that's a
coverage-only relaxation that was already in place under `%default
partial`, unaffected by this change.
## What this does NOT close
8 other ephapax source files under `idris2/src/Ephapax/` still carry
`%default partial` (`IR/AST.idr`, `IR/Decode.idr`, `Parse/Lexer.idr`,
`Parse/Util.idr`, `Parse/Stream.idr`, `Parse/Parser.idr`,
`Affine/Typecheck.idr`, `Affine/Emit.idr`). They can be tackled one
chain at a time using the same fueled-mutual-recursion pattern this PR
establishes.
Refs hyperpolymath/standards#124
Refs hyperpolymath/standards#134
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 0559714 commit 94a8d71
1 file changed
Lines changed: 38 additions & 21 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
| 5 | + | |
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| |||
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
63 | 70 | | |
64 | | - | |
65 | | - | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
66 | 74 | | |
67 | 75 | | |
68 | | - | |
| 76 | + | |
69 | 77 | | |
70 | 78 | | |
71 | 79 | | |
| |||
75 | 83 | | |
76 | 84 | | |
77 | 85 | | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
89 | 105 | | |
90 | 106 | | |
91 | 107 | | |
92 | 108 | | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
0 commit comments