2016-05-20 5 views
2

У меня есть следующее правило (!):проблем Понимания Cut Оператору пример (Пролог Language)

noRepetition([]). 
noRepetition([Elem|Rest]):- not(member(Elem,Rest)), !, noRepetition(Rest). 

Это правило сделано, чтобы решить, если список не имеет повторяющихся элементов в нем и верховенству члена решает если конкретный элемент принадлежит списку. Мой вопрос связан с оператором cut в этом правиле, поскольку я не уверен, что он делает.

я составил следующий след за ?-noRepetition([a,b,b,c,d]) и перебежать проблемы (вероятно, в связи с моим отсутствием понимания оператора вырезания):

?-noRepetition([a,b,b,c,d]) 
Unfies with the second noRepetion rule and instantiates variables to: 
noRepetition([a|b,b,c,d] :- not(member(a,[b,b,c,d])), !, noRepetition([b,b,c,d]). 

Теперь я застрял, как не член возвращает верно этот случай, таким образом, разрез доказан, однако я не уверен, что этот разрез не позволяет программе перейти на noRepetition (3-й гол) или если он делает что-то еще. Если это действительно препятствует переходу программы в noRepetition, это правило будет оцениваться как true, что не так, поскольку в списке есть повторение.

+0

Где вы получили это определение 'noRepetition/1' от? –

ответ

3

На ваш вопрос. Мое мнение: разрез не нужен. Возможно, вы захотите обновить свою память на том, что делает разрез; here is a short summary. Хорошее эмпирическое правило состоит в том, чтобы посмотреть на последнюю цель перед разрезом и попытаться увидеть, оставляет ли она ее точки выбора. Если это так, то все они выбрасываются (вместе со всеми точками выбора из более ранних целей в этом разделе), и вы остаетесь только с первым решением. Поэтому мы смотрим на:

\+ member(Elem, Rest) % just another way to say not... 

Когда это может оставить позади точку выбора? \+ Goal истинно, если Goal false, false в противном случае. Насколько мне известно, \+ Goal никогда не может быть правдой более одного раза и не может быть ложным более одного раза. Итак, зачем тебе нужен разрез? Именно в этой ситуации избыточно и на самом деле ничего не делает.

(я все же хотел бы знать, почему вы положили вырезать там в первую очередь. Был ли подобный предикат, который не использовал отрицание на member/2?)

Предлагая лучшие решения злит спрашивают, но для решения этой проблемы есть at least two other ways. Вы можете даже помять их вместе для следующего определения:

all_dif_list(L) :- 
    ( ground(L) 
    -> sort(L, S), 
     length(L, N), 
     length(S, N) 
    ; all_dif_list_nonground(L) 
    ). 

all_dif_list_nonground([]). 
all_dif_list_nonground([X|Xs]) :- 
    maplist(dif(X), Xs), 
    all_dif_list_nonground(Xs). 

Если вы знаете, что список полностью инстанцирован, вы можете просто сортировать его и сравнивать длины. sort/2 удаляет дубликаты, поэтому, если есть повторения, отсортированный список будет короче.

Если список содержит переменные, то безопасная вещь должна состоять в том, чтобы просто сказать, что каждая пара элементов в списке (и всегда будет) различна.

И имейте в виду, что member/2 сложнее, чем его простое имя и прямолинейное определение. Я мог бы легко написать эссе на 1000 слов о поведении member/2, если бы думал, что выиграю от этого.

+0

Спасибо за быстрый ответ. Это правило на самом деле происходит из набора правил, которые мой учитель отправил для задания. Его член был написан как таковой: член (X, [X | _]). участник (X, [_ | Rest]): - элемент (X, Rest). Я попытался проследить его, но я не понимал, что такое разрез. Если бы я использовал правило, данное, однако, оно делает третий гол первым, а затем пытается разрезать? Извините за все, что находится на одной линии, но не уверен, как редактировать комментарии здесь. – JmanxC

+0

@JmanxC Вы пытались удалить разрез и посмотреть, есть ли разница _any_ с результатом, который вы получаете? –

+0

@JmanxC Как в вашем вопросе, так и в вашем комментарии вы говорите о «третьем цели», и я понятия не имею, о чем вы говорите .... :( –

0
noRepetition([]). 
noRepetition([Item|Rest]) :- member(Item,Rest), !, fail. 
noRepetition([_|Rest]) :- noRepetition(Rest). 

Примечание: результат может быть неожиданным, если товар не является основным термином. Например:

noRepetition([X,a,b]). 

потерпит неудачу ...