Skip to content

Fix VC Function Substitution#267

Merged
rcosta358 merged 5 commits into
mainfrom
fix-vc-function-substitution
Jul 20, 2026
Merged

Fix VC Function Substitution#267
rcosta358 merged 5 commits into
mainfrom
fix-vc-function-substitution

Conversation

@rcosta358

Copy link
Copy Markdown
Collaborator

Description

This PR fixes VC function substitution so function equality premises are removed after they are used to rewrite later premises or the conclusion, similarly to normal VC substitution.

Example

f(x) == 0
f(y) == f(x) + 1

simplified to

f(x) == 0
f(y) == 0 + 1

and now simplifies to 

f(y) == 0 + 1

Related Issue

None.

Type of change

  • Bug fix
  • New feature
  • Documentation update
  • Code refactoring

Checklist

  • Added/updated tests
  • mvn test passes locally
  • Updated docs/README if behavior or API changed

@rcosta358 rcosta358 self-assigned this Jun 24, 2026
@rcosta358 rcosta358 added bug Something isn't working simplification Related to the simplification of expressions labels Jun 24, 2026
@rcosta358
rcosta358 force-pushed the fix-vc-function-substitution branch from bdc9dad to 2d2db90 Compare June 24, 2026 16:46

@CatarinaGamboa CatarinaGamboa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm fine if this works. Can you add an issue with this situation so that we know we might still need to fix it down the line?

@rcosta358

Copy link
Copy Markdown
Collaborator Author

Sure.

@CatarinaGamboa CatarinaGamboa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Left a couple comments. Also, it feels like we are always using .clone() is it actually needed? Also we might consider just making it immutable if we are always cloning it.
The tests seek okay Im stamping anyway

* A substitution discovered from a function invocation equality
*/
private record Substitution(VCImplication node, FunctionInvocation invocation, Expression replacement) {
private record Substitution(VCImplication node, FunctionInvocation invocation, Expression replacement,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This could have better name since it's only for the substitution of function invocations from equalities. Think "how should I read this object". Right now is smt like "substitute at the node the invocation by the replacement because of the sourceEquality" is this the best way to read it? Does it make sense like this? Naming objects, Params, types all have a goal in API design

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.

The naming could be improved, even though it's a private record only within the class.
And yes, that's basically how it should be read. The sourceEquality is needed to then remove the equality from the VC.

*/
private VCImplication removeSourceEquality(VCImplication implication, Expression sourceEquality) {
List<Expression> remaining = new ArrayList<>(implication.getRefinement().getExpression().getConjuncts());
if (!remaining.remove(sourceEquality))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What's does this if mean?

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.

Seeing it now, I think the if itself is not needed, since the sourceEquality will always be in the list.

assertSimplificationSteps(substitution::apply, implication, step("f(x) == 0", "f(y) == 0 + 1", "f(y) == 1"),
step("f(x) == 0", "f(y) == 0 + 1", "0 + 1 == 1"));
assertSimplificationSteps(substitution::apply, implication, step("f(y) == 0 + 1", "f(y) == 1"),
step("0 + 1 == 1"));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why this second step? Shouldn't it be just 1 == 1 ? Probably not related to this change precisely but this step doesnt make much sense to me

@rcosta358 rcosta358 Jul 20, 2026

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.

Here we are just testing the VCFunctionSubstitution, not the VCFolding.

@rcosta358
rcosta358 changed the base branch from track-simplification-passes to main July 20, 2026 17:56
@rcosta358
rcosta358 force-pushed the fix-vc-function-substitution branch from 4012d7e to 585ba2f Compare July 20, 2026 17:57
@rcosta358
rcosta358 merged commit f3466c8 into main Jul 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working simplification Related to the simplification of expressions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants