Заставьте Prolog вернуть одно решение и перестать показывать опцию запроса
Я новичок в прологе и экспериментирую с тем, как заставить его перестать запрашивать после того, как он найдет один ответ. Я использую этот код:
member1(L,[L|_]).
member1(L,[_|RS]) :- member1(L,RS),!.
Результат:
| ?- member1(3,[3,2,3]).
true ? a
yes
Я заблудился о том, как заставить Пролог перестать печатать "правда"? и просто напечатайте "да" вместо этого. Я попытался использовать конструкцию if/else и функцию форматирования, но она по-прежнему выводит "true?". Есть идеи?
2 ответа
Вы режете не в том месте. Вырезать после базового условия, которое гласит: "Как только база достигнута, больше не возвращайтесь":
member1(L,[L|_]) :- !.
member1(L,[_|RS]) :- member1(L,RS).
Если-то у меня работает, возможно, вы реализовали это по-другому? (на swi-прологе)
member1(X,[Y|RS]) :-
( X = Y -> true
; member1(X,RS) -> true
; false
) .
Сви также имеет предикат once/1
,
отредактировано для учета ошибки, указанной ложным.
Из вывода, который вы показываете, я предполагаю, что вы используете GNU Prolog. Но сначала просто важное замечание:
Разрез, который вы разместили, не разрезается так, как вы намереваетесь! На самом деле, это даже не мешает тому, что есть единственный ответ. Вот доказательство тому:
| ?- member1(X,[1,2,3]).
X = 1 ? ;
X = 2
yes
Таким образом, у вас еще есть два ответа. Как правило: разрез после рекурсивной цели часто делает некоторые неожиданные вещи.
Если вы настаиваете на том, чтобы получить именно первый ответ, просто скажите once(member(X,[1,2,3]))
, once/1
это тоже порез, но вполне замаскированный. Приручено делать ровно одну вещь. Да, вы можете также размещать фрагменты в рекурсивных правилах, но для новичка лучше оставить это для более позднего урока.
За всем этим стоит еще один момент, который менее заметен: оболочка верхнего уровня GNU Prolog спросит вас о дальнейших решениях, если увидит открытую альтернативу (жаргон: выбор точки). Поэтому, когда GNU просит вас больше, он знает, что некоторая часть еще не исследована, но нет никакой гарантии, что на самом деле есть другой ответ:
?- member(1-X,[1-a,2-b,3-c]).
X = a ? ;
no
Здесь верхний уровень видит открытую точку выбора и таким образом спрашивает, хотите ли вы изучить запрос дальше. Увы, этот поиск в духе...