Загрузить архив: | |
Файл: 047-0008.zip (830kb [zip], Скачиваний: 100) скачать |
1.Задание на лабораторную работу
Разработать диалоговую систему, оформленную в виде пакета прикладных программ и реализующую идею искусственного интеллекта. Для этого необходимо:
* Самостоятельно выбрать предметную область интеллектуального пакета
* Для выбранной предметной области описать семантическую сеть и правила вывода (базу знаний)
* Разработать блоки системной части пакета, реализующие:
* машину логического вывода
* процедуры работы с семантической сетью
* Подготовить отладочные варианты наборов данных
* Провести машинный эксперимент
* Описать полученные результаты
2.Руководство пользователя
2.1. Назначение программы
В качестве предметной области была выбрана кулинария.
Программа предназначена для получения информации о составе различных кулинарных блюд. Пользователю предоставляется возможность перечислить несколько ингредиентов и получить информацию о том, что из этого набора можно приготовить, или ввести интересующее блюдо и узнать из чего оно состоит, или ввести как ингредиенты так и готовый продукт и узнать достаточно ли введенных компонент для приготовления выбранного блюда.
Программа позволяет корректировать имеющуюся базу знаний и создавать новую. Корректировка заключается в добавлении и удалении знаний и фактов.Но в целях соблюдения целостности базы знаний программа не позволит удалить некоторые знания и факты. Если фактвходит в состав знания, то его удаление повлечет нарушение целостности базы. Программа предложит сначала удалить знания, в которые входит этот факт, а потом уже сам факт.
2.2.Описание базы знаний
База знанийФакты (декларативные знания)Правила (процедурные знания)
Декларативные знания
Числовой кодЗначение12 яйца23 яйца34 яйца4100 грамм молока5200 грамм молока6400 грамм молока70,5 ложки соли81 ложка соли92 ложки соли101 стакан муки112 стакана муки124 стакана муки1310 ложек сахара1413 ложек сахара1515 ложек сахара16Изюм17Дорожжи18Творог19Омлет на 1-го человека20Омлет на 2-х человек21Опара22Тесто23Блины24Яичница на 1-го человека25Яичница на 2-х человек26Кулич27Ватрушка28Жарить29Печь
Процедурные знания
Код порождаемого фактаКоличество
свидетельствСвидетельства1941,4,7,282043,5,8,282145,9,11,1722521,3,4,12,1523222,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,учебный курс. - М.: "Нолидж",1999.
3. В.А. Благодатских, М.А. Енгибарян, Е.В. Ковалевская. Экономика, разработка и использование программного обеспечения ЭВМ. - М.:Финансы и статистика, 1995.
4. Роб Баас, Майк Фервай. Delphi 4 Полное руководство - Киев, издательская группа BHV, 1999.
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;
var
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);
var
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);
var
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);
var 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;
var
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;
var
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
fork:=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);{нажали кнопку ОК}
var
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;
var
i:integer;
FF: TFF;
FactFile:TFactFile;
begin
i:=0;
OpenDialog1.Filter:='База знаний|*.dat';
if not OpenDialog1.Executethen
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);
var
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;
var 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 toBaseKnow.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);
var
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;
var
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;
VectFact[NFF].Number:=t+1;
VectFact[NFF].Znach:=r;
ListBox1.items.add(VectFact[NFF].Znach);
ListBox3.items.add(VectFact[NFF].Znach);
end;
procedure TForm1.AddComplexFact;
var
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;
VectFact[NFF].Number:=t+1;
VectFact[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);
var 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;
var
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);
var
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);
var
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);
var
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