Программирование на языке Пролог | страница 72
средний_ налогоплательщик(X):- иностранец(X), fail.
средний_налогоплательщик(X):-…
В этой выдержке из программы (которая является неверной) в первом правиле делается попытка сказать: «если X – иностранец, то доказательство согласованности целевого утверждения средний_налогоплательщик(X) должно закончиться неудачей». Второе правило должно использовать общий критерий того, что значит быть средним налогоплательщиком в тех случаях, когда X – не иностранец. Ошибка заключается в том, что если бы мы обратились с вопросом
?- средний_налогоплательщик(видслевип).
об иностранце по фамилии видслевип, то произошло бы сопоставление с первым правилом и согласованность целевого утверждения иностранец была бы доказана. Далее, целевое утверждение fail инициировало бы возврат. При попытке найти новое сопоставление для цели средний_налогоплательщик Пролог нашел бы второе правило, определяющее общие критерии вычисления налога, и начал бы применять это правило к видслевип. Вполне вероятно, что этот иностранец удовлетворил бы общим критериям, что привело бы к неверному ответу «да».
Таким образом, первое правило оказалось абсолютно неэффективно при «отбраковке» нашего приятеля как среднего налогоплательщика. Почему так получается? Ответ кроется в том, что при возврате Пролог пытается найти новое сопоставление для каждого целевого утверждения, рассматривавшегося ранее. Поэтому, в частности, будут исследованы альтернативные способы сопоставления для средний_налогоплательщик(видслевип). Для того чтобы остановить поиск альтернатив в данном случае, необходимо отсечь сделанный выбор правила (заморозить решение), прежде чем будет выполнен предикат fail. Мы можем сделать это, вставив отсечение перед fail. Несколько более обстоятельное определение предиката средний_налогоплательщик, включающее эти изменения, приведено ниже:
средний_налогоплателыцик(Х):- иностранец(Х),!,fail.
средний_налогоплательщика(X):-супруга(Х,Y), доход(Y,Доход), Доход › 3000,!, fail.
средний_налогоплателыцик(Х):- доход(X,Доход),2000 ‹ Доход, 20000 › Доход.
доход(Х,Y):- получаемое_пособие(Х,Р),Р‹5000,!, fail.
доход(Х,Y):-жалованье(Х,Z),доход_от_капиталовложений(X,W),Y is Z + W.
доход_от_капиталовложений(Х,Y):-…
Обратите внимание на использование в этой программе других комбинаций «отсечение-fail». Во втором правиле средний_налогоплательщик говорится, что попытка показать, что некоторый человек является средним налогоплательщиком, может быть прервана, если можно показать, что заработок его супруги превышает некоторый порог. Точно так же в определении предиката