Skip to content

Commit a2f5975

Browse files
authored
Simplify Conjunctions (#182)
1 parent 7f0e0af commit a2f5975

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

  • liquidjava-verifier/src/main/java/liquidjava/rj_language

liquidjava-verifier/src/main/java/liquidjava/rj_language/Predicate.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,18 @@ public Predicate clone() {
183183
return new Predicate(exp.clone());
184184
}
185185

186+
@Override
187+
public boolean equals(Object obj) {
188+
if (this == obj)
189+
return true;
190+
if (obj == null)
191+
return false;
192+
if (getClass() != obj.getClass())
193+
return false;
194+
Predicate other = (Predicate) obj;
195+
return exp.equals(other.exp);
196+
}
197+
186198
public Expression getExpression() {
187199
return exp;
188200
}
@@ -195,6 +207,22 @@ private static boolean isBooleanLiteral(Expression expr, boolean value) {
195207
return expr instanceof LiteralBoolean && expr.isBooleanTrue() == value;
196208
}
197209

210+
/**
211+
* Checks if c2 is a conjunct in c1
212+
*/
213+
private static boolean containsConjunct(Predicate c1, Predicate c2) {
214+
if (c1.toString().equals(c2.toString()))
215+
return true;
216+
if (c1.getExpression()instanceof BinaryExpression be && be.getOperator().equals(Ops.AND))
217+
return containsConjunct(new Predicate(be.getFirstOperand()), c2)
218+
|| containsConjunct(new Predicate(be.getSecondOperand()), c2);
219+
return false;
220+
}
221+
222+
/**
223+
* Creates a new predicate representing the conjunction of c1 and c2 Contains simplification rules for redundant
224+
* conjuncts such as not adding conjunct if already present in conjunction
225+
*/
198226
public static Predicate createConjunction(Predicate c1, Predicate c2) {
199227
// simplification: (true && x) = x, (false && x) = false
200228
if (isBooleanLiteral(c1.getExpression(), true))
@@ -205,6 +233,13 @@ public static Predicate createConjunction(Predicate c1, Predicate c2) {
205233
return c1;
206234
if (isBooleanLiteral(c2.getExpression(), false))
207235
return c2;
236+
237+
// check if conjunct is already present in the conjunction
238+
if (containsConjunct(c1, c2))
239+
return c1;
240+
if (containsConjunct(c2, c1))
241+
return c2;
242+
208243
return new Predicate(new BinaryExpression(c1.getExpression(), Ops.AND, c2.getExpression()));
209244
}
210245

0 commit comments

Comments
 (0)