1.入门 1.1.需求 Jess是一个用java语言编写的程序库。因此要使用Jess你需要Java虚拟机(JVM)。你可以从 Sun Microsystems上免费得到一个非常适合用于Windows, Linux,Solaris上的JVM。Jess 7是兼容所有版本的Java,从开始的JDK 1.4到现在的最新版本JDK1.5。版本更老的编号为4.x的Jess兼容JDK 1.0, 5.x版本兼容的是JDK1.1,Jess 6工作在JDK1.2及以上版本。 在使用Jess前请先确认JVM是否正确安装并能正常工作。 使用JessDE集成开发环境,你需要Eclipse SDK的3.1版或更新版本,这个可以从http://www.eclipse.org获得。安装JessDE前请确认Eclipse是已经安装并能正常工作。 Jess类库为另一种语言担任译员,这种语言我在本文档中称为Jess语言。Jess语言是一种高度专业化的Lisp形式语言。 我会认为读者你是将使用这两种或其中一种语言的一个程序员。并且所有的读者都至少有起码Java基础。另外你必须有一个Java运行系统和知道如何以一个简单的方法使用这个系统。你应该知道如何用它来: ? 运行一个Java应用程序 ? 处理如CLASSPATH变量的配置问题 ? 编译Java源文件集(可选) 如果你没有对Java的环境有基本的熟悉,那么我建议你购买了关于java的基础的书籍。对与各种平台的Java软件以及丰富的教程和文档可以免费从http://java.sun.com上获得。 对于那些将要使用jess语言编写程序的读者,我假定你们已经熟悉了一般程序编写的原理。我会说明整个Jess语言,所以熟悉Lisp是不需要(虽然熟悉是有些用的)。此外,在可能范围内,我将努力说明基于规则系统的最重要的概念,因为它们适用于Jess。再次,我将假定读者对这些概念有了一定的熟悉程度和了解更多。如果不熟悉基于规则系统,你也许应当考虑购买一本关于这一主题的书籍。 许多读者都希望提高Jess的能力,无论是通过向Jess语言加入的命令(用JAVA语言写)或以Java应用的方式嵌入Jess库。另外一些人会想用Jess语言的Java集成能力来从Jess语言程序调用Java函数。在本文档专门针对这类读者的一些章节中,我将承担适度Java编程的知识。我不会教Java语言任何方面的知识,有兴趣的读者可到您当地的书店参阅相关书籍。 这个文档包含了一个目录,在很多书上这些主题也都被列举出来。 1.2.准备 1.2.1.安装包的组成 Jess提供一个可用于所有支持平台的单独的.zip压缩包。这个单独的文件压缩包包含在Windows,UNIX,或Macintosh系统上使用Jess的所有你需要(除了JVM你必须自己安装)的资源。当Jess是解压后,你应该有一个命名为jess71a2 /的目录。在这个目录路径有下列文件和子目录: README 快速开始指导. LICENSE 关于Jess使用的您的权利信息. bin 一个包含Windows 批处理文件(jess.bat)和一个UNIX脚本(Jess)的目录,你可以使用它们启动Jess命令提示符. lib 该目录含有作为一个Java档案文件的Jess本身。注意,这不是一个“点击”存档文件,你不可以通过双击它运行Jess。这是要注意的。在这个目录的jsr94.jar包中又包含了符合JSR - 94 (javax.rules)的API。 docs/ 这是一个文档,以“index.html”为首页的Jess手册。. examples/jess 一个包含使用Jess语言编写的小程序的目录. examples/xml 一个包含使用JessML, Jess's XML规则语言编写的小程序的目录. eclipse JessDE, 是Jess集成开发环境, 提供支持Eclipse 3.0的插件集。看这里的安装说明。 src (Optional) 如果这个目录存在,它包含全部的Jess规则引擎和开发环境的源代码,包括一个构建它的Ant脚本。 1.2.2.命令行界面 Jess有一个交互的命令行界面。分布包括两个你能运行Jess命令提示符的脚本:其中一个用于Windows,另一个用于UNIX。它们两个都在bin/ directory目录下。运行适合你系统的那一个,然后你应该看到以下的界面: C:/Jess71a2> bin/jess.bat Jess, the Rule Engine for the Java Platform Copyright (C) 2006 Sandia Corporation Jess Version Jess71a2 9/5/2006 Jess> 这就是Jess的命令。尝试计算一个前缀数学表达式"(+ 2 2)"。不要忘记那些括号! Jess> (+ 2 2) 4 Jess计算了此函数,并打印结果。在这份文档的下一章,我们会发现Jess规则语言本身的语法。 通过Jess命令行执行Jess代码编写的文件,可以使用批处理命令: Jess> (batch "examples/jess/sticks.clp") Who moves first (Computer: c Human: h)? 在前面的例子应注意到,在Jess>提示符后键入命令,Jess将在下一行响应命令。我将在整个这本文档中遵循本约定。 直接从操作系统提示符执行这样的Jess程序,你可以把程序的名字作为Jess脚本的一个参数,这样就可以启动: C:/Jess71a2> bin/jess.bat examples/jess/sticks.clp Jess, the Rule Engine for the Java Platform Copyright (C) 2006 Sandia Corporation Jess Version Jess71a2 8/28/2006 Who moves first (Computer: c Human: h)? jess.console类是一个简单的jess命令行界面的图形版。你在窗口的底部输入一个命令,结果就会出现在滚动窗口之上。试着从Jess71a2路径下键入下面命令: C:/Jess71a2> java -classpath lib/jess.jar jess.Console 1.2.3.Java程序设计语言与Jess 要在你的Java程序中把Jess做为库使用,文件jess.jar(在lib目录下)必须是以一个标准的扩展名安装在类路径之下,或者对你的开发工具配置后能够识别它。做好这些工作的细节是随系统和环境而定的,但在设置一个类路径时通常涉及修改环境变量,并且安装一个标准的扩展名,简单来说就是复制jess.jar到你的$(JAVA_HOME)/jre/lib/ext路径下。可查阅Java文档或介绍Java的文本以了解更多的细节。 1.2.4.Jess例子程序 有一些简单的例子程序(在examples/jess和examples/xml目录下),您可以用这些程序测试你的Jess是否已经安装正确。这些程序包括fullmab.clp,zebra.clp和wordgame.clp。fullmab.clp是关于猴子与香蕉问题的经典版本。要从命令行运行它,只需要输入: C:/Jess71a2> bin/jess examples/jess/fullmab.clp 和要运行的问题,就会在屏幕上输出结果。任何Jess代码的文件都可以以这种方式运行。像使用批处理函数一样在命令行给一个Jess文件名就可以运行了。因此,一般你只需要保证文件是以: Jess> (reset) (run) 结束或根本没有规则将运行。zebra.clp和wordgame.clp程序是两个典型的例子,它们是用来展示Jess如何处理复杂情况的程序。这些例子都产生大量的局部模式匹配,因此它们运行非常慢而且使用了大量的内存。另外的例子包括sticks.clp (互动游戏)和frame.clp (一个使用jess的java集成能力建立图形界面的演示)。 XML的例子在单独的子目录下,每个子目录中都包含有运行例子说明的自述文件。 2.Jess开发环境 Jess 7包括一个基于Eclipse的开发环境。这个开发环境有一个编辑器,一个调试器和一个Rete网络视图。在将来发布的版本中将包含更多组件(规则浏览器和其它工具)。 2.1.安装JessDE Jess开发环境(JessDE)是作为一个插件集支持流行的开源的集成开发环境Eclipse;该插件支持Eclipse 3.1及其更新版本。应该注意的是JessDE仅仅工作在完全的" Eclipse SDK "上——较小的"二进制运行平台"是不能运行的。 安装JessDE,首先要退出Eclipse,然后从Jess71a2/eclipse解压缩所有文件到顶层的Eclipse的安装路径。确认在你的eclipse安装目录有一个名为" plugins/gov.sandia.jess_7.0.0 "的目录存在,然后重新启动Eclipse。 注意!如果你只是从以前的版本的JessDE更新,你必须在Eclipse的命令行使用"-clean "命令开关,强制更新缓存中有关JessDE插件的信息。如果你不这样做,很多的JessDE的选项可能被禁用,安装后你只需要这样做一次。 2.1.1.验证你的安装 在“Help”菜单下选择“about Eclipse SDK”。在" about Eclipse SDK "主窗口有一个有Jess标志的按钮。单击“Plug-in Details”,如果JessDE已安装妥当,你将发现三个或四个Jess相关插件在列表上——在我的Eclipse中,它们出现在底部。 然后使用“New Project”向导建立一个Java工程。在新的工程中创建一个新文件并命名为“hello.clp”。这个文件会在一个Jess的编辑器中打开,这个编辑器有一个带红色“J”字的银色小球的图标。输入一些Jess代码,如下: (printout t "Hello, World" crlf) 你应该看到合适的语法被高亮显示。如果看到,祝贺你!工作一切正常!阅读更多JessDE其他功能的信息。 2.1.2.更多的细节 JessDE编辑器在你的Jess文件中能够标示出语法错误和警告。你很可能希望这些标记能出现在Eclipse的“Problems”视图中,尽管在默认情况下它们可能没有显示出来。安装完成JessDE后,重新启动Eclipse,在Problems的视图,在标题栏点击“Filters”的图标,然后选择标着" Jess Problem "(如果没有被选中的话)多选项。你的Problems视图应该马上就会显示Jess错误和警告。 要使用Rete网络视图,你需要安装Eclipse图形编辑框架(GEF)。你可以从Eclipse工程项目页面得到GEF,或通过Eclipse的内置式更新管理器安装它。然后打开这一视图,在“Jess Debugger”组之下Eclipse的“Show view”对话框找到它。那么在Jess编辑窗口中当光标停在某一内部规则时,Rete网络视图将会为这项规则显示出编译的网络。 2.2.使用JessDE 2.2.1.Jess语言编辑器 JessDE编辑器可以编辑“.clp”格式的文件。在默认情况下你建立的任何 “.clp”格式的文件都将使用JessDE编辑器打开。没有单独Jess的视图,或是Jess项目类型;我们期望大多数人都将使用JessDE工具来写Jess/Java混合应用组成的Jess程序,因此JessDE工具将用在Java项目的文件中。在Jess语言代码中JessDE使用你的Java项目的类路径以解决Java中类名称问题——例如,调用defclass函数。 编辑器有您期望的一个现代程序编辑器所应具有的全部功能。 可定制的语法变色 你可以使用Eclipse全局参数对话框中的“Jess Editor”表来改变默认的颜色。 提供模板,槽和函数名的帮助内容 在许多不同地方使用JessDE编辑器你可引用Eclipse的" Content Assist "功能;JessDE将使输入Jess代码变得更容易。在输入时可以使用快捷键Alt-' / '弹出选择列表清单。 自动修复代码的“Quick fix”助手 这个功能默认使用Ctrl-1快捷键,快速匹配能立即知道怎样定义未定义的deftemplates,并为现有的deftemplates(如果它们在相同的文件里被定义)增加新的槽。 实时错误检测标记和错误高亮显示 当你输入有错误和警告时将被高亮显示 代码自动格式化 当你输入时代码自动缩进。你可以从"Source"菜单下选择"Format"命令来格式化一个全部的缓冲区 使用大纲视图快速导航 Eclipse大纲视图列出了所有在缓冲区中定义的结构;你可以点击其中任何一个就能够迅速定位到它 圆括号匹配和自动插入 当你输入一个'('或’”’符号,JessDE就会插入匹配的符号。当你的光标移动到下一个圆括号时,JessDE会显示与之相匹配的圆括号。 通过悬停获得Jess函数和结构在线帮助 快速访问Jess手册中每一个函数和结构类型的描述。 支持deftemplates 和 deffunctions的悬停帮助 如果你将你的滑鼠移动到一个deftemplate或deffunction的名字上,任何代码处,JessDE都将显示一个关于这个模板或函数信息的"tooltip"。 Jess程序的运行和调试命令 你可以使用正常Eclipse 的" Run... "菜单或由右击导航项或在编辑窗口运行或调试Jess程序。 2.2.2.文件之间的关联 有时候一个*.clp文件依靠其他的*.clp文件中的代码先被阅读执行。例如,rules.clp 也许需要templates.clp中的定义。没有这些定义,rules.clp将会出现语法错误。为了解决这个问题,你可以使用require*函数。"require*"让你清楚的声明这些关联。 如果一个文件rules.clp依靠在Java中执行的Jess命令,你可以仅仅为了这个目标创建一个特殊的文件处理这个问题(你也许称之为ruledepends.clp),这个特殊的文件包括了编辑器中使rule.clp文件能够正确解析的所有声明。如果你添加"(require* ruledepends)"到rules.clp中,仅当这个外部文件存在的话才会解析,因为它有可能正在开发中。当你部署代码时,你不需要部署ruledepends.clp,只要rules.clp能够从Java代码中取得所需声明。 "require"机制代替了JessDE的早期版本中的"Source dependencies"属性表,"Source dependencies"属性表已不再被支持。 2.2.3.Rete网络视图 使用JessDE的"Rete Network View"你可以即时看到一个衍生自任何规则的Rete网的图形展示。当这个视图是打开时(你可以使用Eclipse中的"Windows | View | Other..."对话框打开它),它会显示基于编辑器插字符所在规则的Rete网络,你可以用这个实时看到修改规则所对应的Rete网络变化。图表的布局方式是远胜于你能从Jess视图命令中得到的----因为这样没有重叠和交叉线,而且每一列的高度都可变。 2.2.4.Jess调试器 JessDE调试器可以让你调试一个在.clp文件中定义的Jess程序。它具有您期望的图形调试器所具有的所有功能:你可以暂停和恢复程序,或以步进方式执行。当程序停止时,执行堆栈的内容将会显示出来,这样你就可以检查在每个堆栈结构中定义的变量。选择的堆栈结构也可以导航到被执行的源码处。在编辑器窗口的左手边缘处,你可以通过右键单击某一规则在任何.clp文件中设置(或清除)断点。断点仅能设在函数(内置或用户自定义)中,所以你不能在defrule 或者deftemplate结构中打断程序执行。然而,你能够在一个调用规则 的左边或右手边的函数中暂停。 3.Jess 语言基础 大多数时间你是在使用Jess语言编写Jess规则。如果你从来没有使用过Lisp,第一次使用Jess规则语言也许看起来就有点奇怪了,但它并不需要太长时间来学习。回报也是丰厚的,你将使用非常少的代码表达复杂的逻辑关系。 在这一章,我们将看到Jess语言的基础语法。在后面的章节中,我们再来学习怎样定义像事实与规则这样的高级概念,但现在我们将学习最基础的。 在本语言指导中,我将使用一个非正规的符号来描述语法。在< >中的基本串是必须提供的数据类型,在方括号中([])的内容是可选的,以 + 结束表示可以出现一次或多次,以 * 结束表示可以出现零次或更多。一般来说, Jess的输入格式是自由的。换行不具有特殊的含义,仅被处理为空格,而异常将被标识。 3.1.符号 符号是Jess语言的一个核心概念。符号是非常类似于其他语言中的标识符。Jess符号包括字母,数字和下面的标点符号:$*=+/<>_?#.。一个符号不能以数字开始,可以以一些特殊的标点符号开始(这些字符作为操作员当出现在符号开始时有着特殊的意义) Jess符号对于大小写敏感。foo,FOO,和Foo是不同的符号。 最佳的符号是由字母,数字,下划线和破折号组成。破折号是传统的分隔符。如下所示为合法的符号: foo first-value contestant#1 _abc Jess中有三种特殊的符号。零,和java中的空值有点类似;真和假是Jess中的布尔类型的值。 3.2.数字 Jess分别使用Java函数parseInt(java.lang.String), parseLong(java.lang.String)和parseDouble(java.lang.String)来解析整型,长整型和浮点型数字。参考本文档中关于这些方法精确的语法描述。如下为合法的数字: 3 4. 5.643 5654L 6.0E4 1D 3.3.字符串 Jess中的字符串是用双引呈来标识的(").。反斜线能够区分嵌入的引号。注意Jess的字符串和Java的字符串在一些重要的地方是不一样的。首先,不会认识转义序列。比如说你不能用一个"/n"字符串来换行。另一方面,真正的换行可以通过双引号中的字符串来实现。他们是字符串的一部分。如下为合法的字符串: "foo" "Hello, World" "/"Nonsense,/" he said firmly." "Hello, There" 最后一个字符串相当于Java中的字符串"Hello,/nThere".。 3.4.列表 Jess中的另一个基础语法元素是列表。列表是由圆括号和空,符号,数字,字符串和其他列表组成。如下所示为合法的列表: (+ 3 2) (a b c) ("Hello, World") () (deftemplate foo (slot bar)) Jess中列表的第一个元素(Lisp中称为列表的car)通常被称列表的头。 3.5.注释 Jess支持两种类型的程序注释。Lisp风格的行注释和C风格的块注释。行注释是以分号开头,延伸到文本中本行的最后。这里有一个行注释的例子: ; This is a list (a b c) 块注释就和他们在C语言中的用法一样:他们以两个特征符""结束。块注释不能嵌套。 注释可以在Jess程序的任何地方出现,包括模板和规则的结构里。 3.6.函数调用 和Lisp一样,Jess中的所有代码(控制结构,分配,程序调用)都是以函数调用的方式进行的。没有操作器,一切都是函数调用。然而,有些函数的名字使它们看起来像是Java操作器,在这种情况下,它们就和它们的Java 副本工作的非常相似。 Jess中的函数调用可以理解为简单的列表。函数调用采用前缀表示,如果一个列表的头部是一个已经存在的函数的符号,那么它就可以称为是一个函数调用。举例来说,用+函数来算2和3相加的表达式应该写为(+ 2 3)。在计算时,这个表达式的结果是数字5(不是一个仅包含数字5的列表!)。通常来说,在合适的时候表达式都被看作是这样并通过上下文求值。你可以在Jess>提示符后键入表达式。Jess计算表达式并打印出结果: Jess> (+ 2 3) 5 Jess> (+ (+ 2 3) (* 3 3)) 14 注意你可以嵌套调用函数;外部函数是形成内部函数调用计算的因素。 Jess自身带有大量的内置函数,它们可以用来做一切事情,如数学计算,程序控制和字符处理,让你能够使用Java的API函数。当然你也可以在Jess语言或者是Java语言中定义自己的函数。 其中一个最经常用的函数是printout,它是用来发送文本到Jess的标准输出窗口,或者是输出到一个文件中。完善的解释你必须等待,但是现在,你所要了解的都包含在下面这个例子中: Jess> (printout t "The answer is " 42 "!" crlf) The answer is 42! 另一个常用的函数是batch,它是用来计算一个包含Jess代码文件的。要运行Jess源文件examples/jess/hello.clp,你可以键入: ess> (batch "examples/jess/hello.clp") Hello, world! Jess自带的其他的所有函数的详细说明都在Jess function guide.。 3.7.变量 Jess中程序变量是以问号开始的标识符。问号也是变量名的一部分。名字可以包括字母,数字,破折号,下划线,分号和星号的任何组合。 一个变量可以看作是一个简单的符号,数字,字符串或者是一个列表。你可以用bind函数来为变量指定一个值。 Jess> (bind ?x "The value") "The value" 变量在第一次使用前不需要声明(全局变量除外)。 想在Jess提示符后看到变量 的值,你只需要键入变量的名字: Jess> (bind ?a 123) 123 Jess> ?a 123 3.7.1.全局变量(默认全局) 你在Jess提示符后或者任何Jess语言程序顶层创建的所有变量, 当重置命令运行的时候都将被清除。这样就使它们稍嫌短暂,对于暂时性变量它们很好用,在标准理解的前提下不是永久全局变量。要创建不被reset销毁的全局变量,你可以用全局结构: (defglobal [? = ]+) 全局变量的名称必须是以星号开头以星号结束。合法的全局变量如下: ?*a* ?*all-values* ?*counter* 当全局变量建立以后,它会被初始化赋值。当reset命令随后执行的时候,这个变量可能会用相同的值重新设置,当然这取决于reset-globals的属性设置。有一个称为set-reset-globals的函数可以用来设置这个属性。如例所示: Jess> (defglobal ?*x* = 3) TRUE Jess> ?*x* 3 Jess> (bind ?*x* 4) 4 Jess> ?*x* 4 Jess> (reset) TRUE Jess> ?*x* 3 Jess> (bind ?*x* 4) 4 Jess> (set-reset-globals nil) FALSE Jess> (reset) TRUE Jess> ?*x* 4 您可以阅读Jess function guide.中有关set-reset-globals和相关的get-reset-globals函数的信息。 3.8.控制流 Java中控制流(分支和循环,异常处理等)都是由一些特殊的语法和关键字如if,while,for,和try等来引导的。在Jess中,就如我们前面说过的,所有的一切都是函数调用,控制流也不例外。因此,Jess包含有那些名为if,while,for,和try以及foreach等函数。这些函数就和Java体系中相同名称的结构工作起来类似。 3.8.1.简单循环 例如,如下 是Jess中的一个“while”循环示例: Jess> (bind ?i 3) 3 Jess> (while (> ?i 0) (printout t ?i crlf) (-- ?i)) 3 2 1 FALSE While循环的第一个参数是一个布尔表达式。While函数计算它的第一个参数,如果它为真,就计算它所有其他的参数。它一直进行这个过程直到它的线一个参数值为假。一个while循环总是返回FALSE. Jess中内置有一些其他的循环函数。详情参看Jess function index.中关于for和foreach的有关描述。Jess中有一个break函数,可以有来跳出循环,也可以很早的从一个规则的右手边返回。 |
本文引用地址: http://www.sciencenet.cn/m/user_content.aspx?id=276394 |