Eduardo Costa
Visual Prolog 7.0 for Tyros Перевод с английского
Сафронов Марк a.k.a. ‐S‐ 20.07.2007
Upda...
119 downloads
558 Views
5MB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
Eduardo Costa
Visual Prolog 7.0 for Tyros Перевод с английского
Сафронов Марк a.k.a. ‐S‐ 20.07.2007
Update 1 Revision 73
Комментарий переводчика Ад кромешный ‐ переводить подобные тексты. Во‐первых, большую часть терминов хочется ос‐ тавить вообще без перевода, потому что программисты все равно пользуются сленгом, основанным на английском варианте этих терминов, а общепринятый перевод даже если и есть, то не склоняет‐ ся, или в некоторых фразах выглядит как бред сумасшедшего. Во‐вторых, все время необходимо ре‐ шать классическую проблему перевода: нужно ли переводить дословно, или нужно вместе с перево‐ дом ещё и перерабатывать стилистику текста, чтобы он соответствовал общепринятой стилистике русского языка. Конечно же, можно определить т. н. «идеальный» перевод: текст, написанный так, как его бы написал оригинальный автор, если бы свободно владел языком перевода. Но, чтобы перевести текст так качественно, необходимо быть этим автором, то есть, писать книги на нескольких языках. =) Ещё, я начинал переводить эту книгу, когда она называлась Visual Prolog 6.3 for Tyros, и предна‐ значалась, соответственно, для версии, 6.3,пользуясь в то же самое время средой разработки Visual Prolog 7.0. Это было не самым приятным развлечением, так как некоторые программы из книги ра‐ ботали не так, как надо, или, чаще всего, не работали вообще, о чём мне приходилось писать в ком‐ ментариях. Выход обновлённого текста избавил меня от этих проблем, но произошёл, уже когда пе‐ ревод исходного текста был закончен, что потребовало от меня ещё раз переворошить всю работу. :) Теперь конкретно. Я не переводил имена собственные нигде в тексте. Исключение сделано для имен людей, для которых я привожу русскую транскрипцию и оригинальное английское написание в скобках. Оформление по большей части оставлено авторское, за исключением того, что я позволил себе «продолжить» оформление там, где, как мне показалось, оно должно было быть; это относится к курсивному выделению пунктов меню и моноширинному шрифту листингов кода. Для терминов, подобным project tree, code expert и package, принадлежащих конкретно теме текста, я использовал собственный перевод, так как текст стал бы трудночитабельным, если я бы оставил их без перевода.. Для терминов, имеющих общеупотребительный эквивалент на русском языке, я пользовался этим эквивалентом, даже если, возможно, значение эквивалента отличалось от значения термина на анг‐ лийском языке (тем более что эти термины большей частью из жаргона программистов). Я старался сохранить авторскую стилистику нетронутой – что было довольно легко, так как я ис‐ пользовал дословный перевод везде, где можно – но в некоторых местах пришлось все‐таки пере‐ строить предложения довольно значительно, так как в дословном переводе с небольшими измене‐ ниями, только для простого соответствия правилам русского языка, эти предложения становились похожими на горячечный бред. В некоторых местах я позволил себе полностью изменить некоторые фразы, это касается, в частности, подписей под некоторыми рисунками. Теперь техническая информация. В конце почти каждой главы имеется раздел Examples ‐ приме‐ ры, в котором перечисляются программы, исходные коды которых приложены к этому тексту в от‐ дельном архиве. Также, книга для версии 7.0 является обновлением такой же книги для версии Visual Prolog 6.3 – Visual Prolog 6.3 for Tyros. Это означало, что некоторые изображения окон IDE седьмой версии имели некоторые расхождения с окнами шестой версии, а именно, изображения конкретно для Visual Prolog 7.0 сняты с окон в классическом стиле оформления Windows, в то время как изображения, не требовавшие обновления, автор оставил как были – в стиле WinXP‐Standard (Blue). Я позволил себе в свою очередь обновить эти изображения, чтобы книга выглядела более целостностной. Из оригинального текста полностью удалены перечень рисунков, следовавший сразу за содер‐ жанием, и Index (список использованных в тексте терминов), в самом конце.
2
Предисловие Каждый из нас имел опыт общения с заумными книгами и статьями, которые больше скрывают, чем показывают вклад автора. Например, Пьер‐Симон, маркиз де Лаплас (PierreSimon, Le Marquis de Laplace), вставил только один рисунок в свою «Небесную Механику» (Méchanique Celeste), а Пеано (Peano), как Мел Гибсон (Mel Gibson), написал свою Arithmetices Principia Novo Methodo Exposita на ла‐ тыни! Я думаю, парень, придумавший публиковать книги «для чайников», сделал много денег. Он понимал, что большинство людей предпочтут быть названными «чайником», чем повстречаться с Лапласом. Но так как вы не хотите ни быть названным «чайником», ни иметь дело с маркизом, на‐ звание этой книги Prolog for tyros1, не for dummies. Eduardo Costa
Uxoribus Amantissimis Liberisque Pientissimis
Слово tyro заимствовано из латыни: tyro=tiro – лат. новичок. Таким образом, книга называется «Visual
1
Prolog для новичков» (здесь и далее прим. пер.).
3
Содержание Комментарий переводчика ___________________________________________________ 2 Предисловие ________________________________________________________________ 3 Содержание ________________________________________________________________ 4 Глава 1: 1.1.
Введение __________________________________________________________ 7 Создание проекта в Visual Prolog ______________________________________________ 7
1.1.1. Создание нового GUI проекта _____________________________________________________ 7 1.1.2. Компиляция и запуск программы __________________________________________________ 8
1.2.
Глава 2:
Примеры __________________________________________________________________ 8
Формы ___________________________________________________________ 9
2.1.
Создание формы ___________________________________________________________ 9
2.2.
Включение панели задач: e.g. пункт File/New __________________________________ 11
2.3.
Добавление кода к предмету из дерева проекта в CodeExpert ___________________ 12
2.4.
Примеры _________________________________________________________________ 12
Глава 3:
Mouse events _____________________________________________________ 14
3.1.
Добавим код к событию MouseDown _________________________________________ 14
3.2.
onPaint ___________________________________________________________________ 14
3.3.
Примеры _________________________________________________________________ 15
Глава 4:
Поменьше картинок ______________________________________________ 16
4.1.
Панель задач ______________________________________________________________ 16
4.2.
Дерево проекта ___________________________________________________________ 16
4.2.1. Code Expert ____________________________________________________________________ 17
4.3.
Создание элемента проекта _________________________________________________ 18
4.4.
Панель задач. _____________________________________________________________ 19
4.5.
Сыграем снова. ____________________________________________________________ 19
4.6.
Создание нового класса ____________________________________________________ 20
4.7.
Содержимое строки ввода __________________________________________________ 22
4.8.
Примеры _________________________________________________________________ 23
Глава 5:
Предложения Хорна _______________________________________________ 24
5.1.
Функции __________________________________________________________________ 24
5.2.
Предикаты ________________________________________________________________ 24
5.3.
Решения __________________________________________________________________ 25
5.4.
Множественные решения __________________________________________________ 28
5.4.1. Программа, использующая предикаты с множественными решениями _________________ 28
5.5.
Логические связки. ________________________________________________________ 30
5.6.
Импликация ______________________________________________________________ 30
5.7.
Предложения Хорна. _______________________________________________________ 31 4
5.8.
Объявления _______________________________________________________________ 31
5.8.1. Объявления режимов детерминизма ______________________________________________ 32
5.9.
Предикаты рисования ______________________________________________________ 33
5.10. GDI объект ________________________________________________________________ 33 5.11. Примеры _________________________________________________________________ 34
Глава 6:
Консольные приложения ___________________________________________ 35
6.1.
Отсечение ________________________________________________________________ 35
6.2.
Списки ___________________________________________________________________ 36
6.3.
Схемы обработки списков __________________________________________________ 39
6.4.
Операции со строками. _____________________________________________________ 40
Глава 7:
Грамматика _____________________________________________________ 46
7.1.
Грамматический анализ ____________________________________________________ 46
7.2.
Грамматический синтез ____________________________________________________ 47
7.3.
Почему Пролог? ___________________________________________________________ 48
7.4.
Примеры _________________________________________________________________ 49
Глава 8:
Рисование ________________________________________________________ 50
8.1.
onPainting ________________________________________________________________ 50
8.2.
Пользовательские элементы управления _____________________________________ 52
Глава 9:
Типы данных _____________________________________________________ 54
9.1.
Примитивные типы данных _________________________________________________ 54
9.2.
Множества _______________________________________________________________ 55
9.3.
Множества чисел __________________________________________________________ 55
9.4.
Иррациональные числа ____________________________________________________ 57
9.5.
Действительные числа _____________________________________________________ 58
9.6.
Форматирование __________________________________________________________ 58
9.7.
Домены __________________________________________________________________ 59
9.7.1. Списки ________________________________________________________________________ 59 9.7.2. Функторы _____________________________________________________________________ 60
Глава 10:
Как решать это в Прологе _______________________________________ 63
10.1. Утилиты __________________________________________________________________ 63
Глава 11:
Факты ________________________________________________________ 75
11.1. Класс file _________________________________________________________________ 77 11.1.1. Чтение и вывод строки ________________________________________________________ 77
Глава 12:
Классы и объекты _______________________________________________ 79
12.1. Факты объектов ___________________________________________________________ 80
Глава 13:
Giuseppe Peano __________________________________________________ 82
13.1. Черепашья графика ________________________________________________________ 82 13.2. Рекурсия _________________________________________________________________ 85
5
13.3. Кривая Пеано _____________________________________________________________ 86 13.4. Latino Sine Flexione _________________________________________________________ 87 13.5. Примеры _________________________________________________________________ 90
Глава 14:
L‐системы _____________________________________________________ 92
14.1. Класс draw ________________________________________________________________ 92 14.2. Примеры _________________________________________________________________ 94
Глава 15:
Игры __________________________________________________________ 95
15.1. Объектные факты ________________________________________________________ 100
Глава 16:
Анимация _____________________________________________________ 103
16.1. dopaint __________________________________________________________________ 103 16.2. Управление таймером ____________________________________________________ 104 16.3. Как программа работает ___________________________________________________ 104
Глава 17:
Текстовый редактор ___________________________________________ 106
17.1. Сохранение и загрузка файлов _____________________________________________ 107
Глава 18:
Печать _______________________________________________________ 109
Глава 19:
Баги __________________________________________________________ 111
19.1. Ошибки типа _____________________________________________________________ 111 19.2. Не‐процедура внутри процедуры ___________________________________________ 112 19.3. Неопределённые условия. _________________________________________________ 113 19.4. Невозможно определить тип _______________________________________________ 114 19.5. Шаблон потока ___________________________________________________________ 114
Глава 20:
Менеджер баз данных __________________________________________ 115
20.1. Менеджер базы данных ___________________________________________________ 115 20.2. Класс emails ______________________________________________________________ 117 20.3. Менеджер баз данных ____________________________________________________ 118
Глава 21:
Книги и статьи ________________________________________________ 120
21.1. Грамматика ______________________________________________________________ 120 21.2. Базы данных _____________________________________________________________ 120 21.3. Техники программирования _______________________________________________ 121
Библиография_____________________________________________________________ 122
6
Глава 1: Введение 1.1.
Создание проекта в Visual Prolog
Давайте создадим пустой проект, к которому позже добавим функциональности.
1.1.1. Создание нового GUI1 проекта Этот шаг довольно прост. Выберите команду Project/New из панели задач, как показано на рис. 1.1. Затем, заполните диалоговое окно Project Settings как на рис. 1.2. Нажмите кнопку Create, и перед вами появится окно дерева проекта (рис. 1.3).
Рисунок 1.1 Создание нового проекта
Рисунок 1.2 Настройки проекта
1
Graphical User Interface – графический пользовательский интерфейс.
7
Рисунок 1.3 Дерево проекта
1.1.2. Компиляция и запуск программы Для того, чтобы откомпилировать программу, выберите команду Build/Build из панели задач, как показано на рис. 1.4. Для запуска программы выберите Build/Execute из панели задач, и на экране появится окно, похожее на изображенное на рис. 1.5.
Рисунок 1.4 Сборка проекта
Рисунок 1.5 Пустое приложение
1.2.
Примеры
Примеры в этой главе показывают, как запускать приложение, и находятся в папке plot1.
8
Глава 2: Формы В этой главе вы добавите форму к пустому проекту, который вы создали в главе 1.
Рисунок 2.1 Добавление нового предмета к дереву проекта
Рисунок 2.2 Создание новой формы
2.1.
Создание формы
Чтобы создать форму, выберите команду File/New из панели задач, как на рис. 2.1. Выберите на левой панели пункт Form и заполните диалоговое окно Create Project Item как на рис. 2.2. Название новой формы – query. Удостоверьтесь, что вы поместили форму в корне дерева проекта. Это про‐ изойдет, если вы выбрали корневой каталог в дереве проекта, прежде чем нажать File/New.
9
Когда вы запрашиваете новую форму, Visual Prolog IDE1 показывает вам диалоговое окно под на‐ званием Form Properties (рис. 2.3). Вы можете принять установки по умолчанию в этом диалоговом окне. После диалогового окна Form Properties, IDE покажет вам прототип новой формы, как на рис. 2.4. Вы можете изменить размеры прямоугольника окна, сделав его немного больше прототипа. Чтобы сделать это, нажмите мышкой на нижнем правом углу формы и тяните его, как вы делаете, когда из‐ меняете размеры обычного окна.
Рисунок 2.3 Form Properties
Рисунок 2.4 Изменение размеров окна
1
Visual Prolog Integrated Development Engine – интегрированная среда разработки Visual Prolog.
10
2.2.
Включение панели задач: e.g. пункт File/New
Когда вы запускали пустое приложение, вы, скорее всего, заметили тот факт, что пункт меню File/New отключен. Чтобы включить его, дважды щелкните по ветке дерева проекта под названием TaskMenu.mnu (рис. 2.5). Затем, разверните дерево, находящееся в нижней части диалогового окна TaskMenu, и уберите галочку Disabled, относящуюся к пункту &New/tF7, как на рис. 2.6.
Рисунок 2.5 Панель задач приложения в дереве проекта
Рисунок 2.6 Включение элемента панели задач
11
2.3.
Добавление кода к предмету из дерева проекта в CodeExpert
Чтобы добавить код к пункту File/New, нажмите на ветке дерева проекта TaskWindow.win правой кнопкой мыши, которая откроет контекстное меню. Выберите пункт Code Expert (рис 2.7). Как на рис. 2.8, дважды щелкните на
Наконец, нажмите кнопку Add (ориентируйтесь по рис. 2.8), и дважды щелкните по ветке _ _
Рисунок 2.7 Переход в эксперт кода
Это откроет текстовый редактор, со следующим фрагментом: clauses onFileNew(_Source, _MenuTag).
Откомпилируйте программу, затем измените этот фрагмент так: clauses onFileNew(W, _MenuTag) :X := query::new(W), X:show().
Откомпилируйте программу снова, выбрав пункт Build/Build на панели задач, как на рис. 1.4. За‐ пустите программу, и вы увидите, что, когда вы нажимаете File/New, создается новая форма.
2.4.
Примеры
Пример в этой главе показывает, как создавать новую форму выбором пункта File/New, затем за‐ полнением диалогового окна Create Project Items.
12
Рисунок 2.8 Dialog and Window Expert
Рисунок 2.9 Появляющаяся форма
13
Глава 3: Mouse events В первых двух главах этого документа, вы научились компилировать приложение с формой в нём, которая появляется, когда вы выбираете пункт File/New из меню этого приложения.
3.1.
Добавим код к событию MouseDown
Нажмите на ветку дерева проекта query.frm правой кнопкой мыши, что откроет контекстное ме‐ ню. Выберите пункт Code Expert, как вы делали на рис. 2.8 для TaskWindow.win. Осторожно, на рис. 2.8, вы применяли эксперт кода к TaskWindow.win. Сейчас вам нужно применить его к query.frm. В code expert дважды щелкните на Mouse, затем на MouseDown. Наконец, нажмите кнопку Add, и дваж‐ ды щелкните на ветку
Вам следует вставить следующий код в процедуру onMouseDown/4: clauses onMouseDown(S, Point, _ShiftControlAlt, _Button):W=S:getVPIWindow(), Point=pnt(X,Y), Vpi::drawText(W, X, Y, “Hello, World!”).
Откомпилируйте программу, и запустите её. Выберите File/New чтобы создать новую форму. Ка‐ ждый раз, когда вы нажимаете на форму, программа размещает на ней знаменитое приветствие.
3.2.
onPaint
Вы использовали обработчик события onMouseDown/4 чтобы нарисовать что‐нибудь на форме. Есть программисты, которые не считают это хорошей идеей. Существуют языки, которые делают та‐ кой подход очень трудноосуществимым. Java один из таких языков, и очень популярный, между про‐ чим. В Java любое рисование следует производить внутри public abstract void doPaint(java.awt.Graphics g)
14
Конечно, это ограничение можно обойти, и даже в Java. В любом случае, давайте научимся про‐ изводить всё рисование внутри обработчиков событий onPaint/3. 1. Создайте проект с именем plot0. 2. Добавьте новый пакет plotter к нему, как ранее. 3. Вставьте новую форму query в plotter. 4. Включите пункт панели задач File/New 5. Добавьте фрагмент clauses onFileNew(S, _MenuTag) :Q=query::new(S), Q:show().
к ProjTree/TaskWindow.win/Menu/TaskMenu/id_file/id_file_new. Следующий шаг – добавить фрагмент class facts mousePoint:pnt := pnt(-1, -1). predicates onMouseDown : drawWindow::mouseDownListener. clauses onMouseDown(_S, Point, _ShiftControlAlt, _Button) :mousePoint := Point, Point=pnt(X,Y), R=rct(X-8, Y-8, X+60, Y+8), Invalidate(R).
в query/Code Expert/Mouse/MouseDown→onMouseDown. Вы готовы применять обработчик события onPaint к query. onPaint будет вызван каждый раз, когда прямоугольная область на форме стано‐ вится устаревшей или неверной. Когда это происходит, то есть, когда изображение становится не‐ верным? Когда окно частично или полностью перекрыто другим окном, или когда вы делаете его не‐ действительным с помощью предиката invalidate(R), где R – прямоугольник. Прямоугольник опи‐ сывается координатами его верхнего левого и нижнего правого углов. R=rct(X-8, Y-8, X+60, Y+8)
Вы заметили, что обработчик события onMouseDown/4 делает недействительным прямоуголь‐ ную область вокруг места щелчка мышью. Обработчик события onPaint будет работать с этой обла‐ стью. Под конец, добавьте фрагмент clauses onPaint(_Source, _Rectangle, GDIObject) :pnt(X, Y)=mousePoint, X>0, !, mousePoint:= pnt(-1, -1), GDIObject:drawText(X, Y, “Hello, World!”, -1). onPaint(_Source, _Rectangle, _GDIObject).
к query/Window/Paint→onPaint. Этот новый подход потребует от вас понимания множества но‐ вых понятий, таких, как отсечение (тот восклицательный знак, расположенный после X>0) и факты. Не беспокойтесь пока об этих понятиях. Вы все изучите в свое время.
3.3.
Примеры
Примеры в этой главе показывают, как обрабатывать события мыши, такие, как щелчок левой кнопкой мыши.
15
Глава 4: Поменьше картинок До того, как двигаться дальше, давайте найдем способ описывать наш проект, не опираясь по‐ стоянно на изображения.
4.1.
Панель задач
Панель задач, показанная на рис. 1.1 и 1.4, это главное меню Visual Prolog IDE. Запись A/B отно‐ сится к одному из её пунктов. Например, вы используете команду Project/New для создания нового проекта (рис. 1.1). Оно [диалоговое окно создания нового проекта – прим. пер.] имеет шесть форм, а именно: General, Directories, Build Options, Version Information, File Templates и Run Options. В большинстве слу‐ чаев, вам потребуется заполнять только форму General. General Project Name: plot2 UI Strategy: Object-oriented GUI (pfc/gui) Target Type: Exe Base Directory: E:\VIP7\Tyros
Когда вы найдете шаг, указывающий: Создайте новый GUI проект: plot2 (раздел 1.1.1). вам следует войти в диалоговое окно Project Settings (выбрав пункт Project/New на панели задач VDE1) и заполнить форму General как указано выше. Сделайте это mutatis mudandis2, так как на вашем компьютере может не быть диска E, или вы можете захотеть хранить ваши программы в папке, отли‐ чающейся от E:\VIP70\tyros.
4.2.
Дерево проекта
Самый лёгкий способ ориентироваться в файлах и ресурсах это щелкать мышкой по соответст‐ вующим элементам Дерева проекта:
Если вы дважды щёлкнете по папке, она откроется и отобразит свое содержимое. Если вы щёлк‐ нете по элементу правой кнопкой мыши, откроется контекстное меню, как на рисунке. Если я хочу, чтобы вы зашли в эксперт кода и добавили фрагмент кода в TaskWindow.win, я скажу: В эксперте кода, добавьте код к TaskWindow/TaskWindow.win (раздел 2.3) Чтобы выполнить это указание, отправляйтесь в дерево проекта и сделайте следующее: 1. Дважды щелкните по папке TaskWindow, чтобы открыть её, если она закрыта. 2. Щелкните правой кнопкой мыши по ветке дерева проекта TaskWindow.win, чтобы раскрыть контекстное меню, в котором будут следующие пункты:
1 2
Visual Development Environment – визуальная среда разработки лат. Изменив то, что следует изменить; внеся необходимые изменения.
16
Edit Attribute Delete Code Expert
3. Наконец, выберите пункт Code Expert
4.2.1. Code Expert Эксперт кода тоже имеет форму дерева.
Соответствуя названию, эксперт кода используется для вставки кода во многие файлы проекта. Чтобы добраться до эксперта кода, вы должны щелкнуть правой кнопкой мыши по элементу дерева проекта, к которому вы хотите добавить код. Затем, выберите пункт Code Expert из контекстного ме‐ ню. Чтобы перемещаться по дереву эксперта кода и добираться до точек, куда вы желаете вставить код, щелкайте по нужным веткам дерева. Если вы хотите, чтобы эксперт кода добавил прототип к «листку» дерева, нажмите на этот листок и затем нажмите на кнопку Add, которая появится внизу диалогового окна. Затем дважды щелкните по листку снова, чтобы перейти к коду. Если я попрошу: В Эксперте кода добавьте (раздел 2.3): clauses onFileNew(W, _MenuTag) :S=query::new(W), S:show().
к TaskWindow.win/Code Expert/Menu/TaskMenu/id_file/id_file_new, вот шаги, которым вы должны сле‐ довать: • Дерево проекта – Откройте папку TaskWindow дерева проекта, щелкните правой кноп‐ кой мыши по TaskWindow.win, чтобы открыть его контекстное меню, и выберите пункт Code Expert (рис. 2.7). • Эксперт кода – Дважды щелкните на Menu→дважды щелкните на TaskMenu→дважды щелкните на id_file. Выберите id_file_new и нажмите кнопку Add для создания кода прото‐
17
•
типа. Наконец, дважды щелкните на id_file_new→onFileNew. Ориентируйтесь по рис. 2.7, 2.8 и разделу 2.3. Файл: TaskWindow.pro – Добавьте требуемый код:
clauses onFileNew(W, _MenuTag) :S=query::new(W), S:show().
4.3.
Создание элемента проекта
Для добавления нового элемента к дереву проекта выберите команду File/New из панели задач. Следите за тем, чтобы размещать создаваемые элементы в нужных папках. Примеры можно найти на рис. 2.2 и 2.3. Вот как я попрошу вас создать пакет и добавить к нему форму: • Добавить новый пакет к дереву проекта: plot2/plotter. Внимание, если вы хотите, чтобы пакет располагался в корневом каталоге, не заполняйте поле parent directory, как на рис. 4.1. Один из способов начать с пустого родительского каталога – выбрать корень дерева проекта до того, как нажимать File/New, как показано на рис. 2.1.
Рисунок 4.1 Создание кового пакета
•
Создать новую форму: plotter/query (раздел 2.1). Создайте форму: query. Поместите query в пакет plotter. Чтобы поместить окно внутрь пакета, убедитесь, что выбрана папка пакета, до того, как отправляться в File/New. Выбирайте имена, которые что‐то значат. Например, если пакет хранит диаграммы, назовите его plots1; если он хранит компьютер‐ ную графику, вы можете выбрать имя вроде canvasFolder; если он содержит запросы, хо‐ рошим именем будет queryForms; если он содержит формы для заполнения, это portfolio; и т. д. Когда вы создаете форму, IDE показывает диалоговое окно Form Attributes, которое вы можете принять без изменений. После диалогового окна Form Attributes, IDE покажет диалоговое окно Form Window (см. рис. 4.2). Вы можете воспользоваться возможностью изменить размеры окна и добавить строку ввода (название: edit_ctl) и кнопку, как показано на рисунке. Вы также можете добраться до диалогового окна Form Window, нажав правой кнопкой мыши по имени формы в дереве проекта, и выбрав пункт Edit из появившегося меню.
1
англ. График, чертёж, диаграмма.
18
Рисунокк 4.2 Форма со о строкой ввод да
4.4 4.
Панель зад дач.
Если и вы дважды щёлкнетее по ProjectT Tree/TaskMeenu.mnu, вы получите д диалоговое о окно вроде то‐ го, которое было по оказано на рис. 2.6. Вы ы можете раазвернуть деерево этой сспецификац ции меню щ щел‐ кая по еего веткам, ккак говорил лось ранее. Вам также м может понадобиться вкключить каккой‐либо пункт меню, ккак в раздел ле 2.2. Такжее возможно о создать новый элемен нт меню, какк показано н на рис. 4.2, где я нажал л на кнопку ((иконку) под д названием м New Item и создал пункт Drawingg Tools, запо олнив диало ого‐ вое окно. Как вы м можете увид деть из рисуунка, новый пункт созд дается изначчально вклю юченным. Си им‐ вол & в записи &Filee обозначаеет F как горяячую клавиш шу.
4.5 5.
Сы ыграем сснова.
Даввайте начнем м новый проект с нуля,, чтобы посм мотреть, что о мы сможеем сделать сс меньшим ко‐ личеством картинок и провери ить, сжато ли и мы описываем проектт Visual Prolog. те новый G GUI проект:: factorial l (раздел 1.1.1). • Создайт
1 19
• • • •
Добавьте новый пакет к дереву проекта: factorial/forms. Создайте новую форму: forms/query (раздел 4.3). Добавьте edit field [строку ввода] (с названием edit_ctl) и кнопку (с названием factorial_ctl) на неё, как на рис. 4.2. Включите пункт TaskMenu File/New (раздел 2.2). Откомпилируйте приложение, затем добавьте (раздел 2.3):
clauses onFileNew(W, _MenuTag) :S=query::new(W), S:show().
к TaskWindow.win/Menu/TaskMenu/id_file→id_file_new→onFileNew.
4.6.
Создание нового класса
Чтобы создать новый класс и вложить его в пакет forms, выберите папку forms в дереве проекта и выберите пункт File/New в панели задач VDE. Убедитесь, что убрали галочку Create Objects, как пока‐ зано:
Когда вы нажмёте кнопку Create, Visual Prolog предоставит нам файлы fn.pro и fn.cl, которые со‐ держат прототип класса fn. Наша задача – добавить функциональности к этим файлам. Начнем с fn.cl: class fn open core predicates classInfo : core::classInfo. setVal : (string) procedure. calculate : () procedure. end class fn
На языке объектно‐ориентированного программирования, файл fn.cl содержит интерфейс ме‐ тодов setVal:(string) procedure и calculate:(). Он информирует предполагаемых пользо‐ вателей о том, что метод setVal/1 это процедура (об этом позже), и требует один аргумент, кото‐ рый должен быть строкой; он также говорит, что метод calculate/0 не имеет аргументов. С другой стороны, файл fn.pro содержит определение обеих процедур. %файл fn.pro implement fn open core
20
constants className = “forms/fn”. classVersion = “”. class facts nVal:integer := 0. class predicates fact:(integer, integer) procedure (i,o). clauses classInfo(className, classVersion). setVal(X) :nVal:=toterm(X), stdio::write(“fact(“, nVal, “)=”). fact(0,1) :- !. fact(N, N*F) :fact(N-1, F). calculate() :fact(nVal, F), stdio::write(F, “\n”). end implement fn
Следующий шаг – вызвать предикат setVal/1, когда пользователь введёт что‐нибудь в строку ввода. Отправляйтесь в дерево проекта и примените эксперт кода к query.frm. Если вы не помните, как это делать, прочтите раздел 3.1 заново. В эксперте кода откройте папку Control/edit_ctl (дважды щелкнув на ней), щелкните на LoseFocus, и нажмите кнопку Add, чтобы создать прототип кода. Дваж‐ ды щелкните на LoseFocus→onEditLoseFocus, и добавьте следующий фрагмент кода: predicates onEditLoseFocus : window::loseFocusListener. clauses onEditLoseFocus(S) :fn::setVal(S:getText()).
Когда учишь язык программирования, требуется время, чтобы привыкнуть к новым понятиям. Поэтому, не пытайтесь, на данный момент, понять каждую деталь программ, которые вы найдёте в этом руководстве. Согласно Эзопу, осведомленность прояснит вещи позже. В любом случае, давайте вкратце пройдемся по вещам, которые нужно запомнить. В Visual Prolog есть классы и объекты, принадлежащие классам. Объект имеет набор методов, которые являются программами, которые работают с объектом. Они также называются event driven predicates – движимые событиями предикаты. Если вы поставите курсор в строку ввода, она получит фокус. Строка ввода потеряет фокус, если вы обратите свое внимание на другой объект, например, кнопку. Фрагмент clauses onEditLoseFocus(S) :fn::setVal(S:getText()).
гласит, что, если строка ввода когда‐нибудь потеряет фокус, она должна вызвать метод S:getText(), чтобы получить строку, которую ввел пользователь, и передать её в fn::setVal(X), где она будет сокращена до целого числа: setVal(X) :nVal:=toterm(X).
21
setVal/1 сохранит целое число в факте‐переменной nVal. Следующий шаг – снова применить эксперт кода к query.frm. Отправляйтесь в дерево проекта и добавьте фрагмент clauses onFactorial(_Source) = button::defaultAction() :fn::calculate().
к query.frm/Code Expert/Control/factorial_ctl→onFactorial. Наконец, откомпилируйте проект и за‐ пустите программу. Если вы не помните как компилировать и запускать программу, взгляните на раздел 1.1.2. В новом приложении выберите пункт File/New. Выскочит новая форма. Наберите число в строке ввода и нажмите на кнопку factorial. Класс fn напишет факториал в окне сообщений.
4.7.
Содержимое строки ввода
Получить содержимое строки ввода довольно мудрено. Это верно для Visual C, Delphi, OCAML, Clean, и пр. Оценивая Visual Prolog, я должен сказать, что он предлагает самый легкий доступ к эле‐ ментам управления, по сравнению с остальными языками. Хотя он все равно мудреный. Вы изучили способ получить доступ к содержимому строки ввода: Взять его окно, когда оно по‐ теряет фокус, затем использовать это окно для доступа к его содержимому, которое вы можете ис‐ пользовать для дальнейших вычислений. Вы будете рады узнать, что Visual Prolog хранит окно в фак‐ те‐переменной для вас. Следовательно, вам не требуется заигрывать с фокусом. • Создайте новый GUI проект: fact2 (раздел 1.1.1). • Добавьте новый пакет к дереву проекта: fact2/forms (раздел 4.3). • Создайте новую форму: forms/query (раздел 4.3). Добавьте на неё строку ввода (с назва‐ нием edit_ctl) и кнопку (с названием factorial_ctl), как на рис. 4.2. • Включите пункт панели задач File/New (раздел 2.2). Откомпилируйте программу, что‐ бы включить форму query в проект. • В эксперте кода добавьте (раздел 2.3): clauses onFileNew(W, _MenuTag) :S=query::new(W), S:show().
к TaskWindow.win/Menu/TaskMenu/id_file→id_file_new→onFileNew. Добавьте фрагмент clauses onFactorial(_S)=button::defaultAtcion() :-
22
fn::calculate(edit_ctl:getText()).
к query.frm/Code Expert/Control/factorial_ctl→onFactorial. Создайте класс fn внутри forms. Уберите галочку Creates Objects. Отредактируйте файлы fn.cl и fn.pro как показано ниже. %File: fn.cl class fn open core predicates classInfo : core::classInfo. calculate:(string) procedure. end class fn % File fn.pro implement fn open core constants className = "forms/fn". classVersion = "". class predicates fact:(integer, integer) procedure (i,o). clauses classInfo(className, classVersion). fact(0, 1) :- !. fact(N, N*F) :- fact(N-1, F). calculate(X) :- N= toterm(X), fact(N, F), stdio::write(F, "\n"). end implement fn
Откомпилируйте и запустите программу, как и ранее. В этой новой версии программы, текст из‐ влекается из строки ввода использованием метода edit_ctl:getText(), что гораздо проще, чем ранее.
4.8.
Примеры
В этой главе три примера: plot2 показывает, как создавать форму с кнопками и полями; factorial вычисляет факториал; fact2 тоже вычисляет факториал.
23
Глава 5: Предложения Хорна 5.1.
Функции
Я уверен, что вы знаете, что такое функция. Возможно, вы не знаете математического определе‐ ния функции, но вы имеете представление о функциях, полученное использованием калькуляторов и компьютерных программ или посещением курсов элементарной алгебры. Функция имеет функтор, который является именем функции, и аргументы. Например: sin(X) – функция. Другой пример функ‐ ции – mod(X, Y), которая возвращает остаток от деления. Когда вы хотите использовать функцию, вы подставляете постоянные значения вместо переменных, или аргументов. Например, если вы хотите найти остаток от 13, делённого на 2, вы можете набрать mod(13, 2) на вашем калькуляторе (если он имеет эту функцию, конечно же). Если вы хотите синус 30°, вы можете набрать sin(30). Можно сказать, что функции это отображения возможных значений аргумента в значение из множества результатов вычисления. Доменом называется множество возможных значений аргумен‐ та. Множество результатов вычисления называется образом. В случае функции синуса, элементами домена являются действительные числа между 0 и 2π радиан (или 0° и 360°)1. Есть одна вещь, кото‐ рую следует запомнить. Математики настаивают, что функция должна возвращать только одно зна‐ чение для каждого заданного аргумента. Таким образом, если вычисление производит большее ко‐ личество значений, оно не является функцией. Например, 4 может быть 2 или ‐22. Тогда, квадрат‐ ный корень числа не является функцией3. Что насчет функций нескольких аргументов? Например, функция max(X, Y) принимает два аргу‐ мента, и возвращает наибольший из них. В этом случае, вы можете считать, что она имеет только один аргумент, который является парой значений. Так, аргументом max(5, 2) является пара (5, 2). Ма‐ тематики говорят, что домен подобной функции – декартово произведение R×R. Есть функции, чей функтор располагается между аргументами. Это применимо в случае арифме‐ тических операторов, где пишут 5+7 вместо +(5, 7).
5.2.
Предикаты
Предикаты это функции, чьим образом является множество {verum, falsum}, или, если вам не нравятся латинские названия, используемые в логике, вы всегда можете полагаться на английский эквивалент: {true, false}. Есть несколько предикатов, известных любому, кто приложил руку к программированию, или даже студенту, посещающему лекции элементарной алгебры. Вот они: X>Y возвращает true если X больше, чем Y, иначе возвращает false. X2) && (X2) && (X2) && (X2, X