@@ -69,6 +69,8 @@ public void testExpressionClustering() {
6969 db .forEach (expr -> {
7070 if (ctr .incrementAndGet () % 10 == 0 )
7171 System .out .println ("Done: " + ctr .intValue () + " / " + size );
72+ if (ctr .intValue () > 1000 )
73+ return ; // Skip
7274 // First, build all possible subtrees
7375 System .out .println ("Eval: " + expr .toParsableString (ctx ));
7476 List <RewriterStatement > subExprs = RewriterUtils .generateSubtrees (expr , ctx , 500 );
@@ -163,12 +165,26 @@ private boolean checkRelevance(List<RewriterStatement> stmts) {
163165 TopologicalSort .sort (stmt2 , ctx );
164166
165167 if (!stmt1 .match (RewriterStatement .MatcherContext .exactMatchWithDifferentLiteralValues (ctx , stmt2 ))) {
168+ // TODO: Minimal difference can still prune valid rewrites (e.g. sum(A %*% B) -> sum(A * t(B)))
166169 RewriterStatement .MatcherContext mCtx = RewriterStatement .MatcherContext .findMinimalDifference (ctx , stmts .get (j ));
167170 stmts .get (i ).match (mCtx );
168171 Tuple2 <RewriterStatement , RewriterStatement > minimalDifference = mCtx .getFirstMismatch ();
169172
170173 if (minimalDifference ._1 == stmts .get (i ))
171174 match = false ;
175+ else {
176+ // Otherwise we need to work ourselves backwards to the root if both canonical forms don't match now
177+ RewriterStatement minStmt1 = minimalDifference ._1 .nestedCopy ();
178+ RewriterStatement minStmt2 = minimalDifference ._2 .nestedCopy ();
179+ minStmt1 = converter .apply (minStmt1 );
180+ minStmt2 = converter .apply (minStmt2 );
181+
182+ if (minStmt1 .match (RewriterStatement .MatcherContext .exactMatch (ctx , minStmt2 ))) {
183+ // Then the minimal difference does not imply equivalence
184+ // For now, just keep every result then
185+ match = false ;
186+ }
187+ }
172188 }
173189 }
174190 }
0 commit comments