1、第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计1第11章VisualProlog数据元素本章介绍VisualProlog的数据元素,内容包括论域段(DomainsSections)、通用类型和根类型(UniversalandRootTypes)等。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计2第11章VisualProlog数据元素11.1论域段11.2通用类型和根类型本章小结本章习题第三部分:第第三部分:第1111章章
2、VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计311.1论域段一个论域段在当前作用域内定义一组论域(参见接口、类声明和类实现)。domainsSection:domainsdomainDefinition-dot-term-list-opt论域定义论域定义一个论域定义,声明了一个当前作用域内已命名的论域。domainDefinition:domainName=typeExpression如果在右边的论域表示一个接口或一个复合论域,那么所定义的论域就是类型表达式的同义词(即完全相同)。否则,所定义的论域称为类型表达式所指示的论域的子类。在这里,论域
3、名domainName应当是小写标识符。有些地方必须使用论域名而不是类型表达式:1)作为形式变元类型的声明;2)作为一个常量或一个事实变量的类型;3)作为列表论域中的类型。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计411.1论域段类型表达式类型表达式一个类型表达式指示一种类型。typeExpression:typeNamecompoundDomainlistDomainreferenceDomainpredicateDomainintegralDomainrealDomain第三部分:第第三部分:第111
4、1章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计511.1.1 类型名 一个类型名或者是一个接口名,或者是一个值论域的名字。值论域这一术语用来指定元素不可变的论域。这里可以说,属于与接口名相一致的论域的对象具有可变的声明,任意其它论域的项都是不可变的。因此,实际上数值类型是除了对象类型以外的其它类型。一个类型名指示与现有论域的名称相应的类型。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计611.1.1 类型名typeName:interfaceNamedo
5、mainNameclassQualifiedDomainNameinterfaceName:lowercaseIdentifierdomainName:lowercaseIdentifierclassQualifiedDomainName:className:domainNameclassName:lowercaseIdentifier这里,interfaceName是一个接口名,domainName是一个值域名,className是一个类名。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计711.1.1 类型
6、名举例举例domainsnewDomain1=existingDomain.newDomain2=myInterface.在本例中,论域名是existingDomain,接口名myInterface用来定义新的论域。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计811.1.2 复合论域复合论域(CompoundDomains),也称作代数数据类型,用于表示列表、树和其它树形结构的数值。在其简单形式中,复合论域用于代表结构和枚举数值。复合论域可以递归定义,也可以相互或间接递归。compoundDomain:al
7、ignment-optfunctorAlternative-semicolon-sep-listalignment:alignintegralConstantExpression这里,integralConstantExpression是一个表达式,它必须是在编译时间赋为整数。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计911.1.2 复合论域如果一个复合论域包含一个算符选项,那么它被视为结构,并且具有与C语言中的适当结构二进制兼容的表示法。functorAlternative:functorNamefun
8、ctorName(formalArgument-comma-sep-list-opt)这里,functorName是一个算符选项的名称,它应当是小写标识符。FormalArgument为:formalArgument:typeNameargumentName-optargumentName可以是任意标识符,编译器忽略它。复合论域是从它们派生出来的引用论域的子类,否则复合论域与任何其它论域都不具有这样的子类关系。如果一个论域作为一个等价的复合论域进行定义,那么这两个论域是同义类型而不是子类型。意思就是说它们是同一类型的两个不同名字。第三部分:第第三部分:第1111章章 VisualPrologV
9、isualProlog数据元素数据元素2004.11.3AI程序设计1011.1.2 复合论域举例举例domainst1=ff();gg(integer,t1).t1是一个带有两个选项的复合论域。第一个选项是空变元算符ff。第二个选项是两个变元的算符gg,采用一个整型数论域和论域t1自身作为参数。因此,论域t1是递归定义的。以下表达式是论域t1的项:ff()gg(77,ff()gg(33,gg(44,gg(55,ff()第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计1111.1.2 复合论域举例举例domai
10、nst1=ff();gg(t2).t2=hh(t1,t1).t1是一个带有两个选项的复合论域。第一个选项是空变元算符ff。第二个选项是一元算符gg,采用论域t2的项作为参数。t2是一个带有一个选项算符hh的复合论域,算符hh采用两个t1项作为参数。因此,论域t1和t2是相互递归的。以下表达式是论域t1的项:ff()gg(hh(ff(),ff()gg(hh(gg(hh(ff(),ff(),ff()gg(hh(ff(),gg(hh(ff(),ff()gg(hh(gg(hh(ff(),ff(),gg(hh(ff(),ff()第三部分:第第三部分:第1111章章 VisualPrologVisualP
11、rolog数据元素数据元素2004.11.3AI程序设计1211.1.3 列表论域列表论域(ListDomains)代表一个特定论域的值序列。这样,列表T中的所有元素必须是T类型。listDomain:typeName*T*是T元素列表的类型。下列语法用于列表:listExpression:term-comma-sep-list-optterm-comma-sep-list|constantNameterm-comma-sep-list|factVariableNameterm-comma-sep-list|functionCallterm-comma-sep-list|variableNam
12、eterm-comma-sep-list|anonymousIdentifierterm-comma-sep-list|listExpression这里,functionCall是一个函数调用,返回一个listDomain类型的值。ConstantName,factVariableName和ariableName应当是listDomain类型。每一项都应当是typeName类型。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计1311.1.3 列表论域实际上,列表仅仅是带有两个算符的复合论域:指示空列表;算符H
13、D|TL指示该列表具有表头HD和表尾TL。表头必须是基本元素类型,而表尾必须是一个相关类型的列表。因此列表从语法上可以被修饰为:E1,E2,E3,.,En|L是E1|E2|.En|L.的简记。E1,E2,E3,.,En是E1,E2,E3,.,En|的简记,继而是E1|E2|.En|.的简记。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计1411.1.4 引用论域一个引用论域(ReferenceDomains)与构造它的原始论域类似,除此之外,引用论域变量的值也可以是自由变量(即unknown)。referen
14、ceDomain:referencereferenceDomainDescriptionreferenceDomainDescription:typeNamecompoundDomainlistDomain如果一个引用论域由一个复合论域构造,在算符中嵌套的所有论域也必须是引用论域。一个引用论域是一个基本的非引用论域的超论域。引用论域不是任何其它论域的子类型。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计1511.1.5 谓词论域一个谓词论域(PredicateDomains)的值是具有相同“签名(signat
15、ure)”的谓词。就是说,具有相同的参数和返回类型,相同的流模式以及相同的(或加强的)谓词模式。一个具有返回值的谓词称为函数,而没有返回值的谓词被称为普通谓词,以强调它并不是一个函数。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计1611.1.5 谓词论域predicateDomain:(formalArgument-comma-sep-list-opt)returnArgument-optpredicateModeAndFlow-list-optcallingConvention-optformalArgu
16、ment:predicateArgumentTypevariableName-optellipsisreturnArgument:-formalArgumentpredicateArgumentType:typeNameanonymousIdentifiervariableName:upperCaseIdentifier第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计1711.1.5.1 谓词模式当声明一个谓词时其模式可以省略。在一个实现内部(即对于一个局部谓词而言),所需的流和模式源自谓词的用法。在一个接口或
17、一个类声明内部(即对于一个公有谓词而言),省略谓词模式意味着该谓词是一个过程procedure,省略流模式意味着所有的参数都是输入参数。为构造器声明一个谓词模式是非法的,这种谓词总是有procedure模式。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计1811.1.5.1 谓词模式指定的谓词模式可应用于下列流模式的每个成员。predicateMode:oneoferroneousfailureproceduredetermmultinondeterm谓词模式可用下列集合来描述:erroneous=failu
18、re=Failprocedure=Succeeddeterm=Fail,Succeedmulti=Succeed,BacktrackPointnondeterm=Fail,Succeed,BacktrackPointFail在集合中是指谓词失败。Succeed在集合中是指谓词成功。BacktrackPoint在集合中是指该谓词返回时会带一个活动的回溯点。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计1911.1.5.2 流模式 流模式(FlowPattern)定义了参数的输入/输出方向,这些参数与算符论域相结
19、合,会成为带有单个输入参数的一些部分以及相同输出参数的某些部分的结构。一个流模式由一个流的序列组成,每个流对应一个参数(比如第一个流对应第一个参数)。flowPattern:(flow-comma-sep-list-opt)anyFlowflow:iofunctorFlowlistFlowellipsis第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计2011.1.5.2 流模式省略流(Ellipsisflow)模式省略流(Ellipsisflow)模式必须与一个省略参数匹配,并且因此只能作为流模式中的最后一个
20、流。ellipsis:.算符流functorFlow一个算符流functorFlow声明了一个算符和构成该流的所有的流。当然,算符必须在相应参数的论域内。functorFlow:functorName(flow-comma-sep-list-opt)一个算符流的声明不能包含省略流。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计2111.1.5.2 流模式列表流列表流恰恰与算符流类似,但却与列表论域具有相同的语法修饰。listFlow:flow-comma-sep-list-optlistFlowTail-op
21、tlistFlowTail:|flow一个列表流不能包含省略流。当声明一个谓词时,流模式可以被省略。在一个实现内部(即对于一个局部谓词而言),所需流模式源自该谓词的用法。在一个接口或一个类声明内部(即对于一个公有谓词而言),省略流是指所有参数均为输入参数。特殊的流模式anyflow只能在局部谓词中进行声明(即在一个类的实现内部的谓词声明)。这意味着确切的流模式将在编译过程中估计出来。如果可选的先前谓词模式在这个流模式中被省略,那么就假定它是一个过程(procedure)。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI
22、程序设计2211.1.5.2 流模式举例举例domainspp1=(integerArgument1).pp1是一个谓词论域。具有类型pp1的谓词带有一个整型变量作为参数。由于没有声明流模式,所以该参数被认为是输入参数;而且,没有提到谓词模式,所以该谓词是过程(procedure)。举例举例domainspp2=(integerArgument1)-integerReturnType.类型pp2的谓词带有一个整型变量作为参数,并返回一个整型类型的值。因此,pp2实际上是一个函数论域,具有类型pp2的谓词实际上是函数。由于没有声明流模式,所以该参数被认为是输入参数。而且,没有提到谓词模式,因此该
23、谓词是过程。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计2311.1.5.3 调用约定调用约定(CallingConvention)决定了参数等如何传递给谓词,也决定了从一个谓词名怎样获得一个连接名。callingConvention:languagecallingConventionKindcallingConventionKind:one ofcstdcallapicallprolog如果没有声明一个调用约定,那么就假定用Prolog约定。Prolog调用约定是一个用于Prolog谓词的标准约定。调用约
24、定C继承了C/C+的标准调用约定。一个谓词的连接名用一个加前导下划线(_)的谓词名创建。调用约定stdcall采用C连接名策略,但是它用了不同的变量和堆栈处理规则。表11-1显示了stdcall调用约定的实现情况。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计2411.1.5.3 调用约定表11-1stdcall调用约定的实现特特 性性实实 现现参数传递顺序从右至左 参数传递约定按值传递,除非传递的是一个复合论域项或引用类型。因此不能用于参数数目变化的谓词。堆栈维护职责被调用的谓词从堆栈中弹出自身参数 名称修
25、饰约定一个下划线(_)作为谓词名的前缀大小写转换约定不执行谓词名的大小写转换第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计2511.1.5.3 调用约定调用约定apicall使用与stdcall相同的参数和堆栈处理规则,但是为了方便地调用MS Windows API 函数,apicall采用了大多数MSWindowsAPI函数所用的名称约定。根据apicall的名称约定,一个谓词的连接名结构如下:*下划线符作为谓词名的前缀;*谓词名首写字母用大写;*如果参数和返回类型指示ANSI、双字节字符集和不确定性谓词,
26、则分别用A、W做为后缀字符或无后缀;*以为后缀;*以压入调用堆栈的字节数为后缀。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计2611.1.5.3 调用约定举例举例predicatespredicateName:(integer,string)languageapicall该谓词的参数类型表明这是一个双字节字符集(正如string是双字节字符串论域一样)。在调用堆栈中,一个整型和一个字符串每一类型占4个字节,因此,连接名变成:_PredicateNameW8如果apicall与as结构一起使用,则as结构中声
27、明的名字以相同的方式被修饰。apicall只能在谓词声明中直接使用,而不能在谓词论域定义中直接使用。在谓词论域定义中取而代之的是stdcall。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计2711.1.5.3 调用约定表11-2对比了c、apicall及stdcall调用约定的实现,而prolog调用约定实现比较特殊,这里不予以讨论。表11-2c、apicall及stdcall调用约定的实现对比关键字关键字堆栈清理堆栈清理谓词名大小写转谓词名大小写转换换连接谓词名修饰惯例连接谓词名修饰惯例c调用谓词从堆栈中
28、弹出参数无下划线(_)作谓词名前缀stdcall被调用的谓词从堆栈中弹出自身参数无下划线(_)作谓词名前缀apicall被调用的谓词从堆栈中弹出自身参数谓词首字母大写下划线(_)作名字前缀。首字母变为大写。A,W做后缀或无后缀。符号做后缀。参数列表中的字节数(十进制)做后缀。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计2811.1.5.3 调用约定举例举例假定有下列声明:interfaceactionEventSourcedomainsactionListener=(actionEventSourceSou
29、rce)procedure(i).predicatesaddActionListener:(actionListenerListener)procedure(i).endinterface同样假定类button_class支持actionEventSource。当按钮按下时事件被发送。在myDialog_class类中,实现一个对话框。为了能够响应按钮按下操作而创建了一个按钮,以便监听活动事件。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计2911.1.5.3 调用约定implementmyDialog_cl
30、assclausesnew():-OkButton=button_class:new(.),OkButton:addActionListener(onOk),.factsokPressed:()determ.predicatesonOk:actionListener.clausesonOk(Source):-assert(okPressed().endimplement对于这个例子而言重要的一点是,onOk是一个对象成员。当按钮被按下时,已注册的onOk的调用将在拥有onOk的对象中返回。也就是说,可以断言,我们有权访问对象事实okPressed。第三部分:第第三部分:第1111章章 Visu
31、alPrologVisualProlog数据元素数据元素2004.11.3AI程序设计3011.1.6 整型论域整型论域用于表示整型数,主要分为符号整数和无符号整数两类。整型论域也可以有不同的表示范围。预定义论域integer和unsigned代表有符号和无符号整数,表示的长度与处理器体系结构的自然长度相同(即32位机器就是32位)。integralDomain:domainName-optintegralDomainProperties如果在integralDomainProperties之前声明domainName,那么这个论域本身必须是整型论域,其派生的论域也必须是这一论域的子类型(ch
32、ild-type或sub-type)。这种情况下,integralDomainProperties不可以违背作为子类型的可能性,也就是说,其范围不可扩展,大小不可改变。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计3111.1.6 整型论域integralDomainProperties:integralSizeDescriptionintegralRangeDescription-optintegralRangeDescriptionintegralSizeDescription-optintegralSi
33、zeDescription:bitsizedomainSizedomainSize:integralConstantExpression整型大小描述声明了整型论域以位计算的大小domainSize。编译器实现整型论域的这种表示,它不少于所指定的位数。domainSize的值应当是确定的,并且不超过编译器所支持的最大值(在版本6.x中是32位)。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计3211.1.6 整型论域如果整型范围描述被省略,那么就与父论域相同。如果没有父论域,那就记为处理器的自然长度。integ
34、ralRangeDescription:minimalBoundary-opt.maximalBoundary-optminimalBoundary:integralConstantExpressionmaximalBoundary:integralConstantExpression整型范围描述声明了限定整型论域的最小界minimalBoundary和最大界maximalBoundary。如果该限定被省略,那么就用父论域的限定范围。如果没有父论域,那么用domainSize分别决定这个最大值和最小值。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元
35、素数据元素2004.11.3AI程序设计3311.1.6 整型论域注意:指定的最小值不能超过指定的最大值,即:minimalBoundary=maximalBoundary最小界minimalBoundary和最大界maximalBoundary必须满足bitsize所隐含规定的位长度。论域位长度domainSize的值,以及最小界minimalBoundary和最大界maximalBoundary的值必须在编译期间进行计算。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计3411.1.7 实型论域实型论域用于
36、表示带有小数部分的数(即浮点数)。实型论域可用于表示非常大和非常小的数。内部论域real具有处理器体系结构的自然精度(也是编译器所赋予的精度)。realDomain:domainName-optrealDomainProperties 如果在realDomainProperties之前声明domainName,那么这个论域本身就必须是一个实数论域,并且结果论域是这个论域的子类型。在此情况下,realDomainProperties不能违背作为一个子类型的可能性,就是说,范围不能被扩展,精度不能被增加。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素
37、数据元素2004.11.3AI程序设计3511.1.7 实型论域realDomainProperties:realPrecisionDescriptionrealRangeDescription-optrealRangeDescriptionrealPrecisionDescriptionrealPrecisionDescription:digitsintegralConstantExpression实型精度描述声明了实型论域的精度,精度由小数位数决定。如果精度省略,则与父论域相同。若没有父论域,那么就取处理器的自然精度或是编译器所指定的精度(在VisualProlog6中编译器限制为19位数
38、编译器会给精度一个上限和一个下限,如果精度超过了所用限度,就只获得处理器(编译器)所指定的精度。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计3611.1.7 实型论域realRangeDescription:minimalRealBoundary-opt.maximalRealBoundary-optminimalRealBoundary:realConstantExpressionmaximalRealBoundary:realConstantExpression这里,realConstantExpr
39、ession是一个表达式,必须在编译时间内计算出浮点数值。就是说在编译时间内,实型论域的精度和限制都必须计算出来。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计3711.1.7 实型论域实型论域描述声明了实型论域的上下限。如果这一限制被省略,那就是与父论域相同。如果没有父论域,那么就将使用最大可能的精度范围。注意,指定的最小界不能超过指定的最大界,即:minimalRealBoundary=maximalRealBoundary而且,最小界minimalBoundary和最大界maximalBoundary应
40、当满足指定精度数位所隐含规定的限制范围。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计38VisualProlog使用某些称为根类型(Roottypes)和通用类型(universaltypes)的整数类型。11.2 通用类型和根类型第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计3911.2.1 通用类型 一个数字文字比如1,不具有任何特殊的类型,它可以用作包括实型在内的任意包含1的类型的值。可以说,1具有一个通用类型。通用
41、类型指能够表示其值的任意类型。算术运算也返回通用类型。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计4011.2.2 根类型 算术运算对操作数的运算限制极低:任意整型论域的整数都可以相加。就是说,算术操作数是将根类型作为参数的。整数根类型是任意整型的超类型(即便声明中并没有提及)。因此,任意整型都可以转化为整数根类型。并且,由于算术运算因根类型而存在,就意味着它们其中之一将作用于任意整型论域。关于根类型的具体数目以及操作数的存在形式与基本通用软件库设施有关,不在我们的讨论范围之内。第三部分:第第三部分:第11
42、11章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计41第十一章小结本章介绍VisualProlog的数据元素,内容包括论域段(DomainsSections)、通用类型和根类型(UniversalandRootTypes)等。论域段有简单论域、复合论域、列表论域、引用论域、谓词论域、整型论域及实型论域等。第三部分:第第三部分:第1111章章 VisualPrologVisualProlog数据元素数据元素2004.11.3AI程序设计42第十一章 习 题1、VisualProlog的论域段用来声明谓词参数的非标准论域。它与其他语言中的类型一样吗?2、这里的谓词与其他语言的函数和过程有关系吗?3、引用论域与其他论域有何本质区别?它有什么作用?4、引入通用类型和根类型有什么意义?