@@ -337,6 +337,67 @@ exprt aval_bval(const not_exprt &expr)
337
337
return if_exprt{has_xz, x, aval_bval_conversion (not_expr, x.type ())};
338
338
}
339
339
340
+ exprt aval_bval_reduction (const unary_exprt &expr)
341
+ {
342
+ auto &type = expr.type ();
343
+ auto type_aval_bval = lower_to_aval_bval (type);
344
+ PRECONDITION (is_four_valued (type));
345
+ PRECONDITION (is_aval_bval (expr.op ()));
346
+
347
+ auto has_xz = ::has_xz (expr.op ());
348
+ auto x = make_x (type);
349
+ auto op_aval = aval (expr.op ());
350
+ auto op_bval = bval (expr.op ());
351
+
352
+ if (expr.id () == ID_reduction_xor || expr.id () == ID_reduction_xnor)
353
+ {
354
+ auto reduction_expr = unary_exprt{expr.id (), op_aval, bool_typet{}};
355
+ return if_exprt{has_xz, x, aval_bval_conversion (reduction_expr, x.type ())};
356
+ }
357
+ else if (expr.id () == ID_reduction_and || expr.id () == ID_reduction_nand)
358
+ {
359
+ auto has_zero = notequal_exprt{
360
+ bitor_exprt{op_aval, op_bval},
361
+ to_bv_type (op_aval.type ()).all_ones_expr ()};
362
+
363
+ auto one = combine_aval_bval (bv_typet{1 }.all_ones_expr (), bv_typet{1 }.all_zeros_expr (), type_aval_bval);
364
+ auto zero = combine_aval_bval (bv_typet{1 }.all_zeros_expr (), bv_typet{1 }.all_zeros_expr (), type_aval_bval);
365
+
366
+ if (expr.id () == ID_reduction_and)
367
+ {
368
+ return if_exprt{has_zero, zero,
369
+ if_exprt{has_xz, x, one}};
370
+ }
371
+ else // nand
372
+ {
373
+ return if_exprt{has_zero, one,
374
+ if_exprt{has_xz, x, zero}};
375
+ }
376
+ }
377
+ else if (expr.id () == ID_reduction_or || expr.id () == ID_reduction_nor)
378
+ {
379
+ auto has_one = notequal_exprt{
380
+ bitand_exprt{op_aval, bitnot_exprt{op_bval}},
381
+ to_bv_type (op_aval.type ()).all_zeros_expr ()};
382
+
383
+ auto one = combine_aval_bval (bv_typet{1 }.all_ones_expr (), bv_typet{1 }.all_zeros_expr (), type_aval_bval);
384
+ auto zero = combine_aval_bval (bv_typet{1 }.all_zeros_expr (), bv_typet{1 }.all_zeros_expr (), type_aval_bval);
385
+
386
+ if (expr.id () == ID_reduction_or)
387
+ {
388
+ return if_exprt{has_one, one,
389
+ if_exprt{has_xz, x, zero}};
390
+ }
391
+ else // nor
392
+ {
393
+ return if_exprt{has_one, zero,
394
+ if_exprt{has_xz, x, one}};
395
+ }
396
+ }
397
+ else
398
+ PRECONDITION (false );
399
+ }
400
+
340
401
exprt aval_bval (const bitnot_exprt &expr)
341
402
{
342
403
auto &type = expr.type ();
0 commit comments