0

I am wondering as to how to efficiently encode the following subcircuit for a binary satisfiability solver (cnf, and optionally xor clauses, if this helps):

    eq2 = sum(a, b, c, d, e, f, g, h) == 2
    eq3 = sum(a, b, c, d, e, f, g, h) == 3

(All variables binary. That is, eq2 should be set if and only if exactly two of the eight input variables are set; eq3 should be set if and only if exactly 3 of the eight input variables are set.)

This subcircuit appears many times in the problem, so efficient encoding is important.

Things I have tried thus far:

  1. Just naively emit the $2^8$ miniterms for each. This is simple, but results in 512 clauses of 9 variables each. It also doesn't expose the structure of the problem to the sat solver.
  2. Generate the circuits ge2 = or(and(a, b), and(a, c), ...) / ge3 = or(and(a, b, c), and(a, b, d), ...) / ge4 = or(and(a, b, c, d), and(a, b, c, e), ...) / eq2 = and(ge2, ~ge3) / eq3 = and(ge3, ~ge4). This, unfortunately, results in many clauses still.
  3. Generate circuits implementing an adder-tree, and then eq2 = and(~sum_3, ~sum_2, sum_1, ~sum_0) and eq3 = and(~sum_3, ~sum_2, sum_1, sum_0). This works, however it unnecessarily constrains the solver (there's a lot of propagation that needs to be done even if the sum is >= 4, for instance), and prevents direct propagation between inputs (they may need to go all the way up the adder-tree and back).

Is there a better method of doing this that I'm missing?

TLW
  • 1,500
  • 1
  • 10
  • 16

0 Answers0