专题(四) 一种基于知识规则推理的C++实现方法
1. 引言
决策支持系统(DSS)是一门新兴边缘学科,它不但能够有效支持结构化问题的求解,而且通过把人工智能关于知识表示和处理的技术应用到DSS,与专家系统相结合,从而形成了智能决策支持系统(IDSS),可以有效地支持半结构化和非结构化问题的求解。与单纯利用模型库的定量方法相比,IDSS的优越性突出的表现在其建立了知识库,存放有各种知识规则、因果关系和决策人员经过知识化抽象的经验,并且具有综合利用知识库、数据库和定量计算结果进行推理和问题求解的推理机。由此可见,一个组织恰当的知识库对于IDSS是至关重要的。
通常在IDSS知识库中进行知识表示的方法有:一阶谓词逻辑、语义网络、产生式规则、框架理论、面向对象表示等。其中产生式规则由于Post严格地理论证明,具有完备地理论基础;各产生式之间相互较为独立,修改与扩充都较容易,所以应用较广。本文提出了产生式知识规则的C++语言实现方法,并将推理机与知识表示相结合,构造出了一个简单高效的知识库。
2. 推理机制
每次推理,DSS都依次调用规则链中每个规则对象的Query方法(此即推理函数),直至推理结束,得到结论。在Query方法中,DSS从条件事实链中读取每一个条件事实,并在基本事实链中找相同事实,找到后,考察该事实对象的TorF字段。若为True,则表明条件事实链中的事实已经获得用户确认,则读取下一个条件事实;若为False,则表明条件事实链中的事实已被用户否认,则换一下条规则;若为Unknown,则与用户交互,由用户确认或否认该事实。若用户确认,则置TorF为True;若用户否认,则置TorF为False,并换下一规则。
这样,只有当某规则上的条件事实全部是被用户确认过的,才能得到结论,从而保证了推理的正确性。
3.代码实现
1) 定义基本事实类
class Fact // 基本事实类
{ int Number; int TorF; // 基本事实号,确认标志
public: Fact *Next; // 后继链接指针
Fact (int number) { Number=number; TorF=Unknown; Next=NULL; } //
构造函数
int GetNumber( ){return Number;}
int GetTorF( ){return TorF;}
void SetTorF(int torf){TorF=torf; }
};
2) 定义条件事实类
class List // 条件事实类
{ int Number; // 基本事实号
public: List *Next; // 后继链接指针
List (int number){Number=number; Next=NULL;} // 构造函数
int GetNumber( ){return Number;}
};
3) 定义规则类
class Rule // 规则类
{ int Number; List *pCause; int result; // 规则号,该规则的条件事实链头指针,结论号
public: Rule *Next; // 后继链接指针
Rule(int number, int a[ ]) // 构造函数
{ int i; List *l; pCause=NULL; Next=NULL; Number=number; i=0;
while (a[i]!=-1 && i<3){ l=new List (a[i++]); l->Next
=pCause; pCause=l;} result=a[3]; }
~Rule( ) // 析构函数
{ List *l;
while (pCause){ l=pCause->Next; delete pCause; pCause=l;}}
int Query( ) // 规则查询推理函数
{ char c; List *l; Fact *f=fact; l=pCause;
for (; l != NULL; )
{ f=fact; for (;;){if (l->GetNumber( )==f->GetNumber ( ))
break; f=f->Next ;}
if (f->GetTorF ( )==True) {l=l->Next; continue;}
if (f->GetTorF ( )==False) {return False;}
if (f->GetTorF( )==Unknown)
{ cout<<endl<<str[f->GetNumber ( )]<<"(Y/N)?";
c=getchar( );
if ((c=='Y')|| (c=='y')){f->SetTorF (True); l=l->Next;} else
if ((c=='N')||(c=='n')) {f->SetTorF (False); return False;}}}
if (result<4){ for(;;) { if (result==(f->GetNumber( ))) break;
f=f->Next;}
f->SetTorF(True); return False;} else
{ cout<<"\n"<<str[result]; return True;} }
};
4. 应用实例
产生式规则:中年人是老练的。中年人是细心的。老练、细心且有驾驶经验是不会出交通事故的。
由于规则较少,这里用数组代替数据库实现基本事实库和规则库。其实现代码如下:
char *str[ ]={"中年人", "老练", "细心", "有驾驶经验",
"不出交通事故","\0"};
int a[ ][4]={{1,2,3,4},{0,-1,-1,1},{0,-1,-1,2}};
int main( )
{ Fact *f; Rule *rule,*r; int i=0; fact=NULL;
while(str[i]!="\0"){f=new Fact(i++); f->Next =fact;
fact=f;} rule=NULL;
for (i=0;i<3;i++){ r=new Rule(i,a[i]); r->Next=rule; rule=r;}
for (;;){ i=rule->Query ( ); if ( i==True) break; rule=rule->Next
;
if (rule==NULL) { cout<<endl<<"可能会出交通事故!";
break;}}
return True;
}
5. 结论
本文所提供的IDSS中产生式规则知识表示、推理的实现方法是与DSS数据库相独立的,即用这样的方法产生的知识库是不依赖于数据库的。只要在DSS数据库中构造不同的基本事实库和规则库,系统就可以自动生成相应的知识库,因此具有很高的灵活性。

|