Как вернуть и переменный результат, и true / false в Prolog? - PullRequest
4 голосов
/ 24 ноября 2010

Звучит глупо, но допустим, мой предикат large / 2 возвращает самый большой элемент в списке ... вывод должен выглядеть следующим образом:

?- largest([1,2,3,4,5], X).
X = 5.
false.

Я реализовал наибольший, и он работает как вышеза исключением того, что не выводит «ложь».Как мне сделать так, чтобы он тоже выводил это «ложь».значение?Это для раздражающего задания, которое я должен закончить.(

Ответы [ 4 ]

8 голосов
/ 24 ноября 2010

Эти дополнительные false. или No означают, что человек, запустивший программу, попросил получить все возможные решения для X, а не только первое возможное решение.

В большинстве интерактивных интерпретаторов Prolog вы можете проверить, есть ли другое решение, нажав клавишу с запятой (;).

1 голос
/ 25 марта 2016

Если это было частью назначения, это, вероятно, означает, что ваш предикат не должен давать второй (возможно, другой) результат после возврата. Возврат происходит, если пользователь хочет следующее решение, часто нажимая ; . Интерпретатор часто указывает, что другое решение возможно, когда он знает, что есть еще пути, которые не полностью оценены.

Предположим, у вас есть предикат foo/1 следующим образом:

foo(1).

foo(Bar) :-
   foo(Baz),
   Bar is Baz + 1.

Если вы спросите foo(Bar), переводчик ответит Bar = 1. После многократного нажатия ; переводчик вернется с Bar = 2, Bar = 3 и т. Д.

В вашем примере поиск наибольшего из списка должен быть детерминированным. Откат не должен давать другой ответ.

Вам решать, что это задание означает, что вы должны разрешить возврат, но у вас не получится, или было бы хорошо, если бы оно вообще не возвращалось.

1 голос
/ 24 ноября 2010

звучит как невозможно, как будто предикат не работает, связывание свободных переменных не происходит, см.

 ?- A=5.
A = 5.

 ?- A=5,false.
false.

однако

 ?- A=5;false.
A = 5 ;
false.

Чтобы достичь этого, вы должны сделать свой предикат "самым большим" недетерминированным. Но мне это кажется довольно глупым.

0 голосов
/ 25 марта 2016

Там - это что-то на предыдущие ответы @ aschepler , @ Xonix и @SQB.

В этом ответе мы используем для выражения декларативной целочисленной арифметики.

:- use_module(library(clpfd)).

Мы определяем largest/2, используя встроенный предикат member/2,библиотека maplist/2 и ограничение конечной области (#>=)/2:

largest(Zs, X) :-
   member(X, Zs),            % X is a member of the list Zs
   maplist(#>=(X), Zs).      % all Z in Zs fulfill X #>= Z

Примеры запросов:

?- largest([1,2,3,4,5], X).
X = 5.

?- largest([1,2,3,4,5,4], X).
X = 5 ;
false.

?- largest([1,2,3,4,5,5], X).
X = 5 ;
X = 5.

?- largest([1,2,3,4,5,5,4], X).
X = 5 ;
X = 5 ;
false.

?- largest([A,B,C,D], X).
A = X, X#>=D, X#>=C, X#>=B ;
B = X, X#>=A, X#>=D, X#>=C ;
C = X, X#>=A, X#>=D, X#>=B ;
D = X, X#>=A, X#>=C, X#>=B.
...