Заставьте 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

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

Другие вопросы по тегам