Давайте посмотрим на ваш пример.Это очень просто, поэтому мы представим, что это более сложно.Тем не менее, кажется, что вы принимаете как должное, что побочные эффекты необходимы.Позвольте мне задать вопрос:
В вашем примере вы сделали очень интересное открытие: названия всех сезонов имеют одинаковую длину.Какое потрясающее понимание!Но подождите, это правда?Самый простой способ убедиться в этом:
?- <b>season(S), atom_length(S,L).</b>
S = spring,
L = 6 ;
S = summer,
L = 6 ;
S = autumn,
L = 6 ;
S = winter,
L = 6.
Нет необходимости в findall/3
, нет необходимости в write/1
.
Для большего количества ответов визуальный осмотрне практичноПредставь 400 сезонов.Но мы можем проверить это с помощью:
?- <b>season(S), atom_length(S,L), dif(L,6).</b>
false.
Итак, теперь мы точно знаем, что не существует сезона другой длины.
Это мой самый первый ответ на ваш вопрос:
Пока вы можете, используйте оболочку верхнего уровня, а не свои собственные побочные процедуры!Растянуть вещи немного дальше, чтобы вообще избежать побочных эффектов.Это лучший способ избежать циклов с ошибками с самого начала.
Есть и другие причины, по которым придерживаться оболочки верхнего уровня - это хорошая идея:
Если ваши программы могут быть легко опрошены на верхнем уровне, добавление тестовых примеров для них будет тривиально.
Оболочка верхнего уровня используется многими другими пользователями и поэтому очень хорошо протестирована,Ваше собственное письмо часто ошибочно и не проверено.Подумайте об ограничениях.Подумайте о написании поплавков.Будете ли вы использовать write/1
для поплавков?Как правильно писать плавающие выражения, чтобы их можно было точно прочитать? - это способ сделать это в iso-prolog .Вот ответ:
В оболочке верхнего уровня отображается действительный текст Пролога.На самом деле ответ сам по себе является запросом!Его можно вставить обратно на верхний уровень - только чтобы получить тот же ответ.Таким образом, вы узнаете более экзотические, но неизбежные детали Пролога, такие как цитирование, экранирование и скобки.В противном случае практически невозможно выучить синтаксис, поскольку синтаксические анализаторы Prolog часто чрезвычайно разрешительны.
Скорее всего, ваша программа будет более доступна для декларативных рассуждений.
Скорее всего, ваши две процедуры methodone
и methodtwo
неверны: вы забыли перевод строки после написания Done
.Так что methodone, methodone
содержит искаженную строку.Как это легко проверить?
Но давайте посмотрим немного подробнее на вашу программу.Что характерно для циклов, управляемых ошибками, так это то, что они невинно начинаются как нечто, производящее «только» побочные эффекты, но рано или поздно они также имеют тенденцию привлекать больше семантических частей.В вашем случае, atom_length/2
скрыто в цикле, управляемом отказами, полностью недоступном для тестирования или рассуждений.
Соображения эффективности
Системы Prolog часто реализуют отказ, освобождая стек.Следовательно, циклы, управляемые сбоями, не требуют сборщика мусора.Вот почему люди считают, что отказоустойчивые циклы эффективны.Однако это не обязательно так.Для такой цели, как findall(A, season(A), As)
, каждый ответ на A
копируется в некоторое пространство.Это тривиальная операция для чего-то вроде атомов, но представьте себе более крупный термин.Скажем:
blam([]).
blam([L|L]) :- blam(L).
bigterm(L) :- length(L,64), blam(L).
Во многих системах findall/3
или assertz/1
на этот большой срок заморозят систему.
Кроме того, системы, такие как SWI, YAP, SICStus, имеют довольно сложныесборщики мусора.А использование меньшего количества циклов, управляемых сбоями, поможет еще более улучшить эти системы, поскольку это создает потребность в более сложных методах .