@@ -297,14 +297,90 @@ literalt bv_utilst::adder(
297297{
298298 PRECONDITION (sum.size () == op.size ());
299299
300- literalt carry_out = carry_in;
301-
302- for (std::size_t i=0 ; i<sum.size (); i++)
300+ if (sum.empty () || !prop.has_set_to () || !prop.cnf_handled_well ())
303301 {
304- sum[i] = full_adder (sum[i], op[i], carry_out, carry_out);
302+ literalt carry_out=carry_in;
303+
304+ for (std::size_t i=0 ; i<sum.size (); i++)
305+ {
306+ sum[i] = full_adder (sum[i], op[i], carry_out, carry_out);
307+ }
308+
309+ return carry_out;
305310 }
311+ else
312+ {
313+ bvt first_op = sum;
314+
315+ bvt constants;
316+ constants.reserve (2 );
317+ if (first_op[0 ].is_constant ())
318+ constants.push_back (first_op[0 ]);
319+ if (op[0 ].is_constant ())
320+ constants.push_back (op[0 ]);
321+ else
322+ sum[0 ] = op[0 ];
323+ if (constants.size () == 2 )
324+ sum[0 ] = constants[0 ] == constants[1 ] ? carry_in : !carry_in;
325+ else if (constants.size () == 1 && carry_in.is_constant ())
326+ {
327+ if (constants[0 ] != carry_in)
328+ sum[0 ].invert ();
329+ }
330+ else
331+ {
332+ sum[0 ] = prop.new_variable ();
333+ prop.lcnf ({sum[0 ], first_op[0 ], op[0 ], !carry_in});
334+ prop.lcnf ({sum[0 ], first_op[0 ], !op[0 ], carry_in});
335+ prop.lcnf ({sum[0 ], !first_op[0 ], op[0 ], carry_in});
336+ prop.lcnf ({sum[0 ], !first_op[0 ], !op[0 ], !carry_in});
337+ prop.lcnf ({!sum[0 ], first_op[0 ], op[0 ], carry_in});
338+ prop.lcnf ({!sum[0 ], first_op[0 ], !op[0 ], !carry_in});
339+ prop.lcnf ({!sum[0 ], !first_op[0 ], op[0 ], !carry_in});
340+ prop.lcnf ({!sum[0 ], !first_op[0 ], !op[0 ], carry_in});
341+ }
306342
307- return carry_out;
343+ for (std::size_t i=1 ; i<sum.size (); i++)
344+ {
345+ sum[i] = prop.new_variable ();
346+
347+ prop.lcnf ({sum[i], first_op[i], op[i], !first_op[i-1 ], !op[i-1 ]});
348+ prop.lcnf ({sum[i], first_op[i], op[i], sum[i-1 ], !first_op[i-1 ]});
349+ prop.lcnf ({sum[i], first_op[i], op[i], sum[i-1 ], !op[i-1 ]});
350+
351+ prop.lcnf ({sum[i], first_op[i], !op[i], first_op[i-1 ], op[i - 1 ]});
352+ prop.lcnf ({sum[i], first_op[i], !op[i], !sum[i-1 ], first_op[i-1 ]});
353+ prop.lcnf ({sum[i], first_op[i], !op[i], !sum[i-1 ], op[i-1 ]});
354+
355+ prop.lcnf ({sum[i], !first_op[i], op[i], first_op[i-1 ], op[i - 1 ]});
356+ prop.lcnf ({sum[i], !first_op[i], op[i], !sum[i-1 ], first_op[i-1 ]});
357+ prop.lcnf ({sum[i], !first_op[i], op[i], !sum[i-1 ], op[i-1 ]});
358+
359+ prop.lcnf ({sum[i], !first_op[i], !op[i], !first_op[i-1 ], !op[i-1 ]});
360+ prop.lcnf ({sum[i], !first_op[i], !op[i], sum[i-1 ], !first_op[i-1 ]});
361+ prop.lcnf ({sum[i], !first_op[i], !op[i], sum[i-1 ], !op[i-1 ]});
362+
363+ prop.lcnf ({!sum[i], first_op[i], op[i], first_op[i-1 ], op[i - 1 ]});
364+ prop.lcnf ({!sum[i], first_op[i], op[i], !sum[i-1 ], first_op[i-1 ]});
365+ prop.lcnf ({!sum[i], first_op[i], op[i], !sum[i-1 ], op[i-1 ]});
366+
367+ prop.lcnf ({!sum[i], first_op[i], !op[i], !first_op[i-1 ], !op[i-1 ]});
368+ prop.lcnf ({!sum[i], first_op[i], !op[i], sum[i-1 ], !first_op[i-1 ]});
369+ prop.lcnf ({!sum[i], first_op[i], !op[i], sum[i-1 ], !op[i-1 ]});
370+
371+ prop.lcnf ({!sum[i], !first_op[i], op[i], !first_op[i-1 ], !op[i-1 ]});
372+ prop.lcnf ({!sum[i], !first_op[i], op[i], sum[i-1 ], !first_op[i-1 ]});
373+ prop.lcnf ({!sum[i], !first_op[i], op[i], sum[i-1 ], !op[i-1 ]});
374+
375+ prop.lcnf ({!sum[i], !first_op[i], !op[i], first_op[i-1 ], op[i - 1 ]});
376+ prop.lcnf ({!sum[i], !first_op[i], !op[i], !sum[i-1 ], first_op[i-1 ]});
377+ prop.lcnf ({!sum[i], !first_op[i], !op[i], !sum[i-1 ], op[i-1 ]});
378+ }
379+
380+ return prop.lor (
381+ prop.land (first_op.back (), op.back ()),
382+ prop.land (!sum.back (), prop.lor (first_op.back (), op.back ())));
383+ }
308384}
309385
310386literalt bv_utilst::carry_out (
0 commit comments