Skip to content

Disable non-linear arithmetic in 17 verification packages - #435

Draft
jcp19 wants to merge 3 commits into
masterfrom
claude/scion-nonlinear-arithmetic-verify-1wj115
Draft

Disable non-linear arithmetic in 17 verification packages#435
jcp19 wants to merge 3 commits into
masterfrom
claude/scion-nonlinear-arithmetic-verify-1wj115

Conversation

@jcp19

@jcp19 jcp19 commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

This change disables Gobra's non-linear arithmetic (--disableNL) for 17 of 20 verification packages by adding gobra.json configuration files. Three packages (verification, private/underlay/conn, and router) retain non-linear arithmetic support due to nested wildcard permission patterns in their specifications that require it.

Key Changes

  • Added a comprehensive analysis document (verification/notes/disabling-nonlinear-arithmetic.md) documenting:

    • The impact of disabling non-linear arithmetic on the verification suite
    • Root cause analysis: nested wildcard permissions create non-linear real arithmetic constraints in the permission algebra
    • Detailed test results showing 17 of 20 jobs pass unchanged, while 3 fail with 15 permission-related errors
    • Performance analysis indicating no measurable impact on verification times
    • Evaluation of potential mitigations
  • Added gobra.json configuration files to 17 packages with --disableNL flag:

    • pkg/addr, pkg/experimental/epic, pkg/log, pkg/private/serrors, pkg/scrypto
    • pkg/slayers and all its subpackages (path, path/empty, path/epic, path/onehop, path/scion)
    • private/topology, private/topology/underlay, private/underlay/sockctrl
    • router/bfd, router/control
    • verification/dependencies/github.com/google/gopacket/layers

Implementation Details

  • The root cause is that folding/unfolding predicates held with wildcard permissions scales nested acc(x.f, _) expressions to products of symbolic variables (w1 * w2), which requires non-linear real arithmetic support in Z3
  • Per-package opt-in configuration was chosen over module-level configuration because Gobra's disableNL option lacks a counterpart to re-enable it at the job level
  • Three packages deliberately omit the flag to maintain verification of specs with nested wildcard patterns
  • Performance testing shows no measurable impact on verification times across the pkg/slayers tree

https://claude.ai/code/session_01QsWWKHMTrgrprseiCdh59g

claude added 2 commits August 18, 2026 10:35
Records an experiment replaying all 20 Gobra jobs from the CI workflow with
--disableNL added to gobra-mod.json. Seventeen pass unchanged; verification,
private/underlay/conn and router fail with 15 errors between them.

Every error comes from Viper's permission algebra rather than from integer
arithmetic in the SCION proofs: folding or unfolding a predicate held with
acc(P(), _) whose body also holds acc(..., _) scales one wildcard by another,
and Z3 stops discharging the resulting product once smt.arith.nl is off. The
note pins this down with a 12-line Viper reproduction and the SMT goal that
flips, and evaluates three ways around it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsWWKHMTrgrprseiCdh59g
Seventeen of the twenty Gobra jobs in the CI workflow verify unchanged with
Z3's non-linear arithmetic switched off. Each of them now opts in through a
gobra.json holding `--disableNL`.

The three that are left alone -- verification, private/underlay/conn and
router -- fail without it, in every case because folding or unfolding a
predicate held with acc(P(), _) whose body also holds acc(..., _) scales one
wildcard by another, and Z3 stops discharging that product. The accompanying
note records the analysis.

Opting in per package is forced by the option itself: disableNL has no
--nodisableNL counterpart and is folded in disjunctively, so a flag set once in
gobra-mod.json could not be cleared for the three exceptions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsWWKHMTrgrprseiCdh59g
Comment on lines +44 to +49
| `private/topology/underlay` | PASS | PASS |
| `private/underlay/conn` | PASS 44s | **FAIL — 6 errors** |
| `private/underlay/sockctrl` | PASS | PASS |
| `router/bfd` | PASS | PASS |
| `router/control` | PASS | PASS |
| `router` | PASS 4157s | **FAIL — 8 errors, 1264s** |

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file can be dropped

--unsafeWildcardOptimization also clears the router's 8 errors, so the approach
is not limited to the two small jobs. It is not a speed-up though: the router
takes 4442s with it against 4157s for the configuration CI runs today, which
matches the slayers numbers, where all four configurations landed within noise
of each other.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsWWKHMTrgrprseiCdh59g
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants