基于规则的应用程序开发实战
Dennis Merritt
Amzi! Inc。
摘要:从一个高水平的知识角度来看待不同类型的知识和它们到可执行的计算代码的映射,以便深入了解规则引擎在什么时候为什么有利于常规软件开发工具。
![*](http://img.microsoft.com/library/gallery/templates/MNP2.Common/images/3squares.gif)
本页内容
![]() | 引言 |
![]() | 事实知识 |
![]() | 程序知识 |
![]() | 逻辑知识 |
![]() | 常规vs专门工具 |
![]() | 语义鸿沟 |
![]() | 存在如果那么,那么存在如果那么 |
![]() | 规则数据库 |
![]() | 一个复合方法 |
![]() | 人工智能 |
![]() | 其它逻辑虚拟机 |
![]() | 首先是数据和过程,然后是逻辑 |
![]() | 逻辑知识工具 |
![]() | 简单事例学习 |
![]() | 详细事例学习—接种疫苗 |
![]() | 结论 |
![]() | 资源 |
引言
词语“知识”,像许多应用于计算机科学的词语一样,拥有一个不同于其常规意思的技术意思—并且和许多此类词一样,它被定义和重定义许多次以便适应计算机科学中各种不同方向的需要。
本文从一个高水平的知识角度,在更一般抽象层次上使用这个词,而不是作为一专门技术术语,然后审视了不同类型的知识和它们到可执行计算机代码的映射。目的是深入了解规则引擎在什么时候和为什么有利于常规软件开发工具。
要考查的知识的三种类型是事实,程序,和逻辑。这些划分同计算机的能力相对应。前两个类型可以自然地映射到计算机体系;而第三个不能。
事实知识
事实知识是这样的,事实,或者数据。它可以是关于客户,订单,产品的事实。
计算机有内存和外部存储设备,适应于事实知识的存储和检索。数据库工具和操作内存的程序语言就是从这些基本的机器体系组件发展而来的。
事实知识在计算机中的表现形式可以是数据库中一元素或者计算机语言中的变量,如图1所示。
![aj1rules01](https://i-blog.csdnimg.cn/blog_migrate/a8d20f3bdc8ed71916c0bfe1f93e7d7b.png)
图1:事实知识
程序知识
程序知识是关于如何执行任务的知识。它可以是如何处理订单,搜索网络,或者计算傅立叶变换等。
计算机有一个中央处理器(CPU),它每次能处理一条指令。这就使计算机非常适合于存储和执行程序。使程序知识的编码和执行变得简单的程序语言,就是起源于这个基本的计算组件。
程序知识在计算机中的表现形式是程序语言中的一串语句序列,如图 2所示。
![aj1rules02](https://i-blog.csdnimg.cn/blog_migrate/ff3d297532f482357e4088817dfc2c7b.png)
图2:程序知识
逻辑知识
逻辑知识是关于实体之间关系的知识。它可以是价格和市场分析之间的联系,也可以是产品和它的组件、症状和诊断、或者各种任务之间的关系。
不同于事实和程序知识,计算机里没有核心架构组件能很好地存储和使用逻辑知识。
典型地,有许多独立的大块逻辑知识,他们太复杂以至于不能存在数据库中,并且缺乏潜在的执行顺序,这使得它们不适合于编程。因为它没有被很好地映射到底层的计算机体系 (如图3所示),很难用起源于计算机体系结构的常规数据库和编程工具对逻辑知识进行编码和维护。
![aj1rules03](https://i-blog.csdnimg.cn/blog_migrate/a4e214e974b9b987be6524cc0beea8c2.png)
图3:逻辑知识不能很好地映射到计算机体系
专门的工具-虚拟机可以有效地适应于逻辑知识,经常用来代替常规工具(如图4所示)。规则引擎和逻辑引擎是两个例子。
![aj1rules04](https://i-blog.csdnimg.cn/blog_migrate/a314215beea51871ffc15f8e0f0cd810.png)
图4:对逻辑知识使用虚拟机
常规vs专门工具
逻辑知识经常位于商务自动化的核心,并且常常关联于应用程序的“困难”模块, 比如打电话或者航线座位的价格模块,或者订单设置的模块。此外,逻辑知识经常变化。政府法规被表达为逻辑知识,。正如变化市场条件的影响一样。驱动组织的商务规则几乎总是表达为逻辑知识。
由于逻辑知识所扮演的角色很关键,因此有充足理由使用能更快,更简单,更可靠的专门工具对逻辑知识进行编码。然而也有一些理由反对这样做,首先就是人们熟悉常规工具。许多建议都说要坚持使用熟悉的工具,虽然一般来说代价是增加开发次数,乏味的维护周期,高于正常水平的错误率,降低应用程序的服务质量。另一方面,被设计用于逻辑知识的规则引擎和其它工具也存在下列问题:
• | 存在许多选择,经常由产商指定。没有标准规则语言可用。 |
• | 每个工具都是仅适用于某些类型的逻辑知识。而诊断错误的规则不同于计算价格的规则,计算价格的规则又异于指示如何设置订单的规则。 |
• | 维护有时并不像承诺的那样容易。所有规则使用类似的词项和定义是很重要的,否则规则间的相互关系就不能像设想的那样起作用—这使维护变得困难。此外,由于规则没有顺序,跟踪其相互关系可能非常困难。 |
• | 没有标准的应用程序接口(API) 把规则引擎集成到应用程序的其它组件里。 |
考虑到这些困难,使用基于规则工具带来的好处值得我们去投资吗?在许多情况下是值得的! 比如,一个提供在线抵押服务的组织把用于价格抵押的5000行代码替换成基于逻辑规则的500行。基于逻辑的解决方案在两个月内完成而原来模块计划要一年。由于市场条件会改变,维护代价从数个星期减少到几个小时,并且结果代码中的错误几乎为零。
接近零错误的原因很简单,就是更少的代码会出现错误了,但是主要原因是代码像所表达的那样紧密反映了逻辑知识。而商务规范到不适用的程序代码之间没有这样的巧妙变换。
最大的收获也许是基于逻辑解决方案所提供的弹性,允许他们扩展其产品供应。他们现在能够为他们的顾客提供更多更好的抵押定价服务,包括为每个制度上的顾客提供设置定价逻辑的选项。
这并不是一个罕见的案例。相同的收益和10比1的提升比率一次次接连出现于使用了基于规则和逻辑技术的产商那里。
语义鸿沟
“语义鸿沟”这个概念可以用来解释逻辑知识中的许多论点。语义鸿沟同以下差别有关:应用程序中要编码的知识的自然说明方式同用来编码的计算机语言或工具的语法之间的存在区别。比如,你可以用汇编来编写科学方程式。但这是枯燥的并且容易出错,因为方程式和汇编语法之间存在很大的语义鸿沟。FORTRAN 科学编程语言被发明以减小此语义鸿沟。它允许程序员用和科学家用同在纸上写方程式十分类似的方法来编写方程式。结果就是更容易,更快地对工程和科学应用程序编码,并且更少出现错误。
事实知识和程序知识能很容易地在计算机中被编码,因为在描述事实和程序知识的方法和对它们进行编码的工具之间的语义鸿沟比较小。如前所述,这是因为计算机固有地擅长于事实和程序。而逻辑知识语义却不能被简单地映射到常规工具。考虑以下知识:
如果在星期三起程和返回,辛辛那提到丹佛的机票价格是$741。如果停留时间包括星期六或星期日则是 $356。
这个知识的意思或者语义,在模式匹配情况下能被很好的捕获。它意味着提议的旅行细节应该和规则的条件符合,并且用合适的规则决定机票价格。
这种知识可以被硬写成程序代码,但是程序代码的语义是被设计用来表达一个操作序列,而不是模式匹配搜索。另一方面,规则引擎被设计用来在模式匹配情况下解释规则,因此写入到这种工具中的规则比用程序方式编码的规则的语义鸿沟要小。
存在如果那么,那么存在如果那么
在程序代码中存储如果那么逻辑关系十分诱人,因为程序代码有if-then语句。事实上,不止是诱人,它确实可在一定程度上发挥作用。但是逻辑关系和程序的如果-那么之间存在巨大差异。程序的如果-那么是真正的分支语句,控制着程序的执行流向。如果条件为真,流向一边,如果不是流向另一边。类似于街道的分岔。
引起麻烦的正是路的比特位。逻辑关系可以被编码为程序的如果-那么,但在其所在的程序执行路径上的某个位置必须被替换。此外,如果有更多的逻辑关系,也必须在程序路径上的某点替换它们—这样,某关系的替换就必然会对其它关系的行为造成影响。如果先前的规则里有分支出现,并且紧跟一个规则,那么哪个规则先被替换是有区别的。
如果规则能很容易地映射到一棵决策树,那么这就不是问题了,但是在这种情况下,知识真正是程序的了。如果规则数目很少,那么它也不是问题,但是随着规则数目的增加,要把它们作为程序流里的分岔来维护就变得非常困难。各种规则对执行线索造成的影响越来越复杂,这首先就使代码变得很难写,并且难于维护。这并不是说这个做不到,或者确实做不到,或者确实不能做;但往往是这样的,规则模块的确是系统中最棘手的模块。
一旦被程序地编码,逻辑知识就不再能被容易理解了;即,它看起来不再像规则和声明关系的集合了。知识资源,在某种意义上,已经丢失和埋没于代码之中,就像一个科学方程式一样,如果用汇编编了码,就再也不可读了。
事实或者程序知识却不会发生这样的状况。在这种情况下,阅读代码一般确实可以显示其下面的知识。
规则数据库
在某些情况下可以把逻辑关系引入数据库。如果关系能用表格形式描述,那么可用数据库表来对规则进行编码。举这样的一个例子,如果顾客得到的折扣大小依赖于先前的销售数量的水平,那么这就能被描述成一个表并被存储在数据库中。然而,使用了程序之后,数据库方法就只对非常清晰的关系有效了。
一个复合方法
有时候,应用程序使用由程序和数据库这两种方法组成的复合方法。用表描述的规则被存在数据库中,其余的关系被编码成if-then这样的语句。
这可以简化编码任务,但它增加了维护的难度,因为逻辑知识现在有了两种不同类型的载体。
虽然有这些困难,但仍有强烈的呼声要用数据和程序或者两者都用的方法来对逻辑知识进行编码,这是因为他们熟悉这些技术,并且有大量人熟悉它们的使用。
人工智能
在70年代,斯坦佛大学的研究者首先研究了逻辑关系的编码问题。它们尝试建立一个能在血液和脑膜炎的细菌感染处理过程中为医生作出建议的系统。它们发现医学知识主要由能被表达成为如果-那么规则的逻辑关系组成。
它们多次尝试用传统工具编码这种知识,但由于如前所述的原因,他们失败了。
如果逻辑知识编码问题是由于计算机不擅长表示逻辑关系的本质所决定的,那么答案很明显就是创造一个能适应这种状况的机器。建造专门的硬件是不实际的,但是计算机是创造虚拟计算机的良好工具。这就是斯坦佛研究者们所做的工作。他们创造了能用逻辑规则编码的虚拟机。这种类型的虚拟机常称为规则引擎。
为什么计算机擅长于建立规则引擎,而不是规则本身?这是因为规则引擎的行为可以被表示为程序算法,即按下面的步骤:
• | 搜索匹配于数据模式的规则 |
• | 执行规则 |
• | 转到第一步 |
从事于第一个基于规则的系统的斯坦佛的研究者们起初把他们的工作称为“启发式编程”,即基于规则编程的另一种说法。因为人类的大量想法看起来是动态应用存储在我们大脑里的模式匹配规则,这个想法在某种程度上就是“人工智能”。无论这个词出现的真实原因是单纯的还是交易—人工智能(AI)高级研究比启发式编程能更容易得到国防部基金。'专家系统' 这个词也是出于同样原因被发明出来。
媒体对人工智能和专家系统的想法也感到非常激动,于是软件工业进入了AI泡沫,紧跟着泡沫破灭,因为技术不能做到宣传的那样。那些幸存下来的买卖此技术的公司发现人工智能这个词没有好处,所以他们寻找另一个词作为替代,现在常称为基于规则的编程。
无论你把它称为是启发式编程,人工智能,专家系统,还是商务规则处理,其下的技术都是一样的—一个使用模式匹配搜索来寻找规则并在正确的时候应用正确的逻辑知识的虚拟机。
其它逻辑虚拟机
用声明的规则编成的虚拟机并不是处理逻辑知识的唯一专门软件。也有其它这样的程序,它们戏剧性的改变了计算的历史进程。
在数据处理的早期,从数据库来的报告必须用COBOL编码。但是报告条件被指定为逻辑关系–这些列,这些部分和,等等。Culprit 是一个报告写作器,它让用户通过声明的,逻辑的方法来指定报告知识,然后它将生成程序代码来使报告发生。
这样做的好处就是我们所讨论的—用户现在可以创建和维护他们自己的报告而无需求助于程序员。结果就使新报告更快的产生,并且比通过程序组的程序方法更好的满足了用户的需求。
这项技术的阻力也是同样的。数据处理部门可不想为报告单独使用一种工具,他们熟悉COBOL。产品只有面向最终用户,而不是数据库处理部门,才能获得商业成功。
Culprit 是来自发起软件工业的非硬件公司的第一个商业软件产品。
VisiCalc电子数据表程序是另外一个例子。它让用户可以容易地描述单元间的逻辑关系而不用写程序代码。有了规则语言和报告写作器之后,虚拟引擎的关键就是把逻辑知识翻译为可执行的程序代码
电子表格应用程序促进了个人计算机的早期普及。
首先是数据和过程,然后是逻辑
斯坦佛最近的工作是研究AI为什么没有在医学中得到广泛传播,但是他们的观察只是大体地应用到软件之中。逻辑知识是用来表达实体间的关系的,除非这些实体是可计算得,那么逻辑是不能被自动化的。
一个基于规则的能帮助处理病症和其它健康方面的系统,如果没有后台的病例数据,那么逻辑的价值就十分有限。
对其它应用区域也是一样的。没有数据库产品组件,你就不能建立一个配置系统,没有电话的日期,次数和持续时间等原始数据,你就不能实现定价模型。
后台数据的缺乏延迟了新技术的传播使用。只是在最近,举个例子,大部分医生诊室才开始使用基于计算机的病历。
同样的,只是在近几年,关系数据库中才有越来越多的数据可用,并引导它们自身到多种应用用途,而不是用于显示计算历史的应用程序文件。
早期AI的成功故事同从用户那里动态收集数据的应用程序有关,比如诊断系统,或者是同拥有良好计算机化记录的组织,比如保险和电话公司。随着越来越多的多应用用途的数据变得容易获取,将有更多的程序部署逻辑知识。
逻辑知识工具
用于编码和部署逻辑知识的工具相对来说是直接的。两个关键部分是知识表示语言 和 推理引擎。
知识表示语言
知识表示就是某种特定工具的语法。每种工具都允许以某种格式输入逻辑知识,这些知识可以是引用了简单实体的如果-那么语句,也可以是引用了复杂对象和属性的复杂如果-那么语句。它们可以类似于英语语法或者类似于正规公式。良好的设计要权衡易用性和功能性。
工具也可以提供表达逻辑知识的其它方法,比如层次结构,或者包括表达不确定性的能力。不确定性对于某种类型的应用是非常有用的,比如在没有清晰正确答案的诊断情况下,只是想用某种方式获得某些信息,就像在有唯一正确答案下的定价一样。不确定性本身来自于竞争风格—模糊,贝叶斯,和起初的“确定事实”。
推理引擎
推理引擎决定在运行时如何应用规则。所有的推理引擎基本上都是模式匹配搜索引擎,即循环浏览规则,决定下一步使用哪一个规则,然后重复这个过程直到结束或者到达某个条件。但是,在如何搜索模式,应用规则之后干什么,不同的引擎的是有很大差别的。
两种基本的推理策略是目标驱动和数据驱动。目标驱动推理引擎寻找提供目标答案的规则,比如价格。找到一个之后,然后就搜索任意一个必需的子目标,比如客户状态。数据驱动推理引擎审视当前已知的数据并挑出一条可以用这些数据做一些推理的规则。它然后执行这条规则,这将增加或者改变已知数据。比如一个客户也许想订制一个门,这就是原始数据,并且匹配了一个增加数据的规则,即需要什么样的铰链,这就导致执行一条决定使用什么类型铰链的规则。
有了这两种架构,就会产生许多与应用相关的变种。诊断推理引擎也许使用这样一种策略,即一开始就沿着最有可能发生的路径来得到一个解决方法,或者采用最小花费办法,如果有必要为用户获得更多信息的话。
每种推理引擎的关键部分都是能被其它应用组件调用的API。这就能使逻辑元素能被集成到应用之中,这种方式下,更新逻辑单元时无需更新主应用程序代码。
本体
维护逻辑元素的最大问题之一是定义的一致性。如果你正在写一个技术支持系统,比如,一条关于Microsoft® Windows® 的规则和另一条关于XP的规则,它们不会互相交互除非系统真的能知道XP 就是一种Windows 操作系统。这很不幸的成为了维护逻辑元素过程中很困难的部分。而写和添加规则是很容易的,除非每个规则的作者使用规则不作为粘着单元的技术。
命名问题的一个解决方案是本体。正如其它词语一样,本体是十分适用于计算机科学的一个词。本体字典里的定义和它在计算机科学里的用途没有多大关系。(当然,本体这个词也是同那些认为启发式是比规则好的词的人联系在一起的。)
逻辑元素本体是可被应用中其它组件使用的实体间的关系和定义的集合。本体知道XP是一种Windows,Windows是一种操作系统这样的信息。本体也知道Windows 2000,Win2000,和Win2K是同义词。有了本体,规则现在就可以知道XP并且“懂得”XP是一种操作系统。比如规则可以有这样的条件“如果系统是操作系统Â…”,那么规则将知道系统的值是XP。本体提供了一个方法来描述同更普通规则附属物相联系的逻辑知识
自定义规则引擎
考虑到规则引擎表达知识的多样性,知识的推理,和同周围环境的集成,有时候很难选择正确的那个。一般的目标规则引擎将适用于一定范围内的问题,但也许不能很好的适用于它们,必需需要一些别的东西来作为补充。由于这个原因,你会发现规则引擎产品被设计为适合于某一特定应用。Microsoft BizTalk® Server 就是这样一个恰当的例子。它是被设计用来集成商务处理过程的工具。它'知道' 商务处理过程,在它们之间传递消息,可被用来表达何时调用哪个进程,在什么条件下通知哪个进程什么时候发生了什么规则。
定价问题,支持问题,设置问题和许多其它普通领域中都有各自的产品。它们都适用于各自的领域,但是对其它领域效果就不好。
另外一个问题也需要考虑,就是特定应用的自定义解决方案的创建。规则引擎并不是很难写,为一个特定应用建立一个规则引擎可以最大可能地描述知识,推理和同应用的主要组件集成。其主要的优点又引回到语义鸿沟。自定义知识表示语言可以为应用提供尽可能小的语义鸿沟,减小开发和维护的代价。
简单事例学习
为了更好地理解基于规则解决方案的优点,考虑以下事例的学习。
工作流
许多公司使用逻辑引擎和专门的基于规则的工具来对有关工作流的逻辑知识进行编码。典型地,这些工具通过管理工作流的规则简明地整合到应用程序之中。
比如,长途通讯工业工作流的大供应者已经把所描述的规则集成到应用上下文之中,所以这些规则可直接被用于长途通讯领域的任务。
这允许把定义工作流规则的商务逻辑同实际需要做的程序知识分离开来,而且它的工作流知识表示方法简单易懂和便于维护。
设置
门窗产商通过Microsoft® Visual Basic® 界面用规则逻辑元素来交互式地配置产品。承包商用Visual Basic 程序来决定哪一个工作站点配置最好,然后自动连接那个公司的服务器,发出一个订单。他们以Excel设置他们自己的平台,允许专家用特殊工具直接维护产品配置的逻辑知识。电子表格然后被翻译为低水平规则语言以用于部署此知识。
因为逻辑元素是同主应用程序代码是分离的,所以能很容易地更新它。无论什么时候从事Visual Basic程序的用户连接到服务器,配置逻辑元素的更新会被自动下载。
结果就是产生了这样一个体系,这个体系为他们的客户,承包商提供了一个强大的能为某种特定工作购买最好产品的工具。
采矿
有个成熟的模式匹配应用程序能决定一个地理位置是否有良好的采矿潜力。匹配地理特征和采矿潜力的规则是在一个逻辑元素里面,是从Visual Basic界面对这个逻辑元素单独进行维护的,这个VB界面能以图形方式显示地理地图和其它关于某位置采矿潜力信息。这个应用程序的关键是采矿术语定义的本体,它能允许模式匹配规则容易地访问地质领域的数据。没有本体,规则就很难利用不同地理学家用不同方式表达的相同地质概念的方式输入的领域数据。本体作为逻辑元素的一部分被保存和维护。
这个应用程序当前是单机的Visual Basic程序,但是将要使用Visual Basic。NET把它部署在网络上。
详细事例学习—接种疫苗
Visual Data LLC 提供一个 Microsoft® Windows® 软件,叫做办公室实习。它为病人保留所有医学记录并且完成各种你所期待的数据处理功能。
它能保存的项目之一就是一个病人接种疫苗的历史。儿科医生面临的一个问题就是要遵守接种疫苗的所有复杂规则和制度,并且要根据孩子们的接种疫苗的需求来安排他们。
客户要Visual Data 说出来访的孩子什么疫苗到期了,需要接种什么疫苗。它还要能够通过分析每个孩子接种疫苗的历史来提供关于每个孩子的报告,确认他们符合学校和夏令营的规定。这就把Visual Data带入了逻辑知识编码领域。接种疫苗的知识由CDC以纸质形式出版。每种疫苗都有一个或更多的剂量时间表,基于疫苗所属的类型,每个疫苗都有许多接种和不接种的例外情况。
对这个应用程序我们做了许多有趣的观察。
数据和过程第一,其次是逻辑
斯坦佛对医学方面的AI的第一个有关评论就是AI由于缺乏数据,所以作用有限。他们观察到AI是真正的对逻辑关系进行编码,但是如果没有逻辑知识用于推理的实体,逻辑的自动化就没有任何实际价值。接种疫苗程序就显示了这个情况。
以前从事AI系统的人们使接种疫苗逻辑自动化了,但是关于疫苗历史的病人数据却不是能很容易地得到。这些数据只能通过手工输入到系统之中以便得到接种疫苗的时间表。然而,任何经历过疫苗接种的医生都能在大概相同时间内直接从数据中指出时间表,而无需在这个过程中使用计算机。所以没有多大价值。
办公室实习为儿科医生诊室中的日常商务活动提供了足够的帮助,它收集病人的历史数据。因为数据位于计算机中,,而且办公室已经使用计算机来处理管理病人的其它方面,现在使接种疫苗时间表的逻辑知识自动化就有意义了。实际上,是客户首先要求这一功能的,在用了这个软件之后。他们注意到所有的接种疫苗信息都位于计算机之中了,那么为什么它不能自动产生接种疫苗时间表呢。
程序代码可行,但不切实际
Visual Data 首先试图通过使用程序代码来对接种疫苗逻辑进行编码。他们的应用程序是用Borland的 Delphi开发的,用Pascal编码。这个软件可以工作,但是很难写,有复杂的模块,并且只提供了他们想要提供的功能的一部分。
然而,疫苗的世界总是在变化。通过用成分之间新的更复杂规则把先前几种疫苗结合到单一的疫苗之中,新疫苗不断产生。客户想要知道这个软件什么时候能支持 Pediatrix,一种新的复杂的用于多种疾病的疫苗。软件开发者就只能叹息了。
他们熟悉Delphi,并且乐意用Delphi做他们所有的工作,他们意识到接种疫苗模块太困难以至于无法维护,所以他们选择了逻辑元素解决方案。逻辑元素把代码量从几千行减少到几百行易于理解的规则。比率是10:1。
此外,规则现在是以一个他们当地的儿科医生能理解的格式,而不是只有程序员能理解的格式出现的。应用程序被重新构造以便Delphi 代码能够调用逻辑元素,这同调用数据库很相似。接种疫苗时间表的'知识'现在完全在Delphi核心代码之外了。逻辑元素可以被更新而无需影响主应用程序,就像无需更改主程序更新数据库一样。
不像数据库,逻辑元素必须被测试,并且办公室实习使用一个工具集来独立地测试规则。衰退测试是系统的一部分,所以当逻辑元素有改变的时候,各种情节可以自动重新测试。
疫苗逻辑知识的本质
由于一系列原因,Visual Data 没有使用离架引擎。原因之一是成本,但更重要的,疫苗的逻辑知识看起来需要一套它自己表示知识的方法,包括定义,表和规则。这三者都可以以规则形式存储起来,但这样做就会使从文档到逻辑元素的映射中的一些可视化信息丢失。更好的方法是用CDC表示逻辑元素。
此外,大部分逻辑知识同以日、月、星期、年形式表达的日期和时间段有关。规则里的条件需要正确地使用日期和时间段信息,并能在合适的时候从上下文推算年龄。
因此用于接种疫苗的知识表示语言被设计成拥有以下部分
• | 词项本体以存储定义。 |
• | 输入列表知识的方法。 |
• | 输入规则的方法。 |
• | 认识日期和日期间隔的语言声明。 |
这使得我们易于添加新定义而不用影响规则,允许对基本表的直接编码,并激活同表有关的规则和用诸如最后活着的病毒疫苗这些概念来进行推理。
本体
本体描述了语义关系,比如各种Hib疫苗类型之间的关系,还有含有和不含有PRP—OMP的疫苗之间的区别。这很关键,因为它们都使用不同的时间表。
本体还描述了哪个疫苗是活体病毒疫苗,在许多规则中要注意的另外一个关键事实是含有相同活体病毒的疫苗之间的交互作用。
另外,还存在复合疫苗产品,比如复合了麻疹,腮腺炎和风疹(MMR)的疫苗。还有一些规则只相关于,举个例子,一个小孩接种了麻疹疫苗,但是数据库提示了MMR。这种知识也都在本体中。
在这里,举个例子,下面是说明水痘和小疹是活体病毒疫苗的逻辑元素的定义:
live_virus ->> 'Varicella'。 live_virus ->> 'Small Pox'。
下面是Hib的几种不同类型。
'Hib' ->> 'HbOC'。 'Hib' ->> 'PRP-OMP'。 'Hib' ->> 'PRP-T'。
表
标准表提供最小年龄,推荐年龄,和接种疫苗的最小时间间隔。如果这就是接种疫苗的全部逻辑,那么一个数据库解决方案或者其它表查询就够用了,即使表不那么简单。对一个给定的病毒,不同的表被应用,具体依赖于诸如它是否是复合疫苗,活动成分是什么,小孩是否遵守了标准时间表等这些事实。
下面是一个逻辑元素中表的例子,它描述了包含PRP-OMP的疫苗的Hib时间表。
table('Recommended B', [ % Recommended Schedule B from 'DHS Hib 2003Mar' for vaccines % containing PRP-OMP % Dose Minimum Minimum Recommended % Age Spacing Age [1, 6 weeks, none, 2 months], [2, 10 weeks, 4 weeks, 4 months], [3, 12 months, 8 weeks, 15 months]]).
规则
有了定义和表,规则就能正确工作。在给定的情况下可以用他们来决定哪个表是合适的。他们也提供处理所有异常情况的办法,比如在某一年龄之后,某种疫苗就不需要了,或者如果接种了某个活体病毒之后时间表不能维持下去了,或者某个疫苗被误提前接种后有什么补救措施等。
下面是当Polio序列完成时执行的相对简单的规则。注意到本体在一般情况下将规则引入到Polio,或单独地引到两种主要疫苗: 'IPV' 和 'OPV' 。这个规则描述了OPV 序列什么时候完成。输出包括详细的说明。
complete :- valid_count('OPV') eq 3, vaccination(last, 'OPV') *>= 4 years, !, output('Polio', [ status = complete, citation = 'DHS IPV 2003Mar', note = [ `-Complete: An all OPV, three dose sequence is complete when`, `-the last dose is given after 4 years of age.` ]]).
模块化
模块化是这个应用程序的关键条件。每个疫苗的表和规则被保存在单独得模块里。本体,另一方面,保存在一个公共模块利,所有其它模块都可以使用它。
推理引擎
疫苗逻辑元素的推理引擎被描述为能满足各种应用需求。它把一个小孩接种疫苗的历史作为输入然后到问题里每个疫苗模块得到此疫苗的状态信息。这包括分析这个疫苗过去的接种记录;今天的状态,当前的办公室来访;推荐此疫苗的下次接种的最小时间间隔。
每个模块都被设计为有相同的目标和输出,并且推理引擎调用这个目标,简化了不同疫苗的添加和特殊疫苗的维护。
推理引擎拥有应用程序接口(API),可被其它应用调用。API为不同用途提供了各种报告。比如,它可以说出就诊那天应该接种什么疫苗,或下次就诊应该打什么疫苗。它也可以做出简单或详细的报告和建议,为露营和学校提供历史分析报告。
代价与好处
逻辑元方法带来的好处有:
• | 疫苗逻辑规则程序代码量减少90% |
• | 家庭儿科医生可直接访问知识 |
• | 定位了所有接种疫苗逻辑,以前这些有不同需要的逻辑是分散在应用各个不同部分的 |
• | 易于维护,质量有保证,编码不像以前那样困难了,比如可以分析过去接种疫苗的历史并支持新的符合复合疫苗 |
所有这些好处可以归结为一个主要好处,这就是他们的软件现在能为这个区域中他们的客户提供更好的服务了,这是非常关键的一点。
代价是:
• | 要花费时间调查和学习各种不同的对接种疫苗逻辑进行编码的方法, |
• | 软件许可费, |
• | 两个月的开发时间并且要花费时间学习新技术。 |
结论
逻辑知识,不像事实或者程序知识,它难于在计算机中编码。然而,一个组织如果成功地把它的逻辑知识编码,那么它就能为它的客户提供更好的服务。
然后问题就是如何对逻辑知识进行最好的编码。可以用基于程序的工具硬把它编码,但是编码是困难的,知识变成了不透明的,并且维护成为了噩梦。
基于规则和基于逻辑的工具可以更好地适应逻辑知识的编码,但是需要为待编码的知识选择合适的工具,并且学习怎样使用工具。
离架规则或逻辑工具有时候能提供好的解决方案,但是工具的知识表示经常不适合实际知识,或者推理引擎并不像设想的那样使用知识。这就导致了和传统工具的相同的编码和维护问题,但是受知识和工具之间语义鸿沟的影响更小。
一个可行的办法就是建立一个自定义的基于逻辑的语言和推理引擎。这可以使知识的编码和实际知识距离更近,更好的集成工具和应用程序其余的部分。
资源
斯坦佛知识系统实验室主页, 介绍了他们当前关于本体和其它研究领域的工作,上面还有一些到别的相关站点的链接。
美国人工智能研究协会(AAAI) ,一个致力于AI研究和发展的非赢利机构。他们有会议和杂志,并且还有一个介绍AI和主题的特别好的网站。
Dobb博士的杂志的网站,主要是关于AI的主题和链接。
DDJ AI 专家时事通讯的过刊。你可以在订阅www.ddj.com周刊
杂志PCAI 的网站上有大量关于AI技术和产品的信息。
在Google上搜索“商务 规则 引擎”,你将获得大量商业上的连接。
关于作者
Dennis Merritt Amzi! Inc 的主要负责人 (www.Amzi.com),一个小型私人基金公司,擅长于开发基于知识和AI组件的工具,这些工具可被嵌入到更大的应用程序上下文之中。他写了两本书和几篇关于逻辑编程和专家系统的论文,现在是Dobb博士的杂志AI 专家时事通讯的编辑。Dennis的电子邮件是dennis@amzi.com