2015-09-14 5 views
3

Я не понимаю, как правильно использовать разрез. Например, в этом случае: flatten, действительно ли это необходимо? Он работает для меня даже без обоих предикатов (я попытался удалить). Каковы случаи, которые могут привести к возврату назад к разрезу? Удаления порезов у ​​вас есть та же реализация книги «Искусство Пролога» (Шапиро Е., Sterling L.), который:Пролог - понять использование разреза

flatten([X|Xs],Ys) :- 
    flatten(X,Ysl), 
    flatten(Xs,Ys2), 
    append(Ys1,Ys2,Ys). 
flatten(X,[X]) :- 
    constant(X), 
    X\=[]. 
flatten([],[]). 

, что приводит меня к другому вопросу: нужно во втором чтобы проверить, не является ли это список? Если это один термин, не будет объединяться с первым предложением ... не так ли?

+0

Какое описание предиката 'constant/1'? Это то же самое, что «атомный/1»? – dasblinkenlight

+0

да, эта книга называйте так. – rok

ответ

2

В программе, связанной с вашим вопросом, используется оператор cut !, чтобы код в ответе не объединялся с другими предложениями. Без этих сокращений flatten2/2 от ответа будет унифицировать пустой список в первом аргументе с пунктами один и три, т.е.

flatten2([], []) :- !. 
flatten2(L, [L]). 

Точно так же, без надреза во втором пункте flatten2/2 бы унифицировать непустой список в пунктах два и три, что приводит к неправильному поведению.

Ваш код, с другой стороны, имеет явные проверки, чтобы гарантировать, что каждый раздел flatten/2 сделок с одной конкретной ситуации:

  • Первый пункт рекурсивно сглаживает непустые списки
  • Вторая статья делает один - список элементов из констант, кроме пустых списков
  • Третья статья «сглаживает» пустые списки.

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

необходимо во втором предложении, чтобы проверить, не является ли это список?

Эта проверка необходима, потому что пустой список [] считается постоянным, так что ваша программа будет иметь неправильное поведение, когда пустые списки присутствуют в списке раздавливания (demo).

+0

как насчет перехода на третье предложение в моей программе? Кажется, отлично работает для меня, без каких-либо сокращений и проверки во втором. – rok

+1

@rok Это будет работать для первого матча, но если вы попросите переоценку предиката, вы начнете получать плохие результаты ([demo] (http://ideone.com/Vm0nuM)). – dasblinkenlight

Смежные вопросы