Skip to content

SAWCore fixes for variable name shadowing - #2961

Merged
brianhuffman merged 9 commits into
masterfrom
bh/varname-shadowing
Jan 15, 2026
Merged

brianhuffman merged 9 commits into
masterfrom
bh/varname-shadowing

Conversation

@brianhuffman

Copy link
Copy Markdown
Contributor

This PR fixes a few different SAWCore functions so that they work correctly on terms that have variable name shadowing.

  • scMatch
  • scmConvertible
  • alphaEquiv

Fixes #2939. Fixes #2954.

Currently marked as draft until I replace [VarName] with a more efficient data structure for representing bound variable contexts.

@brianhuffman brianhuffman changed the title Bh/varname shadowing SAWCore fixes for variable name shadowing Jan 9, 2026
@brianhuffman
brianhuffman force-pushed the bh/varname-shadowing branch 3 times, most recently from fa78881 to 10dee9d Compare January 9, 2026 23:18
@brianhuffman
brianhuffman force-pushed the bh/varname-shadowing branch 3 times, most recently from fa47bc1 to a9b1341 Compare January 13, 2026 00:40
@brianhuffman

brianhuffman commented Jan 13, 2026 •

Copy link
Copy Markdown
Contributor Author

I located the problem with the ECDSA proof. In the ec_mul_ov subproof, after proving the first proof obligation, the Haskell evidence-checking function convertibleProps calls scConvertible on a pair of very large terms taken from the proof goal. (How big? See #2965.)

convertibleProps :: SharedContext -> [Prop] -> [Prop] -> IO Bool
convertibleProps _sc [] [] = return True
convertibleProps sc (p1:ps1) (p2:ps2) =
do ok1 <- scConvertible sc True (unProp p1) (unProp p2)
ok2 <- convertibleProps sc ps1 ps2
return (ok1 && ok2)
convertibleProps _sc _ _ = return False

Function scConvertible has a "succeed early" case that returns True immediately if the two terms are the same.

convertibleProps :: SharedContext -> [Prop] -> [Prop] -> IO Bool
convertibleProps _sc [] [] = return True
convertibleProps sc (p1:ps1) (p2:ps2) =
do ok1 <- scConvertible sc True (unProp p1) (unProp p2)
ok2 <- convertibleProps sc ps1 ps2
return (ok1 && ok2)
convertibleProps _sc _ _ = return False

However, this PR made this short-cut case a bit more conservative in the presence of free variables, forcing scConvertible to traverse the terms instead down to the point where it was comparing closed subterms. The real problem is that scConvertible does not take advantage of observable sharing, and the fully-expanded terms are so astronomically large that the term traversal will never finish in practice.

The quick fix is to strengthen the shortcut case so that it applies at least as often as it used to. However, this is really quite fragile: A mismatch in bound variable names somewhere would cause the super-exponential runtime again. The better fix is to make scConvertible use observable sharing to fix the useless slow code path.

Also make early-success condition more precise, to match its
earlier behavior.
We also modify the "succeed early" test to be as precise as
it was before: The terms are not required to be closed, they
just need to avoid the names in the context.
We also update the succeed-early test to be more precise:
We don't require the terms to be closed, they just have
to avoid variables from the context.
@brianhuffman
brianhuffman marked this pull request as ready for review January 15, 2026 00:47
@brianhuffman
brianhuffman merged commit 686be09 into master Jan 15, 2026
93 of 96 checks passed
@brianhuffman
brianhuffman deleted the bh/varname-shadowing branch January 15, 2026 05:47
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.

SAWCore alphaEquiv function is incorrect Unusability of simple proof goals and simplification rules

2 participants