Пролог - понимание использования сокращения

Я не могу четко понять использование сокращения. Например, в этом случае: сглаживание, действительно ли это нужно? У меня это работает даже без обоих предикатов cut (я пробовал удалить). В каких случаях может происходить возврат к разрезу? Убирая надрезы, вы получаете ту же реализацию из книги «Искусство пролога» (Шапиро Э., Стерлинг Л.), а именно:

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

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


person rok    schedule 14.09.2015    source источник
comment
Какое описание предиката constant/1? Это то же самое, что atomic/1?   -  person Sergey Kalinichenko    schedule 14.09.2015
comment
да, в этой книге это так называется.   -  person rok    schedule 14.09.2015


Ответы (1)


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

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

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

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

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

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

нужно ли во втором пункте проверять, не является ли это списком?

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

person Sergey Kalinichenko    schedule 14.09.2015
comment
как насчет того, чтобы переместить третье предложение в мою программу? Мне кажется, он работает отлично, без каких-либо сокращений и проверок во втором. - person rok; 14.09.2015
comment
@rok Это сработает для первого совпадения, но если вы попросите переоценить предикат, вы начнете получать плохие результаты (демо). - person Sergey Kalinichenko; 14.09.2015