章二 软件体系结构的构建模式(3)
一、知识库模式
1、知识库模式特征
采用知识库模式构建的系统通常有两个截然不同的功能构件:
(1)中央数据单元构件:代表系统当前的各种状态;
(2)一些相对独立的组件的集合:对中央数据单元进行操作。
这样,中央数据单元和外部组件集合之间的信息交互就成为基于知识库模式的系统中至关重要的问题。
这种信息交互的方式也存在很大差异。
信息交互方式的差异导致了控制策略的不同。主要的控制策略有两种。依据这两种不同的控制策略,基于知识库模式的系统被分成两个子类。
(1)如系统由输入数据流中的事务信息来驱动,则该系统可以称为基于传统数据库知识库模式的应用系统;
(2)如系统由知识库的当前状态来驱动,则该系统可称为基于黑板型知识库模式的应用系统。
2、一个标准的黑板型知识库模式系统通常包括3个组成部分:
(1)知识源;
(2)中央数据单元:是整个系统的核心部件,它对系统需要解决的问题预先进行了分析和定义,总结出了系统运行过程中将要出现的多种状态,并制定了这些状态下系统的相应对策;
(3)控制单元:其驱动完全是由知识库的状态编号承担的。
3、知识库模式实例:
人工智能领域-->专家系统ES(Expert System)
知识库正是专家系统的基础。
专家系统-->知识工程:知识获取、知识表示、知识推理。
专家系统:把某一领域内专家的知识和人们长期总结出来的经验方法输入其中,模仿人类专家的思维规律和处理模式,按照一定的推理机制和控制策略,利用计算机进行演绎和推理,使专家的经验变成共享资源,从而可克服专家严重短缺的现象。
专家系统的核心内容是知识库和推理机制,主要组成部分是:知识库、推理机、工作数据库、用户界面、解释程序和知识获取程序。
专家系统的结构有:人机接口、知识获取机构、知识库及其管理系统、推理机、数据库及其管理系统、解释机构、ES的通讯方法。
二、解释器模式
1、解释器模式特征:
基于解释器模式的系统核心在于虚拟机。
一个基于解释器模式的系统通常包括正在被解释执行的伪码和解释引擎。
伪码由需要被解释执行的源代码和解释引擎分析所得的中间代码组成;
解释引擎包括语法解释器和解释器当前的运行状态。
一个解释器模式中就有4个基本的构成部分:
(1)完成解释工作的解释引擎;
(2)包含伪码的数据存储区;
(3)记录引擎当前工作状态的数据结构;
(4)记录源代码被解释执行的进度的数据结构。
2、解释器模式实例
解释器模式在模式匹配系统和语言编译器等方面的应用已经非常成熟了。
(1)布尔表达式求值系统
以语法搜索匹配作为布尔表达式求值的理论基础,从语法匹配的角度来分析和解决布尔表达式求值问题。
如果一个特定语法的匹配问题发生的频率足够高,那么就有必要将该语法的各个实例表述为一种语言的句子,这样就可以构建一个解释器,该解释器通过解释这些句子来解决该语法的匹配问题。
正则表达式是描述字符串模式的标准语言,与其为每一个模式都构造一个特定的算法,不如用一种通用的搜索算法来解释执行一个正则表达式,该正则表达式定义了待匹配字符串的集合。
正则表达式的解释执行结果就是布尔表达式的最终计算值。
本实例的内容可概括为如何为正则表达式定义一个布尔表达式,如何表示一个特定的布尔正则表达式,以及如何解释这个正则表达式,得出布尔表达式的结果。
由如下文法定义布尔正则表达式:
BooleanExpression::=VariableExpression | Constant | OrExpression |
AndExpression | NotExpression | '('BooleanExpression ')'
AndExpression::=BooleanExpression 'and' BooleanExpression
OrExpression::=BooleanExpression 'or BooleanExpression
NotExpression::='not' BooleanExpression
Constant::= 'true' | 'false'
VariableExpression::='A'|'B'...'Y'|'Z'
(2)布尔表达式求值系统的优缺点:
在文法规则比较简单的情况下,解释器模式工作得很好,但如果文法规则复杂,则文法的层次变得庞大而无法管理,系统中需要包含许多表示文法规则的类。
最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将它们转换成另一种形式。例如:正则表达式通常被转换为状态机。
易于改变和扩展文法。因为解释器模式使用类来表示文法规则,用户可以使用继承来改变或扩展文法。
易于实现文法。定义抽象语法树中各个节点的类的实现大体类似,易于直接编写,通常它们也可以用一个编译器或语法分析程序生成器自动生成。
(3)布尔表达式求值系统中的角色
BooleanExpression 抽象布尔表达式
TerminalExpression 终结符表达式
NonterminalExpression 非终结符表达式
Context 上下文
Client 客户
描述:Client构建一个布尔表达式,它是TerminalExpression和NonterminalExpression的实例的一个抽象语法树,然后初始化上下文并调用解释操作;每一个NonterminalExpression节点定义相应字表达式的求值操作,而各表达式的求值操作构成了递归求值的基础;每一个节点的求值操作用上下文来存储和访问解释器系统的状态。
(4)布尔表达式求值系统的实现
创建抽象语法树;定义求值操作;共享终结符。
BooleanExpression的实现:
public interface BooleanExpression{
BooleanExpresion();
boolean evaluate(Context aContext);
BooleanExpression replace(String str, BooleanExpression de);
BooleanExpression copy();
}
Context的实现:
class Context{
public boolean lookup(String str);
public void assign(VariableExpression ve, boolean bool);
}
VariableExpression的实现:
class VariableExpression implements BooleanExpression{
private String _name;
VariableExpression(String str){
_name=str;
}
boolean evaluate(Context aContext){
return aContext.lookup(_name);
}
BooleanExpression replace(String str, BooleanExpression be){
if(str.equals(_name)){
return be.copy();
}
else{
return new VariableExpression(str);
}
}
BooleanExpression copy(){
return new VariableExpression(_name);
}
}
AndExpression的实现:
class AndExpression implements BooleanExpression{
private BooleanExpression _operand1, _operand2;
public AndExpression(BooleanExpression be1, BooleanExpression be2){
_operand1=be1;
_operand2=be2;
}
public boolean evaluate(Context aContext){
return (_operand1.evaluate(aContext)&&_operand2.evaluate(aContext));
}
public BooleanExpression replace(String str, BooleanExpression be){
return new AndExpression(_operand1.replace(str.be), _operand2.replace(str,be));
}
public BooleanExpression copy(){
return new AndExpression(_operand1.copy(), _operand2.copy());
}
}
Client的实现:
class Client{
public static void main(String[] args){
public BooleanExpression expression;
public Context context;
VariableExpression x=new VariableExpression("X");
VariableExpression y=new VariableExpression("Y");
expression=new OrExpression(new AndExpression(new Constant(true),x),new AndExpression(Y, new NotExpression(x)));
context.assign(x,false);
context.assign(y,true);
boolean result=expression.evaluate(context);
System.out.println(result);
}
}