I’m trying to do a bit of SAT solving as part of a AoC problem. I’ve written out what I think should be a CLP(B) compatible binary adder, which should be of the form add(+,+,+,+)
and work in every direction. Note that it assumes the inputs are reversed and the output is given in reverse for problem specific convenience.
:- use_module(library(clpb)).
add([], [], [Carry], Carry).
add([X|Xs], [Y|Ys], [Z|Zs], CarryIn) :-
sat(Z =:= (X # Y # CarryIn)),
sat(CarryOut =:= ((X * Y) + (X * CarryIn) + (Y * CarryIn))),
add(Xs, Ys, Zs, CarryOut).
It works well enough for concrete inputs, and you can write add([A,B,C], [D,E,F], Out, 0)
, and it will write out the SAT constraints for the output Out
. Trouble is that it will blow the stack when the inputs get a bit bigger like this:
add([A,B,C,D,E],[F,G,H,I,J],Out,0).
Is this reasonable behaviour? How do I write the predicate I want?