Применение CLP (FD) ограничения
Во-первых, общее замечание: Когда рассуждая над целых в Прологе, я настоятельно рекомендую вам использовать CLP вашей системы (FD) ТРУДНОСТИ.
Как @JimAshworth правильно указывает, такие ограничения работают только над целых, и, в частности, не обеспечивают деление с дробными результатами.
Однако, мы часто можем, и в этом случае, легко обойти такие разделы, применяя чисто алгебраических преобразований .
В этом случае я могу устранить разделение
A/B #= C
просто писать вместо:
A #= B*C
алгебраически, я просто умножаются как стороны уравнения с B
.
Решение
Следовательно, возможное решение может выглядеть следующим образом:
mathmaze(Vs) :-
Vs = [A,B,C,D,E,F,G,H,I],
Vs ins 1..9,
all_different(Vs),
A*C*I + 13*B*I + D*C*I + 12*E*C*I
- F*C*I - 11*C*I + G*C*H - 10*C*I #= 66*C*I.
Пример запрос и результат:
?- mathmaze(Vs), time(labeling([ff], Vs)).
% 5,869,675 inferences, 7.221 CPU in 7.243 seconds (100% CPU, 812897 Lips)
Vs = [1, 2, 6, 4, 7, 8, 3, 5, 9].
корректность
Давайте теперь использовать другой отправляемые рецептура до тест это результат. С принятым ответом мы получаем:
?- mathmaze([1, 2, 6, 4, 7, 8, 3, 5, 9]).
false.
Итак, что это: Это решение или нет?
Судя по тому, номера немного с плавающей точкой может помочь нам, это может быть решением:
?- X is 1+13*2/6+4+12*7-8-11+3*(5/9)-10.
X = 66.0.
Конечно, числа с плавающей точкой имеют чрезвычайно ограниченную помощь в таких случаях, и поэтому мы используем рациональные числа вместо:
?- X is 1+13*(2 rdiv 6) +4+12*7-8-11+3*(5 rdiv 9)-10.
X = 66.
Да, это решение! Однако, так как принятый ответ использует числа с плавающей точкой, она не распознается как таковой, потому что:
?- 66 is 66.0.
false.
Это верно! 66.0 не 66. Добро пожаловать в новаторскую технологию 1940-х годов.
В общей сложности принятый ответ пропустил 136 решений из-за использования чисел с плавающей запятой. Однако, поскольку он находит несколько решений (6 в всего), такие ошибки легко упускать из виду. Чтобы быть в безопасности сторона, я рекомендую вам всегда использовать целые числа, рациональные номера или аналогичные сейф представление при рассуждении о номера в Пролог.
обман: '? - Vs = [A, B, C, D, E, F, G, H, I], Vs ins 0 .. 100, A + ((13 * B) // C) + D + (12 * E) - F - 11 + G * (H // I) - 10 # = 66, метка (Vs). Vs = [0, 0, 1, 0, 0, 0, 1, 87, 1], A = B, B = D, D = E, E = F, F = 0, C = G, G = I, I = 1, H = 87; ... ' – CapelliC
Почему масштаб идет от 0 до 100? –
Это домен *, а не масштаб. Произвольный выбор, только потому, что метка/1 требует его – CapelliC