Commit bf3c38c
proof(idris2): tighten Ephapax.Parse.Util to %default total (#91)
## Summary
Third file in the `%default partial` → `%default total` chain for
`ephapax/idris2/src/Ephapax/`. SExpr.idr (#89) was first; Stream.idr
(#90) second.
Two combinators in `Util.idr` recurse unboundedly on a `Stream` rather
than on a structural recursor:
- `many : Parser a -> Parser (List a)` — repeated application until
first failure
- `sepBy.sepTail` — alternating separator + element
Replace both with Nat-fueled siblings (`manyFuel` / `sepTailFuel`) where
fuel `= integerToNat (cast (s.len - s.index))` — the count of remaining
tokens in the input stream at entry. Each recursive call decrements fuel
by 1, and the inner parser is assumed to consume ≥1 token per success
(the only well-formed usage).
`sepBy1` already delegates to `sepBy` and inherits totality for free.
## Soundness
On a *consuming* inner parser (every real combinator client), the fueled
form is observationally identical to the partial original: the stream is
monotonically advancing, so the parser exhausts the stream before the
fuel exhausts (in the common case it's tight equality — fuel =
tokens-remaining).
On a degenerate non-consuming inner parser, the partial original loops
forever; the fueled form returns a truncated list. Strictly safer.
No `assert_total` / `assert_smaller` / `believe_me` escapes.
## Verification
```
$ IDRIS2_PREFIX=…/idris2/0.8.0 idris2 --check Ephapax/Parse/Util.idr
4/4: Building Ephapax.Parse.Util (Ephapax/Parse/Util.idr)
$ idris2 --check Ephapax/Parse/Parser.idr # downstream
6/6: Building Ephapax.Parse.Parser (Ephapax/Parse/Parser.idr)
```
## Refs
- `#124` (proof-debt audit epic)
- `#134` (ephapax totality sub-issue)
- Companion: PR `#89` (SExpr — file 1), PR `#90` (Stream — file 2)
## Test plan
- [x] `idris2 --check Ephapax/Parse/Util.idr` builds green under
`%default total`
- [x] Downstream `Ephapax.Parse.Parser` still builds
- [ ] CI green
- [ ] No `assert_*` / `believe_me` introduced (verified by inspection —
see diff)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent c42226b commit bf3c38c
1 file changed
Lines changed: 18 additions & 11 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| |||
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
65 | 70 | | |
66 | 71 | | |
67 | 72 | | |
| |||
156 | 161 | | |
157 | 162 | | |
158 | 163 | | |
159 | | - | |
| 164 | + | |
| 165 | + | |
160 | 166 | | |
161 | | - | |
162 | | - | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
163 | 170 | | |
164 | 171 | | |
165 | 172 | | |
166 | 173 | | |
167 | 174 | | |
168 | | - | |
| 175 | + | |
169 | 176 | | |
170 | 177 | | |
171 | 178 | | |
| |||
0 commit comments