DAOK说明书.docx
《DAOK说明书.docx》由会员分享,可在线阅读,更多相关《DAOK说明书.docx(81页珍藏版)》请在冰点文库上搜索。
DAOK说明书
Daok智能系统开发工具
版本1.0
智能分布计算研究组
XidianUniversity
(一九九九年八月九日)
概要
Daok智能系统开发工具1.0版描述的是资源模型的推理模块Daok,它完全采用Java语言编写。
Daok采用规则-基系统,它能与强大的、可移动的Java语言紧密结合。
本手册包含有Daok语法、函数、从Daok中调用Java函数方法以及用Java语言扩展Daok的指南。
一具体介绍
Daok智能系统开发工具,起源于资源模型,它完全采用Java语言编写。
Daok能方便地赋予你的Applet和应用程序以改善自我的能力。
Daok与1.0.2版本的Java语言是兼容的,特别是1.1版本,虽然当你编译时你将看到警告,但对系统工作没有任何影响!
Daok正处在不断的发展完善的过程中,更多特性正在被加入进来。
指令部分地决定了什么是接近人意的,什么是我最需要Daok做的,做它我将不得不花费多少时间。
关注一下Daok的发展,我们可以知道Daok的最新版本的情况,从后面的1.2节中我们可以得到一个大概的了解。
1.1安装与启动Daok
1.1.1打开并安装
如果你在UNIX平台上安装,你可以用tar和uncompress进行解压:
uncompressDaok-4.0.tar.z
tarxfDaok-4.0.tar
如果你在Windows平台上安装,你将得到一个名叫a.zip的文件,用Win32的解压缩软件,如WinZip进行解压缩。
不要使用PKUNZIP(它不能支持长文件名)。
WinZip十分好用。
当Daok被解压时,你应该有一个名为‘Daok1’的目录。
在这个目录中,应该有下列文件:
README.html
即本文;
Daok/
该目录包含‘Daok’文件包。
在这里有许多Java源文件,它们组成Daok的引擎;还有许多Daok的GUIs和命令行参数接口。
Main.java文件即拥有Applet(Java小程序)接口又有命令行参数接口。
命令行参数类是NullDisplay.java。
不论是Applet还是Java应用程序,QuizDisplay都是一个非常简单的、独特的GUI控制台。
Daok/view
用‘view’命令,可选择性的使用Java源工具。
Daok/reflect
利用可选择的Java源工具,在Daok中让你创建和操纵Java的对象。
Examples/
目录中有少量的CLIPS例子。
Daok/examples
目录中有Java文件的例子。
Index.html
是一个包含Applet的网页,但它需要被编辑时才能被使用!
Makefile
是Daok的一个简单的makefile。
1.1.2编译Daok
Daok来自于一套Java源文件。
首先,你需要编译它们。
如果你有了‘make’的共用程序(UNIX的make,或者是Win32的nmake和GUN的make),你将能启动make和附件makefile,这样就行了。
否则在Java编译器中,如Sun的JDK的目录下,键入命令
javacDaok/*.java(UNIX)
或
javacDaok\*.java(Win32)
每种方式都将顺利地进行。
如果出现问题,请确认一下在你的CLASSPATH中所设置的Daok的路径是否正确,它应该包含‘.’。
不要在Daok1/Daok的目录下编译,这样是不能正常工作的。
你可以用1.0.2版本或1.1版本的Java来编辑Daok。
编译结果即可以在1.0或1.1的VMs上运行。
注意如果你用1.1版本的编辑器,你将得到关于deprecated方法的警告(它是可以忽略的)。
我们可以去掉这些警告,但这样一来Daok将不能在1.0.2版本上工作。
如果你按照前面的方法,在Daok1/Daok/view,Daok1/Daok/reflect和Daok1/Daok/examples/*的目录下,将有大量的、可选的源文件不能被编译。
这些文件是任选的调试命令view,以及‘reflection’的命令,例如new,call,set,get,set-member和get-member,对象协议命令有defclass和definstance,它们仅仅能被1.1版本以及1.1以后的版本编译.如果你正好有这样的编译器,你可以键入命令,如
javacDaok/*.javaDaok/view/*.javaDaok/reflect/*.javaDaok/examples/*/*.java
来编译每一个文件。
1.1.3Daok的例子程序
这有一些例子程序你可以试着运行一下。
它们是fullmab.clp,zebra.clp和wordgame.clp。
fullmab.clp程序,这两是关于Daok解决猴子和香蕉问题的程序。
如果从命令行中运行,你可以键入:
javaDaok.Mainexamples/fullmab.clp(orexamples\fullmab.clponWin32)
这样一来将会产生一些全屏幕的输出。
用这种方法,任何由CLIPS代码组成的文件(它包含唯一用CLIPS来构造函数的Daok文件,就象文件描述那样)都能被运行。
注意在命令行给出的Daok的文件名,例如用CLIPS中的‘batch’命令,你应当用以下方式结尾:
(reset)
(run)
否则将不会运行。
zebra.clp和wordgame.clp是CLIPS的其他两个典型的例子,稍微修改就可以在Daok中运行。
这两个例子向我们展示了Daok处理模糊问题的方式。
两者都生成了大量解决问题的实践模式,因此花费了大量的内存,使得它们运行较慢。
1.1.4命令行参数接口
Daok也有交互式的命令行参数接口,在Daok4.0中已经得到提高。
键入javaDaok.Main将获得‘Daok>’提示符。
现在支持交互式的有(exit)等命令。
如果以这方式执行CLIPS代码的文件,要用‘batch’命令:
Daok>(batchmyfile.clp)
(lotsofoutput)
现在Daok运行‘system’命令,意思是说,例如在用‘batch’命令读入文件之前,你能从Daok的命令行中调用编译器编译Daok代码的文件。
利用‘system’,非Java程序员也能把Daok同其他应用程序综合在一起。
在你的系统中打开名为‘notepad’的编译器尝试一下:
Daok>(systemnotepadREADME)
TRUE
1.1.5作为Java小程序的Daok
‘Daok.Main’类中不仅有使主程序允许你从命令行执行的CLIPS代码,也有Applet接口,所以它能在环球网浏览器中运行。
Applet接口是专门运行‘mab.clp’,如猴子与香蕉那个例子的。
反之亦然,我们可以用Daok的类来创建我们自己的Applet,这样可以帮助我们理解和检验在Java中调用Daok。
你们可以修改‘Daok,Main’类,也可以从头开始编辑你自己的类(这也许是较好的主意)。
注意,特别是Daok.Main类的Applet版本并没有可供选择的完整的函数;如果你真要这样做,请查看Java的‘addUserfunction’方法和Daok的(load-function)方法将得到信息。
1.1.6从哪进行下一步
如果你以前从没有接触过CLIPS,你可以从前面跳到第二章详细学习。
如果你是富有经验的CLIPS程序员,你可以浏览一下第二章就行了,要注意Daok与CLIPS的不同之处。
如果你以前用过Daok,那么你可以阅读下一节Daok的新的特征。
1.2新版本增添的内容
如果你以前用过Daok,你将注意到1.0版本所做的更改。
●引擎运行加快许多:
(reset)的运行时间比以前少几个数量级。
●现在,遵守LHSs规则,你能从Daok语言中直接操作Java对象和Java对象的模式匹配,同样地,作为deffunctions,你能在Daok中写JavaGUIs和假设事件处理。
●Daok现在支持I/O路由器:
你能打开和关闭文件,重定标准输出,等等。
●Daok现在支持(测试)条件元件和返回值限制,允许你重写LHSs规则。
●lexer现在把整数数据库和浮点数数据库。
●这有许多有趣的新建Userfunctions,包括内部连网接口:
详细请看socket命令和browse.clp的例子文件(它能在Daok中直接恢复一个网页)。
●所有的default-package类已经被移进‘Daok’包;旧的‘Daok’类就是现在是‘Daok.Main’。
●大量公用的Java方法已经被详细地再命名:
方法名字如_this()和This()更改为This()。
●所有成员变量也都是这样。
注意Userfunction.Call()和Userpackage。
Add()方法已经少量建立。
这样一来,任何Java的扩展都是已经存在的再进行仔细的修改和编译。
●对于Daok1.0,Daok.QuizDisplay类是新增加的,它为Daok提供了非常简单的GUI控制台,我门可以执行‘javaDaok.QuizDisplay’,看一下这种功能与那种命令行形式比较结果。
对于任何GUIs你都可以用这个类作为模板建立你自己的基于Daok的系统。
----------------------------------------------------------------
2Daok语言
Daok起源于CLIPS,是有十分效的用于解释规则语言的程序。
作为CLIPS的继承物(它使用LISP编写的系统受到很大的影响)这种规则语言是基于LISP的较小的,特殊的版本,用Java代替LISP编写而成。
我将在这儿详细的描述这种语言。
CLIPS的作者们将从这儿得到更多的信息。
我将用非正式的语句来描述句法。
通常在中的字符串是一种数据,它必须被给定;在[squarebrackets]的内容是可选的,并且椭圆(...)过去通常指示一种或多种的前述事件。
总之,Daok的输入形式是多种多样的;换行符通常不是很重要,并且它被看作空格。
在对话的例子中,当Daok的提示符出现之后,你敲入信息,系统将以粗体的文本来响应。
2.1原子
在Daok语言中,一个‘原子’或者符号是公用的概念。
原子非常类似于其他语言中的标识符。
一个Daok的原子包含字母,数字和下面一些符号,如$*=+/<_?
#……,它不能以数字开头;它可以以一些标点符号开头(当标点符号在一个原子的开头时,它们常常具有某些特殊的意义)。
最规范的原子应包括字母,数字,下划线和破折号;破折号是传统的单词区分符。
以下是一些合法的原子:
foofiest-valuecontestant#1_abc
2.2数字
Daok分析数字用Java的StreamTokenizer类。
因此,它仅接受简单的浮点数和整数;它不接受科学或工程记数法。
下面是一些合法的数字:
3,4.,5.643
2.3字符串
在Daok中,字符串是用“双引述法”来表示的。
用Backslashes来取出嵌入的引述符号。
下列是是合法的字符串:
“foo”“Hello,World”“\”Nonsense\‘“hesaidfirmly.”
2.3语句
在Daok中,基本的语法单元是语句。
语句总是被封装在括弧内,或是空或是更多的字符,如数字,字符串或其他一些语句。
下列是一些合法的语句:
(+32)(abc)(“Hello,World”)()(deftemplatefoo(slot))
在Daok中,语句(the‘car’ofthelistinLISPparlance)的第一个元素通常被称为语句的头。
2.5注释
在Daok中,程序的注释行是以分号(;)为开始标志,直到这一行的结尾的全部内容。
然而注释不能出现在的构造里面(看看下面的构造)。
这是注释的例子:
;Thisisalist
(abc)
2.6函数
Daok中包括了大量的你可以调用的内部函数;其中许多都是可扩展的。
你可以用Daok(请看下面的Deffunctions)或Java(请看用Java扩展的Daok)编写你自己的函数。
在Daok中,用前缀表示法来进行函数调用。
在语句中,表达式的头一个原子是已存在的函数名,这个被赋值了的语句可以作为一个表达式。
例如,用“+”函数把数字2和3相加应写成(+23)。
当被赋值后,表达式的值为5(并不是语句包括5这个元素!
)。
总之在上下文适当的位置,表达式就是这样被赋值的。
在Daok的提示符下你可以键入表达式;Daok将给表达式赋值并打印出结果。
Daok>(+23)
Daok>5
Daok>(+(+32)(*33))
Daok>14
注意数字结果可以以浮点型或整型被返回,这要根据语句的类型而定。
Daok的工具函数仅仅是CLIPS的很小的子集。
在Daok中建立了许多十分有效的,不能被改动的函数。
所有这些函数都尽可能的被设计成与CLIPS中的相似。
一般地说,支持的内部函数有:
*,+,-,/,<,<=,<>,=,>,>=,and,assert,assert-string,bind,clear,close,eq,eq*,exit,facts,foreach,gensym*,et-var,halt,if,Daok-version-number,Daok-version-string,load-facts,mod,modify,neq,not,open,北or,printout,read,dline,reset,retract,return,rules,run,save-facts,sym-cat,undefrule,unwatch,watch,while
另一方面,我提供了比CLIPS更多的‘Userfunctions’,即用Java编写的外部函数,你可以把它嵌入Daok中,请看文件Daok/StringFunctions.java(字符串处理函数:
str-cat,str-compare等),Daok/MultiFunctions.java(集合函数:
create$,nth$),Daok/predFunctions.java)判定语:
oddp,stringp等),Daok/MiscFunctions.java(batch,system)和Daok/MathFunctions.java(abs,sqrt)。
以上所有这些函数都以默认的方式装入Daok的命令行;在你自己的应用程序中,你可以拾取或选择它们。
特别的,在Applets中,为了减小Applet的容量,你可以仅仅引入你所需要的那个Userfunctions(关于这一点,请查看用Java扩展的Daok)。
下面是所有Daok1.0版本的Userfunctions:
**,abs,bag,batch,build,call,complement$,create$,delete$,definstance,defclass,dive,engine,eval,evenp,exp,explode$,first$,float,floatp,format,get,get-member,implode$,insert$,integer,integerp,intersection$,length$,lexemep,list-function$,load-function,load-pachage,log10,lowcase,max,member$,min,multifieldp,new,nth$,numberp,oddp,pi,ppdefrule,random,replace$,rest$,round,set,set-member,setgen,socket,sqrt,str-cat,str-compare,str-index,str-length,stringp,subsetp,symbolp,system,time,undefinstance,union$,upcase
在本文后面,我们详细地描述了所有这些函数。
2.7变量
在Daok中,程序的变量是以问号(?
)开头的原子。
问号是变量名字的一部分。
一个普通变量可以是单个的原子,数字,也可以是字符串;如果一个变量以“$”开头(例如:
$?
X)时我们称之为多变量,它可以是特殊的,名叫multifield的语句。
你可以用bind函数定义任何变量:
(bind?
x“Thevalue”)
创建Multifields通常要用特殊的multifield函数,象<#createmfcreate$#createmf,这样才能定义多变量:
(bind$?
grocery-list(create$eggsbreadmilk))
在首次使用之前变量不需要(也不能)被定义(Defglobals除外)。
2.8构造
除了表达式和多变量,Daok语言还包含另外一种特殊的语句叫‘构造’,它定义了Daok系统自己的一些东西(详细请看2.9节定义函数)。
一个构造,它如果是正确的就为“TRUE”;反之,不正确就为“FALSE”。
2.9Deffunctions
Deffunction结构用于定义函数,你能从Daok中调用它们,.deffunction结构表示如下:
(deffunction<函数名[注释]([<参数1[<参数2[…]]])
[<表达式1[表达式2[…]]]
[<返回值])
函数名必须是原子,任意参数必须是变量名(所有函数都采用值传递),可选项(注释)是一个由双引号引起来的字符串,用来描述函数的功能。
表达式是一系列的式子,可选项(返回值)给出函数的返回值,它既可以是一个简单的"return"函数调用,也可是任何值或表达式。
在deffunction中由特殊的流向控制结构if和while实现程序流向的控制。
以下是一个deffunction结构,他返回两个参数中数值中较大的那个。
(deffunctionmax(?
a?
b)
(if(?
a?
b)
then
(return?
a)
else
(return?
b)
)
)
2.10事实
Daok包含一系列的"事实",或者说是关于系统当前状态的信息.事实以两种形式出现:
规则的和不规则的。
规则的事实仅仅是一个以原子开头的表。
(temperature98,6)
(shoping-listbreadmilkpater-towels)
(start-processing)
不规则的事实是比较复杂的,包含有限个"槽"(每个槽都要有个槽名)。
与规则的事实相比较,规则的事实不加定义即可应用,而不规则的事实必须用deftemplate结构加以定义.(如下:
deftemplate)
事实是由assert函数产生并置于事实表中的,你可用"facts"函数来察看当前事实表,你也可以将一个事实从事实表中移去,只要你知道它的"事实序号",例如:
Daok(assert(foobar))
Daok(fact)
f-0(foobar))
foratotalof1facts.
TRUE
Daok(retract0)
TRUE
Daok(facts)
foratotalof0fact.
TRUE
2.11 Deftemplates
用Deftemplate结构来定义一系列不规则的事实.
(deftemplate<模板名>
[注释]
(slot<槽名[(default缺省值)][(type[(slot…)…])
模板名是即将由该模板创立的事实的头部,槽名必须是原子。
修饰词"default"表明新事实中的槽的缺省值由"缺省值"给出;若没有给出缺省值,则缺省值为原子"nil"槽修饰词"type"Daok可以接受,(为了与CLIPS兼容)但不起任何作用。
作为例子,我们来定义如下模板:
(deftemplateautomobile
"Aspecificcar."
(slotmake)
(slotmodel)
(slotyear)
(slotcolor(defaultwhite)))
它将允许你这样定义事实:
Daok(assert(automobile(makechrysler)(modelLeboron)(year1997)))
Daok(facts)
f-0(automobile(makechrysler)(modelLeboron)(year1997)(colorwhite))
Foratotalof1facts.
TRUE
我们注意到汽车的颜色缺省给定为白色。
同时注意到应用该模板,任何数量的其他汽车都可以同时被声明到事实表中。
一个给定的槽在一个deftemplate事实中只能有一个值,如果你要求一个槽有多个值,则相应的用"multislot"关键字来实现.
(deftemplatebox
(slotlocation)
(multislotcontents))
(assert(box(locationkitchen)(contentsspatulaspongefrying-pan)))
2.12Defclasses
Defclass结构用来告诉Daok你将如同用deftmplate一样来使用一个特定的Java类。
并将如同像用事实一样使用它们的实例。
defclass句法非常简单。
(defclasspumpDaok.examples.pumps.pump)
Defclass后面的"pump"正像一个模板名,Daok从给定的Java类自动建立一个模板。
本例是从Daok.examples.pumps.pump---Daok附带的类来建立。
将JavaBeans转化成对应的模板的槽,(如果你对javaBeans不熟悉,那么,简单来说就是Java将找到所有的该类的名为get(x)或is(x)的方法,这些方法返回非空,且没有参数.Daok应用beaninfo机理来学习Bean的资源),例如Daok.examples.pumps.pump类大致结构如下(大量内容已被删去)
publicclasspump
{publicstringgetname(){…}
publicintgetlow(){…}
publicvoldsetflow(intf){…}
}
Daok将生成以下模板:
(deftemplatepump"$Java-object$`Daok.examples.pumps.pump"
(slotclass)
(slotname)
(slotflow)
(slotOBJECT))
多出的槽"class"来自getclass()方法,该方法是从java.lang.object继承来的,并且Daok为每个deftmplate添加一个OBJECT槽,它总是包含一个相应模