присоединить(V,U,W),
перест(W,T).
В этом определении перестановки элементов списка выполняет предикат присоединить,а механизм возврата при каждой попытке вновь согласовать целевое утверждение перест(Х, Y)обеспечивает порождение из Xновой перестановки Y. Следует обратить внимание на способ размещения на странице конъюнктов второго утверждения.
Главное – остановить свой выбор на каком-либо согласованном наборе правил оформления текста программы, а на каком – не так уж важно. Как правило, полезно добавлять комментарии, надлежащим образом группировать термы, в случае сомнений относительно приоритета выполнения операций – использовать круглые скобки, а также разумно распоряжаться пустым пространством (пробелами и пустыми строками). Комментарии должны подсказывать, как следует интерпретировать аргументы структур или утверждений: в каком порядке они поступают и каким структурам данных (константам или структурам) они должны соответствовать. Полезно также указывать в комментариях, как должны конкретизироваться переменные в результате согласования данного утверждения с базой данных.
В плане общей организации программы полезно разделять текст программы на более или менее замкнутые части, например, желательно, чтобы все процедуры обработки списков оказались в одном и том же файле. Процедура Пролога, содержащая более пяти – десяти правил, может оказаться трудной для понимания, поэтому путем определения более мелких предикатов попытайтесь как можно более естественным образом разбить ее на части. Если в программе используется много фактов, таких как правила упрощения из разд. 7.12, то все эти факты должны содержаться в одном файле. Большое количество фактов легче читается, чем большое количество правил, и хотя даже несколько правил могут быть трудны для понимания, многие страницы описания конкретного факта могут не вызвать затруднений, поскольку сама семантика фактов более проста.
Еще один момент, который влияет на легкость чтения Пролог-программ, - это использование точки с запятой («или») и восклицательного знака («отсечение»). С проблемами, связанными с чрезмерно широким использованием «отсечения», мы познакомились в гл. 4. Всегда следует пытаться обойтись без ';', возможно за счет дополнительных утверждений. Например, следующая программа:
nospy(X):-
проверить(Х,Функтор,ЧисАрг,А), !,
(контрточка(_,Функтор,А), !,
(отказ(контрточка(Заголовок, Функтор, ЧисАрг),_),
устконтрточку(Заголовок, Тело),
отказ(3аголовок, Тело),
write('контр.точка с терма'), печтерм(Функтор, ЧисАрг),
write(' удалена.'),nl,
fail
; true
)
; write('Heт контр.точек на терме'),
write(X), put(46), nl
),
!.
гораздо труднее для понимания, нежели:
nospy(X):-проверить(Х,Функтор,ЧисАрг,А),!,
попыт_убр(Х,Функтор,ЧисАрг,А).
попыт_убр(_,Функтор, ЧисАрг,А):- контрточка(_,Функтор,А),!,убрконтрточку(Функтор, ЧисАрг, А).
попыт_убр(Х,_,_,_):- write('Heт контр.точек на терме '), write(X), put(46), nl,!.
убрконтрточку(Функтор, ЧисАрг, А):-
отказ(контрточка(Заголовок,Функтор, ЧисАрг), _), устконтрточку(Заголовок,Тело), отказ(3аголовок, Тело),
write('Koнтp.точка с терма'), печтерм(Функтор, ЧисАрг), write(' удалена.'), nl, fail.
убрконтрточку (_,_,_).
которая делает в точности то же самое. Если же вам действительно необходимо использовать «или», то полезно так организовать текст конъюнкции целей, чтобы «или» не терялось среди целей. Полезно также заключить соответствующие цели в скобки, чтобы явно выделить область действия этого «или».
На протяжении всей книги подчеркивалась важность умения учитывать при решении многих задач наряду с общим правилом и граничные условия. Всюду, где это возможно, мы старались разместить граничные условия перед всеми другими утверждениями процедуры. Это выделяет граничные условия и, кроме того, служит в какой-то мере защитой от циклических определений. Однако бывают случаи, когда желательно размещать граничные условия после всех утверждений процедуры. Очевидно, что правила-«ловушки», с которыми мы уже сталкивались несколько раз, нужно размещать в конце процедуры.
Разбирая Пролог-процедуру всегда полезно обращать внимание на следующие важнейшие моменты ее записи:
• Проверьте посимвольно, как записано имя каждого предиката и каждой переменной в процедуре. Ошибки в написании имен довольно распространены.
• Проверьте число аргументов каждого функтора, используемого в процедуре. Убедитесь в том, что число аргументов (и порядок их следования) соответствуют вашим проектным решениям.
Читать дальше