@@ -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,15 @@ private static boolean isBooleanLiteral(Expression expr, boolean value) {
195207 return expr instanceof LiteralBoolean && expr .isBooleanTrue () == value ;
196208 }
197209
210+ private static boolean containsConjunct (Predicate c1 , Predicate c2 ) {
211+ if (c1 .toString ().equals (c2 .toString ()))
212+ return true ;
213+ if (c1 .getExpression ()instanceof BinaryExpression be && be .getOperator ().equals (Ops .AND ))
214+ return containsConjunct (new Predicate (be .getFirstOperand ()), c2 )
215+ || containsConjunct (new Predicate (be .getSecondOperand ()), c2 );
216+ return false ;
217+ }
218+
198219 public static Predicate createConjunction (Predicate c1 , Predicate c2 ) {
199220 // simplification: (true && x) = x, (false && x) = false
200221 if (isBooleanLiteral (c1 .getExpression (), true ))
@@ -205,6 +226,11 @@ public static Predicate createConjunction(Predicate c1, Predicate c2) {
205226 return c1 ;
206227 if (isBooleanLiteral (c2 .getExpression (), false ))
207228 return c2 ;
229+
230+ // check if c2 is already present in the conjunctions of c1
231+ if (containsConjunct (c1 , c2 ))
232+ return c1 ;
233+
208234 return new Predicate (new BinaryExpression (c1 .getExpression (), Ops .AND , c2 .getExpression ()));
209235 }
210236
0 commit comments