Skip to content

Commit 8012829

Browse files
committed
Playing with the adder encoding: no carry variables
This reduces the number of Boolean variables at the expense of introducing more clauses. No measurable difference with CaDiCaL, minor slowdown with MiniSat.
1 parent d4684f6 commit 8012829

File tree

1 file changed

+81
-5
lines changed

1 file changed

+81
-5
lines changed

src/solvers/flattening/bv_utils.cpp

+81-5
Original file line numberDiff line numberDiff line change
@@ -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

310386
literalt bv_utilst::carry_out(

0 commit comments

Comments
 (0)