Repository navigation
feat(verify): VCR-VER-002 Phase B — float→int trunc trap class via ordeal 0.9.1 (#166) - #742
Merged
Merged
Conversation
… (VCR-VER-002 Phase B, #166) ordeal 0.9.1 (ordeal#59/TR-020) adds the float→int truncation trap CLASSIFIER: the trap predicate (NaN ∨ ±∞ ∨ out-of-range) is built purely over the float operand's BIT PATTERN — exponent-field patterns plus sign-split monotonic magnitude threshold compares. Floats enter as BV32/BV64; no FP theory, pure QF_BV, soundness unchanged (LRAT-certified pipeline). synth_verify::trap Phase B: - `trunc_op(WasmOp) -> Option<(FpFmt, IntTarget, bool)>` maps all six decoder-reachable trunc variants (i32/i64.trunc_f32/f64_s/u; i64.trunc_f32_* are not WasmOp variants — the raw builder still covers those shapes). - `trap_trunc(bits, fmt, target, signed)` wraps ordeal's classifier over synth's BV/Bool; loud width assert (bits must be fmt.total_bits()). - Re-export FpFmt/IntTarget; docs: trunc is trap-clause-only (synth models no float→int value function) — exactly the #709 surface (ARM VCVT saturates where WASM traps). Cargo.toml pin 0.9 → 0.9.1 (trap_trunc is 0.9.1-only; lock already resolves 0.9.1 since #723 — no lock change). Refs #166, #242, ordeal#59 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…val (VCR-VER-002 Phase B, #166) Extends the red-first trap-preservation gate (6 → 11 tests) with the float→int trunc class: - trunc_all_six_ops_catch_the_drop_and_accept_preservation: for every variant a guard-dropping lowering (may_trap=false, the #709 VCVT-saturate shape) is CAUGHT (Dropped/Sat) with the counterexample validated as a genuinely trapping input against the real-float reference; an identical-guard lowering is accepted (Preserved/Unsat, LRAT re-checked). - trunc_signedness_confused_guard_is_caught: an unsigned range guard on i32.trunc_f32_s (partial drop — NaN/∞ kept, thresholds wrong) is Sat, counterexample separates signed from unsigned trapping. - trunc_classifier_eval_matches_709_boundary_table: the encoding- correctness check ordeal#59 called for — ordeal's classifier evaluated via ordeal::eval at the exact #709 bit patterns (2^31/0x4F000000 traps signed, -2^31/0xCF000000 in-range, 3e9/-3e9 trap, NaN/±∞ trap, 2.5 in-range; -1.0 traps unsigned, 0.5/-0.0 in-range, 2^32 traps; plus f64 and i64-target anchors — 31 rows), every row self-checked against the real-float reference so the table cannot drift. - trunc_gate_decides_709_boundary_table_through_certified_pipeline: the same table at GROUND inputs through the synth wrapper — trap_trunc(const) ⇔ expected proven valid per pattern (certified Unsat), with a wrong-expectation non-vacuity control (claiming NaN does not trap is rejected). - trunc_op mapping test for all six WasmOp variants + None cases. Refs #166, #242, ordeal#59 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…166) Roadmap entry: title + description gain the float→int trunc class (LANDED item 5: ordeal 0.9.1 trap_trunc bit-pattern classifier, six WasmOp variants mapped, red-first gate + #709 boundary-table eval both via ordeal::eval and through the certified pipeline); documented-gap and steps/preconditions updated. Status stays `proposed` — the live- validator wiring gap is unchanged (trunc, like load/store / call_indirect / unreachable, is gated at the unit level pending the exec-model trap flag). claims.yaml SYNTH-VCR-VER-002-STATUS: claim text updated to the new title verbatim; evidence unchanged (status=proposed + file-exists). claim_check 18/18. Refs #166, #242, ordeal#59 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
VCR-VER-002 Phase B — the float→int truncation trap class (#166, ordeal#59/TR-020)
Follows #723 (Phase A). ordeal 0.9.1 adds
trap_trunc: the WASMiN.trunc_fM_s/utrap predicate (NaN ∨ ±∞ ∨ out-of-range) classified purely over the float operand's bit pattern — exponent-field patterns + sign-split monotonic magnitude threshold compares. Floats enter as BV32/BV64; no FP theory, pure QF_BV, LRAT-certified pipeline unchanged. This is exactly the #709 soundness surface: ARMVCVTsaturates where WASM must trap, so a lowering that keeps the saturated value and drops the guard is value-equal and invisible to a value-only VC.Wrapper (
crates/synth-verify/src/trap.rs)trunc_op(WasmOp) → Option<(FpFmt, IntTarget, bool)>— maps all six decoder-reachable trunc variants (i32/i64.trunc_f{32,64}_{s,u};i64.trunc_f32_*are notWasmOpvariants, the raw builder still covers those shapes).trap_trunc(bits, fmt, target, signed)— ordeal's classifier over synthBV/Bool, loud width assert. Trap-clause-only VC class (synth models no float→int value function).0.9→0.9.1(trap_truncis 0.9.1-only; the lockfile already resolved 0.9.1 since feat(verify): VCR-VER-002 — trap-preservation gate over ordeal::trap (#166) #723 — no lock change).Red-first gate (
tests/trap_preservation.rs, 6 → 11 tests) — which drops are caughtmay_trap=false), all six variantsDropped/Sat, counterexample validated as genuinely trapping against the real-float referencei32.trunc_f32_s— NaN/∞ kept, thresholds wrong: the partial-drop VCVT shape)Sat, counterexample separates signed from unsigned trappingPreserved/Unsat, LRAT certificate re-checkedClassifier-encoding check (the ordeal#59 ask; synth's #709 table is the reference oracle)
The 31-row #709 boundary table evaluated two ways, every row self-checked against the real-float reference so the table cannot drift:
ordeal::evalon the classifier —i32.trunc_f32_s: NaN / +∞ / −∞ / 3e9 / −3e9 trap, 2^31 (0x4F000000) TRAPS, −2^31 (0xCF000000) in-range, 2.5 in-range;i32.trunc_f32_u: −1.0 traps, 0.5 / −0.0 in-range, 2^32 traps; plus f64 and i64-target boundary anchors (largest-below-threshold floats, ±2^63, 2^64, −(2^31+1), …).trap_trunc(const) ⇔ expectedproven valid per pattern (certified Unsat).Roadmap / claims
VCR-VER-002title + description updated (Phase B landed, LANDED item 5); status staysproposed— the live-validator wiring gap is unchanged (trunc, like load/store / call_indirect / unreachable, is gated at the unit level pending the exec-model trap flag).claims.yamlSYNTH-VCR-VER-002-STATUS text updated verbatim;claim_check18/18.Gates
cargo test -p synth-verify+--test trap_preservation(11/11) greencargo test --workspacegreen (119 test binaries, 0 failures)cargo clippy --workspace --all-targets -- -D warningsclean,cargo fmt --checkcleanpython3 scripts/claim_check.py claims.yaml— 18/18 claims holdRefs #166, #242, ordeal#59. Follows #723.
🤖 Generated with Claude Code
https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L