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

📄 aiexpert.cpp

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