With the (semi-official) contracting/1 predicate, you can minimize some domains in one fell swoop. In your case:
| ?- constr(3,Y,Z). clpz:(Z#=1#<==>_A), clpz:(_B#=0#<==>_C), clpz:(_D#=0#<==>_E), clpz:(_F#=0#<==>_G), clpz:(_H#=0#<==>_I), clpz:(_C#\/_E#<==>1), clpz:(_G#\/_I#<==>_A), clpz:(Y mod 3#=_B), clpz:(Y mod 3#=_F), clpz:(Y mod 7#=_D), clpz:(Y mod 7#=_H), clpz:(Y in 3\/5\/7), clpz:(Z in 1..2), clpz:(_C in 0..1), clpz:(_B in 0..2), clpz:(_E in 0..1), clpz:(_D in 0..6), clpz:(_A in 0..1), clpz:(_G in 0..1), clpz:(_F in 0..2), clpz:(_I in 0..1), clpz:(_H in 0..6) ? ; no
And now adding one goal:
| ?- constr(3,Y,Z), clpz:contracting([Z]). Z = 1, clpz:(_A#=0#<==>_B), clpz:(_C#=0#<==>_D), clpz:(_E#=0#<==>_F), clpz:(_G#=0#<==>_H), clpz:(_B#\/_D#<==>1), clpz:(_F#\/_H#<==>1), clpz:(Y mod 3#=_A), clpz:(Y mod 3#=_E), clpz:(Y mod 7#=_C), clpz:(Y mod 7#=_G), clpz:(Y in 3\/5\/7), clpz:(_B in 0..1), clpz:(_A in 0..2), clpz:(_D in 0..1), clpz:(_C in 0..6), clpz:(_F in 0..1), clpz:(_E in 0..2), clpz:(_H in 0..1), clpz:(_G in 0..6) ? ; no
In other words, a more consistent version of your constr/3 predicate would be:
constr_better(X, Y, Z) :- constr(X, Y, Z), clpz:contracting([Z]).
Above, I used SICStus with library(clpz) , which is the successor to library(clpfd) SWI, which also has clpfd:contracting/1 .