@@ -337,6 +337,75 @@ 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 (
364
+ bv_typet{1 }.all_ones_expr (),
365
+ bv_typet{1 }.all_zeros_expr (),
366
+ type_aval_bval);
367
+ auto zero = combine_aval_bval (
368
+ bv_typet{1 }.all_zeros_expr (),
369
+ bv_typet{1 }.all_zeros_expr (),
370
+ type_aval_bval);
371
+
372
+ if (expr.id () == ID_reduction_and)
373
+ {
374
+ return if_exprt{has_zero, zero, if_exprt{has_xz, x, one}};
375
+ }
376
+ else // nand
377
+ {
378
+ return if_exprt{has_zero, one, if_exprt{has_xz, x, zero}};
379
+ }
380
+ }
381
+ else if (expr.id () == ID_reduction_or || expr.id () == ID_reduction_nor)
382
+ {
383
+ auto has_one = notequal_exprt{
384
+ bitand_exprt{op_aval, bitnot_exprt{op_bval}},
385
+ to_bv_type (op_aval.type ()).all_zeros_expr ()};
386
+
387
+ auto one = combine_aval_bval (
388
+ bv_typet{1 }.all_ones_expr (),
389
+ bv_typet{1 }.all_zeros_expr (),
390
+ type_aval_bval);
391
+ auto zero = combine_aval_bval (
392
+ bv_typet{1 }.all_zeros_expr (),
393
+ bv_typet{1 }.all_zeros_expr (),
394
+ type_aval_bval);
395
+
396
+ if (expr.id () == ID_reduction_or)
397
+ {
398
+ return if_exprt{has_one, one, if_exprt{has_xz, x, zero}};
399
+ }
400
+ else // nor
401
+ {
402
+ return if_exprt{has_one, zero, if_exprt{has_xz, x, one}};
403
+ }
404
+ }
405
+ else
406
+ PRECONDITION (false );
407
+ }
408
+
340
409
exprt aval_bval (const bitnot_exprt &expr)
341
410
{
342
411
auto &type = expr.type ();
0 commit comments