@@ -337,6 +337,75 @@ exprt aval_bval(const not_exprt &expr)
337337 return if_exprt{has_xz, x, aval_bval_conversion (not_expr, x.type ())};
338338}
339339
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+
340409exprt aval_bval (const bitnot_exprt &expr)
341410{
342411 auto &type = expr.type ();
0 commit comments