Skip to content

Commit d52b735

Browse files
committed
docs: update sorry reduction plan to reflect 4-sorry state with detailed analysis
Update the plan after proving sorry #1 (exprCompileCore) in commit 08b717e, bringing the count from 5 to 4. Document three failed attempts at sorry #2 (setMappingPackedWord) with root cause analysis: execIRStmts fuel chaining timeouts and bitwise identity gap. All 4 remaining sorries are architecturally blocked. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 90d2f6b commit d52b735

1 file changed

Lines changed: 50 additions & 41 deletions

File tree

docs/SORRY_REDUCTION_PLAN.md

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Sorry Reduction Plan — Pass 5
22

3-
## Current State (as of commit 7dee40c3)
3+
## Current State (as of commit 08b717e3)
44

5-
**Active `sorry`**: 5 (all in `GenericInduction.lean`)
5+
**Active `sorry`**: 4 (all in `GenericInduction.lean`)
66
**TYPESIG_SORRY blocks**: ~57 commented-out theorems with broken type signatures
77
**Build status**: Green (compiles with warnings only)
88

@@ -21,73 +21,82 @@
2121
| `a4c29009` | 10 | bridge theorems (LegacyCompatible + CallsDisjoint) + 3 downstream (−3) |
2222
| `66236a18` | 6 | Add keccak axiom `solidityMappingSlot_add_wordOffset_lt_evmModulus` + prove 4 mapping slot wordOffset≠0 sorries (−4) |
2323
| `7dee40c3` | 5 | Prove aliasSlots TYPESIG_SORRY chain: 3 theorems uncommented (−1) |
24+
| `08b717e3` | 4 | Add ExprCompileCore bitwise constructors, prove exprCompileCore_of_exprTouchesUnsupportedContractSurface (−1) |
2425

25-
## Remaining 5 Sorries — Architecturally Blocked
26+
## Remaining 4 Sorries — Architecturally Blocked
2627

2728
Every remaining sorry depends on fundamental design issues that cannot be resolved
2829
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)
4133
**Theorem**: `validateIdentifierShapes_fieldName_avoidReservedCompilerPrefix`
4234
**Blocker**: Claims no field name starts with `"__"`, but `__immutable_*` fields are
4335
explicitly allowed by the validation pipeline.
4436
**Fix**: Thread stronger field-shape classification that distinguishes mutable vs
4537
immutable fields through the generic induction scope invariant.
4638

47-
### 3. setMappingPackedWord (line 7572)
39+
### 2. setMappingPackedWord (line 7467)
4840
**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)
5864
**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.
6269
**Fix**: Either add a truncation step in the IR compilation of address storage, or
6370
add a hypothesis that the value is already within address range.
6471

65-
### 5. setMappingPackedWord singleton (line 10541)
72+
### 4. setMappingPackedWord singleton (line 10548)
6673
**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).
6875

6976
## Root Causes Summary
7077

7178
| Root Cause | Sorries Blocked | Fix Complexity |
7279
|-----------|----------------|----------------|
7380
| ~~Keccak FFI opaque output bounds~~ | ~~#3, #5, #6, #7~~ | ~~RESOLVED: added axiom~~ |
7481
| ~~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 |
7986

8087
## Conclusion
8188

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
8390
fall into three categories:
8491

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.
8897

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.
91100

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
93102
IR compilation changes or a stronger hypothesis about address values.

0 commit comments

Comments
 (0)