
Costas-Tyros_rus_MS
.pdf
Таблицы истинности. Для того чтобы установить значение истинности формулы, часто полага ются на таблицы истинности. Давайте изучим их на примерах. Рассмотрим верную формулу . Если 1 изображает константу true (истина), а 0 изображает false, таблицы истинности отрицания
(¬p), логической конъюнкции ( |
) и логической дизъюнкции ( |
) выглядят как |
|
||
0 |
0 |
|
1 |
0 |
0 |
0 |
1 |
|
1 |
0 |
1 |
1 |
0 |
|
0 |
0 |
1 |
1 |
1 |
|
0 |
1 |
1 |
Пользуясь неформальным языком, формула |
означает: |
|
|
||
Если p истинно, то q тоже истинно |
|
|
|
Сносная таблица истинности, выражающая эту идею, дана ниже.
0 |
|
0 |
|
1 |
0 |
|
1 |
|
1 |
1 |
|
0 |
|
0 |
1 |
|
1 |
|
1 |
Возможно доказать, что |
|
эквивалентно формуле |
; давайте проверим это утвержде |
|
ние. |
|
|
|
|
0 |
0 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
3.5.Аргументныеформы
Логические программисты часто используют разновидность доводов, называемую MODUS TOL LENDO PONENS. Записанная с помощью логических операторов эта простая и очень полезная аргу ментная форма выглядит так:
Где изображает логическое доказательство. Грубо говоря, мы говорим, что или p или q истин но; затем мы говорим, что p не истинно; таким образом, мы заключаем, что q должно быть истинно.
Очень важной аргументной формой является MODUS PONENS. Она является важной потому, что на ней основан механизм вывода Пролога.
Вы уже знаете, что означает если p то q, то есть, p предполагает q. Отсюда, означает, что q было предположено p, или q если p. Короче, первая строчка аргумента гласит, что q истинно, если p истинно; вторая гласит, что p истинно; тогда человек или машина может заключить, что q ис тинно. Давайте рассмотрим конкретный пример.
21

счастливый Человек слышалСократа Человек слышалСократа Платон
счастливый Платон
Другой допустимый аргумент называется MODUS TOLLENS:
22

Глава 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: factorial
UI Strategy: Object oriented GUI (pfc/gui)
Target Type: Exe
Base Directory: C:\vispro
Когда вы найдете шаг, указывающий:
Создайте новый GUI проект: factorial (раздел 1.1.1).
вам следует войти в диалоговое окно Project Settings (выбрав пункт Project/New из меню задач VDE1) и заполнить форму General как указано выше. Сделайте это mutatis mutandis2, так как на вашем
компьютере может не быть свободного места на диске C, или вы можете захотеть хранить ваши про граммы в папке, отличающейся от C:\vispro.
4.2.Дерево проекта
Самый лёгкий способ ориентироваться в файлах и ресурсах – щелкать мышкой по соответствую щим элементам дерева проекта:
Если вы дважды щёлкнете по папке, она откроется и покажет свое содержимое. Если вы щёлкне те по элементу правой кнопкой мыши, откроется контекстное меню, как на рисунке. Если я хочу, что бы вы зашли в эксперт кода и добавили фрагмент кода в TaskWindow.win, я скажу:
1Visual Development Environment – визуальная среда разработки
2лат. Изменив то, что следует изменить; внеся необходимые изменения.
23

В эксперте кода, добавьте код к TaskWindow/TaskWindow.win (раздел 2.3)
Чтобы выполнить это указание, отправляйтесь в дерево проекта и сделайте следующее:
1.Дважды щелкните по папке TaskWindow, чтобы открыть её, если она закрыта.
2.Щелкните правой кнопкой мыши по ветке дерева проекта TaskWindow.win, чтобы раскрыть контекстное меню, в котором будут следующие пункты:
Edit
Attribute
Delete
Code Expert
File Properties…
3. Наконец, выберите пункт Code Expert
4.2.1. Code Expert
Эксперт кода тоже имеет форму дерева.
В соответствии со своим названием, эксперт кода исполь зуется для вставки кода во многие файлы проекта. Чтобы до браться до эксперта кода, вы должны щелкнуть правой кноп
кой мыши по элементу дерева проекта, к которому вы хотите добавить код. Затем, выберите пункт Code Expert из контекст
ного меню.
В случае с формами,путь до эксперта кода можно сокра тить. Если вы дважды щелкнете по ветке формы в дереве проекта, появится прототип формы, вместе с диалогом Proper ties и двумя панелями компонентов, одна [Controls – прим. пер.] для элементов управления, другая [Layout – прим. пер.] для спо собов компоновки (см. рис. 2.3); если вы перейдёте на за кладку Events диалогового окна Properties, вы получите список событий для выбора. В прошлых главах вы имели возмож
ность работать с двумя обработчиками событий, а именно, с
MouseDownListener и с PaintResponder.
На формах присутствуют такие компоненты, как кноп ки и строки ввода. В верхней части диалогового окна Prop erties расположен раскрывающийся список для выбора этих компонентов; если вы выберете один из этих компо нентов и перейдёте на закладку Events, вы получите список событий, соответствующих выбранному компоненту. Поз же об этом будет сказано больше.
Чтобы перемещаться по дереву эксперта кода и доби раться до точек, куда вы хотите вставить код, щелкайте по нужным веткам дерева. Если вы хотите, чтобы эксперт ко да добавил прототип к листку дерева, нажмите на этот листок и затем нажмите на кнопку Add, которая появится внизу диалогового окна. Затем дважды щелкните по лист
ку снова, чтобы перейти к коду. Если я попрошу: В Экс перте кода добавьте (раздел 2.3):
clauses
onFileNew(W, _MenuTag) :
S= query::new(W), S:show().
24

к TaskWindow.win/Code Expert/Menu/TaskMenu/id_file/id_file_new, вот шаги, которым вы должны сле довать:
•Дерево проекта – Откройте папку TaskWindow дерева проекта, щелкните правой кноп кой мыши по TaskWindow.win, чтобы открыть его контекстное меню, и выберите пункт
Code Expert (рис. 2.6).
•Эксперт кода – Дважды щелкните на Menu→дважды щелкните на TaskMenu→дважды щелкните на id_file. Выберите id_file_new и нажмите кнопку Add для создания прототипа кода. Наконец, дважды щелкните на id_file_new→onFileNew. Ориентируйтесь по рис. 2.6, 2.7 и разделу 2.3. Добавьте требуемый код к файлу TaskWindow.pro.
clauses
onFileNew(W, _MenuTag) :
S= query::new(W), S:show().
4.3.Созданиеэлементапроекта
Чтобы добавить новый элемент к дереву проекта, выберите пункт
File/New in New Package
из меню задач, если вы хотите вложить элемент в новый пакет, названный так же, как и этот элемент. Если вы хотите вложить элемент в существующий пакет, выберите пункт File/New in Existing Package. Следите за тем, чтобы размещать создаваемые элементы в нужных папках.
В следующем примере пакет, содержащий форму query, размещается в корне проекта factori
al. Всегда выбирайте имена, которые что то означают. Например, если ваш пакет содержит компью терную графику, вы можете выбрать имя вроде canvasFolder1; если он содержит запросы, хорошим именем будет formcontainer2; и так далее. Пример:
•Создайте новый пакет в корне дерева проекта factorial (рис. 4.1). Пусть именем па кета будет formcontainer.
Рисунок 4.1 Создание нового пакета
•Создайте новую форму (query) внутри пакета formcontainer, выбрав ветку, соответст вующую этому пакету в дереве проекта, и выбрав пункт File/New in Existing Package из
меню задач (раздел 2.1). Для того, чтобы поместить окно в этот пакет, убедитесь, что пап ка пакета выбрана, до того, как нажимать File/New in Existing Package.
1canvas – англ. холст для рисования.
2form container (англ.) в данном случае означает«контейнер для форм [запросов]».
25

Когда вы создаете форму, IDE показывает диалоговое окно Form Window (см. рис. 4.2). Вы може те воспользоваться возможностью изменить размеры окна и добавить стр оку ввода (п од названием
edit_ct l) и кнопку (под названием facto rial_ctl), как показа но на рисунке. Вы также можете доб раться д о диалогового окна Fo rm Window, дважды щёлкнув левой кнопкой мыши по имени формы в
дереве проекта.
Рисунок 4.2 Форма со строкой ввода
Если вы дважды щёлкнете по ProjectT ree/TaskMe nu.mnu, вы получите диалоговое окно вроде то го, которое было показано на рис. 2.5. Вы можете разворачивать дерево этой спецификации меню, щелкая по его веткам, как говорилось ранее. Вам т акже может понадобиться включить какой л ибо пункт меню, как в р азделе 2.2. Также воз можно создать новый элемент мен ю, как пока зано на ниже приведённом рисунке, где я нажал на кн опку (иконку) под названием New Item и создал пункт Dr aw ing Tools, заполнив диалогово е окно. Как вы можете увидеть из рисунка, новый пункт создается изна чально включенным. Символ & в записи & File обозначает F как клавишу акселератор.
Давайте начнем новый проект с нуля, чтобы посмотреть, что мы сможе м сделать с меньшим ко личеством изображ ений, и пр оверить, сжато ли мы описываем проект Visual Prolog.
•Создайте новый G UI проект: factorial (раздел 1.1.1).
•Добавьте новый пакет к дер еву проек та: factorial/formcon tainer.
•Создайте новую форму: for ms/query (раздел 4.3). Добавьте на неё edit field строку ввода (с названием edit_ctl) и кнопку (сназванием factorial _ctl), как на рис. 4.2.
•Включи те пункт TaskMenu Fi le/New (раздел 2.2), затем добавьте (раздел 2 .3):
clauses
onFileN ew(W, _Me nuTag) :
S= query::ne w(W), S:sh ow().
кTaskW indow.win/Menu/Task Menu/id_file →id_file_new →onFileNe w.
•Постр ойте приложение, чтобы вставить новые классы в проект.
26

4.4.Создание нового класса:folder/name
Чтобы создать новый класс и вложить его в пакет formcontainer, выберите папку formcontainer в дереве проекта и выберите пункт File/New in Existing Package из меню задач VDE. Затем выберите вариант Class в диалоговом окне Project Item и введите fn в качестве имени класса в поле Name. Убе дитесь, что убрали галочку Create Objects.
Когда вы нажмёте кнопку Create, Visual Prolog покажет файлы fn.pro и fn.cl, которые содержат прототип класса fn. Наша задача – добавить функциональности к этим файлам, заменив их содержи мое листингам, приведёнными в разделе 4.6. Затем постройте приложение ещё раз, чтобы убедить ся, что Visual Prolog вставит класс fn в проект.
4.5.Содержимое строки ввода
В Visual C, Delphi, Clean, и пр. довольно сложно получить содержимое строки ввода. Оценивая Visual Prolog, я должен сказать, что он предлагает самый легкий доступ к элементам управления, по сравнению с остальными языками. Хотя он все равно мудреный. Чтобы немного облегчить положе ние вещей, IDE сохраняет дескриптор окна строки ввода в факт переменной. Чтобы оценить все пре имущества от этого, откройте query.frm, дважды щёлкнув по его ветке в дереве проекта.
Выберите button:factorial_ctl из раскрывающегося списка диалогового окна Properties, на жмите кнопку Event, и щёлкните по строчке ClickResponder в списке событий; затем добавьте сле дующий фрагмент к коду кнопки factorial_ctl:
clauses
onFactorialClick(_S) = button::defaultAction() : fn::calculate(edit_ctl:getText()).
Постройте и запустите программу.
4.6.Примеры
В этой главе вы изучили, как создать форму с кноп кой (factorial_ctl) и строкой ввода (edit_ctl); также вы узнали, как получить доступ к содержимому строки ввода. Ниже приведён класс fn, который реализует функцию факториала.
%Файл fn.cl class fn predicates
classInfo : core::classInfo. calculate:(string) procedure.
end class fn
% Файл fn.pro implement fn
open core class predicates
Рисунок 4.3 Класс fn
27

fact:(integer, integer) procedure (i,o).
clauses
classInfo("forms/fn", "1.0").
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
4.7. Представления о логике:Исчислениепредикатов
Исчисление высказываний не имеет переменных и кванторов. Это было исправлено, когда Фридрих Людвиг Готлоб Фреге (Friedrich Ludwig Gottlob Frege) показал человечеству исчисление пре дикатов. Тем не менее, с формой записи Фреге было тяжело работать; современная форма записи была представлена Джузеппе Пеано. Давайте посмотрим, как аристотелевы высказывания выглядят в современной форме записи исчисления предикатов.
Все a являются b Некоторые a являются b
28

Глава 5: Предложения Хорна
5.1.Функции
Я уверен, что вы знаете, что такое функция. Возможно, вы не знаете математического определе ния функции, но вы чувствуете, что это такое, исходя из опыта, полученного использованием кальку ляторов и компьютерных программ или посещением курсов элементарной алгебры. Функция имеет функтор, то есть её имя, и аргументы. Например: sin(X) – функция. Другой пример функции – mod(X, Y), которая возвращает остаток от деления. Когда вы хотите использовать функцию, вы подставляете постоянные значения вместо переменных, или аргументов. Например, если вы хотите найти остаток от 13, делённого на 2, вы можете набрать mod(13, 2) на вашем калькуляторе (если в нём есть эта функция, конечно же). Если вы хотите вычислить синус ⁄3, вы можете набрать sin(3.1416/3).
Можно сказать, что функция – это отображение, которое ставит в соответствие допустимому зна чению аргумента значение из множества результатов вычислений. Домен – это множество допусти мых значений аргумента. Образ – это множество результатов вычисления. В случае функции синуса, элементами домена являются действительные числа. Есть одна важная вещь, которую следует за помнить. Математики настаивают на том, чтобы функция возвращала только одно значение для каж дого заданного аргумента. Таким образом, если вычисление производит больше одного значения, оно не является функцией. Например, √4 может быть равен 2 или 21. Тогда, квадратный корень чис ла не является функцией2; хотя вы можете подогнать его под определение функции, сказав, что в об раз входят только значения больше нуля или равные ему.
А что насчет функций нескольких аргументов? Например, функция 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.
X<Y возвращает true если X меньше, чем Y, иначе возвращает false.
X=Y возвращает true если X равен Y, иначе возвращает false.
Предикат с одним аргументом говорит о свойстве или особенности этого аргумента. Можно ска зать, что такой предикат работает, как прилагательное. В языке C, ~X true, если X false, в противном случае ~X принимает значение false. Предикаты, эквивалентные этому, существуют и в других язы ках программирования. Ещё несколько примеров одноместных предикатов:
positive(X): true если X положительный, false в противном случае. exists(“text.txt”): true если файл text.txt существует, false в противном случае.
1 Под выражением √4 обычно понимается арифметический квадратный корень, т.е. корень из 4 равен 2, а не 2 или 2, как написано в тексте. Автор понимает выражение √4 как решение уравнения 4.
2 С учётом предыдущего примечания – является.
29

Предикат, имеющий более одного аргумента, показывает, что между его аргументами существу ет отношение. В случае X=Y этим отношением является равенство между X и Y. Было бы интересно иметь язык программирования с предикатами, устанавливающими свойства и отношения отличаю щиеся от того небольшого их количества, предлагаемого калькуляторами и основными компьютер ными языками. Например, многие люди чувствовали в своей жизни срочную необходимость в пред сказаниях одного из предикатов, перечисленных на рис. 5.1, особенно третьего. Пролог является языком программирования, изобретенным для удовлетворения этой потребности.
positive(X) true если X положителен, иначе false
rain(Temperature, Pressure, Humidity) возвращает true, если будет дождь при заданных температуре, давлении и влажности. Напри мер,
rain(100, 1.2, 90)
вернет true, если пойдет дождь, когда ваши измерительные при боры покажут 100°F, 1.2 атмосфер, и 90% относительной влажности.
invest(Rate, StandardDeviation, Risk) По заданным Rate,
StandardDeviation, и приемлемом Risk, этот предикат возвращает true, если вам стоит выбрать инвестирование.
Рисунок 5.1 Интересные предикаты.
5.3.Решения
Предположим, что у вас есть предикат city(Name, Point), который определяет координаты го рода на карте. Предикат city/2 имеет домен1
city : (string Name, pnt Position).
и может быть определен как база фактов:
city(“Salt Lake”, pnt(30, 40)). city(“Logan”, pnt(100, 120)). city(“Provo”, pnt(100, 200)). city(“Yellowstone”, pnt(200, 100)).
Этот предикат проверяет, является ли заданное положение заданного города верным, когда кто либо не уверен насчет этого. Вот несколько запросов, которые можно поставить предикату city/2.
city("Salt Lake", pnt(30, 40)) → true city("Logan", pnt(100, 200)) → false city("Provo", pnt(100, 200)) → true
1 N.B. Предикатами являются функции, чьим доменом может быть любое декартово произведение, но чьим образом может быть только множество {true, false}. – прим. авт.
30