@@ -195,11 +195,13 @@ public static XNodeParent<IVar> not(Object operand) {
195
195
}
196
196
197
197
public static XNodeParent <IVar > and (Object ... operands ) {
198
- return operands .length == 1 ? (XNodeParent <IVar >) operands [0 ] : build (TypeExpr .AND , operands ); // modeling facility
198
+ return operands .length == 1 ? (XNodeParent <IVar >) operands [0 ] : build (TypeExpr .AND , operands ); // modeling
199
+ // facility
199
200
}
200
201
201
202
public static XNodeParent <IVar > or (Object ... operands ) {
202
- return operands .length == 1 ? (XNodeParent <IVar >) operands [0 ] : build (TypeExpr .OR , operands ); // modeling facility
203
+ return operands .length == 1 ? (XNodeParent <IVar >) operands [0 ] : build (TypeExpr .OR , operands ); // modeling
204
+ // facility
203
205
}
204
206
205
207
public static XNodeParent <IVar > xor (Object ... operands ) {
@@ -285,8 +287,10 @@ private static class Canonizer<W extends IVar> {
285
287
private Matcher any_lt_k = new Matcher (node (LT , any , val ));
286
288
private Matcher k_lt_any = new Matcher (node (LT , val , any ));
287
289
private Matcher not_logop = new Matcher (node (NOT , anyc ), (node , level ) -> level == 1 && node .type .isLogicallyInvertible ());
288
- private Matcher not_symrel_any = new Matcher (node (symop , not , any )); // , (node, level) -> level == 0 && node.type.oneOf(EQ, NE));
289
- private Matcher any_symrel_not = new Matcher (node (symop , any , not )); // , (node, level) -> level == 0 && node.type.oneOf(EQ, NE));
290
+ private Matcher not_symrel_any = new Matcher (node (symop , not , any )); // , (node, level) -> level == 0 &&
291
+ // node.type.oneOf(EQ, NE));
292
+ private Matcher any_symrel_not = new Matcher (node (symop , any , not )); // , (node, level) -> level == 0 &&
293
+ // node.type.oneOf(EQ, NE));
290
294
private Matcher x_mul_k__eq_l = new Matcher (node (EQ , node (MUL , var , val ), val ));
291
295
private Matcher flattenable = new Matcher (anyc ,
292
296
(node , level ) -> level == 0 && node .type .oneOf (ADD , MUL , MIN , MAX , AND , OR ) && Stream .of (node .sons ).anyMatch (s -> s .type == node .type ));
@@ -307,18 +311,27 @@ private Canonizer() {
307
311
rules .put (neg_neg , r -> r .sons [0 ].sons [0 ]); // neg(neg(a)) => a
308
312
rules .put (any_lt_k , r -> node (LE , r .sons [0 ], augment (r .sons [1 ], -1 ))); // e.g., lt(x,5) => le(x,4)
309
313
rules .put (k_lt_any , r -> node (LE , augment (r .sons [0 ], 1 ), r .sons [1 ])); // e.g., lt(5,x) => le(6,x)
310
- rules .put (not_logop , r -> node (r .sons [0 ].type .logicalInversion (), r .sons [0 ].sons )); // e.g., not(lt(x)) => ge(x)
311
- rules .put (not_symrel_any , r -> node (r .type .logicalInversion (), r .sons [0 ].sons [0 ], r .sons [1 ])); // e.g., ne(not(x),y) => eq(x,y)
312
- rules .put (any_symrel_not , r -> node (r .type .logicalInversion (), r .sons [0 ], r .sons [1 ].sons [0 ])); // e.g., ne(x,not(y)) => eq(x,y)
314
+ rules .put (not_logop , r -> node (r .sons [0 ].type .logicalInversion (), r .sons [0 ].sons )); // e.g., not(lt(x)) =>
315
+ // ge(x)
316
+ rules .put (not_symrel_any , r -> node (r .type .logicalInversion (), r .sons [0 ].sons [0 ], r .sons [1 ])); // e.g.,
317
+ // ne(not(x),y)
318
+ // =>
319
+ // eq(x,y)
320
+ rules .put (any_symrel_not , r -> node (r .type .logicalInversion (), r .sons [0 ], r .sons [1 ].sons [0 ])); // e.g.,
321
+ // ne(x,not(y))
322
+ // =>
323
+ // eq(x,y)
313
324
rules .put (x_mul_k__eq_l , r -> r .val (1 ) % r .val (0 ) == 0 ? node (EQ , r .sons [0 ].sons [0 ], longLeaf (r .val (1 ) / r .val (0 ))) : longLeaf (0 ));
314
325
// below, e.g., eq(mul(x,4),8) => eq(x,2) and eq(mul(x,4),6) => 0 (false)
315
- rules .put (flattenable , r -> { // we flatten operators when possible; for example add(add(x,y),z) becomes add(x,y,z)
326
+ rules .put (flattenable , r -> { // we flatten operators when possible; for example add(add(x,y),z) becomes
327
+ // add(x,y,z)
316
328
int l1 = r .sons .length , pos = IntStream .range (0 , l1 ).filter (i -> r .sons [i ].type == r .type ).findFirst ().getAsInt (), l2 = r .sons [pos ].sons .length ;
317
329
Stream <XNode <W >> list = IntStream .range (0 , l1 - 1 + l2 )
318
330
.mapToObj (j -> j < pos ? r .sons [j ] : j < pos + l2 ? r .sons [pos ].sons [j - pos ] : r .sons [j - l2 + 1 ]);
319
331
return node (r .type , list );
320
332
});
321
- rules .put (mergeable , r -> { // we merge long when possible. e.g., add(a,3,2) => add(a,5) and max(a,2,1) => max(a,2)
333
+ rules .put (mergeable , r -> { // we merge long when possible. e.g., add(a,3,2) => add(a,5) and max(a,2,1) =>
334
+ // max(a,2)
322
335
XNode <W >[] t = Arrays .copyOf (r .sons , r .arity () - 1 );
323
336
long v1 = r .sons [r .arity () - 1 ].val (0 ), v2 = r .sons [r .arity () - 2 ].val (0 );
324
337
t [r .arity () - 2 ] = longLeaf (r .type == ADD ? v1 + v2 : r .type == MUL ? v1 * v2 : r .type .oneOf (MIN , AND ) ? Math .min (v1 , v2 ) : Math .max (v1 , v2 ));
@@ -360,7 +373,8 @@ public XNode<V> canonization() {
360
373
IntStream .range (0 , sons .length ).forEach (i -> sons [i ] = sons [i ].canonization ()); // sons are made canonical
361
374
if (type .isSymmetricOperator ())
362
375
Arrays .sort (sons ); // Sons are sorted if the type of the node is symmetric
363
- // Now, sons are potentially sorted if the type corresponds to a non-symmetric binary relational operator (in that case, we swap sons and
376
+ // Now, sons are potentially sorted if the type corresponds to a non-symmetric binary relational operator (in
377
+ // that case, we swap sons and
364
378
// arithmetically inverse the operator provided that the ordinal value of the reverse operator is smaller)
365
379
if (sons .length == 2 && type .isUnsymmetricRelationalOperator () && (type .arithmeticInversion ().ordinal () < type .ordinal ()
366
380
|| (type .arithmeticInversion ().ordinal () == type .ordinal () && sons [0 ].compareTo (sons [1 ]) > 0 ))) {
0 commit comments