|
1 | 1 | # Sorry Reduction Plan — Pass 5 |
2 | 2 |
|
3 | | -## Current State (as of commit 7dee40c3) |
| 3 | +## Current State (as of commit 08b717e3) |
4 | 4 |
|
5 | | -**Active `sorry`**: 5 (all in `GenericInduction.lean`) |
| 5 | +**Active `sorry`**: 4 (all in `GenericInduction.lean`) |
6 | 6 | **TYPESIG_SORRY blocks**: ~57 commented-out theorems with broken type signatures |
7 | 7 | **Build status**: Green (compiles with warnings only) |
8 | 8 |
|
|
21 | 21 | | `a4c29009` | 10 | bridge theorems (LegacyCompatible + CallsDisjoint) + 3 downstream (−3) | |
22 | 22 | | `66236a18` | 6 | Add keccak axiom `solidityMappingSlot_add_wordOffset_lt_evmModulus` + prove 4 mapping slot wordOffset≠0 sorries (−4) | |
23 | 23 | | `7dee40c3` | 5 | Prove aliasSlots TYPESIG_SORRY chain: 3 theorems uncommented (−1) | |
| 24 | +| `08b717e3` | 4 | Add ExprCompileCore bitwise constructors, prove exprCompileCore_of_exprTouchesUnsupportedContractSurface (−1) | |
24 | 25 |
|
25 | | -## Remaining 5 Sorries — Architecturally Blocked |
| 26 | +## Remaining 4 Sorries — Architecturally Blocked |
26 | 27 |
|
27 | 28 | Every remaining sorry depends on fundamental design issues that cannot be resolved |
28 | 29 | by proof work alone. They require either upstream code changes, new axioms, or |
29 | | -substantial proof rewrites. |
30 | | - |
31 | | -### 1. ExprCompileCore false theorem (line 2728) |
32 | | -**Theorem**: `exprCompileCore_of_exprTouchesUnsupportedContractSurface` |
33 | | -**Blocker**: `exprTouchesUnsupportedContractSurface` returns `false` for `sdiv`, `smod`, |
34 | | -`sgt`, `slt`, but source semantics returns `none` for those ops. This makes the theorem |
35 | | -genuinely unprovable — `ExprCompileCore` constructors would need to handle operations |
36 | | -whose semantics are intentionally unsupported. |
37 | | -**Fix**: Add constructors to `ExprCompileCore` for all operators that pass the surface |
38 | | -check, plus their `eval_compileExpr_core` correctness proofs. Large cascading effort. |
39 | | - |
40 | | -### 2. Identifier shapes (line 5961) |
| 30 | +substantial proof infrastructure. |
| 31 | + |
| 32 | +### 1. Identifier shapes (line 5982) |
41 | 33 | **Theorem**: `validateIdentifierShapes_fieldName_avoidReservedCompilerPrefix` |
42 | 34 | **Blocker**: Claims no field name starts with `"__"`, but `__immutable_*` fields are |
43 | 35 | explicitly allowed by the validation pipeline. |
44 | 36 | **Fix**: Thread stronger field-shape classification that distinguishes mutable vs |
45 | 37 | immutable fields through the generic induction scope invariant. |
46 | 38 |
|
47 | | -### 3. setMappingPackedWord (line 7572) |
| 39 | +### 2. setMappingPackedWord (line 7467) |
48 | 40 | **Theorem**: `compiledStmtStep_setMappingPackedWord_singleSlot_of_slotSafety_preserves` |
49 | | -**Blocker**: The commented-out proof (lines 7573-7755) uses the old `evalExpr : Nat` API |
50 | | -but `evalExpr` now returns `Option Nat`. The proof needs complete rewriting (~180 lines) |
51 | | -to handle Option unwrapping across 5 IR let-statements, each requiring re-derivation of |
52 | | -`evalIRExpr` in modified states via `eval_compileExpr_core_of_scope`. The keccak modulus |
53 | | -issue (previously blocking) has been resolved by axiom, but the API rewrite remains. |
54 | | -**Fix**: Rewrite the entire proof with `rcases` pattern for Option handling and |
55 | | -re-derive key/writeSlot expression evaluations in each modified IR state. |
56 | | - |
57 | | -### 4. setStorageAddr — Address modulus (line 9923) |
| 41 | +**Blocker**: Requires proving a 5-statement IR block body executes correctly, plus a |
| 42 | +bitwise identity (`storedIR = packedWordWrite`) bridging IR-level Nat operations with |
| 43 | +Uint256-level `packedWordWrite`. Three proof attempts were made: |
| 44 | +- **Attempt 1**: Explicit state chain with raw `Nat.land`/`Nat.xor` — 6 errors including |
| 45 | + notation mismatches (`&&&` vs `Nat.land`) and getVar/setVar resolution failures. |
| 46 | +- **Attempt 2**: Restructured with fuel decomposition (`obtain ⟨ef, rfl⟩`) and concrete |
| 47 | + `Nat.succ` fuel — timed out at 200k heartbeats on `simpa [compiledIR] using hslack`, |
| 48 | + `simp [YulStmt.block.sizeOf_spec]`, and `set state1 := ...`. |
| 49 | +- **Attempt 3**: Considered increased heartbeats (800k) and early `by_cases` on |
| 50 | + `wordOffset == 0` to avoid conditional terms, but fundamental timeout on term-level |
| 51 | + `sizeOf` computation with abstract subexpressions remains. |
| 52 | +**Root causes**: |
| 53 | + 1. `execIRStmts` requires `Nat.succ` fuel at each cons, needing explicit fuel |
| 54 | + decomposition that triggers `sizeOf` computation timeouts. |
| 55 | + 2. The bitwise identity `storedIR = packedWordWrite oldWordNat valueNat packed` |
| 56 | + requires bridging IR builtins (`Nat.xor`, `Nat.land`, `Nat.lor` with `% evmModulus`) |
| 57 | + and Uint256 operations (`Uint256.not`, `Uint256.and`, `Uint256.or`, `Uint256.shl`). |
| 58 | +**Fix**: Create a dedicated helper theorem in FunctionBody.lean (similar to |
| 59 | +`execIRStmts_let_then_sstore_lit_ident_slots_continue`) that proves the 5-statement |
| 60 | +packed word block body execution with its own `maxHeartbeats` budget. This isolates |
| 61 | +the expensive term reduction. The bitwise identity also needs a separate lemma. |
| 62 | + |
| 63 | +### 3. setStorageAddr — Address modulus (line 9944) |
58 | 64 | **Theorem**: `stmtListGenericCore_singleton_setStorageAddr_singleSlot` |
59 | | -**Blocker**: `runtimeStateMatchesIR_writeAddressSlot` needs `value < Address.modulus` |
60 | | -(2^160) but `evalExpr` only gives `< evmModulus` (2^256). Source semantics truncates |
61 | | -to 160 bits via `wordToAddress` but IR stores full 256 bits. |
| 65 | +**Blocker**: Depends on `compiledStmtStep_setStorageAddr_singleSlot_preserves` (TYPESIG_SORRY |
| 66 | +at line 6134). That theorem needs `runtimeStateMatchesIR_writeAddressSlot` which requires |
| 67 | +`value < Address.modulus` (2^160), but `evalExpr` only gives `< evmModulus` (2^256). |
| 68 | +Source semantics truncates to 160 bits via `wordToAddress` but IR stores full 256 bits. |
62 | 69 | **Fix**: Either add a truncation step in the IR compilation of address storage, or |
63 | 70 | add a hypothesis that the value is already within address range. |
64 | 71 |
|
65 | | -### 5. setMappingPackedWord singleton (line 10541) |
| 72 | +### 4. setMappingPackedWord singleton (line 10548) |
66 | 73 | **Theorem**: `stmtListGenericCore_singleton_setMappingPackedWordSingle_of_slotSafety` |
67 | | -**Blocker**: Depends on #3 being resolved first (the `_preserves` theorem it wraps). |
| 74 | +**Blocker**: Depends on #2 being resolved first (the `_preserves` theorem it wraps). |
68 | 75 |
|
69 | 76 | ## Root Causes Summary |
70 | 77 |
|
71 | 78 | | Root Cause | Sorries Blocked | Fix Complexity | |
72 | 79 | |-----------|----------------|----------------| |
73 | 80 | | ~~Keccak FFI opaque output bounds~~ | ~~#3, #5, #6, #7~~ | ~~RESOLVED: added axiom~~ | |
74 | 81 | | ~~TYPESIG_SORRY dependency (aliasSlots)~~ | ~~#8~~ | ~~RESOLVED: proved chain~~ | |
75 | | -| `evalExpr` Option Nat API rewrite | #3, #5 | ~180 lines of proof rewriting | |
76 | | -| ExprCompileCore missing constructors | #1 | 20+ new constructors + proofs | |
77 | | -| `__immutable_*` field prefix | #2 | Validation pipeline change | |
78 | | -| Address modulus semantic mismatch | #4 | IR compilation change or hypothesis | |
| 82 | +| ~~ExprCompileCore missing constructors~~ | ~~#1~~ | ~~RESOLVED: added constructors~~ | |
| 83 | +| `execIRStmts` 5-stmt block + bitwise identity | #2, #4 | Dedicated helper theorem + bitwise lemma | |
| 84 | +| `__immutable_*` field prefix | #1 | Validation pipeline change | |
| 85 | +| Address modulus semantic mismatch | #3 | IR compilation change or hypothesis | |
79 | 86 |
|
80 | 87 | ## Conclusion |
81 | 88 |
|
82 | | -The sorry count has been reduced from 44 to 5 (89% reduction). The remaining 5 sorries |
| 89 | +The sorry count has been reduced from 44 to 4 (91% reduction). The remaining 4 sorries |
83 | 90 | fall into three categories: |
84 | 91 |
|
85 | | -1. **Proof rewrite needed** (#3, #5): The `setMappingPackedWord` proof exists but uses a |
86 | | - stale API (`evalExpr : Nat` vs `Option Nat`). Rewriting is feasible but requires ~180 |
87 | | - lines of intricate IR state stepping. This is the most tractable remaining work. |
| 92 | +1. **Proof infrastructure needed** (#2, #4): The `setMappingPackedWord` proof requires a |
| 93 | + dedicated helper theorem for the 5-statement block body execution (to isolate the |
| 94 | + expensive `sizeOf`/fuel computation within its own heartbeat budget) plus a bitwise |
| 95 | + identity lemma bridging IR and Uint256 operations. This is the most tractable remaining |
| 96 | + work but requires adding ~100 lines of helper infrastructure in FunctionBody.lean. |
88 | 97 |
|
89 | | -2. **Genuinely unprovable** (#1, #2): These require upstream code changes to |
90 | | - `ExprCompileCore` or the field validation pipeline. |
| 98 | +2. **Genuinely unprovable** (#1): The `__immutable_*` field prefix issue requires upstream |
| 99 | + changes to the field validation pipeline classification. |
91 | 100 |
|
92 | | -3. **Semantic mismatch** (#4): The Address modulus gap (2^160 vs 2^256) requires either |
| 101 | +3. **Semantic mismatch** (#3): The Address modulus gap (2^160 vs 2^256) requires either |
93 | 102 | IR compilation changes or a stronger hypothesis about address values. |
0 commit comments