diff --git a/liquidjava-verifier/src/main/java/liquidjava/rj_language/SimplifiedPredicate.java b/liquidjava-verifier/src/main/java/liquidjava/rj_language/SimplifiedPredicate.java new file mode 100644 index 000000000..bf86d4c20 --- /dev/null +++ b/liquidjava-verifier/src/main/java/liquidjava/rj_language/SimplifiedPredicate.java @@ -0,0 +1,108 @@ +package liquidjava.rj_language; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import spoon.reflect.reference.CtTypeReference; + +/** + * Represents a predicate simplified from another predicate. Stores the original predicate and any variables that must + * be reintroduced as binders when relating the simplified predicate back to its origin. + *

+ * For example, simplifying {@code x == 1 && y > x} with binders {@code x: int, y: int} may produce {@code y > 1}. The + * origin {@code x == 1 && y > x} and binder {@code x: int} are kept so we can relate the simplified predicate back to + * the original. + */ +public class SimplifiedPredicate extends Predicate { + + private final Predicate origin; + private final List binders; + + public SimplifiedPredicate(Predicate simplified, Predicate origin) { + this(simplified, origin, List.of()); + } + + public SimplifiedPredicate(Predicate simplified, Predicate origin, List binders) { + super(simplified.getExpression()); + this.origin = origin; + this.binders = new ArrayList<>(binders); + } + + public Predicate getSimplifiedPredicate() { + return new Predicate(getExpression()); + } + + public Predicate getOrigin() { + return origin; + } + + public List getBinders() { + return binders; + } + + @Override + public SimplifiedPredicate clone() { + return new SimplifiedPredicate(new Predicate(getExpression().clone()), origin.clone(), binders); + } + + @Override + public int hashCode() { + return Objects.hash(getExpression(), origin, binders); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SimplifiedPredicate other = (SimplifiedPredicate) obj; + return getExpression().equals(other.getExpression()) && origin.equals(other.origin) + && binders.equals(other.binders); + } + + /** + * Represents a variable that must be bound when relating the simplified predicate to its origin + */ + public static class Binder { + private final String name; + private final String type; + + public Binder(String name, String type) { + this.name = name; + this.type = type; + } + + public Binder(String name, CtTypeReference type) { + this(name, type.getQualifiedName()); + } + + public String getName() { + return name; + } + + public String getType() { + return type; + } + + @Override + public int hashCode() { + return Objects.hash(name, type); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Binder other = (Binder) obj; + return name.equals(other.name) && type.equals(other.type); + } + } +}