Skip to content

Add VC Substitution Simplification#249

Open
rcosta358 wants to merge 22 commits into
mainfrom
vc-substitution
Open

Add VC Substitution Simplification#249
rcosta358 wants to merge 22 commits into
mainfrom
vc-substitution

Conversation

@rcosta358

@rcosta358 rcosta358 commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Description

This PR adds VC simplification for binder equalities through VCImplication chains. When a binder refinement establishes a known value (constant or not), the simplifier rewrites later refinements with that value and removes the substitution source from the VC chain preserving its origin and substituted binders.

It also adds focused unit tests and property-based tests using JUnit Quickcheck to randomly generate VCs and assert if the simplified VC is equivalent to the original.

Example

x:int. x == 3 --> x > 0

is simplified to

3 > 0

with originx:int. x > 0

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 requested a review from CatarinaGamboa June 9, 2026 13:56
@rcosta358 rcosta358 self-assigned this Jun 9, 2026
@rcosta358 rcosta358 added enhancement New feature or request simplification Related to the simplification of expressions labels Jun 9, 2026

@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.

Tests look good, some code organization changes

}

public boolean hasBinder() {
return name != null && type != null;

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.

so dont all have binders? i think every VCImplication had a name and type, the question might be if they appear inside the refinement, but i didnt think this would be a possibility

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.

Not all of them. We have this constructor VCImplication(Predicate ref) which does not set the name and type. For example in ∀x:int. x == 1 => x > 0 the first vc has a binder but the second doesnt.


class VCSimplificationUtils {

public static Expression activeExpression(Predicate refinement) {

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.

whats an activeExpression? maybe we can add a method to Predicate to get the expression clone instead of this utils

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 active expression is the current expression we are simplifying. Yes we can remove this method and simply clone the current expression.

return refinement.getExpression().clone();
}

public static Predicate originPredicate(Predicate refinement) {

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.

Same here

return new VCImplication(refinement);
}

public static boolean sameVc(VCImplication left, VCImplication right) {

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.

Equals in VCImplication?

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.

Yep, that's better. I'll add it.

return refinement.clone();
}

public static VCImplication copyWithRefinement(VCImplication implication, Predicate refinement) {

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 actually be a new constructor of VCImplication right?

return substitute(implication.getNext(), source, value);

Predicate refinement = substituteRefinement(implication.getRefinement(), source, value);
VCImplication result = VCSimplificationUtils.copyWithRefinement(implication, refinement);

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.

shouldnt we also set the origin here?

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 origin is already set in substituteRefinement.

/**
* Checks whether an expression is a variable with a given name
*/
public static boolean isVar(Expression expression, String name) {

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.

public?

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.

Yeah simply because we need it in the tests and I didn't want to repeat the same code.

/**
* Checks whether an expression contains a variable name
*/
public static boolean containsVariable(Expression expression, String name) {

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.

same

static final String[] BINDERS = { "x", "y", "z" };
static final String[] FREE_VARS = { "a", "b", "c" };
private static final String[] COMPARISON_OPS = { "==", "!=", ">=", ">", "<=", "<" };

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.

then you'll add other operations when you implement those substitutions?
like &&, ite, etc?

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.

Yep!

@rcosta358 rcosta358 requested a review from CatarinaGamboa June 9, 2026 16:00
@rcosta358 rcosta358 changed the base branch from vc-simplification to main June 9, 2026 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request simplification Related to the simplification of expressions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants