📄 aiexpert.cpp
字号:
if (SearchInsideBackward(mt,numRule,ruleExist) == FactTrue)
//此处返回FactFalse表示推理未成立
{
AddFact(pData->GetMt());
for (int i=0;i<numRule;i++)
ruleExist[i] = tempRuleExist[i];
delete tempRuleExist;
return FactTrue;
}
}
} ruleExist[presentRule] = false;
delete tempRuleExist;
return FactUnknow;
}
int pre;
if (aimMt.GetPre() != NULL)
{
pre = SearchInsideBackward(*aimMt.GetPre(),numRule,ruleExist);
if (pre == FactUnknow){
delete tempRuleExist;
return FactUnknow;
}
if (pre == FactFalse){
delete tempRuleExist;
return FactFalse;
}
ASSERT(pre == FactTrue);
for(int i=0;i<numRule;i++)
ruleExist[i] = tempRuleExist[i];
delete tempRuleExist;
return own;
}
delete tempRuleExist;
return own;
}
int AiExpert::AskFact(AiMt mt)
{
//返回消息框的输入
int id = mt.GetId();
/*if (AskOnlyOnce)
if (m_Actived[id] == 1)
return IDCANCEL;
else m_Actived[id] = 1;
*/
CString str = m_mention[id].GetQuestionMention();
int msg;
if (m_mtCanUnknow[mt.GetId()])
msg = ::MessageBox(NULL,str,"请确认下述事实是否成立",MB_YESNOCANCEL | MB_DEFBUTTON3
| MB_ICONQUESTION |MB_SETFOREGROUND | MB_TOPMOST );
else
msg = ::MessageBox(NULL,str,"请确认下述事实是否成立",MB_YESNO | MB_DEFBUTTON1
| MB_ICONQUESTION |MB_SETFOREGROUND | MB_TOPMOST );
if (msg == IDYES){
m_fact[id].SetTrue();
m_factBA[id].SetTrue();
SearchSingle();
return IDYES;
}
else if (msg == IDNO){
m_fact[id].SetFalse();
m_factBA[id].SetFalse();
SearchSingle();
return IDNO;
}
ASSERT(IDCANCEL);
return IDCANCEL;
}
int AiExpert::SearchBackwardWithAsk(AiMt& unknowMt)
{
//返回是否需要询问。
POSITION p;
AiMt* pData;
for (p=pRunGoal->GetHeadPosition();p!=NULL;)
{
pData = ((AiMt*)(pRunGoal->GetNext(p)));
int thismt = GetFact(*pData);
if ( thismt== FactTrue
|| thismt == FactFalse){
}
else
{
if (!m_Actived[pData->GetId()] &&
!m_NeedNotAsk[pData->GetId()]){
unknowMt = *pData;
m_Actived[pData->GetId()] = 1;
return 1;
}
ASSERT(thismt == FactUnknow);
POSITION rulep;
AiRule* pD;
const int numRule = GetNumRule();
int* ruleExist = new int[numRule];
for (int i=0;i<numRule;i++)
ruleExist[i] = false;
int presentRule = -1;
for (rulep=m_ruleList.GetHeadPosition();rulep!=NULL;)
{
presentRule++;
pD = ((AiRule*)(m_ruleList.GetNext(rulep)));
if (GetFact(*pData) != FactUnknow)
continue;
if ( pD->GetMt().GetId() == pData->GetId() )
{
ruleExist[presentRule] = true;
AiMt mt;
AiWffs* wff =& pD->GetWffs();
mt.SetId(wff->GetId());
mt.SetPre(wff->GetPre());
mt.SetSign(wff->GetSign());
//输入的命题 推出系统目标规则的前提的最后个命题
int s = SearchInsideBackwardWithAsk(mt,unknowMt,numRule,ruleExist);
if (s == FactTrue) {
AddFact(pD->GetMt());
}
else
if (s == FactFalse){
}
else {
ASSERT(s == FactUnknow);
//仅当调用此函数时,已经进行一次搜索,才一遇到“不知”就须进行询问。
return 1;
}
}
ruleExist[presentRule] = false;
//目标本身不需要进行询问。
//if (GetFact(*pData->GetMt()) == FactUnknow)
//{//unknowMt = new AiMt;*unknowMt = *pData->GetMt();return 1;}
}
}
}
return 0;
}
int AiExpert::SearchInsideBackwardWithAsk(AiMt aimMt,AiMt& unknowMt,int numRule,int* ruleExist)
{
//返回aimMt的值,if aimMt is equal to unknow,the unknowMt must be valued!
int own;
own = GetFact(aimMt);
if (own == FactFalse)
return FactFalse;
//先处理前提,
int pre;
int* tempRuleExist = new int[numRule];
for (int i=0;i<numRule;i++)
tempRuleExist[i] = ruleExist[i];
if (aimMt.GetPre() != NULL)
{
pre = SearchInsideBackwardWithAsk(*aimMt.GetPre(),unknowMt,numRule,ruleExist);
if (pre == FactUnknow){
delete tempRuleExist;
return FactUnknow;
}
if (pre == FactFalse){
delete tempRuleExist;
return FactFalse;
}
ASSERT(pre == FactTrue);
}
if (own == FactUnknow)
{
if (!m_Actived[aimMt.GetId()] &&
!m_NeedNotAsk[aimMt.GetId()] ){
//如果未问过,进行询问。
unknowMt = aimMt;
m_Actived[aimMt.GetId()] = true;
//一旦要进行询问,设置已查询表示
delete tempRuleExist;
return FactUnknow;
}
else
{
ASSERT(own == FactUnknow);
POSITION rulep;
AiRule* pD;
int presentRule = -1;
for (rulep=m_ruleList.GetHeadPosition();rulep!=NULL;)
{
presentRule++;
pD = ((AiRule*)(m_ruleList.GetNext(rulep)));
if (ruleExist[presentRule])
continue;
if ( pD->GetMt().GetId() == aimMt.GetId() )
{
ruleExist[presentRule] = true;
AiMt mt;
AiWffs* wff =& pD->GetWffs();
mt.SetId(wff->GetId());
mt.SetPre(wff->GetPre());
mt.SetSign(wff->GetSign());
int s = SearchInsideBackwardWithAsk(mt,unknowMt,numRule,ruleExist);
ruleExist[presentRule] = false;
if (s == FactTrue) {
AddFact(pD->GetMt());//这句好象没有用。
for (int i=0;i<numRule;i++)
ruleExist[i] = tempRuleExist[i];
delete tempRuleExist;
return FactTrue;
}
else
if (s == FactFalse){
//return FactFalse;
continue;
}
else {
ASSERT(s == FactUnknow);
//无法使此不知命题成立,返回
//return FactFalse;
delete tempRuleExist;
return FactUnknow;
}
}
}
delete tempRuleExist;
return FactFalse;
}
}
ASSERT(own == FactTrue);
for (int j=0;j<numRule;j++)
ruleExist[j] = tempRuleExist[j];
delete tempRuleExist;
return own;
}
int AiExpert::Search(int once)
{
AskOnlyOnce = once;
InitForSearch();
int s;
SearchSingle();
s = CheckResultState();
if (s == ResultSingleCertitude
|| s == ResultMultiAllOk){
MessageBeep(-1);
return s;
}
//
s = SearchBackward();
if (s == ResultSingleCertitude
|| s == ResultMultiAllOk){
MessageBeep(-1);
return s;
}
//
if (!GetIsMultiGoal() &&
CheckResultStateIsAnyoneTrue())
return s;
AiMt unknowMt;
while (SearchBackwardWithAsk(unknowMt))
{
AskFact(unknowMt);
SearchSingle();
SearchBackward(); //进行及时的推理
s = CheckResultState();
if (!GetIsMultiGoal() &&
CheckResultStateIsAnyoneTrue())
return s;
}
s = CheckResultState();
MessageBeep(-1);
return s;
}
int AiExpert::CheckAndAskAssign(int id,int value)
{
if (m_fact[id].GetValue() != FactUnknow
&& m_fact[id].GetValue()!=value ){
CString str = "对下述命题进行确认时发现矛盾:\n “";
str+=m_mention[id].GetAbbreviation();
if (value == FactTrue)
str+=m_mention[id].GetTrueMention();
else if (value == FactFalse)
str+=m_mention[id].GetFalseMention();
else {
ASSERT(value == FactUnknow);
return IDYES;
}
str+="”\n不考虑矛盾,继续进行吗?";
return ::MessageBox(NULL,str,"检测到矛盾",MB_YESNO
| MB_TOPMOST | MB_ICONERROR);
}
return IDYES;
}
void AiExpert::SetAnswerTreeCtrl(CTreeCtrl * treeCtrl)
{
m_TreeCtrl = treeCtrl;
}
CString AiExpert::GetAssertMention(int id, int sign)
{
if (sign == NeedVersa)
return m_mention[id].GetFalseMention();
else
return m_mention[id].GetTrueMention();
}
BOOL AiExpert::LoadFromFile(CString filename)
{
CFile f;
if (f.Open(filename,CFile::modeRead))
{
CArchive ar(&f,CArchive::load);
Serialize(ar);
ar.Close();
f.Close();
}
else return FALSE;
return TRUE;
}
BOOL AiExpert::StoreToFile(CString filename)
{
CFile f;
if (f.Open(filename,CFile::modeWrite | CFile::modeCreate))
{
CArchive ar(&f, CArchive::store);
Serialize(ar);
ar.Close();
f.Close();
}
else return FALSE;
return TRUE;
}
CString AiExpert::GetAnswerString()
{
POSITION p;
CString str;
AiMt* pMt;
for (p=m_goalList.GetHeadPosition();p!=NULL;)
{
pMt = (AiMt*)m_goalList.GetNext(p);
if (GetFact(*pMt) == FactTrue)
{
str+=GetFactMention(*pMt);
str+=" ";
}
}
return str;
}
CString AiExpert::GetAnswerString(int goal)
{
POSITION p;
CString str;
if (m_goalList.GetCount()<goal)
return "";
AiMt* pMt;
int i=0;
for (p=m_goalList.GetHeadPosition();p!=NULL && i<goal;i++){
pMt = (AiMt*)m_goalList.GetNext(p);
}
return GetFactMention(*pMt);
}
CString AiExpert::GetGoalString()
{
POSITION p;
CString str;
AiMt* pMt;
int numAssert = GetNumAssert();
int* goalExist = new int[numAssert];
for (int i=0;i<numAssert;i++)
goalExist[i] = 0;
for (p=m_goalList.GetHeadPosition();p!=NULL;)
{
pMt = (AiMt*)m_goalList.GetNext(p);
if (!goalExist[pMt->GetId()])
str+=GetAssertQuestionMention(pMt->GetId());
goalExist[pMt->GetId()] = 1;
}
delete goalExist;
return str;
}
CString AiExpert::GetGoalString(int goal)
{
POSITION p;
CString str;
if (m_goalList.GetCount()<goal)
return "";
AiMt* pMt;
int i=0;
for (p=m_goalList.GetHeadPosition();p!=NULL && i<goal;i++){
pMt = (AiMt*)m_goalList.GetNext(p);
}
str = GetAssertQuestionMention(pMt->GetId());
return str;
}
void AiExpert::SetESName(CString str)
{
m_expertSystemName = str;
}
CString AiExpert::GetESName()
{
return m_expertSystemName;
}
void AiExpert::SearchForTree()
{
//恢复询问前知识
int tempfact[MaxNum];
for (int i=0;i<m_numAssert;i++)
tempfact[i] = m_fact[i].GetValue();
//
AiTree* nowGoal = new AiTree; //多加的头节点
AiTree* firstGoal = nowGoal;
AiTree* goal = NULL;
POSITION p;
AiMt* pData = NULL;
for (p=m_goalList.GetHeadPosition();p!=NULL;)
{
//每次搜索恢复知识
for (i=0;i<m_numAssert;i++) {
if (m_factBS[i].GetValue() == FactTrue
|| m_factBA[i].GetValue() == FactTrue)
m_fact[i].SetTrue();
else if (m_factBS[i].GetValue() == FactFalse
|| m_factBA[i].GetValue() == FactFalse)
m_fact[i].SetFalse();
else{
ASSERT(m_fact[i].GetValue() == FactUnknow
|| m_factBA[i].GetValue() == FactUnknow);
m_fact[i].SetUnknow();
}
}
////每次搜 索恢复知识;END
pData = ((AiMt*)(m_goalList.GetNext(p)));
int thismt = GetFact(*pData);
if ( thismt== FactTrue){
goal = new AiTree;
goal->SetMention(GetAssertMention(pData->GetId(),pData->GetSign()));
goal->SetId(pData->GetId());
goal->SetSign(pData->GetSign());
nowGoal->SetLch(goal);
nowGoal = goal;
}
else
if (thismt == FactFalse)
continue ;
else {
ASSERT(thismt == FactUnknow);
AiTree* goalson = NULL;
int result = SearchInsideForTree(*pData,&goalson);
if (result == FactTrue || result == FactFalse){
if (GetFact(*pData) == FactTrue){
//goal = new AiTree;
//goal->SetMention(GetAssertMention(pData->GetId(),pData->GetSign()));
//goal->SetId(pData->GetId());
//goal->SetSign(pData->GetSign());
nowGoal->SetLch(goalson);
//nowGoal->SetLch(goal);
nowGoal = goalson;
}
else {
delete goalson;
}
}
}
}
m_SearchTree = new AiTree;//?
m_SearchTree->SetMention(_T("结论"));
m_SearchTree->SetId(999);
m_SearchTree->SetRch(firstGoal->GetLch());
//恢复询问的知识
for (i=0;i<m_numAssert;i++) {
if (tempfact[i] == FactTrue)
m_fact[i].SetTrue();
else if (tempfact[i] == FactFalse)
m_fact[i].SetFalse();
else {
ASSERT(tempfact[i] == FactUnknow);
m_fact[i].SetUnknow();
}
}
}
int AiExpert::SearchInsideForTree(AiMt aimMt, AiTree** father)
{
//如果成功,对father赋值,否则不用
int own;
own = GetFact(aimMt);
if (own == FactFalse)
return FactFalse;
//先考虑前面的命题
*father = new AiTree;
(*father)->SetId(aimMt.GetId());
(*father)->SetSign(aimMt.GetSign());
(*father)->SetMention(GetAssertMention(aimMt.GetId(),aimMt.GetSign()) );
int pre;
if (aimMt.GetPre() != NULL)
{
AiTree* sonPre;
pre = SearchInsideForTree(*aimMt.GetPre(),&sonPre);
if (pre == FactUnknow || pre==FactFalse){
delete (*father);
return pre;
}
ASSERT(pre == FactTrue);
//将按照规则的命题次序列出
//?
AiTree* temp = sonPre;
while(temp->GetLch() != NULL)
temp = temp->GetLch();
temp->SetLch(*father);//将本命题挂到已推出前级命题 的后面
//*father = son;
//修改错误
if (own == FactTrue){
*father = sonPre;
return FactTrue;
}
if (own == FactUnknow)
{
POSITION p;
AiRule* pData;
for (p=m_ruleList.GetHeadPosition();p!=NULL;)
{
pData = ((AiRule*)(m_ruleList.GetNext(p)));
if ( pData->GetMt().GetId() == aimMt.GetId() )
{
AiMt mt;
AiWffs* wff =& pData->GetWffs();
mt.SetId(wff->GetId());
mt.SetPre(wff->GetPre());
mt.SetSign(wff->GetSign());
AiTree* son;
int w = SearchInsideForTree(mt,&son) ;
if (w == FactTrue)
//此处返回FactFalse表示推理未成立
{
AddFact(pData->GetMt());
// for tree
if (GetFact(aimMt) == FactTrue){
(*father)->SetRch(son);
*father = sonPre;
return FactTrue;
}
else{
ASSERT(GetFact(aimMt) == FactFalse);
(*father)->SetRch(son);
*father = sonPre;
return FactFalse;
}
}
else if (w == FactFalse || w == FactUnknow){
//
//每次搜索恢复知识
for (int i=0;i<m_numAssert;i++) {
if (m_factBS[i].GetValue() == FactTrue
|| m_factBA[i].GetValue() == FactTrue)
m_fact[i].SetTrue();
else if (m_factBS[i].GetValue() == FactFalse
|| m_factBA[i].GetValue() == FactFalse)
m_fact[i].SetFalse();
else{
ASSERT(m_fact[i].GetValue() == FactUnknow
|| m_factBA[i].GetValue() == FactUnknow);
m_fact[i].SetUnknow();
}
}
////每次搜 索恢复知识;END
}
}
}
}
delete sonPre;
return FactFalse;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -