⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aiexpert.cpp

📁 一个面向对象的产生式推理模型
💻 CPP
📖 第 1 页 / 共 4 页
字号:
{
	//
	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 + -