deman_ru
Junior Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору Я опять к Вам за помощью со своей экспертной системой. Я уже публиковал вопрос, но к сожалению никто не ответил( я кое что добавил, выложу, надеюсь вы поможете, очень нужно! Такая вот база данных (она же база знаний): Для механизма вывода используется алгоритм обратного логического вывода, я его нашел в нете, вот его и пытаюсь реализовать: Код: функция Доказана_Цель(Цель): boolean; | Поместить Цель в стек целей. | пока стек целей не пуст | цикл | | Выбор цели из стека целей и назначение ее текущей. | | Поиск множества правил, в правой части которых | | находится текущая цель (множества подходящих правил). | | Считать, что Цель не доказана. | | пока множество походящих правил не пусто | | и Цель не доказана | | цикл | | | Выбор из этого множества одного текущего правила | | | с использованием определенной стратегии. | | | Считать текущим элементарным условием первое. | | | пока не проверены все элементарные условия правила | | | и не надо прервать проверку условия | | | цикл | | | | если в текущем элементарном условии | | | | | участвует факт, | | | | | встречающийся в правой части | | | | | какого-то правила | | | | | то | | | | | если не Доказана_Цель(Этот факт) | | | | | | то | | | | | | Надо прервать проверку условия | | | | | конец_если | | | | иначе | | | | | Запросить информацию о факте. | | | | | Проверить элементарное условие. | | | | | если элементарное условие истинно | | | | | | то | | | | | | Добавить факт в базу данных. | | | | | | Перейти к следующему элементарному | | | | | | Условию. | | | | | иначе | | | | | | Надо прервать проверку условия. | | | | | конец_если | | | | конец_если | | | конец_цикла | | | если условие правила истинно | | | | то | | | | Выполнить заключение. | | | | Исключить Цель из стека целей. | | | | Считать, что Цель доказана. | | | конец_если | | конец_цикла | конец_цикла конец_функции. | Вот что я написал на Си: Код: //Функция вставки целей в стек int n=100; int x; int MASS[100]; int INSERT (int x) { int p=1; for (int j=n-1; j>=p-1;j--) { MASS[j+1]=MASS[j];}//Перемещение элементов списка и вставка нового MASS[p-1]=x; } //Функция удаления цели из стека int DEL (void) { for (int j=0; j<=n; j++) { MASS[j]=MASS[j+1]; } } //Функция поиска решения char POISK_RESHENIYA (int cel) { INSERT(cel);//Поместить цель в стек целей //Просмотр пуст ли стек for (int j=0; j<=n; j++) { int k=0; if (MASS[j]!="0") { k=k+1; } } //Конец просмотра пуст ли стек while (k=!0)//Пока стек целей не пуст { int p=0;//Позиция цели (первая позиция) cel_tek=MASS[p];//Выбираем текущую цель, значение из первой позиции //Поиск правил, в правой части которых находится текущая цель DataModule2->IBQuery1->Active=false; DataModule2->IBQuery1->SQL->Clear(); DataModule2->IBQuery1->SQL->Add("SELECT * FROM RULE WHERE RULE.ZAKLUCHENIYE=:A;"); DataModule2->IBQuery1->Params->ParamValues["A"]=DBEdit2->Text; DataModule2->IBQuery1->Active=true; //Конец поиска правил, в правой части которых находится текущая цель int cel_dokaz=0;//Считать что цель не доказана, доказана если cel_dokaz=1 //Пока множество подходящих правил не пусто и цель не доказана while (!DataModule2->IBQuery1->Eof && cel_dokaz!=1) { //Выбор из этого множества одного текущего правила, с использованием определенной стратегии, считать текущим элементарным условием первое DataModule2->IBQuery1->First(); //--------------------------------------------------------------------------------------------------------------------------------------- While (!DataModule2->IBQuery1->Eof)//Пока не проверены все элементарные условия правила и не надо прервать проверку условия { AnsiString predpos=DataModule2->IBQuery1->FieldByName("PREDPOSILKA")->AsString;//Выбор первого элементарного условия (предпосылки) //Поиск правил в правой части которых (заключении) учавствует факт, выбраный строчкой выше DataModule2->IBQuery2->Active=false; DataModule2->IBQuery2->SQL->Clear(); DataModule2->IBQuery2->SQL->Add("Select * From RULE where ZAKLUCHENIYE = ("+predpos+")"); DataModule2->IBQuery2->Active=true; //---------------------------------------------------------------------Конец поиска правил //Проверка нашло ли правила в соответствии с условием выше int n2=0; while (!DataModule2->IBQuery2->Eof) { n2++; DataModule2->IBQuery2->Next(); } //Конец проверки------------------------------------------- //Если в текущем элементарном условии учавствует факт, встречающийся в правой части какого то правила if (n!=0) { if (!POISK_RESHENIYA (predpos))//Если не доказана цель { break;//Прервать проверку условия } else { //Запросить информацию о факте //Вывод вопроса для факта DataModule2->IBQuery3->Active=false; DataModule2->IBQuery3->SQL->Clear(); DataModule2->IBQuery3->SQL->Add("Select QUESTION From FACT where IDFACT=predpos");//Вывод в DBEdit DataModule2->IBQuery3->Active=true; //Конец вывода вопроса для факта //Вывод значений для факта DataModule2->IBQuery4->Active=false; DataModule2->IBQuery4->SQL->Clear(); DataModule2->IBQuery4->SQL->Add("Select NAMEVALUE From VALUE_FACT where IDFACT=predpos");//Вывод в DBGrid DataModule2->IBQuery4->Active=true; //Конец вывода значений для факта //Конец запроса информации о факте //Проверить элементарное условие AnsiString predpos_value=DataModule2->IBQuery1->FieldByName("VALUE_PREDPOSILKA")->AsString;//Выбор значения первой предпосылки(элементарного условия) AnsiString predpos_value_select=DataModule2->IBQuery4->FieldByName("IDVALUEFACT")->AsString;//Выбор значения которое отметил пользователь для текущей предпосылки (элементарного условия) if(predpos_value==predpos_value_select)//Если элементарное условие истино { //Добавить факт в базу данных Memo1->Lines->Add(predpos); Memo2->Lines->Add(predpos_value); //Конец добавления факта в базу данных DataModule2->IBQuery1->Next();//Перейти к следующему элементарному словию } else {break;} } //Если условие правила истино int n; n=Memo1->Lines->Count();Считаем количество записей в Memo1 (базе данных) в Memo2 считать не будем, так как их количество должно быть одинаково AnsiString predposilki; AnsiString value_predposilki; for (int j=0; j<=n; j++) { if (!predposilki.IsEmpty()){ predposilki += ", "; predposilki += Memo1->Lines[j];} if (!value_predposilki.IsEmpty()){ value_predposilki += ", "; value_predposilki += Memo1->Lines[j];}} //Находим правила по установленым предпосылкам DataModule2->IBQuery5->Active=false; DataModule2->IBQuery5->SQL->Clear(); DataModule2->IBQuery5->SQL->Add("SELECT * FROM RULES WHERE PREDPOSILKA IN ("+ predposilki + ") AND VALUE_PREDPOSILKA IN ("+ value_predposilki + ") "); DataModule2->IBQuery5->Active=true; //Считаем были ли найдены правила int n3=0; while (!DataModule2->IBQuery5->Eof) { n3++; DataModule2->IBQuery5->Next(); } if (n3!=0) { AnsiString zaklucheniye=DataModule2->IBQuery5->FieldByName("VALUE_PREDPOSILKA")->AsString;//Выбираем из найденых правил заключение Edit2->Text=zaklucheniye;//Вывод заключения в Edit del();//Исключить цель из стека целей cel_dokaz=1;//Считать что цель доказана } }//Конец цикла }//Конец цикла }//Конец функции | Прошу у Вас помощи в выявлении ошибок в этом коде. Вообще хотелось бы сделать так чтобы: пользователь запускал консультацию, механизм вывода доходил до последнего правила, где его предпосылки не участвуют в выводах других правил, и задал вопрос к первой предпосылке, пользователь выбрал ответ и нажал далее, на вторую предпосылку тоже ответил и нажал далее, и так до конца, пока программа не выдаст результат. Пожалуйста помогите!   |