Пролог возвращает результаты - PullRequest
1 голос
/ 22 ноября 2011

Для домашней работы, так что ничего явного, пожалуйста:

Есть ли способ заставить Prolog вернуть только цель first , найденную программой, игнорируя другие найденные цели?

В иллюстративных целях приведена программа:

permutation([X|Xs],Zs):-permutation(Xs,Ys), insert(X,Ys,Zs).
permutation([],[]).

Можно ли заставить программу только возвращать перестановку first в качестве единственного решения?В следующем случае:

| ?- permutation([1,2,3],X).

X = [1,2,3] ? ;

X = [1,3,2] ? ;

X = [2,1,3] ? ;

X = [2,3,1] ? ;

X = [3,1,2] ? ;

X = [3,2,1] ? ;

no

Можем ли мы просто принять

X = [1,2,3] ?;
no

в качестве решения?

Ответы [ 3 ]

6 голосов
/ 22 ноября 2011

cut - это элемент управления, который вы ищете. Поместите его туда, где вам нужно зафиксировать решение (я полагаю, здесь на верхнем уровне). Существует также встроенный Once / 1 , который позволяет ограничить область действия коммита «локально» (полезно, например, внутри конъюнкции, встроенной в findall / 3).

4 голосов
/ 22 ноября 2011

Пролог устанавливает точки выбора всякий раз, когда возможна альтернативная ветвь в дереве поиска.Чтобы избежать возврата к точке выбора и изучения таких альтернатив, вы должны добавить вырез (!/0).

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

2 голосов
/ 22 ноября 2011

Лучший способ придерживаться первого решения - once/1, так как это сохраняет эффекты как можно более локальными.Использование !/0 часто приводит к непредвиденным последствиям, поскольку область действия !/0 больше.Давайте рассмотрим очень простой пример: запрос ( X = 1 ; X = 2 ; X = 3 ) in

p(X) :- ( X = 1 ; X = 2 ; X = 3 ).
p(4).

Используя once/1, мы получим:

p1(X) :- once( ( X = 1 ; X = 2 ; X = 3 ) ).
p1(4).

?- p1(X).
X = 1 ;
X = 4.

Используя !, мы получим только один ответ:

p2(X) :- ( X = 1 ; X = 2 ; X = 3 ), !.
p2(4).

?- p2(X).
X = 1.

Часто это не предназначено.

Но есть более общая проблема с фиксацией первого решения.

?- p1(2).
true.

?- dif(X,1),p1(X).
X = 2 ;
X = 4.

Итак, теперь также 2первое решение?Именно по таким причинам совершение должно использоваться довольно осторожно.Предикату, который демонстрирует поведение, аналогичное p1/1, не хватает стойкости.Такой предикат нельзя понимать как отношение, поскольку он меняет свое значение в зависимости от фактического запроса.

...