Разработка диалоговой системы, оформленной в виде пакета прикладных программ и реализующей идею искусственного интеллекта
1.Задание на лабораторную работу
Разработать диалоговую систему, оформленную в виде пакета прикладных программ и реализующую идею искусственного интеллекта. Для этого необходимо:
* Самостоятельно выбрать предметную область интеллектуального пакета
* Для выбранной предметной области описать семантическую сеть и правила вывода (базу знаний)
* Разработать блоки системной части пакета, реализующие:
* машину логического вывода
* процедуры работы с семантической сетью
* Подготовить отладочные варианты наборов данных
* Провести машинный эксперимент
* Описать полученные результаты
2.Руководство пользователя
2.1. Назначение программы
В качестве предметной области была выбрана кулинария.
Программа предназначена для получения информации о составе различных кулинарных блюд. Пользователю предоставляется возможность перечислить несколько ингредиентов и получить информацию о том, что из этого набора можно приготовить, или ввести интересующее блюдо и знать из чего оно состоит, или ввести как ингредиенты так и готовый продукт и знать достаточно ли введенных компонент для приготовления выбранного блюда.
Программа позволяет корректировать имеющуюся базу знаний и создавать новую. Корректировка заключается в добавлении и далении знаний и фактов. Но в целях соблюдения целостности базы знаний программа не позволит далить некоторые знания и факты. Если факта входит в состав знания, то его даление повлечет нарушение целостности базы. Программа предложит сначала далить знания, в которые входит этот факт, потом же сам факт.
2.2.Описание базы знаний
База знанийакты (декларативные знания)Правила (процедурные знания)
Декларативные знания
Числовой кодЗначение12 яйца23 яйца34 яйца4100 грамм молока5200 грамм молока6400 грамм молока70,5 ложки соли81 ложка соли92 ложки соли101 стакан муки112 стакана муки124 стакана муки1310 ложек сахара1413 ложек сахара1515 ложек сахара1Изюм1Дорожжи1Творог1Омлет на 1-го человека2Омлет на 2-х человек2Опара2Тесто2Блины2Яичница на 1-го человека2Яичница на 2-х человек2Кулич2Ватрушка2Жарить2Печь
Процедурные знания
Код порождаемого фактКоличество
свидетельствСвидетельства1941,4,7,282043,5,8,282145,9,11,1722521,3,4,12,1523,282431,7,282533,8,2826322,16,2927322,18,29
2.3. Описание диалога
Данная программа построена по принципу диалога с пользователем, что обеспечивает добство и психологический комфорт при работе с ней.
После запуска программы появляется стандартное windows-окно - в данном случае главное окно, приглашающее вас к работе. Данное окно содержит картинку, располагающую вас к приятной реализации программного продукта, и меню из трех пунктов: Главное меню, содержащее подпункты: Работ с системой и Выход, "Помощь" и О программе. Выбрав Работ с системой, вы не только знаете о ее названии и версии, но и о создателях таковой. Выбор можно осуществлять кроме мыши с помощью сочетания клавиш (Alt + соответствующая буква). Нажав меню Работ с системой, вы окажитесь в окне CulinaryMiracles где вам будет представлены следующие возможности системы: Правка, Работа, Выход. Ознакомившись с пунктом Помощь, в котором содержится общая информация по данному программному продукту, вы смело можете приступать к реализации основных действий.
При выборе Работ с системойа появится рабочее окно, где вам будет предложены имеющиеся факты и цели исходной базы знаний. Теперь все в ваших руках. Данная программа предоставляет три варианта реализации ее возможностей. Во-первых, вы можете выбрать интересующие вас факты и спросить у системы, что можно из них приготовить, во-вторых, выбрать желаемые цели и запросить, какие факты необходимы для их реализации, и наконец в-третьих, выбрать и факты и цели, затем система выдаст сообщение о том, что все в порядке либо подскажет вам какие из выбранных фактов оказались лишними, каких не хватает. Выше перечисленные действия реализуются легко и просто с помощью кнопок: добавить факт/цель в список выбранных фактов/целей - "(", далить факт/цель из списка выбранных фактов/целей - "(" и запуск на выполнение "OK". Для выполнения последующих запросов вам необходимо нажать кнопку "Сброс".
Для модернизации возможностей "Culinary Miracles" воспользуйтесь пунктом Правка, где вам будут представлены факты, снабженные информацией, то есть, простой ли это факт или порождаемый факт с содержащимися в нем свидетельствами. В данном пункте меню вы можете не только добавить или далить факты исходной базы знаний, но и сохранить измененную (новую) базу в файл, также открыть любую из предложенных.
Все компоненты программы снабжены помощью, подсказками, что облегчает работу пользователя, как-то: сообщения о допущенных ошибках, запрос системы о том, действительно ли вы хотите совершить то или иное действие и т.д. Окончив работу, вы покидаете систему с помощью пункта Выход или другими стандартными способами Windows.
2.4. Описание работ машинного логического вывода
2.4.1. Описание стратегии
Стратегия реализации поставленной задачи разбита на 3 возможных варианта желаний пользователя. Все зависит от того, что пользователь введет: только факты (компоненты), только знания (блюда), и факты и знания. Система сама распознает, какой вариант введен и пойдет по нужному пути.
Случай 1. Введены только факты. В данном случае система задействует алгоритм планирования с прямым ходом. Если хоть один целевой факт (т.е. съедобное блюдо) достижим, то программа покажет, что именно. Результатом может стать только одно блюдо. Т.е. на неимеющее смысла перечисление всех ингредиентов, программа скромно выдаст только одно блюдо.
Случай 2. Введены только знания. В этом случае программа задействуета алгоритм планирования с обратным ходом. Можно ввести как одно, так и несколько блюд, и программа выдаст все ингредиенты для интересующих знаний.
Случай 3. Введены и факты и знания. В этом случае система анализирует, что необходимо для введеных знаний, потом какие необходимые факты ввел пользователь и в заключении сообщает какие факты лишние, каких недостает.
2.4.2. Прямое планирование
Подготовка: обнуление различных ключей и счетчиков.
Цикл на организацию обработки базы знаний до тех пор, пока не будет получено первое целевое значение или не станет ясна невозможность его получения.
Цикл на просмотр всех правил до порождения целевого факта.
.Внутри этого цикла осуществляется проверка н необходимость порождения правила и возможность порождения правила. Если и то и то подтверждается, то порождается факт (правило), и если этот факт целевой, то обработка заканчивается и этот факт запоминается, иначе переход к следующему правилу.
. Конец цикла.
Конец алгоритма, еслиа был порожден целевой факт, то выдача результата на экран, иначе выдача сообщения о невозможности приготовления ни одного блюда из предложенных компонентов.
лгоритм прямого планирования реализована в процедуре Direct.
2.4.3. Обратное планирование
Подготовка: обнуление различных ключей и счетчиков.
Цикл на просмотр всех введенных пользователем правил. Занесение этого значения в специальный массив.
Цикл на разложение каждого введенного пользователем правила на простые компоненты. Все компоненты (факты и знания)а заносятся в специальный массив, которыйа анализируется на наличие в нем правил. Если правило найдено, то его разлагают на более простые составляющие, и так то тех пор, пока от введенного правила останутся только простые факты.
Конеца цикла. Переход к следующему введенному правилу.
Конец алгоритма. Выдача результатов на экран.
лгоритм прямого планирования реализована в процедуре Inv.
2.5.Примеры реализации основных функций пользователя
Задание фактов и получение цели
Задание целей и получение фактов
Задание фактов и целей и получение информации о лишних и недостающих фактах
Задание фактов и целей и получение положительного сообщения системы
Добавление факта в базу
3.Описание программы
3.1. Общие свойства
Любая программа в интегрированной среде разработки приложений Delphi 4 состоит из файла проекта (файл с расширением dpr) и нескольких модулей (файлы с расширением pas), каждый из которых описывает программную единицу Object Pascal. Файл проект представляет собой программу, написанную на языке Object Pascal и предназначенную для обработки компилятором. Эта программа автоматически создается Delphi, содержит лишь несколько строк и не предназначена для редактирования.
Данная программа написана с помощью инструмента программирования Delphi 4 и состоит из файла проекта CulinaryMiraclesи трех модулей: Culinary.pas, About.pas, Help.pas.
3.2. Логическая структура программы
Так как язык программирования Object Pascal - это объектно-ориентированный язык, то отобразить схематично многообразие процедур - обработчиков событий нажатий на многочисленные кнопки, вызовов меню и прочее не позволяет лист бумаги. Так что логическая структура отображает только модули работы системы по обработке введенных данных, добавлению и удалению фактов, сохранению и открытию базы знаний.
3.3.Описание функций модулей
1procedure FormActivate Задание начальных параметров, загрузка базы знаний Base.dat2.
2procedure Timer1Timer Обеспечивает бегущие надписи при заставке3. 3procedure N6ClickОбработчик вызова меню О программе4.
4procedure N2ClickОбработчик вызова меню Работ с системой5.
5Procedure SpeedButton3ClickОбработчик нажатия кнопки Выход, выход из программы6.
6Procedure SpeedButton1ClickОбработчик нажатия кнопки Правка7.
7Procedure SpeedButton8ClickОбработчик нажатия кнопки Возврат, возврат в главное меню8.
Procedure SpeedButton2ClickОбработчик нажатия кнопки Работа, появления окна для выбора фактов и знаний9.
procedure N7ClickОбработчик вызова пункта Возврат в окне выбора фактов
procedure BitBtn1ClickЗанесение фактов в окошко "Выбранные факты"11.
Procedure BitBtn3ClickЗанесение фактов в окошко "Выбранные цели"12.
Procedure BitBtn5ClickОбработчик нажатия кнопки ОК, обработка введеных данных, выдача резльтатов13.
Procedure BitBtn6ClickОбработчик нажатия кнопки Сброс, обнуление счетчиков14. Procedure Timer2TimerОбеспечивает выплывание надписи ОК!15.
Procedure LoadBaseПроцедура открытия новой базы16.
procedure SaveBaseПроцедура сохранения текущей базы17.
Procedure SpeedButton6ClickОбработчик нажатия кнопки Открыть БЗ, выдача соответствующего диалогового окна18.
Procedure SpeedButton7ClickОбработчик нажатия кнопки Сохранить как, выдача соответствующего диалогового окна19.
procedure ListBox1ClickОтображение фактов в окне "Имеющиеся факты"20.
Procedure SpeedButton4Click Обработчик нажатия кнопки Добавить, отображение окошка для добавления в БЗ фактов21.
Procedure SpeedButton10ClickОбработчик нажатия кнопки Отмена в окошке для добавления фактов, возврат в окно Правка22.
Procedure RadioGroup1ClickОбработчик выбора типа факта в окне добавления фактов23.
procedure AddSimpleFactПроцедура добавления простого факта24.
Procedure SpeedButton9ClickОбработчик нажатия кнопки ОК в окошке для добавления фактов, вызов процедуры AddSimpleFact25.
Procedure SpeedButton11ClickОбработчик нажатия кнопки Добавить при добавлении фактов в БЗ, эта кнопка добавляет факты в знание при его определении26. Procedure AddComplexFactПроцедура добавления правила27.
procedure DeleteFactПроцедура даления факта28.
Procedure SpeedButton5ClickОбработчик нажатия кнопки Удалить29.
Procedure BitBtn2ClickУдаление фактов в окне "Выбранные факты"30.
procedure BitBtn4ClickУдаление фактов в окне "Выбранные цели"31.
procedure N5ClickВызов пункта меню Помощь, появление окна Помощь32.
procedure N4ClickВызов пункта меню Выход, выход из программы
4.Список литературы
1. В.А.Благодатских, С.Н.Семенов, А.М.Хамов. Лабораторный практикум по прикладному и системному программированию.- М.: Финансы и статистика, 1985.
2. Фаронов В.В. Delphi4,учебный курс. - М.: "Нолидж",1.
3. В.А. Благодатских, М.А. Енгибарян, Е.В. Ковалевская. Экономика, разработка и использование программного обеспечения ЭВМ. - М.:Финансы и статистика, 1995.
4. Роб Бс, Майк Фервай. Delphi 4 Полное руководство - Киев, издательская группа BHV, 1.
5.Приложения
5.1.Листинги программы
unit Culinary;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, jpeg, Menus, Buttons;
type
TForm1 = class(TForm)
Image1: TImage;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Timer1: TTimer;
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
N6: TMenuItem;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
ListBox1: TListBox;
ListBox2: TListBox;
Label4: TLabel;
Label5: TLabel;
Bevel1: TBevel;
Bevel2: TBevel;
SpeedButton4: TSpeedButton;
SpeedButton5: TSpeedButton;
SpeedButton6: TSpeedButton;
SpeedButton7: TSpeedButton;
SpeedButton8: TSpeedButton;
Bevel3: TBevel;
ListBox4: TListBox;
ListBox5: TListBox;
ListBox6: TListBox;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
BitBtn3: TBitBtn;
BitBtn4: TBitBtn;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
Bevel4: TBevel;
Bevel5: TBevel;
N7: TMenuItem;
BitBtn5: TBitBtn;
ComboBox1: TComboBox;
ComboBox2: TComboBox;
Label11: TLabel;
Label12: TLabel;
BitBtn6: TBitBtn;
Label13: TLabel;
Timer2: TTimer;
ListBox3: TListBox;
OpenDialog1: TOpenDialog;
SaveDialog1: TSaveDialog;
Bevel6: TBevel;
Bevel7: TBevel;
Label6: TLabel;
ComboBox3: TComboBox;
Edit1: TEdit;
RadioGroup1: TRadioGroup;
Panel1: TPanel;
SpeedButton9: TSpeedButton;
SpeedButton10: TSpeedButton;
Label14: TLabel;
Label15: TLabel;
SpeedButton11: TSpeedButton;
procedure FormActivate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure N6Click(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure SpeedButton3Click(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton8Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
procedure N7Click(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
procedure BitBtn3Click(Sender: TObject);
procedure BitBtn5Click(Sender: TObject);
procedure BitBtn6Click(Sender: TObject);
procedure Timer2Timer(Sender: TObject);
procedure LoadBase;
procedure SaveBase;
procedure SpeedButton6Click(Sender: TObject);
procedure SpeedButton7Click(Sender: TObject);
procedure ListBox1Click(Sender: TObject);
procedure SpeedButton4Click(Sender: TObject);
procedure SpeedButton10Click(Sender: TObject);
procedure RadioGroup1Click(Sender: TObject);
procedure AddSimpleFact;
procedure SpeedButton9Click(Sender: TObject);
procedure SpeedButton11Click(Sender: TObject);
procedure AddComplexFact;
procedure DeleteFact;
procedure SpeedButton5Click(Sender: TObject);
procedure BitBtn2Click(Sender: TObject);
procedure BitBtn4Click(Sender: TObject);
procedure N5Click(Sender: TObject);
procedure N4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TFactFile = record {факт}
Number:integer; {номер факта}
Znach:string[40]; {значение факта}
Q:integer; {количество порождаемых фактов}
FactIn:array[1..10] of integer; {массив порождаемых фактов}
Zel:byte;{Целевой или нецелевой факт}
end;
TKnow = Record {порождаемый факт}
Number:integer; {номер порождаемого факта}
Q:integer; {количество порождаемых фактов}
FactIn:array[1..10] of integer; {массив порождаемых фактов}
Zel:byte;
end;
TFact= record {факт}
Number:integer; {номер факта}
Znach:string[40]; {значение факта}
end;
TBase=Record
Fact:array[1..40] of integer;
Rule:array [1..40] of TKnow;
end;
TFF=file of TFactFile;
ar
Form1: TForm1;
FF:TFF;
TermFact:array[1..50] of integer; {массив c тем что хотим иметь на выходе}
NE,NK,NF,NF1,NFF,NR,KEND,Rez,NST,Num:integer;
Spis:array[1..30] of integer; {необходимые факты для цели}
SpisF:array[1..30] of integer; {выбранные факты}
BaseKnow:TBase;
Knowledge:array[1..5] of integer; {массив с выбранными правилами}
VectFact:array[1..50] of TFact; {база фактов}
implementation
uses About, Help;
{$R *.DFM}
procedure TForm1.FormActivate(Sender: TObject);
ar
Know:TKnow;
Fact:TFact;а FactFile:TFactFile;
i,j:integer;
begin
NF:=0;NF1:=0;NK:=0;
AssignFile(FF,'Base.dat'); {Файл с фактами}
Reset(FF);
NFF:=0;
While Not eof(FF) do
begin
Read(FF,FactFile);
NFF:=NFF+1;
VectFact[NFF].Number:=FactFile.Number;
VectFact[NFF].Znach:=FactFile.Znach;
ListBox1.Items.Add(VectFact[NFF].Znach);
ListBox3.Items.Add(VectFact[NFF].Znach);
if FactFile.Q>1 then
begin
NR:=NR+1;
BaseKnow.Rule[NR].Number:=FactFile.Number;
BaseKnow.Rule[NR].Zel:=FactFile.Zel;
ListBox5.Items.Add(FactFile.Znach);
BaseKnow.Rule[NR].Q:=FactFile.Q;
for i:=1 to BaseKnow.Rule[NR].Q do
BaseKnow.Rule[NR].FactIn[i]:=FactFile.FactIn[i];
end;
end;
closefile(FF);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
label1.top:=label1.top-2;
label2.left:=label2.left+4;
label3.top:=label3.top+2;
if label2.left=100 then
timer1.Enabled:=false;
end;
procedure TForm1.N6Click(Sender: TObject);
begin
AboutBox.Show;
end;
procedure TForm1.N2Click(Sender: TObject);
begin
N1.Visible:=false;
N2.Visible:=false;
N3.Visible:=false;
N4.Visible:=false;
{N5.Visible:=false;
N6.Visible:=false;}
label1.Visible:=false;
label2.Visible:=false;
label3.Visible:=false;
form1.Height:=150;
form1.Width:=185;
form1.BorderStyle:=bsDialog;
form1.Position:=poScreenCenter;
speedbutton1.Visible:=true;
speedbutton2.Visible:=true;
speedbutton3.Visible:=true;
end;
procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
close;
end;
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
form1.Height:=343;
form1.Width:=450;
form1.BorderStyle:=bsSingle;
form1.Position:=poScreenCenter;
speedbutton1.Visible:=false;
speedbutton2.Visible:=false;
speedbutton3.Visible:=false;
speedbutton4.Visible:=true;
speedbutton5.Visible:=true;
speedbutton6.Visible:=true;
speedbutton7.Visible:=true;
speedbutton8.Visible:=true;
listbox1.Visible:=true;
listbox2.Visible:=true;
bevel1.Visible:=true;
bevel2.Visible:=true;
bevel3.Visible:=true;
bevel3.Width:=430;
label4.Visible:=true;
label5.Visible:=true;
label6.Visible:=true;
end;
procedure TForm1.SpeedButton8Click(Sender: TObject);
begin
form1.Height:=150;
form1.Width:=185;
form1.BorderStyle:=bsDialog;
form1.Position:=poScreenCenter;
speedbutton1.Visible:=true;
speedbutton2.Visible:=true;
speedbutton3.Visible:=true;
speedbutton5.Visible:=false;
speedbutton6.Visible:=false;
speedbutton7.Visible:=false;
speedbutton8.Visible:=false;
listbox1.Visible:=false;
listbox2.Visible:=false;
bevel1.Visible:=false;
bevel2.Visible:=false;
bevel3.Visible:=false;
bevel3.Width:=481;
label4.Visible:=false;
label5.Visible:=false;
label6.Visible:=false;
panel1.Visible:=false;
edit1.Visible:=false;
combobox3.Visible:=false;
radiogroup1.Visible:=false;
speedbutton11.visible:=false;
end;
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
form1.Height:=343;
form1.Width:=503;
form1.BorderStyle:=bsSingle;
form1.Position:=poScreenCenter;
speedbutton1.Visible:=false;
speedbutton2.Visible:=false;
speedbutton3.Visible:=false;
BitBtn5.Visible:=true;
BitBtn6.Visible:=true;
bevel3.Visible:=true;
bevel4.Visible:=true;
bevel5.Visible:=true;
bevel6.Visible:=true;
bevel7.Visible:=true;
ListBox3.Visible:=true;
ListBox4.Visible:=true;
ListBox5.Visible:=true;
ListBox6.Visible:=true;
label7.Visible:=true;
label8.Visible:=true;
label9.Visible:=true;
label10.Visible:=true;
label11.Visible:=true;
label12.Visible:=true;
ComboBox1.Visible:=true;
ComboBox2.Visible:=true;
BitBtn1.Visible:=true;
BitBtn2.Visible:=true;
BitBtn3.Visible:=true;
BitBtn4.Visible:=true;
N7.Visible:=true;
end;
procedure TForm1.N7Click(Sender: TObject);
begin
form1.Height:=150;
form1.Width:=185;
form1.BorderStyle:=bsDialog;
form1.Position:=poScreenCenter;
speedbutton1.Visible:=true;
speedbutton2.Visible:=true;
speedbutton3.Visible:=true;
BitBtn5.Visible:=false;
BitBtn6.Visible:=false;
bevel3.Visible:=false;
bevel4.Visible:=false;
bevel5.Visible:=false;
bevel6.Visible:=false;
bevel7.Visible:=false;
ListBox3.Visible:=false;
ListBox4.Visible:=false;
ListBox5.Visible:=false;
ListBox6.Visible:=false;
label7.Visible:=false;
label8.Visible:=false;
label9.Visible:=false;
label10.Visible:=false;
BitBtn1.Visible:=false;
BitBtn2.Visible:=false;
BitBtn3.Visible:=false;
BitBtn4.Visible:=false;
N7.Visible:=false;
label11.Visible:=false;
label12.Visible:=false;
ComboBox1.Visible:=false;
ComboBox2.Visible:=false;
BitBtn6Click(Sender);
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
ar
rab:integer;
begin
rab:=ListBox3.itemindex;
listbox4.Items.Add(VectFact[rab+1].Znach);
NF1:=NF1+1;
SpisF[NF1]:=VectFact[rab+1].Number;
BaseKnow.Fact[NF1]:=VectFact[rab+1].Number;
NF:=NF1;
end;
procedure TForm1.BitBtn3Click(Sender: TObject);
ar rab,i,j:integer;
begin
rab:=ListBox5.itemindex;
for i:=1 to NFF do
if BaseKnow.Rule[rab+1].Number=VectFact[i].Number then
begin
listbox6.Items.Add(VectFact[i].Znach);
NK:=NK+1;
Knowledge[NK]:=VectFact[i].Number;
end;
end;
Procedure Direct;
ar
KIZ,NS,KA,k,i,l,j:integer;
begin
{Теперь алгоритм прямого хода}
KEnd:=0;KIZ:=0;NS:=0;
While ((KEnd=0) and (KIZ=0)) do
begin
{организация обработки БЗ до тех пор, пока не получим}
{требуемое целевое значение или не станет ясна }
{невозможность его получения}
KIZ:=1;
i:=1;
While (i<=NR) and (Kend=0) do
begin
{Просмотр всех правил до порождения}
{целевого факта}
KA:=0; {Проверка: нужно ли порождать факт?}
k:=1;
While ((KA=0) and (K<=NF)) do
begin
if BaseKnow.Rule[i].Number=BaseKnow.Fact[k] then
KA:=1; {Факт входит в множество имеющихся}
k:=k+1;
end;
{Проверка: можно ли породить факт?}
j:=1;
While ((j<=BaseKnow.Rule[i].Q) and (KA=0)) do
begin
{Анализ порождающих фактов}
KA:=1; k:=1;
While (k<=NF) and (KA=1) do
begin
{Проверка наличия порождающего факта}
{есть ли факт в БЗ}
if BaseKnow.Rule[i].FactIn[j]=BaseKnow.Fact[k] then
KA:=0;
k:=k+1;
end;
{если при выходе КА=1, то нет факта,}
{необходимого для порождения}
j:=j+1;
end;
if KA=0 then
begin
{Все факты, необходимые для порождения}
{нового факта, есть в наличие}
NF:=NF+1;
BaseKnow.Fact[NF]:=BaseKnow.Rule[i].Number;
KIZ:=0;
{Проверка: является ля порожденный факт}
{целевым}
if BaseKnow.Rule[i].Zel=1 then
begin
KEND:=1;
Rez:=BaseKnow.Rule[i].Number;
end;
end;
i:=i+1;
end;
{Конец очередного просмотра всех правил}
{Конец обработки БЗ}
end;
end;
Procedure Inv;
ar
KVPC,KVPF,AnFact,NS1,Rab,FindFactAn:integer;
L,NS,i,j,k,KA:integer;
begin
{Алгоритм обратного хода}
KEnd:=0; L:=1; NST:=0;
While (L<=NK) do
begin
{Организация просмотра всех целевых}
{фактов, пока не подтвердится возможность}
{порождения каког-л. из них}
KEND:=0;
Nst:=Nst+1;
Spis[Nst]:=Knowledge[l];
While (Kend=0)do
begin
FindFactAn:=0;
j:=0;
While (FindFactAn=0)and( j<=NST) doа {выбор факта для анализа}
begin
forа k:=1 to NR do
if BaseKnow.Rule[k].Number=Spis[j]
then
begin
FindFactAn:=1; {Ищем, есть ли правило}
AnFact:=Spis[j]; {которое можно породить}
for i:=j to Nst-1 do
Spis[i]:=Spis[i+1];
Nst:=Nst-1;
end;
j:=j+1;
end;
if FindFactAn=0 then
KEnd:=1 {Факта для анализа нет, конец анализа}
else
begin
i:=1;
While (I<=NR) do
begin
{анализ возм-ти порождения}
{выбранного факта}
if AnFact=BaseKnow.Rule[i].Number then
begin
{требуемый факт является порожденным}
for j:=1 to BaseKnow.Rule[i].Q do
begin
NST:=NST+1;
Spis[Nst]:=BaseKnow.Rule[i].FactIn[j];
end;
end;{конец анализа порождаемого факта}
i:=i+1;
аend;{While }
end;
end;
l:=l+1;
end;{Окончание обработки всех целевых фактов}
if NST=NK then KEND:=0 else KEND:=1;
{Ни один из целевых фактов не может быть порожден}
end;
procedure TForm1.BitBtn5Click(Sender: TObject);а {нажали кнопку ОК}
ar
i,j,k,KA,l:integer;
begin
BitBtn5.enabled:=false;
if (NF1<>0) and (NK=0) then {факты введены, цель не введена}
begin
Direct;
if Kend<>0 then
begin
for i:=1 to NFF do
if VectFact[i].Number=Rez then
ListBox6.Items.Add(VectFact[i].Znach);
Label10.Caption:='Вы приготовите:';
Label10.Font.Color:=clnavy;
end
else
Application.MessageBox('Из выбранных компонентов ничего нельзя приготовить!','Ошибка!',mb_iconwarning);
end;
if (NF1=0) and (NK<>0) then {факты не введены, цель введена}
begin
Inv;
if KEnd<>0 then
begin
for i:=1 to NST do
for j:=1 to NFF do
if Spis[i]=VectFact[j].Number then
ListBox4.Items.Add(VectFact[j].Znach);
Label8.Caption:='Вам необходимо:';
Label8.Font.Color:=clnavy;
end;
аend;
if (NK<>0) and (NF1<>0) then {анализ на совпадение фактов с целью}
begin
k:=1;
While (k<=NR) do
begin {Если есть порождаемые факты}
i:=1; {то раскладываем их на простые составляющие}
KA:=0;
While (i<=NF1)and (KA=0) do
begin
if BaseKnow.Rule[k].Number=SpisF[i] then
begin
for j:=i to NF1-1 do
SpisF[j]:=SpisF[j+1];
NF1:=NF1-1;
KA:=1;
end;
i:=i+1;
end;
if KA=1 then
begin
for i:=1 to BaseKnow.Rule[k].Q do
begin
NF1:=NF1+1;
SpisF[NF1]:=BaseKnow.Rule[k].FactIn[i];
end;
k:=0;
end;
k:=k+1;
end;
INV;
i:=1;
While i<=NF1 do {Проверка, что лишнее}
begin {или чего не хватает}
KA:=0;
j:=1;
While (j<=NST) and (KA=0) do
begin
if SpisF[i]=Spis[j] then
Ka:=1;
j:=j+1;
end;
if KA=1 then
begin
for k:=i to NF1-1 do
SpisF[k]:=SpisF[k+1];
i:=i-1;
NF1:=NF1-1;
for l:=j-1 to NST-1 do
Spis[l]:=Spis[l+1];
NST:=Nst-1;
end;
i:=i+1;
end;
if (Nst=0)and (NF1=0) then
Timer2.Enabled:=true else
begin
KA:=0;
for i:=1 to NST do
for j:=1 to NFF do
begin
if (Spis[i]=VectFact[j].Number) and (KA=0)а then
begin
combobox2.Text:=VectFact[j].Znach;
KA:=1;
end;
if (Spis[i]=VectFact[j].Number) and (KA=1)а then
combobox2.Items.Add(VectFact[j].Znach);
end;
KA:=0;
for i:=1 to NF1 do
for j:=1 to NFF do
begin
if (SpisF[i]=VectFact[j].Number) and (KA=0) then
begin
аcombobox1.Text:=VectFact[j].Znach;
KA:=1;
end;
if (SpisF[i]=VectFact[j].Number) and (KA=1) then
combobox1.Items.Add(VectFact[j].Znach);
end;
end;
end;
if (Nk=0) and (NF1=0) then
begin
Application.MessageBox('Исходные данные не введены!','Ошибка',mb_iconwarning);
BitBtn5.Enabled:=true;
end;
end;
procedure TForm1.BitBtn6Click(Sender: TObject);
begin
listbox4.Items.Clear;
listbox6.Items.Clear;
label10.Caption:='Выбранные цели';
label8.Caption:='Выбранные факты';
Label10.Font.Color:=cllime;
Label8.Font.Color:=cllime;
NK:=0;
NF1:=0;
label13.Visible:=false;
label13.Top:=104;
ComboBox1.Clear;
ComboBox2.Clear;
BitBtn5.enabled:=true;
end;
procedure TForm1.Timer2Timer(Sender: TObject);
begin
label13.Visible:=true;
label13.top:=label13.top+2;
if label13.top=150 then
timer2.Enabled:=false;
end;
procedure TForm1.LoadBase;
ar
i:integer;
FF: TFF;
FactFile:TFactFile;
begin
i:=0;
OpenDialog1.Filter:='База знаний|*.dat';
if not OpenDialog1.Executeа then
exit;
if FileExists(OpenDialog1.FileName)=false then
begin
Application.MessageBox('Файл с таким именем не найден!','Error',MB_iconwarning);
exit;
end
else
begin
AssignFile(FF,OpenDialog1.FileName);
reset(FF);
NR:=0;
NFF:=0;
While Not eof(FF) do
begin
Read(FF,FactFile);
NFF:=NFF+1;
VectFact[NFF].Number:=FactFile.Number;
аVectFact[NFF].Znach:=FactFile.Znach;
ListBox3.Items.Add(VectFact[NFF].Znach);
ListBox1.Items.Add(VectFact[NFF].Znach);
if FactFile.Q>1 then
begin
NR:=NR+1;
BaseKnow.Rule[NR].Number:=FactFile.Number;
BaseKnow.Rule[NR].Zel:=FactFile.Zel;
ListBox5.Items.Add(FactFile.Znach);
BaseKnow.Rule[NR].Q:=FactFile.Q;
for i:=1 to BaseKnow.Rule[NR].Q do
BaseKnow.Rule[NR].FactIn[i]:=FactFile.FactIn[i];
end;
end;
end;
closefile(FF);
end;
procedure TForm1.SpeedButton6Click(Sender: TObject);
ar
inf:integer;
begin
inf:=Application.Messagebox('Загрузить новую БЗ?','Question',MB_YESNO+MB_ICONQUESTION);
if inf=idNO then
аexit;
if inf=idYes then
begin
ListBox1.Clear;
ListBox2.Clear;
ListBox3.Clear;
ListBox4.Clear;
ListBox5.Clear;
ListBox6.Clear;
LoadBase;
end;
end;
procedure TForm1.SaveBase;
ar i,k,j:integer;
FF: TFF;
FactFile:TFactFile;
begin
SaveDialog1.Filter:='База знаний|*.dat';
if SaveDialog1.Execute then
begin
assignfile(FF,SaveDialog1.filename);
rewrite(FF);
for i:=1 to NFF do
Begin
FactFile.Number:=VectFact[i].Number;
FactFile.Znach:=VectFact[i].Znach;
FactFile.Q:=0;
FactFile.Zel:=0;
for j:=1 to NR do
if VectFact[i].Number=BaseKnow.Rule[j].Number then
begin
FactFile.Q:= BaseKnow.Rule[j].Q;
FactFile.Zel:= BaseKnow.Rule[j].Zel;
for k:=1 toа BaseKnow.Rule[j].Q do
FactFile.FactIn[k]:=BaseKnow.Rule[j].FactIn[k];
end;
write(ff,FactFile);
end;
end
else exit;
closefile(FF);
end;
procedure TForm1.SpeedButton7Click(Sender: TObject);
begin
SaveBase;
end;
procedure TForm1.ListBox1Click(Sender: TObject);
ar
i,j,rab,r,t:integer;
begin
label6.Visible:=true;
t:=0;
ListBox2.Clear;
rab:=ListBox1.Itemindex;
for i:=1 to NR do
if VectFact[rab+1].Number=BaseKnow.Rule[i].Number then
begin
t:=1;
for j:=1 to BaseKnow.Rule[i].Q do
for r:=1 to NFF do
if VectFact[r].Number=BaseKnow.Rule[i].FactIn[j]then
ListBox2.Items.Add(VectFact[r].Znach);
end;
if t=1 then
label6.Caption:='Порождаемый факт';
if t=0 then
label6.Caption:='Простой факт';
{}
end;
procedure TForm1.SpeedButton4Click(Sender: TObject);
begin
speedbutton6.Enabled:=false;
speedbutton7.Enabled:=false;
speedbutton8.Enabled:=false;
panel1.Visible:=true;
edit1.Visible:=true;
combobox3.Visible:=true;
radiogroup1.Visible:=true;
radiogroup1.ItemIndex:=0;
Num:=0;
edit1.SetFocus;
edit1.Clear;
end;
procedure TForm1.SpeedButton10Click(Sender: TObject);
begin
panel1.Visible:=false;
edit1.Visible:=false;
combobox3.Visible:=false;
radiogroup1.Visible:=false;
speedbutton11.visible:=false;
speedbutton6.Enabled:=true;
speedbutton7.Enabled:=true;
speedbutton8.Enabled:=true;
end;
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
if radiogroup1.ItemIndex=0 then
begin
combobox3.Enabled:=false;
label14.Enabled:=false;
speedbutton11.visible:=false;
edit1.SetFocus;
end;
if radiogroup1.ItemIndex=1 then
begin
combobox3.Enabled:=true;
label14.Enabled:=true;
speedbutton11.visible:=true;
edit1.SetFocus;
end;
end;
procedure TForm1.AddSimpleFact;
ar
i,t:integer;
r:string;
begin
r:=edit1.text;
for i:=1 to NFF do
if r=VectFact[i].Znach then
begin
Application.MessageBox('Такой факт же существует!','Ошибка',mb_iconwarning);
exit;
end;
t:=VectFact[NFF].Number;
NFF:=NFF+1;
ectFact[NFF].Number:=t+1;
ectFact[NFF].Znach:=r;
ListBox1.items.add(VectFact[NFF].Znach);
ListBox3.items.add(VectFact[NFF].Znach);
end;
procedure TForm1.AddComplexFact;
ar
i,t:integer;
r:string;
begin
r:=edit1.text;
for i:=1 to NFF do
if r=VectFact[i].Znach then
begin
Application.MessageBox('Такой факт же существует!','Ошибка',mb_iconwarning);
exit;
end;
t:=VectFact[NFF].Number;
NFF:=NFF+1;
ectFact[NFF].Number:=t+1;
ectFact[NFF].Znach:=r;
ListBox1.items.add(VectFact[NFF].Znach);
ListBox3.items.add(VectFact[NFF].Znach);
ListBox5.items.add(VectFact[NFF].Znach);
NR:=NR+1;
BaseKnow.Rule[NR].Number:=VectFact[NFF].Number;
BaseKnow.Rule[NR].Q:=Num;
BaseKnow.Rule[NR].Zel:=1;
for i:=1 to Num do
BaseKnow.Rule[NR].FactIn[i]:=SpisF[i];
end;
procedure TForm1.SpeedButton9Click(Sender: TObject);
begin
if radiogroup1.ItemIndex=0 then
if edit1.Text='' then
begin
Application.MessageBox('Не введены данные!','Ошибка',mb_iconwarning);
exit;
end
else
AddSimpleFact;
if radiogroup1.ItemIndex=1 then
if (edit1.Text='') or (ComboBox3.Text='')or (Num=0)then
begin
Application.MessageBox('Введены не все данные!','Ошибка',mb_iconwarning);
exit;
end
else
begin
AddComplexFact;
combobox3.Clear;
end;
edit1.Clear;
Num:=0;
end;
procedure TForm1.SpeedButton11Click(Sender: TObject);
ar rab:integer;
begin
rab:=ListBox1.itemindex;
ComboBox3.Items.Add(VectFact[rab+1].Znach);
ComboBox3.ItemIndex:=0;
Num:=Num+1;
SpisF[Num]:=VectFact[rab+1].Number;
end;
procedure TForm1.DeleteFact;
ar
i,j,rab,t,k:integer;
begin
rab:=ListBox1.ItemIndex+1;
k:=VectFact[rab].Number;
for i:=1 to NR do
for j:=1 to BaseKnow.Rule[i].Q do
if BaseKnow.Rule[i].FactIn[j]=k then
begin
Application.MessageBox('Для сохранения целостности базы далите вначале факт, содержащий в себе данный!','Предупреждение',mb_iconwarning);
exit;
end;
for i:=rab to NFF-1 do
begin
VectFact[i].Number:=VectFact[i+1].Number;
VectFact[i].Znach:=VectFact[i+1].Znach;
end;
NFF:=NFF-1;
for i:=1 to NR do
if k=BaseKnow.Rule[i].Number then
begin
for t:=i to NR-1 do
begin
BaseKnow.Rule[t].Number:=BaseKnow.Rule[t+1].Number;
BaseKnow.Rule[t].Q:=BaseKnow.Rule[t+1].Q;
BaseKnow.Rule[t].Zel:=BaseKnow.Rule[t+1].Zel;
for j:=1 to BaseKnow.Rule[t].Q do
BaseKnow.Rule[t].FactIn[j]:=BaseKnow.Rule[t+1].FactIn[j];
end;
NR:=NR-1;
end;
ListBox1.Clear;
ListBox2.Clear;
ListBox3.Clear;
ListBox5.Clear;
for i:=1 to NFF do
begin
ListBox1.Items.Add(VectFact[i].Znach);
ListBox3.Items.Add(VectFact[i].Znach);
for j:=1 to NR do
if VectFact[i].Number=BaseKnow.Rule[j].Number then
ListBox5.Items.Add(VectFact[i].Znach);
end;
end;
procedure TForm1.SpeedButton5Click(Sender: TObject);
ar
inf:integer;
begin
inf:=Application.Messagebox('Удалить факт?','Question',MB_YESNO+MB_ICONQUESTION);
if inf=idNO then
exit;
if inf=idYes then
DeleteFact;
end;
procedure TForm1.BitBtn2Click(Sender: TObject);
ar
rab,i,j:integer;
begin
if NF1>0 then
begin
rab:=ListBox4.Itemindex;
for i:=rab+1 to NF1-1 do
begin
аSpisF[i]:=SpisF[i+1];
BaseKnow.Fact[i]:=BaseKnow.Fact[i+1];
end;
NF1:=NF1-1; NF:=NF1;
ListBox4.Clear;
for i:=1 to NF1 do
for j:=1 to NFF do
if SpisF[i]=VectFact[j].Number then
ListBox4.Items.Add(VectFact[j].Znach);
end;
end;
procedure TForm1.BitBtn4Click(Sender: TObject);
ar
rab,i,j:integer;
begin
if NK>0 then
begin
rab:=ListBox6.Itemindex;
for i:=rab+1 to NK-1 do
Knowledge[i]:=Knowledge[i+1];
NK:=NK-1;
ListBox6.Clear;
for i:=1 to NK do
for j:=1 to NFF do
if Knowledge[i]=VectFact[j].Number then
ListBox6.Items.Add(VectFact[j].Znach);
end;
end;
procedure TForm1.N5Click(Sender: TObject);
begin
HelpBox.show;
end;
procedure TForm1.N4Click(Sender: TObject);
begin
close;
end;
end.
5.2.Распечатка экранных форм
а
Заставка
Был выбран пункт меню Работ с системой
Окно пункта меню Правка
Пользователь пожелал добавить факт, отобразилось окошко
В окне Правка можно просмотреть все факты, при этом знать их статус и состав
PAGEа 13
PAGEа 1