Проблема с «больше, чем»

#io #prolog

#io #пролог

Вопрос:

Кто-нибудь знает, почему это продолжает терпеть неудачу?

 foo :- write('3 numbers: '),
     read(A),
     read(B),
     read(C),
     (A > B,B > C,write(A),tab(1),write(B),tab(1),write(C));
     (A > C,C > B,write(A),tab(1),write(C),tab(1),write(B));
     (B > A,A > C,write(B),tab(1),write(A),tab(1),write(C));
     (B > C,C > A,write(B),tab(1),write(C),tab(1),write(A));
     (C > B,B > A,write(C),tab(1),write(B),tab(1),write(A));
     (C > A,A > B,write(C),tab(1),write(B),tab(1),write(A)).
  

Это функция prolog для печати 3 входных чисел по порядку.
Я продолжаю получать эту ошибку:

 uncaught exception: error(instantiation_error,(>)/2)
  

Ответ №1:

Я думаю, было бы лучше, если бы вы не записывали все в одно предложение. Это не только сделало бы ваш код более читаемым, но и не допустило бы этой ошибки.

Проблема в том, что ваш код анализируется примерно так:

 (read AND read AND read AND test) OR test OR test OR …
  

Это означает, что A B и C имеют значение только в первом тесте. И > требует, чтобы оба аргумента имели значение. Чтобы исправить это, вы можете использовать круглые скобки:

 foo :- write('3 numbers: '),
     read(A),
     read(B),
     read(C),
     ((A > B,B > C,write(A),tab(1),write(B),tab(1),write(C));
     (A > C,C > B,write(A),tab(1),write(C),tab(1),write(B));
     (B > A,A > C,write(B),tab(1),write(A),tab(1),write(C));
     (B > C,C > A,write(B),tab(1),write(C),tab(1),write(A));
     (C > B,B > A,write(C),tab(1),write(B),tab(1),write(A));
     (C > A,A > B,write(C),tab(1),write(B),tab(1),write(A))).
  

Комментарии:

1. Приятно! Спасибо! проблема решена. Еще одно сомнение, после того, как он показывает ответ, он продолжает спрашивать меня «правда?» .. почему?

2. @julio algeria: я подозреваю, что вы видите подсказку, которая отражает вероятность того, что foo / 0 может преуспеть в более чем одном «решении». Вы могли бы предотвратить эту возможность, добавив сокращение ! в конце вашего правила. Некоторые реализации Prolog будут пропускать запрос верхнего уровня на дополнительные решения, если цель не содержит свободных переменных (как здесь ).

Ответ №2:

Используйте истинное значение if-then-else:

 (A > B, B > C ->
    write(A),tab(1),write(B),tab(1),write(C)
; A > C, C > B ->
    write(A),tab(1),write(C),tab(1),write(B)
; B > A, A > C ->
    write(B),tab(1),write(A),tab(1),write(C)
; % etc