📄 aiexpert.cpp
字号:
{
//
if (Present == Total)
{
int* OldValue = new int[Total];
for (int i=0;i<Total;i++)
OldValue[i] = GetFact(i);
int numRule = GetNumRule();
int* ruleExist = new int[numRule];
for (i=0;i<numRule;i++)
ruleExist[i] = 0;
//
BOOL FactChanged = TRUE;
POSITION p;
AiRule* t;
for (; FactChanged ;)
{
FactChanged = FALSE;
int whichRule=-1;
for (p=m_ruleList.GetHeadPosition();p!=NULL;)
{
whichRule++;
t = (AiRule*) m_ruleList.GetNext(p);
if (!ruleExist[whichRule]){
if (QueryWffsForSelfCheck((t->GetWffs()) ) == FactTrue){
if (AddFactInSelfCheck(t->GetMt()) == false){
int id = t->GetMt().GetId();
CString str = "对下述命题进行确认时发现矛盾:\n“";
str+=m_mention[id].GetAbbreviation();
str+=":";
if (t->GetMt().GetSign() == NeedNotVersa)
str+=m_mention[id].GetTrueMention();
else if (t->GetMt().GetSign() == NeedVersa)
str+=m_mention[id].GetFalseMention();
str+="”\n错误出现在[第";
char temp[4];
itoa(whichRule+1,temp,10);
str+=temp;
str+="条规则]:\n";
str+=GetRuleString(whichRule);
int choice = ::MessageBox(NULL,str,"检测到知识库中存在矛盾",
MB_ABORTRETRYIGNORE | MB_DEFBUTTON3
| MB_TOPMOST | MB_ICONERROR);
if(choice == IDIGNORE)
ruleExist[whichRule] = 1; //忽略
else if (choice == IDRETRY){
//重试
p=m_ruleList.GetHeadPosition();
ruleExist[whichRule] = 0;
whichRule=-1;
}
else{
//终止
for (i=0;i<Total;i++)
SetAssertValueWithoutCheck(i,OldValue[i]);
delete OldValue;
return false;
}
}
FactChanged = TRUE;
ruleExist[whichRule] = 1;
t->SetExist();
}
}
}
}
for (i=0;i<Total;i++)
SetAssertValueWithoutCheck(i,OldValue[i]);
delete OldValue;
return true;
}
//
SetAssertValueWithoutCheck(Present,FactTrue);
for (int i=Present;i<Total;i++)
if (InsideSelfCheck(Leave,Total,i+1) == false)
return false;
SetAssertValueWithoutCheck(Present,FactFalse);
for (i=Present;i<Total;i++)
if (InsideSelfCheck(Leave,Total,i+1) == false)
return false;
SetAssertValueWithoutCheck(Present,FactUnknow);
for (i=Present;i<Total;i++)
if (InsideSelfCheck(Leave,Total,i+1) == false)
return false;
return true;
}
int AiExpert::QueryWffsForSelfCheck(AiWffs wffs)
{
int own;
own = GetIdFact(wffs.GetId());
if (own == FactUnknow)
return FactUnknow;
int pre;
if (wffs.GetPre()!=NULL)
{
pre = QueryWffsForSelfCheck(*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::AddFactInSelfCheck(AiMt mt)
{
int oldValue = GetFact(mt);
if (oldValue == FactFalse){
return false;
}
AddFact(mt);
return true;
}
int AiExpert::MoveRuleUpOneStep(int oldIndex)
{//使第index条规则前移一位,index从0开始
//返回新的位置,-1表示错.
if (oldIndex<=0 || oldIndex>=m_ruleList.GetCount())
return -1;
if (oldIndex == 0)
return 0;
POSITION p;
int i=0;
AiRule* pRule;
for (p=m_ruleList.GetHeadPosition();p!=NULL && i<oldIndex;i++)
pRule = (AiRule*)m_ruleList.GetNext(p);
POSITION thatp = p;
pRule = (AiRule*)m_ruleList.GetNext(thatp);
m_ruleList.RemoveAt(p);
//
oldIndex--;
for (p=m_ruleList.GetHeadPosition();p!=NULL && i<oldIndex;i++)
pRule = (AiRule*)m_ruleList.GetNext(p);
m_ruleList.InsertBefore(p,pRule);
return oldIndex;
}
int AiExpert::MoveRuleDownOneStep(int oldIndex)
{
if (oldIndex<=0 || oldIndex>=m_ruleList.GetCount())
return -1;
if (oldIndex == m_ruleList.GetCount()-1)
return oldIndex;
POSITION p;
int i=0;
AiRule* pRule;
for (p=m_ruleList.GetHeadPosition();p!=NULL && i<oldIndex;i++)
pRule = (AiRule*)m_ruleList.GetNext(p);
POSITION thatp = p;
pRule = (AiRule*)m_ruleList.GetNext(thatp);
m_ruleList.RemoveAt(p);
//
oldIndex;
for (p=m_ruleList.GetHeadPosition();p!=NULL && i<oldIndex;i++)
pRule = (AiRule*)m_ruleList.GetNext(p);
m_ruleList.InsertAfter(p,pRule);
return oldIndex+1;
}
int AiExpert::SelfCheckLikeAsk()
{
//模拟启发式搜索的全部可能,进行知识的安全性检测
//返回true安全,false有错误。
//为检测多目标交互矛盾,在检测时,添加临时命题、规则
//改变临时目标
const int maxnum = GetNumAssert();
int* OldValue = new int[maxnum];
for (int i=0;i<maxnum;i++){
OldValue[i] = GetFact(i);
}
CObList tempGoalList;
POSITION p;
for (p=m_goalList.GetHeadPosition();p!=NULL;)
tempGoalList.AddTail((AiMt*)m_goalList.GetNext(p));
AiAssert("临时附加命题为真","临时附加命题为假");
SetMention(maxnum,"★","这是一个临时的附加命题",
"临时附加命题值为真","临时附加命题值为假");
int* goalUsed = new int[maxnum];
for (i=0;i<maxnum;i++)
goalUsed[i] = 0;
AiMt* pPreMt = NULL;
AiMt* pNowMt = NULL;
AiMt* pTempMt;
for (p=m_goalList.GetHeadPosition();p!=NULL;){
pTempMt = (AiMt*)m_goalList.GetNext(p);
if (!goalUsed[pTempMt->GetId()]){
pNowMt = new AiMt;
*pNowMt = *pTempMt;
pNowMt->SetPre(pPreMt);
pPreMt = pNowMt;
goalUsed[pTempMt->GetId()] = 1;
}
}
AiMt tempGoal;
tempGoal.SetId(maxnum);
AddRule(*pNowMt,tempGoal);
m_goalList.RemoveAll();
m_goalList.AddTail(&tempGoal);
//开始模拟启发式搜索的全部可能。
const int numRule = GetNumRule();
int* ruleExist = new int[numRule];
for (i=0;i<numRule;i++)
ruleExist[i] = 0;
//m_NeedNotAsk[maxnum] = 1;
int resultOK = SuspectSearchForSelfCheck(tempGoal,ruleExist,numRule);
//恢复临时命题目标和规则
m_numAssert--;
m_goalList;
m_ruleList.RemoveTail();
m_goalList.RemoveAll();
for (p=tempGoalList.GetHeadPosition();p!=NULL;)
m_goalList.AddTail((AiMt*)tempGoalList.GetNext(p));
//恢复数据
for (i=0;i<maxnum;i++)
SetAssertValueWithoutCheck(i,OldValue[i]);
delete OldValue;
delete ruleExist;
delete goalUsed;
//判断搜索结果
if (resultOK){
::MessageBox(NULL,"知识通过自检,没有发现矛盾!","自检完成",MB_OK
| MB_ICONEXCLAMATION |MB_SETFOREGROUND | MB_TOPMOST );
return true;
}
else{
return false;
}
}
int AiExpert::SuspectSearchForSelfCheck(AiMt mt,int* ruleExist,int numRule)
{
//对命题的值进行模拟,查看是否有错。
//错返回false ,否则true
const int maxnum = GetNumAssert();
int* OldValue = new int[maxnum];
for (int i=0;i<maxnum;i++)
OldValue[i] = GetFact(i);
int* oldRuleExist = new int[numRule];
for (i=0;i<numRule;i++)
oldRuleExist[i] = ruleExist[i];
if (mt.GetPre()!=NULL){
//有前面内容,先检测前提
if (!SuspectSearchForSelfCheck(*mt.GetPre(),ruleExist,numRule)){
delete OldValue;
delete oldRuleExist;
return false;
}
//当此命题赋值,再检测
if (!m_NeedNotAsk[mt.GetId()] &&
m_fact[mt.GetId()].GetValue()==FactUnknow)
{
//改错,应该先访问能推出当前命题的规则,和当前命题的左侧联合
//是否可推出
{
POSITION p;
AiRule* pRule;
int indexOfRule=-1;
for (p=m_ruleList.GetHeadPosition();p!=NULL;)
{
indexOfRule++;
pRule = (AiRule*)m_ruleList.GetNext(p);
if (!ruleExist[indexOfRule])
if (pRule->GetMt().GetId() == mt.GetId())
{
ruleExist[indexOfRule] = 1;
//设置,让其实现前提和推出的联合搜索。
//将本命题的前缀和可推出此命题的规则前提暂时连接起来。
//e.g. 当前B: A&B=>C;d&e=B;=====>>>A&d&e
AiMt wffsMt = pRule->GetWffsAsMt();
AiMt* pNow = new AiMt;
AiMt* pPreNow = pNow;
AiMt* pHead = pNow;
AiMt* pTemp; //用于指向所读方位
for (pTemp = &wffsMt;pTemp != NULL;
pTemp = pTemp->GetPre() ) {
*pNow = *pTemp;
pPreNow = pNow;
pNow->SetPre(new AiMt);
pNow = pNow->GetPre();
}
//连入本命题的前缀:
for (pTemp = mt.GetPre();pTemp != NULL;
pTemp = pTemp->GetPre() ){
*pNow = *pTemp;
pPreNow = pNow;
pNow->SetPre(new AiMt);
pNow = pNow->GetPre();
}
pPreNow->SetPre(NULL);
delete pNow;
//能推出本命题的,都应不用问
int alreadyNeedNotAsk = m_NeedNotAsk[mt.GetId()];
m_NeedNotAsk[mt.GetId()] = 1;
if (!SuspectSearchForSelfCheck(*pHead,ruleExist,numRule)){
//删除临时命题链AND临时规则询问值:
m_NeedNotAsk[mt.GetId()] = alreadyNeedNotAsk;
pNow = pHead;
for (pTemp = pHead->GetPre();pTemp->GetPre()!=NULL;
pTemp = pTemp->GetPre() ){
delete pNow;
pNow = pTemp;
}
delete OldValue;
delete oldRuleExist;
return false;
}
//
pNow = pHead;
for (pTemp = pHead->GetPre();pTemp->GetPre()!=NULL;
pTemp = pTemp->GetPre() ){
delete pNow;
pNow = pTemp;
}
pHead->SetPre(NULL);
ruleExist[indexOfRule] = 0;
}
}
}//改错的结尾
//所有能推出此 命题的规则,均不必使用
POSITION p;
AiRule* pRule;
int indexOfRule=-1;
int* before = new int[numRule];
for (int j=0;j<numRule;j++)
before[j] = ruleExist[j];
for (p=m_ruleList.GetHeadPosition();p!=NULL;)
{
indexOfRule++;
pRule = (AiRule*)m_ruleList.GetNext(p);
if (pRule->GetMt().GetId() == mt.GetId())
ruleExist[indexOfRule] = 1;
}
//
SetAssertValueWithoutCheck(mt.GetId(),FactTrue);
if (!SuspectSearchForSelfCheck(mt,ruleExist,numRule)){
delete OldValue;
delete oldRuleExist;
return false;
}
SetAssertValueWithoutCheck(mt.GetId(),FactFalse);
if (!SuspectSearchForSelfCheck(mt,ruleExist,numRule)){
delete OldValue;
delete oldRuleExist;
return false;
}
for (j=0;j<numRule;j++)
ruleExist[j] = before[j];
delete before;
}
if (m_fact[mt.GetId()].GetValue()==FactUnknow)
{
}
for (i=0;i<maxnum;i++)
SetAssertValueWithoutCheck(i,OldValue[i]);
delete OldValue;
for (i=0;i<numRule;i++)
ruleExist[i] = oldRuleExist[i];
delete oldRuleExist;
return true;
}
ASSERT(mt.GetPre() == NULL);
//查看有无规则可推出此命题
if (m_fact[mt.GetId()].GetValue() ==FactUnknow)
{
POSITION p;
AiRule* pRule;
int indexOfRule=-1;
//int* moreTempRuleExist = new int[numRule];
for (p=m_ruleList.GetHeadPosition();p!=NULL;)
{
indexOfRule++;
pRule = (AiRule*)m_ruleList.GetNext(p);
if (!ruleExist[indexOfRule])
if (pRule->GetMt().GetId() == mt.GetId())
{
AiMt wffsMt = pRule->GetWffsAsMt();
ruleExist[indexOfRule] = 1;
if (!SuspectSearchForSelfCheck(wffsMt,ruleExist,numRule)){
delete OldValue;
delete oldRuleExist;
return false;
}
ruleExist[indexOfRule] = 0;
}
}
}
if (m_NeedNotAsk[mt.GetId()] ||
m_fact[mt.GetId()].GetValue()!=FactUnknow){
//此命题的值不会询问
int r = SingleSearchForSelfCheck();
if (r == false){
for (i=0;i<maxnum;i++)
SetAssertValueWithoutCheck(i,OldValue[i]);
delete OldValue;
delete oldRuleExist;
return false;
}
else{
for (i=0;i<maxnum;i++)
SetAssertValueWithoutCheck(i,OldValue[i]);
delete OldValue;
for (i=0;i<numRule;i++)
ruleExist[i] = oldRuleExist[i];
delete oldRuleExist;
return true;
}
}
if (!m_NeedNotAsk[mt.GetId()] &&
m_fact[mt.GetId()].GetValue()==FactUnknow)
{ //所有能推出此 命题的规则,均不必使用
POSITION p;
AiRule* pRule;
int indexOfRule=-1;
int* before = new int[numRule];
for (int j=0;j<numRule;j++)
before[j] = ruleExist[j];
for (p=m_ruleList.GetHeadPosition();p!=NULL;)
{
indexOfRule++;
pRule = (AiRule*)m_ruleList.GetNext(p);
if (pRule->GetMt().GetId() == mt.GetId())
ruleExist[indexOfRule] = 1;
}
//
SetAssertValueWithoutCheck(mt.GetId(),FactTrue);
if (!SingleSearchForSelfCheck()){
delete OldValue;
delete before;
delete oldRuleExist;
return false;
}
SetAssertValueWithoutCheck(mt.GetId(),FactFalse);
if (!SingleSearchForSelfCheck()){
delete OldValue;
delete oldRuleExist;
delete before;
return false;
}
for (j=0;j<numRule;j++)
ruleExist[j] = before[j];
delete before;
for (i=0;i<maxnum;i++)
SetAssertValueWithoutCheck(i,OldValue[i]);
delete OldValue;
for (i=0;i<numRule;i++)
ruleExist[i] = oldRuleExist[i];
delete oldRuleExist;
return true;
}
ASSERT(0);
return false;
}
int AiExpert::SingleSearchForSelfCheck()
{
//保存当前搜索状态的值
int Total = GetNumAssert();
int* OldValue = new int[Total];
for (int i=0;i<Total;i++)
OldValue[i] = GetFact(i);
int numRule = GetNumRule();
int* ruleExist = new int[numRule];
for (i=0;i<numRule;i++)
ruleExist[i] = 0;
//
BOOL FactChanged = TRUE;
POSITION p;
AiRule* t;
for (; FactChanged ;)
{
FactChanged = FALSE;
int whichRule=-1;
for (p=m_ruleList.GetHeadPosition();p!=NULL;)
{
whichRule++;
t = (AiRule*) m_ruleList.GetNext(p);
if (!ruleExist[whichRule]){
if (QueryWffsForSelfCheck((t->GetWffs()) ) == FactTrue){
if (AddFactInSelfCheck(t->GetMt()) == false){
int id = t->GetMt().GetId();
CString str = "对下述命题进行确认时发现矛盾:\n“";
str+=m_mention[id].GetAbbreviation();
str+=":";
if (t->GetMt().GetSign() == NeedNotVersa)
str+=m_mention[id].GetTrueMention();
else if (t->GetMt().GetSign() == NeedVersa)
str+=m_mention[id].GetFalseMention();
str+="”\n错误出现在[第";
char temp[4];
itoa(whichRule+1,temp,10);
str+=temp;
str+="条规则]:\n";
str+=GetRuleString(whichRule);
int choice = ::MessageBox(NULL,str,"检测到知识库中存在矛盾",
MB_ABORTRETRYIGNORE | MB_DEFBUTTON3
| MB_TOPMOST | MB_ICONERROR);
if(choice == IDIGNORE)
ruleExist[whichRule] = 1; //忽略
else if (choice == IDRETRY){
//重试
p=m_ruleList.GetHeadPosition();
ruleExist[whichRule] = 0;
whichRule=-1;
}
else{
//终止
for (i=0;i<Total;i++)
SetAssertValueWithoutCheck(i,OldValue[i]);
delete OldValue;
return false;
}
}
FactChanged = TRUE;
ruleExist[whichRule] = 1;
t->SetExist();
}
}
}
}
for (i=0;i<Total;i++)
SetAssertValueWithoutCheck(i,OldValue[i]);
delete OldValue;
return true;
}
int AiExpert::GetIsMultiGoal()
{
return m_IsMultiGoal;
}
void AiExpert::SetIsMultiGoal(int isMulti)
{
if (isMulti)
m_IsMultiGoal = true;
else
m_IsMultiGoal = false;
}
bool AiExpert::CheckResultStateIsAnyoneTrue()
{//检测目标集中是否至少有一个已经成立:为真
POSITION p;
AiMt* pData;
for (p=m_goalList.GetHeadPosition();p!=NULL;){
pData = ((AiMt*)(m_goalList.GetNext(p)));
if (GetFact(*pData) == FactTrue)
return true;
}
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -