第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 1
第 11章 Visual Prolog数据元素
本章介绍 Visual Prolog的数据元素,内容包括论
域段( Domains Sections)、通用类型和根类型
( Universal and Root Types)等。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 2
第 11章 Visual Prolog数据元素
11.1 论域段
11.2 通用类型和根类型
本章小结
本章习题
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 3
11.1 论域段
一个论域段在当前作用域内定义一组论域(参见接口、类声明和类实现)。
domainsSection,
domains domainDefinition-dot-term-list-opt
论域定义
一个论域定义, 声明了一个当前作用域内已命名的论域 。
domainDefinition,
domainName = typeExpression
如果在右边的论域表示一个接口或一个复合论域, 那么所定义的论域就是类
型表达式的同义词 ( 即完全相同 ) 。 否则, 所定义的论域称为类型表达式所指
示的论域的子类 。 在这里, 论域名 domainName应当是小写标识符 。
有些地方必须使用论域名而不是类型表达式,
1) 作为形式变元类型的声明;
2) 作为一个常量或一个事实变量的类型;
3) 作为列表论域中的类型。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 4
11.1 论域段
类型表达式
一个类型表达式指示一种类型 。
typeExpression,
typeName
compoundDomain
listDomain
referenceDomain
predicateDomain
integralDomain
realDomain
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 5
11.1.1 类型名
一个类型名或者是一个接口名,或者是一个值论域的
名字。值论域这一术语用来指定元素不可变的论域。这里
可以说,属于与接口名相一致的论域的对象具有可变的声
明,任意其它论域的项都是不可变的。因此,实际上数值
类型是除了对象类型以外的其它类型。一个类型名指示与
现有论域的名称相应的类型。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 6
11.1.1 类型名
typeName,
interfaceName
domainName
classQualifiedDomainNa
me
interfaceName,
lowercaseIdentifier
domainName,
lowercaseIdentifier
classQualifiedDomainName,
className,,domainName
className,
lowercaseIdentifier
这里,interfaceName是一个接口
名,domainName是一个值域
名,className是一个类名。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 7
11.1.1 类型名
举例
domains
newDomain1 = existingDomain,
newDomain2 = myInterface,
在本例中,论域名是 existingDomain,接
口名 myInterface用来定义新的论域。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 8
11.1.2 复合论域
复合论域( Compound Domains),也称作代数数据类型,用于
表示列表、树和其它树形结构的数值。在其简单形式中,复合论域用于
代表结构和枚举数值。复合论域可以递归定义,也可以相互或间接递归。
compoundDomain,
alignment-opt functorAlternative-semicolon-sep-list
alignment,
align integralConstantExpression
这里,integralConstantExpression是一个表达式,它必须是在编
译时间赋为整数。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 9
11.1.2 复合论域
如果一个复合论域包含一个算符选项, 那么它被视为结构, 并且具有与 C语
言中的适当结构二进制兼容的表示法 。
functorAlternative,
functorName
functorName ( formalArgument-comma-sep-list-opt )
这里, functorName是一个算符选项的名称, 它应当是小写标识符 。
FormalArgument为,
formalArgument,
typeName argumentName-opt
argumentName可以是任意标识符, 编译器忽略它 。 复合论域是从它们派
生出来的引用论域的子类, 否则复合论域与任何其它论域都不具有这样的子类关
系 。 如果一个论域作为一个等价的复合论域进行定义, 那么这两个论域是同义类
型而不是子类型 。 意思就是说它们是同一类型的两个不同名字 。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 10
11.1.2 复合论域
举例
domains
t1 = ff(); gg(integer,t1),
t1是一个带有两个选项的复合论域。第一个选项是空变元算符 ff。
第二个选项是两个变元的算符 gg,采用一个整型数论域和论域 t1自身
作为参数。因此,论域 t1是递归定义的。
以下表达式是论域 t1的项,
ff()
gg(77,ff())
gg(33,gg(44,gg(55,ff())))
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 11
11.1.2 复合论域
举例
domains
t1 = 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()))))
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 12
11.1.3 列表论域
列表论域( List Domains)代表一个特定论域的值序列。这样,列表 T中的所有元素
必须是 T类型。
listDomain,
typeName *
T*是 T元素列表的类型。
下列语法用于列表,
listExpression,
[ term-comma-sep-list-opt ]
[ term-comma-sep-list | constantName ]
[ term-comma-sep-list | factVariableName ]
[ term-comma-sep-list | functionCall ]
[ term-comma-sep-list | variableName ]
[ term-comma-sep-list | anonymousIdentifier ]
[ term-comma-sep-list | listExpression ]
这里,
functionCall是一
个函数调用,返回
一个 listDomain
类型的值。
ConstantName,
factVariableNam
e和 ariableName
应当是
listDomain 类型。
每一项都应当是
typeName 类型。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 13
11.1.3 列表论域
实际上, 列表仅仅是带有两个算符的复合论域,[]指示空列表;算
符 [ HD | TL ]指示该列表具有表头 HD和表尾 TL。 表头必须是基本元素
类型, 而表尾必须是一个相关类型的列表 。
因此列表从语法上可以被修饰为,
[E1,E2,E3,...,En | L ] 是 [E1 |[ E2 |[,..[ En | L ]...]]]的
简记 。
[E1,E2,E3,...,En]是 [E1,E2,E3,...,En |[]]的简记, 继而是
[E1 |[ E2 |[,..[ En | [] ]...]]]的简记 。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 14
11.1.4 引用论域
一个引用论域( Reference Domains)与构造它的原始论域类似,
除此之外,引用论域变量的值也可以是自由变量(即 "unknown")。
referenceDomain,
reference referenceDomainDescription
referenceDomainDescription,
typeName
compoundDomain
listDomain
如果一个引用论域由一个复合论域构造,在算符中嵌套的所有论域也
必须是引用论域。
一个引用论域是一个基本的非引用论域的超论域。引用论域不是任何
其它论域的子类型。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 15
11.1.5 谓词论域
一个谓词论域( Predicate Domains)的值是具有相同“签名
( signature)”的谓词。就是说,具有相同的参数和返回类型,相同
的流模式以及相同的(或加强的)谓词模式。
一个具有返回值的谓词称为函数,而没有返回值的谓词被称为普通
谓词,以强调它并不是一个函数。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 16
11.1.5 谓词论域
predicateDomain,
( formalArgument-comma-sep-list-opt ) returnArgument-opt
predicateModeAndFlow-list-opt callingConvention-opt
formalArgument,
predicateArgumentType variableName-opt
ellipsis
returnArgument,
-> formalArgument
predicateArgumentType,
typeName
anonymousIdentifier
variableName,
upperCaseIdentifier
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 17
11.1.5.1 谓词模式
当声明一个谓词时其模式可以省略 。 在一个实现内部 ( 即对于一个局
部谓词而言 ), 所需的流和模式源自谓词的用法 。 在一个接口或一个类
声明内部 ( 即对于一个公有谓词而言 ), 省略谓词模式意味着该谓词是
一个过程 procedure,省略流模式意味着所有的参数都是输入参数 。
为构造器声明一个谓词模式是非法的, 这种谓词总是有 procedure模式 。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 18
11.1.5.1 谓词模式
指定的谓词模式可应用于下列流模式的每个成员。
predicateMode, one of
erroneous failure procedure determ multi nondeterm
谓词模式可用下列集合来描述,
erroneous = {}
failure = {Fail}
procedure = {Succeed}
determ = {Fail,Succeed}
multi = {Succeed,BacktrackPoint}
nondeterm = {Fail,Succeed,BacktrackPoint}
Fail在集合中是指谓词失败。 Succeed在集合中是指谓词成功。
BacktrackPoint在集合中是指该谓词返回时会带一个活动的回溯点。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 19
11.1.5.2 流模式
流模式( Flow Pattern)定义了参数的输入 /输出方向,这些参数与算符
论域相结合,会成为带有单个输入参数的一些部分以及相同输出参数的某些部分
的结构。一个流模式由一个流的序列组成,每个流对应一个参数(比如第一个流
对应第一个参数)。
flowPattern,
( flow-comma-sep-list-opt )
anyFlow
flow,
i
o
functorFlow
listFlow
ellipsis
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 20
11.1.5.2 流模式
?省略流( Ellipsis flow)模式
省略流( Ellipsis flow)模式必须与一个省略参数匹配,并且因此只能作
为流模式中的最后一个流。
ellipsis,
,.,
?算符流 functorFlow
一个算符流 functorFlow声明了一个算符和构成该流的所有的流。当然,
算符必须在相应参数的论域内。
functorFlow,
functorName ( flow-comma-sep-list-opt )
一个算符流的声明不能包含省略流。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 21
11.1.5.2 流模式
?列表流
列表流恰恰与算符流类似,但却与列表论域具有相同的语法修饰。
listFlow,
[ flow-comma-sep-list-opt listFlowTail-opt ]
listFlowTail,
| flow
一个列表流不能包含省略流 。
当声明一个谓词时, 流模式可以被省略 。 在一个实现内部 ( 即对于一个局部
谓词而言 ), 所需流模式源自该谓词的用法 。 在一个接口或一个类声明内部 ( 即
对于一个公有谓词而言 ), 省略流是指所有参数均为输入参数 。
特殊的流模式 anyflow只能在局部谓词中进行声明 ( 即在一个类的实现内部的谓
词声明 ) 。 这意味着确切的流模式将在编译过程中估计出来 。 如果可选的先前谓
词模式在这个流模式中被省略, 那么就假定它是一个过程 ( procedure) 。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 22
11.1.5.2 流模式
举例
domains
pp1 = (integer Argument1),
pp1是一个谓词论域 。 具有类型 pp1的谓词带有一个整型变量作为参数 。 由
于没有声明流模式, 所以该参数被认为是输入参数;而且, 没有提到谓词模式,
所以该谓词是过程 ( procedure) 。
举例
domains
pp2 = (integer Argument1) -> integer ReturnType,
类型 pp2的谓词带有一个整型变量作为参数, 并返回一个整型类型的值 。 因
此, pp2 实际上是一个函数论域, 具有类型 pp2的谓词实际上是函数 。 由于没有
声明流模式, 所以该参数被认为是输入参数 。 而且, 没有提到谓词模式, 因此该
谓词是过程 。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 23
11.1.5.3 调用约定
调用约定( Calling Convention)决定了参数等如何传递给谓词,
也决定了从一个谓词名怎样获得一个连接名。
callingConvention,
language callingConventionKind
callingConventionKind, one of
c stdcall apicall prolog
如果没有声明一个调用约定,那么就假定用 Prolog约定。 Prolog调用
约定是一个用于 Prolog谓词的标准约定。
调用约定 C继承了 C/C++的标准调用约定。一个谓词的连接名用一个
加前导下划线 (_)的谓词名创建。
调用约定 stdcall采用 C连接名策略,但是它用了不同的变量和堆栈处
理规则。表 11-1显示了 stdcall调用约定的实现情况。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 24
11.1.5.3 调用约定
表 11-1 stdcall调用约定的实现
特 性 实 现
参数传递顺序 从右至左
参数传递约定 按值传递,除非传递的是一个复合论域项或引用类型。因此 不能用于参数数目变化的谓词。
堆栈维护职责 被调用的谓词从堆栈中弹出自身参数
名称修饰约定 一个下划线 (_)作为谓词名的前缀
大小写转换约定 不执行谓词名的大小写转换
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 25
11.1.5.3 调用约定
调用约定 apicall使用与 stdcall相同的参数和堆栈处理规则, 但是为
了方便地调用 MS Windows API 函数, apicall采用了大多数 MS
Windows API 函数所用的名称约定 。 根据 apicall的名称约定, 一个谓
词的连接名结构如下,
* 下划线符作为谓词名的前缀;
* 谓词名首写字母用大写;
* 如果参数和返回类型指示 ANSI,双字节字符集和不确定性谓词,
则分别用 'A','W' 做为后缀字符或无后缀;
* 以 ‘ @’为后缀;
* 以压入调用堆栈的字节数为后缀 。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 26
11.1.5.3 调用约定
举例
predicates
predicateName, (integer,string) language apicall
该谓词的参数类型表明这是一个双字节字符集 ( 正如 string是双字节
字符串论域一样 ) 。 在调用堆栈中, 一个整型和一个字符串每一类型占 4
个字节, 因此, 连接名变成,
_PredicateNameW@8
如果 apicall与 "as"结构一起使用, 则 "as"结构中声明的名字以相同
的方式被修饰 。
apicall 只能在谓词声明中直接使用, 而不能在谓词论域定义中直接
使用 。 在谓词论域定义中取而代之的是 stdcall。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 27
11.1.5.3 调用约定
表 11-2对比了 c,apicall及 stdcall调用约定的实现,而 prolog调用
约定实现比较特殊,这里不予以讨论。
表 11-2 c,apicall及 stdcall调用约定的实现对比
关键字 堆栈清理 谓词名大小写转换 连接谓词名修饰惯例
c 调用谓词从堆栈中弹出参数 无 下划线 (_)作谓词名前缀
stdcall 被调用的谓词从堆栈中弹出自身参数 无 下划线 (_)作谓词名前缀
apicall 被调用的谓词从堆栈中弹出自身参数 谓词首字母大写
下划线 (_)作名字前缀。首字母变为大写。
'A','W'做后缀或无后缀。 @符号做后缀。
参数列表中的字节数(十进制)做后缀。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 28
11.1.5.3 调用约定
举例
假定有下列声明,
interface actionEventSource
domains
actionListener = (actionEventSource Source) procedure (i),
predicates
addActionListener, (actionListener Listener) procedure (i),
,.,
end interface
同样假定类 button_class支持 actionEventSource。当按钮按下时事件被
发送。在 myDialog_class类中,实现一个对话框。为了能够响应按钮按下操作
而创建了一个按钮,以便监听活动事件。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 29
11.1.5.3 调用约定
implement myDialog_class
clauses
new(),-
OkButton = button_class::new(...),
OkButton:addActionListener(onOk),
,.,
facts
okPressed, () determ,
predicates
onOk, actionListener,
clauses
onOk(Source),-
assert(okPressed()),
end implement
对于这个例子而言重要的一
点是,onOk是一个对象成
员。当按钮被按下时,已注
册的 onOk的调用将在拥有
onOk的对象中返回。也就
是说,可以断言,我们有权
访问对象事实 okPressed。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 30
11.1.6 整型论域
整型论域用于表示整型数,主要分为符号整数和无符号整数两类。整
型论域也可以有不同的表示范围。预定义论域 integer和 unsigned代表
有符号和无符号整数,表示的长度与处理器体系结构的自然长度相同
(即 32位机器就是 32位)。
integralDomain,
domainName-opt integralDomainProperties
如果在 integralDomainProperties之前声明 domainName,那么
这个论域本身必须是整型论域,其派生的论域也必须是这一论域的子类
型( child- type或 sub-type)。这种情况下,
integralDomainProperties不可以违背作为子类型的可能性,也就是
说,其范围不可扩展,大小不可改变。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 31
11.1.6 整型论域
integralDomainProperties,
integralSizeDescription integralRangeDescription-opt
integralRangeDescription integralSizeDescription-opt
integralSizeDescription,
bitsize domainSize
domainSize,
integralConstantExpression
整型大小描述声明了整型论域以位计算的大小 domainSize。编译器
实现整型论域的这种表示,它不少于所指定的位数。 domainSize的值
应当是确定的,并且不超过编译器所支持的最大值(在版本 6.x中是 32
位)。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 32
11.1.6 整型论域
如果整型范围描述被省略, 那么就与父论域相同 。 如果没有父论域,
那就记为处理器的自然长度 。
integralRangeDescription,
[ minimalBoundary-opt,,maximalBoundary-opt ]
minimalBoundary,
integralConstantExpression
maximalBoundary,
integralConstantExpression
整型范围描述声明了限定整型论域的最小界 minimalBoundary和最
大界 maximalBoundary。 如果该限定被省略, 那么就用父论域的限定
范围 。 如果没有父论域, 那么用 domainSize分别决定这个最大值和最
小值 。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 33
11.1.6 整型论域
注意:指定的最小值不能超过指定的最大值, 即,
minimalBoundary <= maximalBoundary
最小界 minimalBoundary和最大界 maximalBoundary必须满足
bitsize所隐含规定的位长度 。
论域位长度 domainSize的值,以及最小界 minimalBoundary和最
大界 maximalBoundary的值必须在编译期间进行计算。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 34
11.1.7 实型论域
实型论域用于表示带有小数部分的数(即浮点数)。实型论域可用于
表示非常大和非常小的数。内部论域 real具有处理器体系结构的自然精
度(也是编译器所赋予的精度)。
realDomain,
domainName-opt realDomainProperties
如果在 realDomainProperties之前声明 domainName,那么这个
论域本身就必须是一个实数论域,并且结果论域是这个论域的子类型。
在此情况下,realDomainProperties不能违背作为一个子类型的可能
性,就是说,范围不能被扩展,精度不能被增加。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 35
11.1.7 实型论域
realDomainProperties,
realPrecisionDescription realRangeDescription-opt
realRangeDescription realPrecisionDescription
realPrecisionDescription,
digits integralConstantExpression
实型精度描述声明了实型论域的精度,精度由小数位数决定。如果精
度省略,则与父论域相同。若没有父论域,那么就取处理器的自然精度
或是编译器所指定的精度(在 Visual Prolog 6中编译器限制为 19位
数)。编译器会给精度一个上限和一个下限,如果精度超过了所用限度,
就只获得处理器(编译器)所指定的精度。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 36
11.1.7 实型论域
realRangeDescription,
[ minimalRealBoundary-opt,,maximalRealBoundary-opt ]
minimalRealBoundary,
realConstantExpression
maximalRealBoundary,
realConstantExpression
这里,realConstantExpression是一个表达式,必须在编译时间内
计算出浮点数值。就是说在编译时间内,实型论域的精度和限制都必须
计算出来。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 37
11.1.7 实型论域
实型论域描述声明了实型论域的上下限 。 如果这一限制
被省略, 那就是与父论域相同 。 如果没有父论域, 那么就将
使用最大可能的精度范围 。
注意, 指定的最小界不能超过指定的最大界, 即,
minimalRealBoundary <= maximalRealBoundary
而且,最小界 minimalBoundary和最大界
maximalBoundary应当满足指定精度数位所隐含规定的限
制范围。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 38
Visual Prolog 使用某些称为根类型
( Root types)和通用类型( universal
types)的整数类型。
11.2 通用类型和根类型
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 39
11.2.1 通用类型
一个数字文字比如 1,不具有任何特殊的类型,它可以用
作包括实型在内的任意包含 1的类型的值。
可以说,1具有一个通用类型。通用类型指能够表示其值
的任意类型。
算术运算也返回通用类型。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 40
11.2.2 根类型
算术运算对操作数的运算限制极低:任意整型论域的整
数都可以相加。就是说,算术操作数是将根类型作为参数的。
整数根类型是任意整型的超类型(即便声明中并没有提及)。
因此,任意整型都可以转化为整数根类型。并且,由于算术
运算因根类型而存在,就意味着它们其中之一将作用于任意
整型论域。
关于根类型的具体数目以及操作数的存在形式与基本通
用软件库设施有关, 不在我们的讨论范围之内 。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 41
第十一章小结
本章介绍 Visual Prolog的数据元素,内容包括论域段( Domains
Sections)、通用类型和根类型( Universal and Root Types)等。
论域段有简单论域、复合论域、列表论域、引用论域、谓词论域、整型
论域及实型论域等。
第三部分:第 11章 Visual Prolog数据元素
2004.11.3 AI程序设计 42
第十一章 习 题
1,Visual Prolog 的论域段用来声明谓词参数的非标准论域。它与其他语言中
的类型一样吗?
2、这里的谓词与其他语言的函数和过程有关系吗?
3、引用论域与其他论域有何本质区别?它有什么作用?
4、引入通用类型和根类型有什么意义?