Каковы лучшие практики программирования Prolog и рекомендации по стилю?

Хорошо, я знаю, что это очень общий вопрос и было написано несколько статей по этому вопросу, но у меня есть ощущение, что эти публикации охватывают очень простой материал, и я ищу что-то более продвинутое, что улучшило бы стиль и эффективность. Вот что я имею в статье:

  • "Отчет об исследовании AI-1989-08" Эффективный пролог: практическое руководство "", Майкл А. Ковингтон, 1989
  • "Эффективное прологическое программирование" Тимо Кнуутила, 1992
  • "Руководство по кодированию для Пролога", Ковингтон, Баннара, О'Киф, Wielemaker, Цена, 2011

Примеры предметов, охватываемых этими: хвостовая рекурсия и дифференциальные списки, правильное использование индексации, правильное использование сокращений, избегание утверждений и отказов, избегание CONSing, рекомендации по форматированию кода (отступы, if-then-elses и т. Д.), Соглашения об именах, документирование кода, порядок рассуждений, тестирование.

Что бы вы добавили сюда из своего личного опыта с Прологом? Существуют ли какие-либо особые рекомендации по стилю, применимые только к программированию CLP? Знаете ли вы о некоторых общих проблем эффективности и знаете, как их решать?

ОБНОВИТЬ:

Здесь приводятся некоторые интересные (но все же слишком общие и слишком общие для меня) замечания: рекомендации по программированию на прологе группы Lifeware

Просто, чтобы подчеркнуть всю проблему, я хотел бы процитировать "Рекомендации по кодированию для Пролога" (Covington et al.):

Насколько нам известно, последовательный и достаточно полный набор руководств по кодированию для Prolog никогда не был опубликован. Более того, когда мы смотрим на корпус опубликованных программ Prolog, мы не видим появления фактического стандарта. Самая важная причина этого очевидного упущения заключается в том, что небольшое сообщество Прологов из-за отсутствия всеобъемлющего языкового стандарта далее фрагментировано на суб-сообщества, сосредоточенные вокруг отдельных систем Пролог, ни одна из которых не занимает доминирующее положение.

1 ответ

Решение

Для проектирования чистых интерфейсов в Prolog, я рекомендую прочитать стандарт Prolog, см. Iso-prolog.

В частности, конкретный формат кодирования встроенных предикатов, который включает в себя определенный стиль документации, а также способ сообщения об ошибках. См. 8.1 Формат определений встроенных предикатов ISO/IEC 13211-1:1995. Вы найдете определения в этом стиле онлайн в Cor.2 и прологе Пролога.

Очень хорошим примером библиотеки, которая следует буквенным соглашениям об ошибках ISO (и пока не стандартизирована), является реализация library(clpfd) в SICStus и SWI. Хотя обе реализации принципиально различаются по своему подходу, они используют соглашения об ошибках в своих лучших интересах.

Вернуться к ISO. Это формат ISO для встроенных предикатов:

xyz Имя / Арити

В начале может быть короткое необязательное неофициальное замечание.

xyz1 Описание

Дается декларативное описание, которое очень часто начинается с самой общей цели с использованием описательных имен переменных, чтобы к ним можно было обращаться позже. Если значение предиката вообще не является декларативным, то оно либо указывается как "верно", либо используется какое-либо иное ненужное операционализирующее слово, например "унифицирует", "собирает". Позвольте мне привести пример:

8.5.4 copy_term / 2

8.5.4.1 Описание

copy_term(Term_1, Term_2) это правда, если Term_2 объединяет с термином T которая является переименованной копией (7.1.6.2) Term_1,

Таким образом, это объединяет большой красный предупреждающий знак: никогда не думайте, что этот предикат является отношением, его можно понять только процедурно. И даже более того, он (неявно) утверждает, что определение является стойким во втором аргументе.

Другой пример: sort/2, Это отношение сейчас или нет?

8.4.3 сортировка / 2

8.4.3.1 Описание

sort(List, Sorted) это правда, если Sorted объединяется с отсортированным списком List (7.1.6.5).

Так что, опять же, никакого отношения. Удивлены? Посмотрите на 8.4.3.4 Примеры:

8.4.3.4 Примеры

...

sort([X, 1], [1, 1]).
   Succeeds, unifying X with 1.

sort([1, 1], [1, 1]).
   Fails.

При необходимости добавляется отдельное процедурное описание, начиная с "Процедурно". Это снова не покрывает никаких ошибок вообще. Это одно из больших преимуществ стандартных описаний: все ошибки отделены от "дел", что помогает программисту (= пользователю встроенного) более систематически отлавливать ошибки. Чтобы быть справедливым, это немного увеличивает нагрузку на разработчика, который хочет оптимизировать вручную и на индивидуальной основе. Такой оптимизированный код часто склонен к тонким ошибкам в любом случае.

xyz2 Шаблон и режимы

Здесь дается исчерпывающая, одно или двухстрочная спецификация режимов и типов аргументов. Нотация очень похожа на другие нотации, которые берут свое начало в объявлениях режима DECsystem-10 1978 года.

8.5.2.2 Шаблон и режимы

arg(+integer, +compound_term, ?term)

Однако существует большая разница между подходом ISO и руководством Covington et al., Которое носит неформальный характер и устанавливает, как программист должен использовать предикат. Подход ИСО описывает, как будет вести себя встроенный модуль, в частности, какие ошибки следует ожидать. (Существует 4 ошибки, следующие из вышеперечисленных, плюс одна дополнительная ошибка, которую нельзя увидеть из спецификации выше, см. Ниже).

Ошибки xyz3

Все условия ошибки даны, каждый в своем собственном подпункте пронумерован в алфавитном порядке. Кодекс в 7.12 Ошибки:

Когда удовлетворяется более чем одно условие ошибки, ошибка, о которой сообщает процессор Prolog, зависит от реализации.

Это означает, что каждое условие ошибки должно содержать все предварительные условия, к которым оно относится. Все они. Условия ошибки не читаются как if-then-elsif-then...

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

Многие условия ошибок непосредственно следуют из спецификации, приведенной в xyz2, в соответствии с ПРИМЕЧАНИЯМИ в 8.1.3 Ошибки и в соответствии с 7.12.2 Классификация ошибок ( резюме). Для встроенного предиката arg/3, ошибки a, b, c, d следуют из спецификации. Только ошибка е не следует.

8.5.2.3 Ошибки

а) N переменная
- instantiation_error,

б) Term переменная
- instantiation_error,

с) N не является ни переменной, ни целым числом
- type_error(integer, N),

г) Term не является ни переменным, ни составным термином
- type_error(compound, Term),

е) N целое число меньше нуля
- domain_error(not_less_than_zero, N),

Примеры xyz4

(Необязательный).

Встроенные предикаты начальной загрузки xyz5

(Необязательный). Определяет другие предикаты, которые настолько похожи, что они могут быть "загружены".

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