@@ -297,14 +297,90 @@ literalt bv_utilst::adder(
297
297
{
298
298
PRECONDITION (sum.size () == op.size ());
299
299
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 ())
303
301
{
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;
305
310
}
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
+ }
306
342
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
+ }
308
384
}
309
385
310
386
literalt bv_utilst::carry_out (
0 commit comments