Т. Пратт, М. Зелковиц - Языки программирования - разработка и реализация (4-е издание_ 2002) (1160801), страница 181
Текст из файла (страница 181)
Они оформлены в виде и-кортежа?(а,. а,,..., а„) и устанавливают отношение между и аргументами в соответствии с отношением б В ответ на ввод функции, соппц)ь(нвег), которая добавляет данные к базе данных, пользователь может ввести епр)оуег(ге1воыттх.ыптчегвтву). ещр1оуег(впп~п.пава). ещр1оуег(рга(в.пава). роы твоег(ге)йоы)Ы .ргепь)сепа11). роб)твпег(ргагцргепг1сеьа11), <С'ьг1><<В> Эти отношения инвариантны, Они не могут быль унифицированы к некоторому другому значению. Правила. Правила — вто импликации, которые задаются во время операции сопвв11. Синтаксис для правил следующий: епр1оуео(х):-ввр1оуег(х, ) /*х работающий. еспи у х инеетсп работоаатепь*? впр)оуеббу(х) :-ввр1оуег(х,ч), нюсе(т).
Правило епр1оуео только проверяет, что в базе данных имеется отношение-предикатепр1 оуег(Х, что-то), таким образом, конкретный работодатель игнорируется. Но правило ептр1оуе()Ьу(Х) использует отношение епр!оуег(Х у) для отображения имени работодателя: епр1оуеа(ргаы ) чев еър1оуеаьу(зе)йоытсв) оптчегы' Су уев Запросы. Запросы состоят из последовательности термов, завершающейся точкой: о, о. -"о,. Мы хотим, чтобы ассоциация для переменных в каждом терме была такой, чтобы все термы были истинными.
Запрос выполняется следующим образом: унифи- 658 Приложение. Обзоры языков цируется терм о,. (возможно, путем обращения к определению о, в базе данных); если он истннен, то терм оа унифицируется с помощью своего определения. Если в какой-либо точке процесс унификации сообшает об отказе, то он возвращается к предыдущему правильному выбору и пробует альтернативный путь, как описано в разделе 8зЕЗ. Правила могут быть скомбинированы в сложные запросы. Например, вопрос «Кто работает в ЫАВА и написал книгу, которая издана в „Прентис-Холл" » может быть выражен с помощью запроса; евр1оуег(х паза) пюы шпег(х.ргепг)сепа11>.
Х = ргатт? уел Хотя и ае1Хон> (а, и рга(( унифицируют предикат рцЫ 15»е, (Х, ргеп(л се)>а11), только рга ь ь унифицирует предикат ел>р1оуег( Х, пака ). Отсечение. Процесс вычисления запросов часто требует выполнения значительного числа откатов, Для экономии времени было предложено отсечение. Отсечение (обозначается символом «!») предписывает, что если в запросе необходимо применить откат, то мы получаем отказ в данном запросе. Действие отсечения заключается в том, чтобы ограничить пространство поиска для нахождения решения. Использование отсечения никогда не добавит решения, которое могло бы быть найдено без отсечения, но может исключить некоторые верные решения.
Например, если бы предьщущпй запрос был записан в виде епр1оуег(х,пала),!.роышпег(х,ргепг)села)1) тогда мы получили бы для него отказ. Сначала был бы унифицирован предикат еп>р1оуег(Х,паза), нополуч>пи бы отказ при унификации предиката издатель(Х,ПрелтлсХолл) атомом злпь». Обычно в такой ситуации Рго)ой выполнил бы откат и начал поиск другой подстановки для унификации преднката еп>р1оуег(Х, паза), но отсечение запрещает это делать.
Отсечения не имеют никакого действия в прямом направлении. Проблемы с отрицанием. Отрицание определяется следующим образом; по"(Х):- Х,!,(а11 пом >. Заметим, это не соответствует тому, что следует возвратить истину, если Х лолсно. Если Х истинно, то по((Х) вычислит Х как истина, откажет на га)1, но отсечение приведет к отказу этого правила. Если Х ложно, то при вычислении первого правила получим отказ, но по(( ) выполнится успешно.
Однако нри вычислении первого правила можно получить отказ, если Х ложно или просто отсутствует в базеданных. Разницу можно увидеть на примере следующих двух запросов: Х )з 5. пот(Х-10>, пот(Х=10) Х )ь 5 В первом случае Х уннфицируется целым 5 и по1(Х=10) выполннтся успешно. Во втором слу ше Х сначала унифицируется целым 10 н возникает отказ прн вычислении по»( Х=10), так что унификация целым 5 никогда не выполняется. Ввод и вывод Для большинства простых запросов, чтобы записать ответы, вполне достаточно вывода по умолчанию унифицированных переменных.
Тем не менее в Рго)ой су- П.12. Вгпай!а!Н 659 Стандартные Функции В большинство реализаций языка Рго! оя включены следующие встроенные функ- ции, которые помогают генерировать программы: Читает файл с заданныль именем и добавляет иоаыс факты и правила н базу данных. иия файла может быть записано также в виде ' иня фаияа', если имя файла содсржьп символы, не используемые в идентификаторах. сапяа!миня файла) часто может быть заменено ирасто иа Гиня фаина) Переписывает отпошсния в бвзс данных Всегда означает отказ Счи ) ы вист вхоаныс паин ыс из указанного файла в виде наборов правил Выводит па пермь геры Наььравля(т вывод функции нюте в файл с заданным именем Закрывает файл, исиользоваяншйся в функшш (е11, и цсренаправляет вывод функции нгя (е иа стаидартоос устройство ны вола (терминал) Переходит )и новую строку (цри вводе и выводе) Предикая который возвращает исьину, сели Х является ать)яьгьяя (строковой константой или именем переменной) Предикат, который назара)пает истину, сел н х является переменной Прсдикат, который возвраьцаст истину, если х является цсяым числом Включает отладочный режим трассировки программы, наказывая выполнение каждого шага программы Выключает отладочный режим трассировки программы санта)С(ичя фаина) гесопм)с(иня фаияа) тая) яее(иия фаина) ню те(гери) те1)(иия файна) то)о атач(Х) чаг(Х) япсеоег(Х) '.гасе по!гасе П.12.
Згпа! ЫаИс Пример с пояснениями Мы возвращаемся к ншпему примеру суммирования элементов массива. В этой версии даьшые хранятся в файле ба(а. Для входных данных 412345123450 программа, приведешьая в листинге И.14, даст следующий результат: 1 2 3 4 50М =10 1 2 3 4 5 50М =15 Листинг П.14. Пример суммирования элементов массива на языке Ягпай!а1Н 1 А(тау чаг)ай!ебцйс!азз: ))па(аз(осе !пз(апсеуаг!ай!ейавез: 3 с1азьуаюаы ецавез: '0а!аг)1е дгг!пцех 5(огаре 5)хе' 4 роа10)ст!опаю ез 5 сатейогу. и!1 ! б )Оатазтоге с1азз веьцосзгог: !пз!апсе сгеа()оп'! 7 пен 8 Оасау)1е Г)1е5!геав преп.'бата' фойе( 9 5(огайе Аггау пеи: 99.
10 5)хе 99. продолженное ществует также функция иг! Ге для вывода на печать любой строки. Например, мш Ге('аЬс') напечатает аЬс. Функция п) печатает символ новой строки. 660 Приложение. Обзоры языков Листинг П.14 (продолжение) 11 зе)1 гесс! !! 12 )Оатастоге с)асс яетчопеРог: гваюс') 13 асчп: аЧа)пе 14 Агг1паех Агг1паех + 1.
15 5согаве ас: Агг)паем пас: ача)пе ! 16 ОеСма) 1) Агг1ппех Агг1паех + 1. 18 "5тогаче ат: Агг1паех ! 19 мех[ха) 20 "((Оатаг))е пех!) ЮО)СЧа)пе - $0 гдвзСЧ41пе)! 21 гЕСЕС 22 Агг1ппех 0 !! 23 (К ) спи( 24 Оатасгоге пен 25 "1п)С!41ые К" 26 [(К Оатаыоге мех!ма)) > О) 2) нт )етгпе: [ 1 сп: к по: [() Оасазспге пехсча)) рг!пс. 28 ОПагастег зрасе рг!пт. 29 Оасасспге 440п: )]. 30 Оасассоге гезес. 31 щя О.
32 '50Н -' рг)гт. 33 1 Со: к 00: [5пя евм+ Оаысгоге Оетча1). 34 5ОВ рг)птв1. 35 Омастоге сесе!] ! Строка 1. Здесь определяется Ратаз[оге как подкласс класса Яггау. Строка 2. Пустой список указывает, что в лк)бом объекте класса Оатаз[оге отсутствуют локальные переменные. В данном примере все данные обрабатываются в определении класса. Вообще говоря, каждый экземпляр класса имеет свой набор локальных переменных.
Строка 3. Переменные Оатз[п1е, Ягг1пдех, 5тога9е и 5) те являются глобальными переменными объектов класса Оатззтоге. Строки 4 — 5. Эти строки нужны для корректного определения ключевого метода, но их обсуждение выходит за рамки данного примера. Символ [! ) означает конец определения подкласса. Строка 6. Здесь указано начало определения методов для класса Оз[аз[сгЕ, то есть вызовов методов вида 0414ЗСОГЕ МММ МЕГОАа Строка 7. Определяется метод пем Этот метод открывает файл входных данных и инициализирует массив, в котором будут храниться данные.
Строка 8. Файл с(а[а открывается в режиме 'г' для чтения, Класс Г~)е5[гезп) возвращает обьект-дескриптор для этого файла, который присваивается переменной ОаЬаг))е — глобальной переменной в определении подкласса РаЬаьЬоге в строке 3.
Строка 9. Метод пен: посылается классу Аггау с параметром 99. Возвращается массив из 99 элементов, который присваивается переменной 5[огз9е, обьявленной в строке 3. Строка 11. Метод газе! посылается объекту, представленному переменной зе)1, который является объектом, куда изначально посылался метод пен.
Это приводит П.!2. Яша!!!а!К 661 к вызову метода гелена для класса Оатазсоге, определенному в строке 21. Два символа (! ) указывают завершение определения вызываемых методов для класса Оа !аз 1о ге из строки 6. Строка 12. Для класса Оасазтоге определяются основные операционные методьь Строки 16 — 18. Унарпый метод Оейна! увеличивает значение переменной Агг1пеех, представляющей индекс массива, на единицу и возвращает соответствующий элемент массива ( ), используя л~етод ай: для экземпляров массивов, в данном случае для массива 5йога0е.
Строки 19-20. Метод пехена1 для файлового объекта ОайаГ~ )е возвращает следукш!ий символ из файла. Метод 0)р сна! ое, переданный этому символу, возвращает целое значение этого ЛВСП-символа. Вычитая пз этого числа значение символа О, получаем правильное численное значение для цифры ц.лого числа (папример, Спагасйег 0 ($0) возвратит целое число О,Спагастег 1 ($1) возвратитцелоечисло1 и т. д.). Строка 23.
Р, ) и зпп определяются как локальныс переменные. Все переменные объявляются без указания их типа, так как типы присваиваются динамически. Строка 24. Вызывается метод пен кчасса Оа1з51оге, объявленный в строке 7, для того чтобы открыть файл ввода и разместить массив данных. Строка 23. Это комментарий 5шайгайс, Строка 26.