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

📄 aiexpert.cpp

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