管理科学与系统科学研究新进展——第6届全国青年管理科学与系统科学学术会议论文集2001年·大连337一个知识库系统与外部数据源接口的研究马金平邢筠(青岛大学商学院管理系,266071)摘要本文论述了一个知识库系统与外部数据源接口的描述定义和程序实现方法。关键词知识库系统数据库数据源1引言随着智能决策支持系统应用领域的不断扩大,原来由模型库系统完成的部分定量分析任务,将归并到知识库系统中。即要求知识库中,不仅有专家的定性知识,而且也应该具有计算知识,形成一个广义的知识库系统。在广义知识库系统中,要求推理机不仅要具有一般的推理功能,而且能够从外部数据源获取数据,对数学模型进行求解的功能。如何从外部数据源获取数据,是使推理机具有模型求解功能的关键技术之一。笔者在生产成本管理知识库系统的开发过程中,使用Visualc++6.0成功地研究开发了该知识库系统与外部数据源的接口,拓宽了推理机的功能,收到了比较好的效果。外部数据源主要是指文本数据文件、数据库和Excel电子表。由于受篇幅限制,本文主要针对知识库系统与文本数据文件、数据库接口的设计实现问题进行讨论。知识库系统与Excel电子表的接口问题,笔者将另撰文介绍。2接口的描述定义在生产成本管理知识库中,以知识数据块的形式对外部数据源进行如下描述定义。2.1文本数据文件接口的定义格式DATAFILE//可以定义多个文件的接口。文件句柄=OPEN(文件名称)//在一个接口中,可以定义任意个输入数据文件。变量=READ(文件句柄,行号,列号)//可以有多行。|//或WITH文件句柄变量=READ(行号,列号)//可以有多行。ENDWITHENDDATAFILE2.2数据库接口的定义格式DATABASE//在一个知识库中可以定义多个这样的接口CONNECTIONADO连接对象名=连接字符串//可以同时定义多个连接对象管理科学与系统科学研究新进展——第6届全国青年管理科学与系统科学学术会议论文集2001年·大连338INPUTTABLE//每个接口只能定义一个输入块。RECORDSETADO记录集对象名=SQL查询语句,CONNECTIONADO连接对象名//可以定义多个记录集对象名。〈变量〉=ADO记录集对象名.FIELDS(字段序号)//可以有多行|//或WITH〈ADO记录集对象名变量=.FIELDS(字段序号)//可以有多行ENDWITHENDINPUTTABLEOUTPUTTABLE//定义与存储结果数据表的接口,每个接口最多可以定义一个输出块。RECORDSETADO记录集对象名=SQL查询语句,ADO连接对象名;ADO记录集对象名.FIELDS(字段序号)=〈变量〉;|//或WITHADO记录集对象名.FIELDS(变量序号)=变量;ENDWITHENDOUTPUTTABLEENDDATABASE在上述格式中,〈变量〉是指计算表达式及模型中需要用户提供值的参数,或存储表达式及模型的求解结果。“//”表示注释。此外,笔者在生产成本管理知识库系统开发工具中,开发了知识库与外部数据源接口定义的辅助工具,用户利用这些工具可以十分方便地完成接口的描述定义工作。3接口程序的实现在推理机运行之前,首先将知识库读入内存,并且转换成计算机的内部表现形式。接口程序再根据知识库与外部数据源接口的定义,将外部数据源的数据读入内存缓冲区后,最后在进行推理。为了便于查找知识库与外部数据源接口的定义语句,首先定义如下数据结构:structLineText//存储知识库语句行文本。{CStringText;//存储知识库语句行文本structlinetext*pNextLine;//下一行指针}*pLineTextHead;//知识库语句首行指针。structDataObject//知识数据块对象索引表{CStringObjecType;//对象类型structLineText*pTextLine;//对象首行在LineText中的指针structDataObject*pNextObject;};//指向下一个知识数据块对象。structKnowClsName//存储知识类名称定义语句文本{CStringClsName;//知识类名称管理科学与系统科学研究新进展——第6届全国青年管理科学与系统科学学术会议论文集2001年·大连339终止structKnowClsName*pNextCls;//下知识类名称的指针structLlineText*pTextLine;//知识类名称在LineText中的指针structDataObject*pFirstObject;//指向知识类中第一个知识数据块对象的指针structMethod*pFirstMethod;//指向知识类中第一个知识方法的指针}*pClsHead;//指向知识类的头指针。根据上述数据结构的定义,接口程序总体实现的程序流程如图1所示。在图1中,当pDo-ObjectType等于“DATAFILE“或“DATABASE”或“EXCEL”时,系统分别调用从文本数据文件、数据库和EXCEL电子表获取数据的接口函数。其中:文本数据文件接口函数的程序流程如图2所示,数据库接口函数的程序流程如图3所示。“OTHER”表示知识库中的其它知识数据块对象。NoYesYesNoDATABASEEXCELOTHERDATAFILE图1接口程序总体实现的程序流程3.1数据文件接口函数程序的实现为了存储从外部数据文件获取的数据,定义如下数据结构:structDataFileBuffer//数据文件缓冲区{CStringVariableName;/变量名称doubleDataValue;//从文本文件获取的变量值structDataBuffer*pNextPata;//指向下一个变量的指针}*pDataBufferHead,*pDataBufferTail;//缓冲区的头指针和尾指针。据此,绘出从外部数据文件获取数据的接口函数的程序流程如图2。由于受篇幅限制,图2仅给出了程序的主要算法流程。在编程时,还必须考虑具体实现的细节,例如:如何从一个数据行中,确定数据项数量,找到Col列;如何创建DataFileBuffer的链表结构等。3.2数据库接口函数程序的实现根据上述知识库与数据库接口的定义格式以及知识库内部存储结构,可以绘制出数据开始pCls=pClsHeadpCls=NULL???pDo=pCls->pFirstObjectpDo=NULL?pCls=pCls->pNextClsABCpDo=pDo->pNextObjectpDo->ObjectType=?管理科学与系统科学研究新进展——第6届全国青年管理科学与系统科学学术会议论文集2001年·大连340库接口函数程序总体流程如图3所示。其中:D表示输入数据表接口程序流程,如图4所示;E表示输出数据表接口程序流程。3.2.1输入数据表接口程序的实现为了存储从输入数据表获取的数据,定义数据结构如下:structInputDataBuffer//存储从数据库获得的数据,每一个变量建立一个数据区{_variant_tDataValue;//可以存储不同类型的数据;structInputDataBuffer*pNextDataValue;};structPremiseVariableBuffer//前提变量(自变量)集区,接受来自数据库的数据{CStringVariableName;structInputDataBuffer*pInputDataBufferHead;//指向数据区头指针。structPremiseVariableBuffer*pNextVariable;//指向下一个变量。}*pPremiseVariableBufferHead,pPremiseVariableBufferTail;据此,可以绘制出知识库从外部数据库获取数据的接口程序流程如图4所示。NoYesNoYesYesYesNoYesNoNoYesNoYesNoYes图2从外部数据文件获取数据的接口函数程序流程A定义变量、初始化pTL1=pDo->pTextLinepTL1=pTL1->pNextLinepTL1->Text=”ENDDATAFILE”?pTL2=pTL1;nFind1=pTL2-Text。Find(”OPEN”)找出文件名称、文件句柄名称,并且打开数据文件(设对象名为MyFile)。Ptl2=PTL2-pNextLinePtl2-Text=”ENDDATAFILE”?nfind1-1?在Ptl2-Text中是否存在“READ”和文件句柄名称?pTL2=pTL2-pNextLinepTL1=pTL1-pNextLine返回在Ptl2-Text中,找出变量名称VariableName,行号(Row)和列号(Col);MyFile.SeekToBegin();Boolflag=MyFile.ReadString(mDataLine);设MyFile当前行nLine=1;Flag=False?flag=MyFile.ReadStirng(mDataLine);nLine++;Row=nLine?在mDataLine中找Col列找到否?将数据和VariableName采用DataFIleBuffer结构存入内存显示消息通知用户存在错误管理科学与系统科学研究新进展——第6届全国青年管理科学与系统科学学术会议论文集2001年·大连341NoYesYesNoYesNoYesNoNoNoYesYes图3数据库接口程序实现的总体流程YesYesNoNoNoYesYesNoYesNoYesNo图4从外部数据库获取数据的接口程序流程3.2.2输出数据表接口程序的实现输出数据表用来存储推理机对表达式或模型的求解结果。因此,需要在推理机运行之定义变量、初始化pTL1=pDo->pNextLinepTL1=pTL1->pNextLinepTL1-Text=”ENDDATABASE”nFind1-1?找出ADO连接对象名称和连接字符串,并打开连接pTL1=pTL1-pNextLine返回pIT=pTL1-pNextLine;pOT=pTL1-pNextLinepIT-Text=”INPUTTABLE”pIT=pIT-pNextLineDpIT-Text=”ENDDATABASE”?nFind1=pTL1-Text.Find(“CONNECTION”)pOT-Text=”OUTPUTTAB?LE”pOT=pOT-pNextLineEpOT-Text=”ENDDATABASE”?pIT=pIT-pNextLinepIT-Text=”ENDINPUTTABLE”?pRec=pIT;在pRec-Text中,查找记录集对象名称RecName、已经打开的连接对象名称conName,pRec=pRec-pNextLine找到否?pRec-Text=”ENDINPUTTABLE”?返回pField=pRec-pNextLine从pRec-Text截出SQL命令字符串,执行。在pField-Text中找RecName找到否?pField=pField-pNextLinepField-Text=”ENDINPUTTABLE”?在pField-Text中截出变量名,并且存入PremiseVariableBuffer缓冲区;截出字段序号nFieldRecName.GetadoEOF()?将第nField字段值存入InputDataBuffer内存缓冲区RecName.MoveNext()DB管理科学与系统科学研究新进展——第6届全国青年管理科学与系统科学学术会议论文集2001年·大连342前,根据输出数据表接口描述的定义,准确地建立结果变量与打开数据表的记录集对象之间以及记录集对象与连接对象之间的链接关系,使得推理完成后,系统能够正确地连