Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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