Skip to content

Fix eqModACRect renaming check and Injectivity success_3 expectation - #890

Merged
mezpusz merged 1 commit into
vprover:masterfrom
shalashaska117:fix-eqmodacrect-renaming
Jul 29, 2026
Merged

Fix eqModACRect renaming check and Injectivity success_3 expectation#890
mezpusz merged 1 commit into
vprover:masterfrom
shalashaska117:fix-eqmodacrect-renaming

Conversation

@shalashaska117

@shalashaska117 shalashaska117 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Fixes #889.

TestUtils::eqModAC_ opened with

if (lhs == rhs) { return true; }

On shared terms that is pointer equality, and it returned without recording the variable renaming, so eqModACRect accepted clause pairs that are not equal up to renaming whenever the two happened to share a subterm.

success_3 in tInferences_HOL_Injectivity was riding on that. Its input makes f injective in its second argument, so the left inverse is inv(x, f(x,z)) = z, but the expectation was copied from success_2 and says inv(z, f(x,z)) = x. Which clause Injectivity derives depends on the evaluation order of the two operands of !=, because equality arguments are normalised by term id. clang derives inv(X0, f(X0,X2)) = X2, which shares f(X0,X2) with the expectation and short-circuits, so CI stayed green. gcc derives inv(X0, f(X0,X1)) = X1, and the test fails.

Three changes:

  • Drop the fast path in eqModAC_.
  • Correct the success_3 expectation.
  • Fix the TermList overload of eqModACRect, which collected vr from lhs and so compared lhs against itself in its variable count guard. Nothing in the suite goes through that overload, so it is a separate bug I noticed while reading rather than something this PR needed.

Checked with gcc 15.2, Debug: 97/97 in about 20s, unchanged from before, so no other test was relying on the fast path.

With the fast path gone the old expectation also fails under clang's ordering. I reproduced that ordering under gcc by swapping the written order of the two operands, which builds the same clause but reverses the creation order:

[     case ]: { X1 = X2 | ~(f @ X0 @ X2 = f @ X0 @ X1) }
[       is ]: [ { inv_f_0 @ X0 @ (f @ X0 @ X2) = X2 } ]
[ expected ]: exactly: [ { inv_f_0 @ X2 @ (f @ X0 @ X2) = X0 } ]
[ FAIL ] success_3

Disclosure: I used AI to generate this PR text. The code has been wrote by myself.

eqModAC_ returned early on syntactically identical subterms without
checking them against the renaming it was building up, so two clauses
that shared a subterm could compare equal even when no consistent
renaming existed.

success_3 in tInferences_HOL_Injectivity relied on that. Its expected
clause was copied from success_2, which inverts the first argument of f,
but its input makes f injective in the second. Which clause Injectivity
derives depends on argument evaluation order, because equality arguments
are normalised by term id: clang puts f(X0,X2) on the lhs and derives
inv(X0, f(X0,X2)) = X2, which shares f(X0,X2) with the expectation and
short-circuits. gcc puts f(X0,X1) there, derives inv(X0, f(X0,X1)) = X1,
and fails.

Also fixes the TermList overload of eqModACRect collecting vr from lhs.

Closes vprover#889

@mezpusz mezpusz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The tests are seemingly not slowed down by the removed check, so I approve. Thanks for the fix!

@mezpusz
mezpusz merged commit 9215937 into vprover:master Jul 29, 2026
1 check passed
@mezpusz

mezpusz commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

This should also fix the coverage build, rerunning now 🤞 https://github.com/vprover/vampire/actions/runs/30460258799

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.

eqModACRect accepts clauses that are not equal up to renaming; Injectivity success_3 fails on gcc

2 participants