📄 aiexpert.cpp
字号:
#include "stdafx.h"
#include "AiExpert.h"
#include "AiMt.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_SERIAL(AiExpert,CObject,0)
AiExpert::AiExpert()
{
AiAssert::SetAssertNumTo(&m_numAssert);
AiAssert::SetAssertMentionTo(m_mention);
m_SearchTree = NULL;
InitData();
}
void AiExpert::InitData()
{
//call when expert system be defined
m_numMention = 0;
m_numFact = 0;
m_numGoal = 0;
m_numRule = 0;
m_numAssert = 0;
m_goalList.RemoveAll();
m_ruleList.RemoveAll();
for (int i=0;i<MaxNum;i++)
{
m_fact[i].SetUnknow();
m_factBS[MaxNum].SetUnknow();
m_factBA[MaxNum].SetUnknow();
m_Actived[i]=0;
m_NeedNotAsk[i] = 0;
m_mtCanUnknow[i] = true;
}
m_TreeCtrl = NULL;
IsAnswerTreeOK = FALSE;
AskOnlyOnce = 1;
if (m_SearchTree != NULL){
delete m_SearchTree;
m_SearchTree = NULL;
}
m_IsMultiGoal = 1;
}
void AiExpert::ResetData()
{
//需要再次进行搜索时,调用此函数进行数据初始化
IsAnswerTreeOK = FALSE;
for (int i=0;i<MaxNum;i++)
{
if (m_factBS[i].GetValue() == FactTrue)
m_fact[i].SetTrue();
else if (m_factBS[i].GetValue() == FactFalse)
m_fact[i].SetFalse();
else
m_fact[i].SetUnknow();
m_Actived[i]=m_NeedNotAsk[i];
m_factBA[i].SetUnknow();
}
if (m_SearchTree != NULL){
delete m_SearchTree;
m_SearchTree = NULL;
}
AskOnlyOnce = 1;
}
void AiExpert::InitForSearch()
{
ASSERT(m_numAssert>=0 && m_numAssert<MaxNum);
m_numFact = m_numMention = m_numAssert;
POSITION p;
pRunGoal = new CObList;
for (p=m_goalList.GetHeadPosition();p!=NULL;)
{
AiMt* pData = new AiMt;
*pData = *((AiMt* )(m_goalList.GetNext(p)));
pRunGoal->AddTail(pData);
}
for (int i=0;i<MaxNum;i++)
{
if (m_fact[i].GetValue() == FactTrue)
m_factBS[i].SetTrue();
else if (m_fact[i].GetValue() == FactFalse)
m_factBS[i].SetFalse();
else
m_factBS[i].SetUnknow();
m_Actived[i]=m_NeedNotAsk[i];
m_factBA[i].SetUnknow();
}
if (m_SearchTree != NULL){
delete m_SearchTree;
m_SearchTree = NULL;
}
}
void AiExpert::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
//写入专家系统名称
ar<<m_expertSystemName;
//写入断言
ar<<m_numAssert;//数目
CString str = "A";
for (int i=0;i<m_numAssert;i++)
{
//if (m_abbreviation.GetAt(i) == NULL)
// ar<<str;
//else
// ar<<m_abbreviation.GetAt(i);//谓词缩写
ar<<m_mention[i].GetAbbreviation();
ar<<m_mention[i].GetTrueMention();
ar<<m_mention[i].GetFalseMention();
ar<<m_mention[i].GetQuestionMention();
}
//写入事实
ar<<m_numAssert;
for (i=0;i<m_numAssert;i++) {
ar<<m_fact[i].GetValue();
}
//写入命题是否需要询问
for (i=0;i<m_numAssert;i++) {
ar<<m_NeedNotAsk[i];
}
//写入回答能否为不知道
for (i=0;i<m_numAssert;i++) {
ar<<m_mtCanUnknow[i];
}
//写入规则
str = "begin of rule";
ar<<str;
int t=m_ruleList.GetCount();//规则数
ar<<t;
POSITION p;
AiRule* pData;
int count;
for (p=m_ruleList.GetHeadPosition();p!=NULL;)
{
pData = (AiRule*) m_ruleList.GetNext(p);
pData->GetMt().Serialize(ar); //规则右端
AiMt* pMt = pData->GetWffs().GetPre();
count = 1;
while(pMt!=NULL){
count++;
pMt = pMt->GetPre();
}
ar<<count;//规则前提个数
AiMt tempMt;
tempMt.SetId(pData->GetWffs().GetId());
tempMt.SetSign(pData->GetWffs().GetSign());
tempMt.Serialize(ar);//规则前提首端
pMt = pData->GetWffs().GetPre();
while(pMt!=NULL){
pMt->Serialize(ar); //规则前提首
pMt = pMt->GetPre();
}
}
//写入目标
str = "begin of goal";
ar<<str;
ar<<m_goalList.GetCount();//目标数
m_goalList.Serialize(ar);
//****************************************
str = "stage end";
ar<<str;
ar<<m_IsMultiGoal; //写入是否为多目标搜索
}
else
{
//读入,首先清空原有的数据。
InitData();
//读入专家系统名称
ar>>m_expertSystemName;
//读入断言
ar>>m_numAssert;
ASSERT(m_numAssert<MaxNum);
CString str;
for (int i=0;i<m_numAssert;i++)
{
//temp =
ar>>str;
m_mention[i].SetAbbreviation(str);//谓词缩写
ar>>str;
m_mention[i].SetTrueMention(str);
ar>>str;
m_mention[i].SetFalseMention(str);
ar>>str;
m_mention[i].SetQuestionMention(str);
}
//读入事实
int t;
ar>>t;////读入事实数
for (i=0;i<m_numAssert;i++)
{
ar>>t;
switch(t){
case FactTrue:
m_fact[i].SetTrue();
break;
case FactFalse:
m_fact[i].SetFalse();
break;
case FactUnknow:
m_fact[i].SetUnknow();
break;
default:
ASSERT(0);
}
}
//读入命题是否需要询问
for (i=0;i<m_numAssert;i++) {
ar>>m_NeedNotAsk[i];
}
//读入回答能否为不知道
for (i=0;i<m_numAssert;i++) {
ar>>m_mtCanUnknow[i];
}
//读入规则
ar>>str;
ASSERT(str == "begin of rule");
ar>>t;//规则数
for (i=0;i<t;i++)
{
AiMt aimMt;
AiMt headMt;
aimMt.Serialize(ar);
int preNum;
ar>>preNum; //当前规则前提数
AiRule* rule = new AiRule;
headMt.Serialize(ar); //读入
AiMt* pNow = &headMt;
for (int j=0;j<preNum-1;j++){
AiMt loadMt;
loadMt.Serialize(ar);
AiMt* pMt = new AiMt;
*pMt = loadMt;
pNow->SetPre(pMt);
pNow = pMt;
}
rule->SetMt(aimMt);
rule->SetWffs(headMt);//可能有错?
m_ruleList.AddTail(rule);
}
//读入目标
ar>>str;
ASSERT(str == "begin of goal");
ar>>t;//目标数
m_goalList.Serialize(ar);
//****************************************
ar>>str;
ASSERT(str == "stage end");
ar>>m_IsMultiGoal; //读出是否为多目标搜索
}
}
int AiExpert::GetNumMention()
{
return m_numMention;
}
void AiExpert::SetNumMention(int numM)
{
ASSERT(numM>=0 && numM<MaxNum);
m_numMention = numM;
}
int AiExpert::GetNumFact()
{
return m_numFact;
}
void AiExpert::SetNumFact(int numF)
{
ASSERT(numF>=0 && numF<MaxNum);
m_numFact = numF;
}
int AiExpert::GetNumAssert()
{
return m_numAssert;
}
void AiExpert::SetNumAssert(int numA)
{
ASSERT(numA>=0 && numA<MaxNum);
m_numAssert = numA;
}
void AiExpert::SetMention(int id,CString Tstr,CString Fstr)
{
ASSERT( id>=0 && id<MaxNum);
m_mention[id].SetTrueMention(Tstr);
m_mention[id].SetFalseMention(Fstr);
char temp[4];
itoa(id,temp,10);
char str[10];
strcpy(str,"#");
strcat(str,temp);
m_mention[id].SetAbbreviation(str);
}
void AiExpert::AddFact(AiMt mt)
{
if (mt.GetSign() == NeedNotVersa)
SetFactTrue(mt.GetId());
else
SetFactFalse(mt.GetId());
}
void AiExpert::SetFactTrue(int id)
{
if (CheckAndAskAssign(id,FactTrue) != IDYES)
return ;
m_fact[id].SetTrue();
}
void AiExpert::SetFactFalse(int id)
{
if (CheckAndAskAssign(id,FactFalse) != IDYES)
return ;
m_fact[id].SetFalse();
}
int AiExpert::GetFact(AiMt mt)
{
int t = m_fact[mt.GetId()].GetValue();
if (t == FactUnknow)
return FactUnknow;
if (mt.GetSign() == NeedNotVersa)
return t;
else if (t == FactTrue)
return FactFalse;
else
return FactTrue;
}
void AiExpert::AddRule(AiWffs wff,AiMt mt)
{
ASSERT(m_numRule>=0 && m_numRule<MaxNum);
m_numRule++;
AiRule* rule = new AiRule;
rule->SetWffs(wff);
rule->SetMt(mt);
m_ruleList.AddTail(rule);
}
void AiExpert::AddGoal(AiMt mt)
{
AiMt* aimt = new AiMt;
aimt->SetId(mt.GetId());
aimt->SetSign(mt.GetSign());
aimt->SetPre(NULL);
ASSERT(m_numGoal>=0 && m_numGoal<MaxNum);
m_numGoal++;
m_goalList.AddTail(aimt);
}
void AiExpert::SearchSingle()
{
BOOL FactChanged = TRUE;
POSITION p;
AiRule* t;
int numRule = GetNumRule();
int* ruleExist = new int[numRule];
for (int i=0;i<numRule;i++)
ruleExist[i] = 0;
for (; FactChanged ;)
{
FactChanged = FALSE;
int whichRule=-1;
for (p=m_ruleList.GetHeadPosition();p!=NULL;)
{
whichRule++;
t = (AiRule*) m_ruleList.GetNext(p);
//if (!t->GetExist()){
//if (GetFact( t->GetMt() ) == FactUnknow){
if (!ruleExist[whichRule]){
if (QueryWffs((t->GetWffs()) ) == FactTrue){
//仅当Horn字句推理成功时,推出结论
//不成功或未知不推出。
AddFact(t->GetMt());
FactChanged = TRUE;
t->SetExist();
ruleExist[whichRule] = 1;
}
}
}
}
}
int AiExpert::QueryWffs(AiWffs wffs)
{
int own;
own = GetIdFact(wffs.GetId());
if (own == FactUnknow)
return FactUnknow;
int pre;
if (wffs.GetPre()!=NULL)
{
pre = QueryWffs(*wffs.GetPre());
if (pre == FactUnknow)
return FactUnknow;
if (pre == FactFalse)
return FactFalse;
ASSERT(pre == FactTrue);
}
if (wffs.GetSign() == NeedVersa){
if (own == FactTrue)
return FactFalse;
else
return FactTrue;
}
else
return own;
ASSERT(0);
return FactUnknow;
}
int AiExpert::GetIdFact(int id)
{
return m_fact[id].GetValue();
}
CString AiExpert::GetAssertMention(AiMt mt)
{
ASSERT(mt.GetId()>=0 && mt.GetId()<MaxNum);
if (mt.GetSign() == NeedVersa)
return m_mention[mt.GetId()].GetFalseMention();
else
return m_mention[mt.GetId()].GetTrueMention();
}
CString AiExpert::GetFactMention(AiMt mt)
{
//返回
int value = GetFact(mt);
if (value == FactUnknow)
return "推不出来";
if (mt.GetSign() == NeedNotVersa)
{ if ( value == FactTrue)
return m_mention[mt.GetId()].GetTrueMention();
else if (value == FactFalse)
return m_mention[mt.GetId()].GetFalseMention();
}
else
{
if ( value == FactFalse)
return m_mention[mt.GetId()].GetTrueMention();
else if (value == FactTrue)
return m_mention[mt.GetId()].GetFalseMention();
}
ASSERT(0);
return "";
}
BOOL AiExpert::CheckMtTorF(AiMt mt)
{
int t = m_fact[mt.GetId()].GetValue();
if (mt.GetSign() == NeedNotVersa)
if (t == FactTrue)
return TRUE;
else
return FALSE;
else
if (t == FactTrue)
return FALSE;
else
return TRUE;
}
int AiExpert::CheckResultState()
{
POSITION p;
AiMt* pData;
if (m_goalList.GetCount() == 1)
{
p=m_goalList.GetHeadPosition();
pData = ((AiMt*)(m_goalList.GetNext(p)));
if (GetFact(*pData) != FactUnknow)
m_resultState = ResultSingleCertitude;
else
m_resultState = ResultSingleIncertitude;
}
else if( !m_goalList.GetCount() == 0)
{
POSITION p;
AiMt* pData;
int ok=0;
for (p=m_goalList.GetHeadPosition();p!=NULL;)
{
pData = ((AiMt*)(m_goalList.GetNext(p)));
if (GetFact(*pData) != FactUnknow)
ok++;
}
if (ok == m_goalList.GetCount())
m_resultState = ResultMultiAllOk;
else if (ok == 0)
m_resultState = ResultMultiAllNotOk;
else
m_resultState = ResultMultiNotAllOk;
}
return m_resultState;
}
int AiExpert::GetResultState()
{
return m_resultState;
}
int AiExpert::SearchBackward()
{
//进行简单的反向搜索,返回搜索状态。
POSITION p;
AiMt* pData;
int total=0,ok=0;
const int numRule = GetNumRule();
int* ruleExist = new int[numRule];
for (p=pRunGoal->GetHeadPosition();p!=NULL;total++)
{
for (int i=0;i<numRule;i++)
ruleExist[i] = false;
pData = ((AiMt*)(pRunGoal->GetNext(p)));
int thismt = GetFact(*pData);
if ( thismt== FactTrue
|| thismt == FactFalse)
ok++;
else{
ASSERT(thismt == FactUnknow);
if (SearchInsideBackward(*pData,numRule,ruleExist) == FactTrue){
ok++;
}
}
}
delete ruleExist;
if (total == 1){
if (ok == 0)
m_resultState = ResultSingleIncertitude;
else
m_resultState = ResultSingleCertitude;
}
else if(total>1){
if (ok == total)
m_resultState = ResultMultiAllOk;
else if (ok == 0)
m_resultState = ResultMultiAllNotOk;
else
m_resultState = ResultMultiNotAllOk;
}
return m_resultState;
}
int AiExpert::SearchInsideBackward(AiMt aimMt,int numRule,int* ruleExist)
{
int own;
own = GetFact(aimMt);
int* tempRuleExist = new int[numRule];
for (int i=0;i<numRule;i++)
tempRuleExist[i] = ruleExist[i];
if (own == FactUnknow)
{
POSITION p;
AiRule* pData;
int presentRule = -1;
for (p=m_ruleList.GetHeadPosition();p!=NULL;)
{
presentRule++;
pData = ((AiRule*)(m_ruleList.GetNext(p)));
if (ruleExist[presentRule])
continue;
ruleExist[presentRule] = true;
if ( pData->GetMt().GetId() == aimMt.GetId() )
{
AiMt mt;
AiWffs* wff =& pData->GetWffs();
mt.SetId(wff->GetId());
mt.SetPre(wff->GetPre());
mt.SetSign(wff->GetSign());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -