Math game using clpfd: expecting only 9 and not 0..18

- choose a number X between 1 and 9
- Y = (X * 3 + 3 ) * 3
- Z = sum of the digits of Y
- Z should be always 9

I tried with

?- X in 1..9, Y #= (X * 3 + 3) * 3, Z #= Y rem 10 + Y div 10.
X in 1..9,
Y#=9*X+9,
Y in 18..90,
_71856+_71858#=Y,
Y mod 10#=_71858,
Y rem 10#=_71900,
_71856 in 9..90,
_71856//10#=_71948,
_71948 in 0..9,
_71900+_71948#=Z,
_71900 in 0..9,
Z in 0..18,
_71858 in 0..9.

Try:

?- X in 1..9, Y #= (X * 3 + 3) * 3, Z #= (Y rem 10) + (Y div 10), label([Z]).
Z = 8,
X in 1..9,
Y#=9*X+9,
Y in 18..90,
_23556+_23558#=Y,
Y mod 10#=_23558,
Y rem 10#=_23600,
_23556 in 9..89,
_23556//10#=_23648,
_23648 in 0..8,
_23600+_23648#=8,
_23600 in 0..8,
_23558 in 0..9 ;
Z = 9,
X in 1..9,
Y#=9*X+9,
Y in 18..90,
_27596+_27598#=Y,
Y mod 10#=_27598,
Y rem 10#=_27640,
_27596 in 9..90,
_27596//10#=_27688,
_27688 in 0..9,
_27640+_27688#=9,
_27640 in 0..9,
_27598 in 0..9 ;
false.

Thanks but I cannot understand why I get also the result Z=8

If I test each number from 1 to 9 I get always Z=9. See below

?- X =1, Y #= (X * 3 + 3) * 3, Z #= (Y rem 10) + (Y div 10), label([Z]).
X = 1,
Y = 18,
Z = 9.

?- X =2, Y #= (X * 3 + 3) * 3, Z #= (Y rem 10) + (Y div 10), label([Z]).
X = 2,
Y = 27,
Z = 9.

?- X =3, Y #= (X * 3 + 3) * 3, Z #= (Y rem 10) + (Y div 10), label([Z]).
X = 3,
Y = 36,
Z = 9.

?- X =4, Y #= (X * 3 + 3) * 3, Z #= (Y rem 10) + (Y div 10), label([Z]).
X = 4,
Y = 45,
Z = 9.

?- X =5, Y #= (X * 3 + 3) * 3, Z #= (Y rem 10) + (Y div 10), label([Z]).
X = 5,
Y = 54,
Z = 9.

?- X =6, Y #= (X * 3 + 3) * 3, Z #= (Y rem 10) + (Y div 10), label([Z]).
X = 6,
Y = 63,
Z = 9.

?- X =7, Y #= (X * 3 + 3) * 3, Z #= (Y rem 10) + (Y div 10), label([Z]).
X = 7,
Y = 72,
Z = 9.

?- X =8, Y #= (X * 3 + 3) * 3, Z #= (Y rem 10) + (Y div 10), label([Z]).
X = 8,
Y = 81,
Z = 9.

?- X =9, Y #= (X * 3 + 3) * 3, Z #= (Y rem 10) + (Y div 10), label([Z]).
X = Z, Z = 9,
Y = 90.

There is probably some constraint that is not being propagated by the CLP system, if we do:

103 ?- X in 1..9, Y #= 9*X + 9, Z #= (Y rem 10) + (Y div 10), label([X]).
X = 1,
Y = 18,
Z = 9 ;
X = 2,
Y = 27,
Z = 9 ;
X = 3,
Y = 36,
Z = 9 ;
X = 4,
Y = 45,
Z = 9 ;
X = 5,
Y = 54,
Z = 9 ;
X = 6,
Y = 63,
Z = 9 ;
X = 7,
Y = 72,
Z = 9 ;
X = 8,
Y = 81,
Z = 9 ;
X = Z, Z = 9,
Y = 90.

you get the expected result.

My guess is that the constraint that is not being propagated has to do with rem or div. Might be a good idea to ask Markus Triska who wrote the CLP system and see what he thinks. Contact info is in his website: https://www.metalevel.at/

Hello

The solution suggested by Markus at https://github.com/mthom/scryer-prolog/issues/358 is

" in general, all variables must be labeled to make sure that there is a solution"

?- X in 1..9, Y #= (X * 3 + 3) * 3, Z #= (Y rem 10) + (Y div 10), setof(Z, X^Y^label([X,Y,Z]), Sol).
Sol = [9],
X in 1..9,
Y#=9*X+9,
Y in 18..90,
_2156+_2158#=Y,
Y mod 10#=_2158,
Y rem 10#=_2200,
_2156 in 9..90,
_2156//10#=_2248,
_2248 in 0..9,
_2200+_2248#=Z,
_2200 in 0..9,
Z in 0..18,
_2158 in 0..9.
2 Likes