v1.8.0 (FEAT-016 slice-2b-ii): octagon relational product wired into the analyzer#43
Merged
Conversation
The octagon relational domain is now carried through the structured-CFG interpreter, so a loop counter bounded by a VARIABLE relation (i < n, n not constant) stays bounded where the interval domain + constant-guard refinement alone widen it to ⊤. This moves the FEAT-016 acceptance criterion (a relational constraint between two locals preserved across loop iterations without false widening) → FEAT-016 status implemented. Integration (crates/scry-analyze-core): - FuncCtx.octagon (dim = #locals), joined/widened/NARROWED in lockstep with the interval locals at every merge point (block exit; loop entry⊔back-edges; widen threshold; narrowing phase — octagon widening drops the slowly-growing i-n bound to ⊤ exactly like intervals, narrowing re-derives it). Break-state carries the octagon too. - try_guard_brif_rel: `local.get A; local.get B; cmp; br_if D` adds the octagon difference constraint A-B≤c on each edge (the variable-relation case the v1.6 constant peephole can't reach). - octagon_transfer / classify_store: local.set/tee classified by look-behind into x:=c / x:=y / x:=y±c (incl. the increment shift). SAFETY NET: any write the transfer doesn't model FORGETs that variable's relations; br_table / unsupported → octagon reset to ⊤. - reduce_locals / inject_intervals: reduced product at emission — inject interval bounds into the octagon, close, project back, meet (i≤n ∧ n≤10 ⟹ i≤10; no WIT change). Loop entry octagon seeded with entry interval bounds so the relation survives the first join. A top octagon projects to identity, so prior interval-only behaviour is preserved exactly. fixture-11-var-bound (counter bounded by i<n, n in a local) → i converges to [0,10] (hi≤10). Native oracle feat016_octagon_var_bounds_counter; fixture added to the live scry-mcdc corpus (proved 164→180 mac, floor held 155). Soundness composes proven/falsified pieces at the established merge points: v1.7 γ-tested octagon transfers + OctagonProject.v projection rounding + LoopFixpoint.v post-fixpoint (instantiated at the octagon transfer); host oracle over all fixtures is the integration gate. SCRY_VERSION → 1.8.0; CHANGELOG [1.8.0] + falsification; FEAT-016 → implemented (slice-3 Miné closure, AC-011, remains as precision-only follow-up). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
📐 rivet artifact deltaPR: #43 Base SHA: Validationhead — `rivet validate` resultbase — `rivet validate` result (for comparison)Artifact stats
full stats — headDiff (base → head)AADL model — headPosted by the |
The v1.8.0 octagon integration added `scry-octagon` to scry-analyze-core's Cargo.toml but not its Bazel BUILD deps; Bazel uses explicit BUILD deps, so the `//:scry` component build (and the Test job that builds it first) failed with `error[E0432]: unresolved import scry_octagon`. Add `//crates/scry-octagon:scry_octagon` to the deps (scry-octagon is a local crate with public visibility, so no crate_universe/MODULE.bazel regeneration). Native cargo + clippy already resolved it via Cargo.toml. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Summary
The octagon relational domain is now carried through the structured-CFG interpreter, so a loop counter bounded by a variable relation (
i < n,nnot constant) stays bounded — where the interval domain + v1.6 constant-guard refinement alone widen it to ⊤. This moves the FEAT-016 acceptance criterion (a relational constraint between two locals preserved across loop iterations without false widening), so FEAT-016 →implemented.Builds on the v1.7 octagon primitives (#42).
What changed —
crates/scry-analyze-coreFuncCtx.octagon(dim = local count), joined / widened / narrowed in lockstep with the interval locals at every merge point — block exit, the loopentry ⊔ back-edgesjoin, the widening threshold, and the narrowing phase. Octagon widening drops the slowly-growingi − nbound to ⊤ exactly as interval widening drops a counter, so narrowing (v1.7'snarrow) is what re-derives it. The branch break-state carries the octagon too.try_guard_brif_rel—local.get A; local.get B; <signed cmp>; br_if Dadds the octagon difference constraintA − B ≤ con each edge (the variable-relation case the constant peephole can't reach).octagon_transfer/classify_store— alocal.set/local.teeis classified by look-behind intox := c/x := y/x := y ± c(the in-place increment uses v1.7's shift). Safety net: any write the transfer does not modelforgets that variable's relations — never retain a stale one.br_table/unsupported → octagon reset to ⊤.reduce_locals/inject_intervals— reduced product at emission: inject interval bounds into the octagon, close, project back,meet(i ≤ n ∧ n ≤ 10 ⟹ i ≤ 10; no WIT change). The loop entry octagon is seeded with the entry interval bounds so the relation survives the first join. Atopoctagon projects to the identity, so all prior interval-only behaviour is preserved exactly.Evidence
fixture-11-var-bound(counter bounded byi < n,nin a local) + native oraclefeat016_octagon_var_bounds_counter:iconverges to[0,10](hi ≤ 10), where interval + constant-guard alone give ⊤.OctagonProject.vprojection rounding (proj_interval_sound);LoopFixpoint.vpost-fixpoint soundness (loop_postfixpoint_sound) instantiated at the octagon transfer; injecting true interval bounds only tightens. The integration gate is the host soundness oracle over the whole fixture corpus (abstract ⊒ concrete) + the forget-on-unmodelled-write net.Falsification statement
A loop counter bounded by a variable relation
i < nconverges to a finite interval, soundly. Falsifier:fixture-11-var-boundcountsiup whilei < nwithn = 10in a local; if the analyzer reportsias ⊤ after the loop, or if the concrete10falls outsidei's interval, the claim is false. Does not claim Miné strong/tight closure (AC-011, the remaining slice-3) or relations beyond a single guarded-counter difference.Scope
FEAT-016 →
implemented(AC met). Slice-3 (Miné strong closure) remains as a precision-only follow-up.🤖 Generated with Claude Code