第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 1
第 14章 内部论域、谓词和常量
14.1 概述
14.2 内部常量详解
14.3 内部论域详解
14.4 内部谓词详解
本章小结
本章习题
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 2
14.1 概述
Visual Prolog包含嵌入式隐藏类,它提供了对所有内部
常量、论域和谓词的声明和实现。
这些内部常量, 论域和谓词既可以用于编译单元,也可以
应用于实现 ( 运行时间支持这些程序 ) 。
每一编辑单元都隐含着嵌入式隐藏类的声明, 但事实上这
一类有着专门的惟一内部名, 在代码的任何地方都不能直接
引用 。 在内置项的名字前可以加,,:”进行限定 。
注意, 子句变量 This是在对象谓词子句中自动定义的 。
下面的表 14-1、表 14-2、表 14-3分别是内部常量、内
部论域、内部谓词的简要描述
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 3
14.1 概述
内 部 常 量
说 明
compilation_date
编译日期
compilation_time
编译时间
compiler_buildDate
编译器建立时间
compiler_version
编译器版本
maxFloatDigits
定义编译器支持的 "digits"的最大值
null
空指针
platform_bits
定义一编译平台的数字容量
platform_name
定义目标平台名称
表 14-1 内部常量简述
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 4
14.1 概述
表 14-2 内部论域简述
内 部 论 域
说 明
char
宽字符
string
以 0终止的宽字符序列
symbol
以 0终止的宽字符序列
binary
字节序列
integer
有符号整数
unsigned
无符号整数
real
浮点数
pointer
指向内存地址的 4字节指针
boolean
布尔值
factdb
内部数据库的命名描述
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 5
14.1 概述
表 14-3 内部谓词简述
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 6
14.2 内部常量详解
本节以字母顺序,详细解读 Visual Prolog的内部常量。
::compilation_date
编译日期。这里 YYYY 表示年,MM 表示月数,DD表示天数。
compilation_date,,:string = "YYYY-MM-DD",
::compilation_time
编译时间。这里 HH表示小时,MM表示分钟,SS表示秒。
compilation_time,,:string = "HH-MM-SS",
::compiler_buildDate
编译器建立时间。
compiler_buildDate,,:string = "YYYY-MM-DD HH-MM-SS",
::compiler_version
编译器版本,该值决定编译器版本。
compiler_version = 6003,
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 7
14.2 内部常量详解
::maxFloatDigits
定义编译器支持的 "digits"的最大值。
maxFloatDigits = 19,
::null
空指针,或缺省的 NULL指针。
null,,:pointer = uncheckedConvert(::pointer,0),
::platform_bits
定义一编译平台的数位容量。
platform_bits = 32,
::platform_name
定义目标平台的名字。
platform_name, string = "Windows 32bits",
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 8
14.3 内部论域详解
本节按字母顺序,详细解读 Visual Prolog的内部论域。
::char
宽字符集 。 该论域的值是 UNICODE字符, 采用双字对字符编码 。 只有赋值和比较 ( 按
字典顺序的意义来说 ) 操作应用该论域的值 。 字符的映射有如下语法,
char_image,
' char_value '
char_value,
letter
digit
graphical_symbol
\ escape_seq
escape_seq,
t
n
r
\
'
"
u HHHH
在这里的语法中,HHHH对应于 4个 16进制的
数字。同样,反斜线符号和单引用号只能用
一种转义序列表示。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 9
14.3 内部论域详解
::string
宽的 0终止的宽字符序列 。 一
个字符串是一串 UNICODE字
符 。 它作为指向宽的 0终止的
宽字符序列的指针 。 只有赋值
和比较 ( 按字典顺序的意义来
说 ) 操作应用该论域的值 。 在
源代码中, 一个字符串文字可
用双引号内的一串字符定义 。
stringLiteral,
stringLiteralPart-list
stringLiteralPart,
@" anyCharacter-list-opt "
" characterValue-list-opt "
\\ 表示 \
\t 表示制表符
\n 表示换行符
\r 表示回车
\' 表示单引号
\" 表示双引号
一个 "u"后面跟着四个十六进制数表
示与数值对应的 Unicode 字符 。
字符串中的双引号只能用转义序列表
示 ( 单引号既可以用转义序列也可以
用图形符号表示 ) 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 10
14.3 内部论域详解
::symbol
宽的 0终止的宽字符序列 。
与字符串相似, 一个符号也是一个 UNICODE 字符序列 。 它是通过指向包
含字符串的符号表的入口的指针而实现的 。 可应用于符号的操作与可应用
于字符串的操作相同 。
一个符号的映像用 <string_literal>表示 ( 任何用双引号括起来的字符 ) 。
符号和字符串大部分是可互换的, 但它们存储的方式不同 。 符号保存在一
个查询表中, 而它们的地址, 不是符号本身, 被存储以代表对象 。 这意味
着符号可以快速匹配, 而且如果一个符号在一个程序中反复出现, 它们可
以非常简洁地存储 。 字符串并不存在于查询表中 。 无论何时字符串需要匹
配, Visual Prolog都会逐字符检查 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 11
14.3 内部论域详解
::binary
N个字节的序列 。
该论域的值用于保存二进制数据 。 一个二进制值作为一个指向字节序列的
指针实现, 该指针代表二进制项的内容 。
二进制项的长度在紧接于字节序列之前的双字中 。 实际上这个双字包含,
TotalNumberOfBytesOccupiedByBinary = ByteLen + 4
这里 ByteLen是二进制项的长度, 而 4是双字占用的字节数 。
只有赋值和比较操作使用二进制论域的值 。
以下比较两个二进制项:如果它们的长度大小不一, 则认为长的那个比较
大 。 否则, 将它们视为无符号值, 逐字节比较 。 当发现两个不同字节时比
较结束, 它们比较的结果就是二进制项比较的结果 。 若两个二进制项长度
相同, 所有的字节也相同, 则认为它们相同 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 12
14.3 内部论域详解
::integer
有符号整型数 。 该论域的值占据 4个字
节 。 算术运算 (+,-,/,*),比较, 赋
值, div,mod操作可应用该论域的值 。
整数允许的范围为从 -2147483648至
2147483647。
整数映像的语法由整数规则确定,
integer,
dec_number
0x hex_number
0o oct_number
oct_number,
oct_digit-list
oct_digit, one of
0 1 2 3 4 5 6 7
dec_number,
dec_digit-list
dec_digit, one of
oct_digit 8 9
hex_number,
hex_digit-list
hex_digit, one of
dec_digit a b c d e f
A B C D E F
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 13
14.3 内部论域详解
::unsigned
无符号整型数 。
该论域的值占 4个字节 。 算术操作 (+,-,/,*),比较, 赋值, div以及 mod
操作可应用该论域的值 。
无符号整数映像的语法与整数的一样。无符号整数不能使用负号,允许
数的范围为从 0 至 4294967295。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 14
14.3 内部论域详解
::real
浮点数 。 该实数论域仅为用户方
便而引入 。 所有的算术, 比较和
赋值操作都可应用该实数论域的
值 。 实数允许的范围为从 1*10-
307到 1*10+308,即 1e-307
到 1e+308。 在必要时, 整数论
域的值自动转换为实数论域 。 浮
点数映像的语法由实数规则确定,
real,
fraction exponent-opt
fraction,
dec_number fractional_part-opt
fractional_part,
, dec_number
exponent,
exp add_operation-opt
dec_number
exp,
e
E
add_operation,
+
-
dec_number,
dec_digit-list
dec_digit, one of
0 1 2 3 4 5 6 7 8 9
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 15
14.3 内部论域详解
::pointer
指向内存地址的 4字节指针 。
一个指针直接与内存地址对应并由 4字节值实现。只有等于操作可应用
该论域的值。指针的映像不能在源文件中显式写出。只有内置的空常量 null
可获得该论域的空值 NULL。
::boolean
布尔值 。
该论域仅为用户方便而引入 。 可以象一般具有下列定义的混合论域来对待
它 。
domains
boolean = false(); true()
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 16
14.3 内部论域详解
::factdb
命名内部数据库的描述符 。
该论域有如下的隐藏声明,
domains
factdb = struct
@factdb( named_internal_database_domain,::object ),
所有用户定义的事实段的名字都是该论域中的常数 。 只要有必要, 编译器
会自动从这些常数中建立相应的混合项 。 运行时, 这一结构的第一个字段
包含相应论域描述符的地址, 第二个字段包含着零 ( 对于类事实段而言 )
或指向对象的指针 This( 对于对象事实段而言 ) 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 17
14.4 内部谓词详解
本节按字母顺序,详细解读 Visual Prolog的内部谓词。
::* //2
乘法算术运算 。 乘法既可应用于整数也可应用于浮点数 。 若操作数之一为浮点数,
则结果也是浮点数 。
::+ //2
加法算术运算 。 加法既可应用于整数也可应用于浮点数 。 若操作数之一为浮点数,
则结果也是浮点数 。
::- //2
减法算术运算 。 减法既可应用于整数也可应用于浮点数 。 若操作数之一为浮点数,
则结果也是浮点数 。
::/ //2
除法算术运算 。 除法既可应用于整数也可应用于浮点数, 结果总是浮点数 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 18
14.4 内部谓词详解
::assert/1
assert/1
procedure (i),
在被匹配的内部事实数据库的底部插入指定事实 。 assert(Fact) 谓词在被匹配
的内部事实数据库插入一个事实, 插入点位于为相应的数据库谓词存储的其他任
何事实之后 。 该事实必须是一个属于内部事实数据库论域的项 。 用于单个事实的
assert/1将已有事实的实例变为指定的事实 。 assert/1与 assertz/1的作用相同 。
参见 assertz/1。
异常
对声明为 determ的事实进行声明, 但该事实实例已经存在 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 19
14.4 内部谓词详解
::asserta/1
asserta/1
procedure (i),
在被匹配的内部事实数据库顶部插入事实 。 asserta(Fact) 谓词在被匹配的内部
事实数据库插入一个事实, 插入点位于为相应谓词存储的其他任何事实之前 。 该
事实必须是一个属于内部事实数据库论域的项 。 用于单个事实的 asserta/1将已
有事实的实例变为指定的事实 。 参见 assert/1和 assertz/1。
异常
对声明为 determ 的事实进行声明, 但该事实实例已经存在 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 20
14.4 内部谓词详解
::assertz/1
assertz/1
procedure (i),
在匹配内部事实数据库底插入事实 。 assertz(Fact) 谓词在被匹配的内部事实
数据库插入一个事实, 插入点位于为相应的数据库谓词存储的其他任何事实之后 。
该事实必须是一个属于内部事实数据库论域的项 。 用于单个事实的 assertz/1将
已有事实的实例变为指定的事实 。 参见 assert/1和 asserta/1。
异常
对声明为 determ的事实进行声明, 但该事实实例已经存在 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 21
14.4 内部谓词详解
::bound/1
bound/1
determ (i),
检查一指定变量是否绑定到一个值上 。 若变量已绑定, 则 bound(Variable)成
功, 若变量是自由的, 则 bound(Variable)失败 。 bound 用来控制流模式并检
查引用变量的绑定 。 如果指定变量的任一部分已初始化, Bound谓词视其为已
绑定 。 参见 free/1。
::class_Name//0
class_Name, ()
->,:string ClassName
procedure (),
这一编译时间谓词返回字符串 ClassName,表示当前接口或类的名字 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 22
14.4 内部谓词详解
::convert//2
convert//2
procedure (i,i),
有检查的项转换 。 该函数的调用模板为,
ReturnTerm = convert ( returnDomain,InputTerm )
参数,
returnDomain:指定一论域, convert//2函数将 InputTerm 转换到该论域 。 这里
returnDomain必须是一内置 Visual Prolog论域名, 接口论域, 或一用户定义的与一个
内部 Visual Prolog论域同义的论域名 。 论域名 returnDomain 必须在编译时间指定, 即
它不能由变量得来 。
InputTerm,指定要转换的值 。 InputTerm可以是任何 Prolog 项或表达式 。 若
InputTerm为一表达式, 那么它将在转换前得到计算 。
ReturnTerm,返回参数 ReturnTerm将是 returnDomain类型 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 23
14.4 内部谓词详解
::convert//2
注意
转 换 谓 词 对 给 定 的 InputTerm 进 行 清 除 和 真 正 的 转 换, 返 回 一 指 定 新 论 域
returnDomain 的项 ReturnTerm 。 如 果 不 能 进 行 要 求 的 转 换, 就产生错误 。
Tryconvert谓词提供相似的功能, 但在不能执行转换时 Tryconvert不产生任何执行错误 。
允许的转换,
? 数字论域之间的转换
? 接口类型之间的转换
? string 和 symbol论域之间的转换
? 从 binary到 pointer
? 上述论域的同义字
? 引用论域和相应的非引用论域之间
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 24
14.4 内部谓词详解
::convert//2
与之相对应的是无检查的转换谓词 uncheckedConvert//2,它完成任意两个
论域之间不加限制的转换, 只要两论域之间具有相同的位长度 。
当源论域和目标论域在编译过程中都静态已知时, convert//2 (或
tryconvert//2)谓词完成有检查的显式转换 。 显式转换的结果可以是如下之一
? ok,成功地转换至目标论域 ;
? run-time-check,为兼容性产生的运行时间检查向目标论域的转换 ;
? error,不可能转换, 错误输出 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 25
14.4 内部谓词详解
::convert//2
有检查的显式转换规则,
? 论域的同义字按论域本身转换的规则转换 。
? 数字论域只能转换为数字论域 。
? 整型常量代表匿名整数论域,[const,,const]。
? 实型常量代表匿名浮点数论域,digits dig [const,,const],这里 dig是
不包括无意义的零的尾数数位的个数 。
? 符号论域的值可以转换为字符串论域, 反之亦然 。
? 二进制论域的一个值可以转换为指针论域 。
? 为接口隐含引入的论域只可以按下述规则转换为接口论域 。
? 所有其他的论域不能转换 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 26
14.4 内部谓词详解
::convert//2
数字论域的转换
? 这种转换中, 范围是首先要考虑的 。 若源和目标的范围不相交, 则产生错误 。 如果源
和目标的范围部分相交, 则产生一致性运行检查 。 同样, 如果一个论域是实数而另一
个是整数, 则在比较前, 整数论域转换为实数论域 。
? 当输入项是实数而输出项是整数, 则 convert//2 和 tryconvert//2谓词截断输入值
为靠近 0的最邻近的整数值 。
接口类型的转换
谓词 convert//2可将任何对象转换为接口类型 。 实际的正确性在运行中检查 。 当对象被
创建时, 它的类型存储在内部, 因此当对象作为参数被传递时, 它仍然保留它最初的
类型 。 这一最初类型用来检查转换的允许与否 。 举例,
interface x
supports a,b
end interface x
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 27
14.4 内部谓词详解
::convert//2
如果对象是由实现 x接口的类创建的, 则对象作为类型为 a的参数传递给某些谓
词, 然后它被允许转换为 b类型的对象 。
异常,
检查范围错误 。
不支持的接口类型 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 28
14.4 内部谓词详解
::digitsOf//1
digitsOf//1 -> unsigned
procedure (i),
返回指定浮点论域的精度 。 该函数的调用模板为,
Precision = digitsof ( domainName )
该编译时间谓词的输入参数 domainName为一浮点论域, 它应在编译时间显
式指定 (也就是说, domainName不能由变量得到 )。 谓词返回的数字
Precision由论域声明中的 digits属性决定 。
编译器保证论域 domainName 的值不少于有意义小数的 Precision位数 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 29
14.4 内部谓词详解
::div//2
算术运算, 返回一整数除法的商 。 操作数和结果都是整数, I div K返回 I被 K
除的商 。
::errorExit/1
errorExit, (::unsigned ErrorNumber)
erroneous (i),
执行具有指定返回代码 ErrorNumber的运行时间错误, 它可用在 trap/3中 。
::fail/0
fail, ()
failure (),
调用回溯 。 fail谓词强迫谓词失败, 因此总是导致回溯 。 在一个以失败结束的子
句中, 它不能为子句绑定输出参数 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 30
14.4 内部谓词详解
::finally/2
finally/2
determ (i,i),
finally元谓词使应用程序保证清除代码 Final_Predicates的执行, 即使当代码块
Do_Predicates的执行被打断 。 Final_Predicates在 Do_Predicates之后立刻执行, 即
使 Do_Predicates退出或失败 。
描述,
该谓词调用模板如下,
finally ( Do_Predicates,Final_Predicates )
该元谓词对强制动作的安全程序设计实现有帮助, 就象在执行正确或不正确的操作后保
证释放资源一样 。
Do_Predicates 和 Final_Predicates 都 必 须 是 determ ( 或更强 ) 。 从
Do_Predicates的谓词输出的变量 ( 如果有 ) 不能用在 Final_Predicates的谓词中 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 31
14.4 内部谓词详解
::finally/2 -接上页
谓词 finally/2有以下语义,
首先执行 Do_Predicates;
如果它们失败, 或者发生任何意外, 执行 Final_Predicates 。 所有在 Do_Predicates
的执行过程中获得值的变量在失败或意外发生时变得不确定 。 因此任何使用它们的企图
( 在 Final_Predicates中或谓词 finally外 ) 都是错误的 。
如果 Do_Predicates顺利执行, 则 Final_Predicates 在 Do_Predicates的最后一个语句
被执行后, 立即正常执行 。
finally 结束时产生以下结果,
如果 Do_Predicates失败或产生意外, 则 finally以失败或相应意外而终止 ( 如果在
Final_Predicates中没有失败或意外时 ) 。 若 Do_Predicates成功, 则 finally根据
Final_Predicates 的 结 果 终 结 。 若 Do_Predicates 产 生 意 外 N1, 接着
Final_Predicates产生意外 N2,那么 finally以意外 N2终结 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 32
14.4 内部谓词详解
::findall/3
findall/3
procedure (i,i,o),
搜集不确定性谓词返回的所有解的列表 。
该谓词的调用模板为,
findall ( ArgumentName,predicateCall,ValuesList )
参数,
ArgumentName:在指定谓词 predicateCall的参数中, 指定哪一个参数将被
搜集进表 ValuesList。
predicateCall:指出从中搜集值的谓词 。
ValuesList,输出变量, 保存通过回溯搜集到的值之列表 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 33
14.4 内部谓词详解
::findall/3 -接上页
注意,
谓词 findall通过回溯至谓词 predicateCall来建立表 ValuesList,直至它失败 。
ValuesList由变量 ArgumentName的所有实例组成, 该变量必是指定谓词
predicateCall的一个输出参数 。
为使 findall 工作, 必须在用户论域声明中对列表论域进行声明 。 这里不允许自
由变量存在 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 34
14.4 内部谓词详解
::free/1
free/1
determ (i),
检查变量是否是自由的 。
该谓词调用模式如下,
free ( Variable )
若指定的变量是自由的, 则谓词 free成功;若指定的变量已被绑定, 则谓词
free失败 。 如果指定变量的任一部分被绑定, 谓词 free视其为已绑定 。 参见
bound/1。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 35
14.4 内部谓词详解
::hasDomain/2
hasDomain/2
procedure (i,o),
检查变量 VariableName是否有论域 domainName。
该谓词调用模式如下,
hasDomain ( domainName,VariableName ) (i,o)
该谓词创建属于由参数 domainName定义的论域的自由变量 VariableName 。
参数 domainName必须是标准的或用户定义的论域;该论域名必须在编译时
间显式指定 ( 即它不能由变量得来 。 )
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 36
14.4 内部谓词详解
::lowerBound//1
lowerBound//1
procedure (i),
返回指定数字论域的低界 。 该谓词调用模式如下,
LowerBoundValue = lowerBound ( domainName )
LowerBound是一个编译时间谓词 。 lowerBound 返回指定数字论域 domainName 的
低界绑定值 。 返回值 LowerBoundValue 属于与 domainName 相同的论域 。 参数
domainName应是任一数字论域的名字;该论域名必须在编译时间显式指定 ( 即它不能
由变量得来 ) 。 参见 upperBound//1。
异常
如果指定论域 domainName不是数字论域, 则发生编译时间错误 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 37
14.4 内部谓词详解
::maxDigits//1
maxDigits//1 -> undsigned
procedure (i),
检索与浮点指针论域 domainName相应的基本论域的数字值 ( 精度 ) 。
该谓词调用模式如下,
MaxDigitsNumber = maxdigits ( domainName )
对 VIP 6.0 而言, 返 回 值 MaxDigitsNumber 总 是 等 于 19 。 参数
domainName应是任一浮点论域的名称;该论域名必须在编译时间显式指定
( 即它不能由变量得来 ) 。 返回值论域为无符号数 。
异常
如果指定论域 domainName不是浮点论域, 则发生错误 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 38
14.4 内部谓词详解
::mod//2
算术运算, 返回整数除法的余数 。 操作数和结果都是整数, I mod K返回 I被 K
除的余数 。
::not/1
not/1
determ (i),
对子目标的结果 ( 成功/失败 ) 求反 。 该谓词调用模式如下,
not ( PredicateCall )
若 PredicateCall代表的目标在求值时失败, 则 not成功 。 在对 not的调用中,
命名的输出变量是不允许使用的, 因为变量不能在 not操作中进行绑定 。 将 not
视为, 若条件真则失败, 或, 若条件假则成功, 是个好主意 。 如果调用
PredicateCall成功则方法失败 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 39
14.4 内部谓词详解
::predicate_Fullname//0
predicate_FullName, ()
->,:string PredicateFullName
procedure (),
这一编译时间谓 词返回一个 字符串 PredicateFullName, 它表示 在其子句体 中
predicate_name得到调用的谓词名字 。 返回的谓词名用一作用域名进行限制 。
predicate_FullName 仅 可 用 在 谓 词 定 义 的 子 句 体 内 。 在 其 他 地 方 使 用
predicate_FullName将导致编译时间错误 。 参见 predicate_Name。
::predicate_name//0
predicate_name, ()
->,:string PredicateName
procedure (),
这 一 编 译 时 间 谓 词 返 回 字 符 串 PredicateFullName, 它 表 示 在 其 子 句 体 中
predicate_name得到调用的谓词名称 。 predicate_Name仅可用在谓词定义的子句体
内 。 在 其 他 地 方 使 用 predicate_Name 将 导 致 编 译 时 间 错 误 。 参见
predicate_FullName。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 40
14.4 内部谓词详解
::retract/1
retract/1
nondeterm (i)
nondeterm (o),
从被匹配的内部事实数据库中除去一匹配的事实 。 该谓词调用模式如下,
retract( FactTemplate )
这里事实模板 FactTemplate是一事实项 。 谓词 retract/1在合适的事实数据库中删除第
一个与 FactTemplate匹配的事实 。 其他匹配事实将在回溯中删除 。
注意, FactTemplate可以有任何级别的实例 。 FactTemplate与事实数据库中的事实匹
配, 这意味着任何自由变量在 retract/1的调用中都将被绑定 。 FactTemplate可以包含
任何匿名变量 。 例如,
retract ( person("Hans",_Age) )
将撤消第一个匹配的 person事实, 该事实第一个参数为, Hans”,第二个参数任意 。
当撤消一个声明为 determ的事实时, retract/1的调用将是确定性的 。 参见 retractall/1
和 retractall/2。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 41
14.4 内部谓词详解
::retract/1 -接上页
警告,
如果在项目的当前范围内声明了单个事实, 那么应注意在调用 retract/1时要具
有自由 FactTemplate变量 。 如果撤消单个事实, 就会发生运行时间错误 。 当
没有更多的匹配时, 方法失败 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 42
14.4 内部谓词详解
::retractall/1
retractall/1
procedure (i),
从被匹配的内部事实数据库中删除所有匹配的事实 。
该谓词调用模式如下,
retractall ( FactTemplate )
这里 FactTemplate应是一事实项 。
retractall/1谓词为事实库中所有的事实数据库谓词撤消所有与 FactTemplate匹配的谓
词 。 它总是成功, 即使无事实可撤消 。
从 retractall/1不可能得到任何输出值 。 因此, 调用中的变量必须被绑定或是单个下划线
( 匿名 ) 。 注意 FactTemplate可以有任何级别的实例, 但自由变量必须是单下划线
(, 无条件匿名, ) 。 与 retract/1不同, 以下划线开头的, 有条件匿名, 变量 (比如
_AnyValue)在 retractall/1中不能使用 。 参见 retract/1 和 retractall/2。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 43
14.4 内部谓词详解
::retractall/2
retractall/2
procedure (i,i),
从指定的内部事实数据库 FactsSectionName中删除所有匹配的事实 。
该谓词调用模式如下,
retractall ( FactTemplate,FactsSectionName )
retractall/2 从 指 定 的 事 实 数 据 库 FactsSectionName 中 删 除 所 有 与
FactTemplate 匹配的事实 。
从 retractall/2不可能得到任何输出值 。 因此, 调用中的变量必须被绑定或是
单个下划线 ( 匿名 ) 。 名为 FactsSectionName的事实数据库应在编译时指定,
它不能从变量中获得 。
retractall/2是确定性的并将总是成功 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 44
14.4 内部谓词详解
::sizeBitsOf//1
sizeBitsOf//1 -> unsigned
procedure (i),
检索内存中被指定论域 DomainName实体占用的位数 。
该谓词调用模式如下,
Bits_Size = sizeBitsOf ( DomainName )
这一编译时间谓词接收论域 DomainName作为输入参数并返回给定论域占用
内存的位数 。 结果度量单位为位 。 对实数论域而言, 谓词 sizeBitsOf//1返回论
域声明中长度字段所定义的值 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 45
14.4 内部谓词详解
::sizeOf//1
sizeOf//1 -> unsigned
procedure (i),
检索内存中被指定项占用的字节数 。
描述
该谓词调用模式如下,
ByteSize = sizeOf ( Term )
函数 sizeOf//1接收一个项 Term作为输入参数并返回无符号值字节长度
ByteSize,该值代表了内存中该项 Term占用的字节数 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 46
14.4 内部谓词详解
::sizeOfDomain//1
sizeOfDomain//1 -> unsigned
procedure (i),
检索内存中被指定论域 DomainName实体占用的字节数 。
该谓词调用模式如下,
Bytes_Size = sizeOfDomain ( DomainName )
这一编译时间谓词接收论域 DomainName作为输入参数并返回被给定论域占
用内存的大小 。 结果度量单位为字节 。 返回值 Bytes_Size属于无符号数 。 与
sizeBitsOf//1相比, sizeBitsOf//1返回用位数度量的项的大小, 而该谓词返
回用字节数度量的论域的大小 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 47
14.4 内部谓词详解
SourceFile_LineNo//0
sourceFile_LineNo, ()
->,:unsigned
procedure (),
返回在编译器中处理的源文件的当前行号 。
这一编译时间谓词返回正在编译的文件中正由编译器处理的行号 。
::sourceFile_Name//0
sourceFile_Name, ()
->,:string
procedure (),
返回在编译器中处理的源文件的名称 。
这一编译时间谓词返回正在编译的文件名称的字符串 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 48
14.4 内部谓词详解
::sourceFile_TimeStamp//0
sourceFile_TimeStamp, ()
->,:string
procedure (),
返回表示在编译器中处理的源文件的日期和时间的字符串 。
这一编译时间谓词返回当前被编译源文件的时间和日期的字符串, 字符串格式
为,YYYY-MM-DD HH:MM:SS的形式 。
::succeed/0
succeed/0,
谓词 succeed/0总是成功 。
标准谓词 succeed/0正好成功一次 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 49
14.4 内部谓词详解
::toBinary//1
toBinary//1 -> binary
procedure (i),
将指定项转换为二进制表示 。
该函数调用模式如下,
Binary_Term = toBinary ( Term )
当 Term (属于某论域 domainName)被转换为二进制时, 它可安全地存储于一
文件内或通过网络送到另一程序中 。 以后, 通过函数 toTerm//1,得到的二进
制值 Binary_Term 可以转换回 Visual Prolog项 ( 被转换项的论域必须适合
domainName) 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 50
14.4 内部谓词详解
::toBoolean//1
toBoolean//1 -> boolean
procedure (i),
这一元谓词的用途是将一确定性调用 ( 谓词或事实 ) 转换为返回值为 boolean论域的程
序 。 该谓词调用模式如下,
True_or_False = toBoolean ( deterministic_call )
toBoolean//1元谓词返回 boolean 值 。 如果 deterministic_call成功, 则结果为真 。
如果 deterministic_call失败 。 则结果为假 。
::toString//1
toString//1 -> string
procedure (i),
将一指定的项转换成字符串表示 。 该谓词调用模式如下,
String_Term = toString ( Term )
当 Term (属于某论域 domainName)被转换为字符串时, 它可安全地存储于一文件内或
通过网络送到另一程序中 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 51
14.4 内部谓词详解
::toTerm//1
toTerm//1
procedure (i),
将指定项 SrcTerm的字符或二进制表示转换成与返回值的 PrologTerm变量的
论域相应的表示 。
描述,
该谓词调用模式如下,
PrologTerm = toTerm ( SrcTerm )
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 52
14.4 内部谓词详解
::toTerm//1 -接上页
编译时编译器应能确定返回值 PrologTerm的论域 。 注意, 谓词 toTerm的二进制形
式执行几乎是逐字节的转换, 并只检查 SrcTerm 数据与返回值 PrologTerm要求的论域
的一般兼容性 。 程序员完全负责提供能够被正确转换为期望论域的项的 SrcTerm二进制
数据 。 谓词 toTerm 与谓词 toBinary//1和 toString//1 相似 。 当 Term( 属于某论域 )
被转换为二进制或字符串表示 SrcTerm时 ( 分别通过 toBinary//1和 toString//1), 它
可安全地存储于一文件内或通过网络送到另一程序中 。 以后, 通过相应的函数
toTerm//1,将得到的字符串或二进制值 SrcTerm转换回 Visual Prolog项 PrologTerm。
为保证反转换的正确性, 子句变量 PrologTerm的论域应适合初始论域 domainName。
异常
若编译器不能确定返回值的论域, 则发生编译时间错误 。
当谓词 toTerm//1不能将字符串或二进制值转换为指定论域的项时, 产生运行错误 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 53
14.4 内部谓词详解
::trap/3
trap/3
determ (i,o,i),
在谓词 PredicateCall中捕获退出, 中断和运行时间错误 。 该函数调用模式如下,
trap ( PredicateCall,ErrorCode,ErrorHandler )
谓词 trap执行错误捕获和异常处理 。 如果 PredicateCall成功, trap就会完全成功,
PredicateCall失败, trap也失败 。 然而, 如果在 PredicateCall执行的过程中发生异常
( 或在其子目标执行的过程中发生异常 ), 则 ErrorCode将接收合适的错误代码值, 而
ErrorHandler将得到调用 。 当 ErrorHandler返回时, trap也将返回 。
如果 PredicateCall失败或在调用错误处理器 ErrorHandler后出现异常, 则该方法
( Method) 失败 。
注意
编译器暂时有以下限制,ErrorHandler谓词必须用错误或失败模式声明 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 54
14.4 内部谓词详解
::tryConvert//2
tryConvert//2
determ (i,i),
检查输入项 InputTerm是否能严格地转换成指定论域 returnDomain并返回转换后的项
ReturnTerm。 该函数调用模式如下,
ReturnTerm = tryConvert ( returnDomain,InputTerm )
参数,
returnDomain:指定一个论域, 谓词 tryconvert//2试图转换指定的 InputTerm至该
论域中 。 这里 returnDomain 可 以 是 当 前 作 用 范 围 内 可 得 到 的 任 意 项 。 名为
returnDomain 的论域必须在编译时间指定, 即它不能从变量中得到 。
InputTerm:指定必须转换的项 。 InputTerm可以是任何 Prolog项或表达式 。 如果
InputTerm是一表达式, 那么它将在转换前得到计算 。
ReturnTerm,返回项 ReturnTerm将为 returnDomain 论域 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 55
14.4 内部谓词详解
::tryConvert//2 -接上页
注意,
转换规则与嵌入谓词 convert//2 一样, 但是当 convert//2 产生转换错误时,
tryconvert//2失败 。
若相应转换成功则该谓词成功, 否则失败 。 谓词 tryconvert//2试图执行一次清除操作,
并且执行从已知 InputTerm到指定论域 returnDomain的值的真实转换 。 如果要求的转
换不能执行, 谓词 tryconvert//2失败 。 当谓词 tryconvert//2成功时, 它返回转换至指
定论域 returnDomain的项 ReturnTerm。
关于有检查的显式转换, 其允许的转换和规则参见谓词 convert//2。
参见 uncheckedConvert//2。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 56
14.4 内部谓词详解
::uncheckedConvert//2
uncheckedConvert//2
procedure (i,i),
无检查的论域转换 。 该函数调用模式如下,
ReturnTerm = uncheckedConvert ( returnDomain,InputTerm )
参数,
returnDomain:指定一个论域, 谓词 uncheckedConvert不安全地转换指定的输入项
InputTerm到该论域中 。 这里返回论域 returnDomain可以是当前作用域内可得到的任
意项 。 返回项 ReturnTerm与 输入项 InputTerm大小应一样 。 名为 returnDomain 的论
域必须在编译时间指定, 即它不能从变量中得到 。
InputTerm:指定必须转换的值 。 InputTerm可以是任何 Prolog项或表达式 。 如果
InputTerm是表达式, 那么它将在转换前得到计算 。
ReturnTerm:返回的参数 ReturnTerm将为 returnDomain类型 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 57
14.4 内部谓词详解
::uncheckedConvert//2 -接上页
注意,
谓词 uncheckedConvert 几 乎 执 行 任 意 的 转 换 。 谓词 uncheckedConvert 执行
InputTerm 的初步计算 (如果它是一表达式 ),将现有的类型换成 returnDomain 类型
并与 ReturnTerm合一 。 谓词 uncheckedConvert 不执行运行时间的检查 。 它仅进行等
同于被转换论域位长度的编译时间检查 。 所以几乎任何项都可以不顾一切的转换为其他
任何项 。 所以如果试图使用被 uncheckedConvert 不正确地转换的变量, 可能发生十分
危险的结果 。 使用 uncheckedConvert要格外小心, 我们强烈建议在大多数情况下或必
要时尽量使用 convert//2和 tryconvert//2。 但请注意, 当一个对象由 COM系统返回时,
有必要用 uncheckedConvert来转换, 因为 Prolog 程序没有它实际类型的信息 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 58
14.4 内部谓词详解
::upperBound//1
upperBound//1
procedure (i),
返回指定数论域的上界值 。 该函数调用模式如下,
UpperBoundValue = upperBound ( domainName )
upperBound 是一编译时间谓词 。 upperBound 返回指定数字论域
domainName 的上界值 。 返回值 UpperBoundValue 属于相同的论域
domainName。 参数 domainName 应是任何数字论域的名字;该论域名应
在编译时间显式指定 ( 也就是说, domainName不能从变量中得到 ) 。 参见
lowerBound//1。
异常,如果指定的论域 domainName不是数字论域, 则产生编译时间错误 。
第三部分:第 14章 内部论域、谓词和常量
2004.11.3 AI程序设计 59
第十四章小结
本章介绍所有内部常量、论域和谓词的声明和描述。
第十四章习题
1、内部论域、谓词和常量与自定义论域、谓词和常量在概念上有何
异同?
2、内部论域、谓词和常量与自定义论域、谓词和常量在使用上有何
差别?