Аргументы пролога недостаточно проработаны

Я пытаюсь найти максимальное, среднее и минимальное число из 3 заданных номеров. Код является:

t_max(X,Y,Z):-
    A is max(max(X,Y),max(Y,Z)),
    C is min(min(X,Y),min(Y,Z)),
    (X>=A,X=<C)->B is X;
    (Y>=A,Y=<C)->B is Y;
    (Z>=A,Z=<C)->B is Z;
    format('~w      ~w      ~w',[A,B,C]).

Когда я пытаюсь запустить метод с любыми тремя числами, я получаю эту ошибку

ERROR: >=/2: Arguments are not sufficiently instantiated

Почему я получаю эту ошибку?

1 ответ

Решение

Проблема в том, что ; связывает с более низким приоритетом, чем , так что вы написали эквивалентно:

t_max(X, Y, Z) :-
    (   A is max(max(X, Y), max(Y, Z)),
        C is min(min(X, Y), min(Y, Z)),
        X>=A,
        X=<C
    ->  B is X
    ;   Y>=A,
        Y=<C
    ->  B is Y
    ;   Z>=A,
        Z=<C
    ->  B is Z
    ;   format('~w      ~w      ~w', [A, B, C])
    ).

Что это значит: Пролог оценивает:

A is max(max(X,Y),max(Y,Z)),
C is min(min(X,Y),min(Y,Z)),

Сначала проверяем условие:

X>=A,X=<C

однако, если это не удается, программа полностью возвращается к началу предложения. А сейчас A а также C снова не созданы, и Пролог выполняет новую попытку, проверяя:

Y>=A,Y=<C

но сейчас A а также C не заземлены.

Вы можете решить проблему, добавив скобки:

t_max(X,Y,Z):-
    A is max(max(X,Y),max(Y,Z)),
    C is min(min(X,Y),min(Y,Z)),
    ((X>=C,X=<A)
     -> B is X
     ; ((Y>=C,Y=<A)
        ->B is Y
        ; ((Z>=C,Z=<A)
           -> B is Z;
           true
          )
       )
    ),
    format('~w      ~w      ~w',[A,B,C]).

Если я правильно понимаю вашу проблему. Однако если вы хотите отсортировать их от большого к маленькому, компактный способ сделать это для трех чисел:

t_max(X,Y,Z) :-
    Max is max(X,max(Y,Z)),
    Min is min(X,min(Y,Z)),
    Mid is X+Y+Z-Max-Min,
    format('~w      ~w      ~w',[Max,Mid,Min]).
Другие вопросы по тегам