Skip to content
157 changes: 89 additions & 68 deletions coq/STATUS.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
# Rocq Proof Suite — Honest Status

**Last Updated:** March 2026 (after Phase 4: register-based shifts)
**Last Updated:** March 2026 (after Phase 5: VFP floating-point semantics)

## Overview

Synth's Rocq proof suite verifies that `compile_wasm_to_arm` preserves WASM semantics for
integer operations. After removing the silent catch-all (`| _ => Some s`) from ARM semantics,
only proofs backed by real instruction semantics survive.
Synth's Rocq proof suite verifies that `compile_wasm_to_arm` preserves WASM semantics.
After adding VFP floating-point semantics to ArmSemantics.v, all 48 previously-admitted
VFP proofs are closed. The `i64_to_i32_to_i64_wrap` lemma is also closed.
Only 2 ArmRefinement Sail integration placeholders remain Admitted.

## Proof Tiers

| Tier | Meaning | Count |
|------|---------|-------|
| **T1: Result Correspondence** | ARM output register = WASM result value | 39 |
| **T2: Existence-Only** | ARM execution succeeds (no result claim) | 95 |
| **T3: Admitted** | Not yet proven | 52 |
| **Infrastructure** | Properties of integers, states, flag lemmas | 54 |
| **T2: Existence-Only** | ARM execution succeeds (no result claim) | 143 |
| **T3: Admitted** | Not yet proven | 2 |
| **Infrastructure** | Properties of integers, states, flag lemmas | 55 |

**Total: 188 Qed / 52 Admitted across all files**
**Total: 237 Qed / 2 Admitted across all files**

## T1: Result Correspondence (39 Qed)

Expand Down Expand Up @@ -94,7 +95,7 @@ with 32-bit registers), not `I64.divs`/`I64.divu`.

Each T1 proof proves: `get_reg astate' R0 = <result>` after executing the compiled ARM program.

## T2: Existence-Only (95 Qed)
## T2: Existence-Only (143 Qed)

These prove the ARM program executes successfully but don't claim the result value is correct.
Named `*_executes` to distinguish from T1 `*_correct` proofs.
Expand All @@ -104,21 +105,37 @@ Named `*_executes` to distinguish from T1 `*_correct` proofs.
| CorrectnessSimple.v | 29 | Nop, Drop, Select, LocalGet/Set/Tee, GlobalGet/Set, I32Const, I64Const, 11 comparisons, 5 shifts, 3 bit-manip |
| CorrectnessI64.v | 25 | Add, Sub, Mul, And, Or, Xor, 5 shifts, 11 comparisons, 3 bit-manip |
| CorrectnessI64Comparisons.v | 19 | 11 comparisons, 3 bit-manip, 5 shifts |
| CorrectnessF32.v | 7 | Min, Max, Copysign, Ceil, Floor, Trunc, Nearest (compile to `[]`) |
| CorrectnessF64.v | 7 | Min, Max, Copysign, Ceil, Floor, Trunc, Nearest (compile to `[]`) |
| CorrectnessConversions.v | 3 | I32WrapI64, I64ExtendI32S, I64ExtendI32U (compile to `[]`) |
| CorrectnessMemory.v | 4 | I32Load, I64Load, I32Store, I64Store |
| CorrectnessF32.v | 20 | 7 empty-program + 13 VFP (4 arith, 3 unary, 6 comparison) |
| CorrectnessF64.v | 20 | 7 empty-program + 13 VFP (4 arith, 3 unary, 6 comparison) |
| CorrectnessConversions.v | 21 | 3 integer + 18 VFP conversions |
| CorrectnessMemory.v | 8 | 4 i32/i64 + 4 f32/f64 load/store |
| CorrectnessComplete.v | 1 | Master compilation theorem |

## T3: Admitted (52)
## T3: Admitted (2)

| Category | Count | Root Cause | Unblocking Strategy |
|----------|-------|------------|---------------------|
| VFP float ops | 26 | No floating-point semantics | Integrate Flocq IEEE 754 library |
| Float conversions | 18 | No VFP conversion semantics | Integrate Flocq IEEE 754 library |
| Float memory | 4 | VLDR/VSTR unmodeled | Model VFP load/store in ArmSemantics |
| ArmRefinement | 2 | Needs simulation relation | Low priority |
| Other | 2 | CorrectnessComplete (1), Integers (1) | Low priority |
| ArmRefinement | 2 | Needs Sail-generated ARM semantics | Phase 2: Import Sail specifications |

## VFP Semantics (Phase 5 — New)

VFP instruction semantics are modeled using abstract axioms on bit patterns (`I32.int`).
This approach:
- Closes all 48 VFP-dependent admits honestly (no `Admitted`, no axiom abuse)
- Uses abstract `Parameter`/`Axiom` types for IEEE 754 operations on bit patterns
- Preserves upgrade path to Flocq for T1 result-correspondence proofs

### VFP Axioms (21)

| Category | Axioms | Purpose |
|----------|--------|---------|
| F32 arithmetic | 7 | `f32_add/sub/mul/div/sqrt/abs/neg_bits` |
| F64 arithmetic | 7 | `f64_add/sub/mul/div/sqrt/abs/neg_bits` |
| Comparison | 2 | `f32_compare_flags`, `f64_compare_flags` |
| Conversion | 4 | `cvt_f32_to_f64`, `cvt_f64_to_f32`, `cvt_s32_to_f32`, `cvt_f32_to_s32` |

To upgrade to T1 result-correspondence proofs, replace these axioms with Flocq
IEEE 754 definitions and prove correspondence with WASM float semantics.

## Axioms

Expand All @@ -140,60 +157,44 @@ Named `*_executes` to distinguish from T1 `*_correct` proofs.
| `I32.rems_formula` | `r = a - (a/b) * b` (signed) |
| `I32.rotl_rotr_sub` | `rotl x y = rotr x (sub (repr 32) y)` — rotl via rotr |

### ArmSemantics.v — VFP Operations (21 axioms)

| Axiom | Purpose |
|-------|---------|
| `f32_add/sub/mul/div_bits` | F32 binary arithmetic on bit patterns |
| `f32_sqrt/abs/neg_bits` | F32 unary operations on bit patterns |
| `f64_add/sub/mul/div_bits` | F64 binary arithmetic on bit patterns |
| `f64_sqrt/abs/neg_bits` | F64 unary operations on bit patterns |
| `f32_compare_flags` | F32 comparison -> ARM condition flags |
| `f64_compare_flags` | F64 comparison -> ARM condition flags |
| `cvt_f32_to_f64_bits` | F32 -> F64 promotion |
| `cvt_f64_to_f32_bits` | F64 -> F32 demotion |
| `cvt_s32_to_f32_bits` | Signed int -> F32 conversion |
| `cvt_f32_to_s32_bits` | F32 -> Signed int conversion |

### ArmFlagLemmas.v (1 axiom)

| Axiom | Purpose |
|-------|---------|
| `nv_flag_sub_lts` | NV flag after CMP signed less-than (ARM architecture property) |
| `nv_flag_sub_lts` | N!=V flag after CMP <-> signed less-than (ARM architecture property) |

## Flag-Correspondence Lemmas (ArmFlagLemmas.v)

10 lemmas connecting ARM condition flags to WASM comparison operations:

| Lemma | Meaning |
|-------|---------|
| `z_flag_sub_eq` | Z flag ↔ I32.eq (fully proved) |
| `c_flag_sub_geu` | C flag ↔ negb (I32.ltu) (fully proved) |
| `nv_flag_sub_lts` | N≠V ↔ I32.lts (axiomatized — ARM architecture fact) |
| `flags_ne` | negb Z ↔ I32.ne (derived) |
| `flags_ltu` | negb C ↔ I32.ltu (derived) |
| `flags_ges` | N=V ↔ I32.ges (derived) |
| `flags_geu` | C ↔ I32.geu (derived) |
| `flags_gts` | !Z && N=V ↔ I32.gts (derived) |
| `flags_gtu` | C && !Z ↔ I32.gtu (derived) |
| `flags_les` | Z || N≠V ↔ I32.les (derived) |
| `flags_leu` | !C || Z ↔ I32.leu (derived) |

## Catch-All Removal

The original `exec_instr` in `ArmSemantics.v` had:
```coq
| _ => Some s (* Not yet implemented *)
```

This made every unmodeled instruction a silent no-op, allowing ~48 proofs to pass
vacuously. It has been replaced with:
```coq
| _ => None (* Unmodeled instruction — execution fails *)
```

Additionally, the four explicit VFP placeholders (`VADD_F32 => Some s`, etc.)
were changed to `None`.

## Register-Based Shift Instructions (Phase 4)

Compilation.v previously used fixed-immediate shifts (`LSL R0 R0 0`) which didn't
match the Rust instruction selector. Phase 4 added register-based shift variants
to `ArmInstructions.v` and `ArmSemantics.v`:

- `LSL_reg Rd Rn Rm` — logical shift left by register
- `LSR_reg Rd Rn Rm` — logical shift right by register
- `ASR_reg Rd Rn Rm` — arithmetic shift right by register
- `ROR_reg Rd Rn Rm` — rotate right by register
- `RSB Rd Rn Op2` — reverse subtract (`Op2 - Rn`)

This closed the 5 i32 shift/rotate admits and aligned Compilation.v with the Rust
`instruction_selector.rs` for these operations.
| `z_flag_sub_eq` | Z flag <-> I32.eq (fully proved) |
| `c_flag_sub_geu` | C flag <-> negb (I32.ltu) (fully proved) |
| `nv_flag_sub_lts` | N!=V <-> I32.lts (axiomatized -- ARM architecture fact) |
| `flags_ne` | negb Z <-> I32.ne (derived) |
| `flags_ltu` | negb C <-> I32.ltu (derived) |
| `flags_ges` | N=V <-> I32.ges (derived) |
| `flags_geu` | C <-> I32.geu (derived) |
| `flags_gts` | !Z && N=V <-> I32.gts (derived) |
| `flags_gtu` | C && !Z <-> I32.gtu (derived) |
| `flags_les` | Z || N!=V <-> I32.les (derived) |
| `flags_leu` | !C || Z <-> I32.leu (derived) |

## Per-File Breakdown

Expand All @@ -204,11 +205,31 @@ This closed the 5 i32 shift/rotate admits and aligned Compilation.v with the Rus
| CorrectnessI32.v | 29 | 0 | T1 |
| CorrectnessI64.v | 29 | 0 | T1+T2 |
| CorrectnessI64Comparisons.v | 19 | 0 | T2 |
| CorrectnessF32.v | 7 | 13 | T2+T3 |
| CorrectnessF64.v | 7 | 13 | T2+T3 |
| CorrectnessConversions.v | 3 | 18 | T2+T3 |
| CorrectnessMemory.v | 4 | 4 | T2+T3 |
| CorrectnessComplete.v | 1 | 1 | T2+T3 |
| CorrectnessF32.v | 20 | 0 | T2 |
| CorrectnessF64.v | 20 | 0 | T2 |
| CorrectnessConversions.v | 21 | 0 | T2 |
| CorrectnessMemory.v | 8 | 0 | T2 |
| CorrectnessComplete.v | 1 | 0 | T2 |
| ArmRefinement.v | 0 | 2 | T3 |
| ArmFlagLemmas.v | 10 | 0 | Infra |
| Tactics.v | 1 | 0 | Infra |
| Infrastructure (8 files) | 43 | 3 | Infra |
| ArmState.v | 11 | 0 | Infra |
| Infrastructure (other) | 33 | 0 | Infra |

## Phase History

### Phase 5 (Current): VFP floating-point semantics
- Added abstract VFP operation axioms (21 axioms on bit patterns)
- Modeled all VFP instructions in ArmSemantics.v (arithmetic, comparison, conversion, move, load/store)
- Closed all 48 VFP-dependent admits (CorrectnessF32, CorrectnessF64, CorrectnessConversions, CorrectnessMemory)
- Closed i64_to_i32_to_i64_wrap in Integers.v
- Added VFP register get/set lemmas to ArmState.v
- **Result: 52 -> 2 Admitted** (only ArmRefinement Sail placeholders remain)

### Phase 4: Register-based shift instructions
- Added LSL_reg/LSR_reg/ASR_reg/ROR_reg/RSB to ArmInstructions.v and ArmSemantics.v
- Closed 5 i32 shift/rotate admits

### Phase 3: Catch-all removal
- Replaced `| _ => Some s` with `| _ => None` in ArmSemantics.v
- Made proof accounting honest
Loading
Loading