![](https://csdnimg.cn/release/download_crawler_static/86593151/bg1.jpg)
Visual Prolog 7.3
语言参考手册
(c) 2010 Prolog Development Center A/S
http://www.visual-prolog.com
乙丁 译
2010年6月
![](https://csdnimg.cn/release/download_crawler_static/86593151/bg3.jpg)
1
Visual Prolog 7.3语言参考手册
本文档描述 Visual Prolog 编程语言的语法与语义。
Visual Prolog 是面向对象的强类型编程语言,它的基础是逻辑编程语言 Prolog。
一个 Visual Prolog 程序是由一个
goal
(目标)及一些:
y
interfaces(接口)
y
Class declarations(类声明)及
y
Class implementations(类实现)
构成的,它们当中包含有下面一些 Prolog 实体的声明与定义:
y
Domains (域)
y
Constants (常数)
y
Predicates (谓词)
y
Properties (属性)
y
Fact databases (事实数据库)。
Visual Prolog的实际代码是类实现当中的
clauses(子句),谓词是由它实现的。
![](https://csdnimg.cn/release/download_crawler_static/86593151/bg4.jpg)
2
基本概念
Types and Subtypes (类型和子类型)
Types
Visual Prolog 的类型分为对象类型与值类型。对象的状态是可变的而值是不可变的。
对象的类型是由 interface(接口)定义的。
值的类型包括 numerical types(数值类型)、strings(串)、character types(字符类型)和 compound
domains(复合域)。复合域又称为代数数据类型,它的简单形式有结构及枚举类型,而其复杂形式表现为
树状结构。
Subtypes
类型是由子类型体系构成的。子类型用来引入多态包容性:任何期望某类型值的语境也能很好地接受
任意子类型的值。也可以反过来说,某个类型的值在需要的时候可以自动地转换成任意父类型加以应用,
而不需要显式的类型转换。
子类型可以由除代数数据类型而外的任何值类型派生出来。代数数据类型派生出的类型是异名类型而
不是子类型,也就是说,它们是相同的类型而非子类型。
子类型和子集在概念上很相近,但是一定要注意,即便一个类型“算术上”是另一个类型的子集它也
末必就是一个子类型。只有声明了之后一个类型才可以是另一个类型的子类型。
domains
t1 = [1..17].
t2 = [5..13].
t3 = t1 [5..13].
t1
是整数类型,它的值从 1 到 17(含)。而 t2 的值是 5 到 13,所以,t2 是 t1 的一个子集,但它
并非
t1 的一个子类型。另一方面,t3(它也含有与 t2 一样的值)则是 t1 的一个子类型,因为声明如此。
本语言中有几个隐含的子类型关系,但一般而言子类型关系都必须在类型定义中显式地说明。
对象类型也是由子类型体系构成的,根是预定义的对象类型
Object,也就是说任意对象类型都是
Object 的子类型。对象子类型的定义是通过声明说一个接口支持另一个而实现的。如果一个对象具有支
持某个其它接口的接口/对象,那么该对象就有了那个类型,可以无冲突地当作那个对象来使用。
参看:
Universal and Root Types(通用类型和根类型)
对象系统
外视图
这一节的描述不是对类的一般性的介绍,而是对 Visual Prolog 中类的概念说明,希望读者已经熟悉
通常的类概念。描述完全是纯概念意义上的,不涉及语法、实现等,也不考虑操作或编程方面的问题。尽
管引入类、对象的主要原因是程序本质上的要求,但只描述基本观念而不去考虑程序上的原因还是很有价
值的。
Visual Prolog 中类的概念是以如下三个语义实体为基础的:
y
objects
y
interfaces
y
classes
Object
![](https://csdnimg.cn/release/download_crawler_static/86593151/bg5.jpg)
3
一个对象,就是一套命名了的对象成员谓词及一套支持的接口。
其实对象也有状态,但这个状态只能通过成员谓词才能改变和观察。我们称之为状态封装在对象中。
这里的封装,意味着对象有隐藏其内部数据和方法的能力,使对对象的访问受控。封装和模块化的重
要性是众所周知的。封装有助于构建更加结构化和易读的程序,因为对象可以看作为一个黑盒子。要解一
个复杂的问题,先找出可以下断言和描述的一部分,把它封装在一个对象里,构造一个接口,接着再往下,
直到声明了所有子问题。封装了问题对象后,只要保证它们工作正常,就可以从对象中抽取数据。
Interface
接口是一个对象类型,它有一个名字并定义一组命名了的对象谓词。
接口按支持体系构建(这个结构是半格状的,根是
interface 对象)。如果一个对象具有一个接口表示
的类型,它也就有所有支持接口的类型。因此,支持体系也是类型体系。一个接口是所有它支持的接口的
一个子类型。也可以说对象支持接口,如果接口名为
X,我们可以说这个对象是一个 X,或是一个 X 对象。
Class
类是命名了的对象工厂,它创建相应于某个接口的对象。任何对象都是由类创建的,如果一个类是用
接口
C构造对象的,那么这个类创建的所有对象都叫C对象。
由某个类构造的所有对象共享相同的对象成员谓词定义,但每个对象有其自己的状态。因此,对象成
员谓词实际上是类的一部分,而对象的状态则是对象本身的一部分。
类还含有被称为类成员和类状态的另一组命名了的谓词和封装的状态。类成员与类状态存在于各个类
中,而对象成员与对象状态存在于各个对象中。类成员和对象成员都可以访问类状态。
注意!一个类所定义的对象成员谓词组是在该类的接口中声明的谓词联合体,更明确地说,如果在不
同的两个接口中声明了同一个谓词,类只会提供该谓词的一个定义。因此,类只是检测实际意义,也就是
说只是看这两个继承谓词的预期语义是否一致。
要注意,接口支持必须明确地指定。某个类提供相应某个接口的谓词并不意味着这个类支持这个接口。
Module(模块)
事实上,类不必非得能产生对象。不产生对象的类只有类成员和类状态,而这样的类当模块看待更恰
当。
Identity(标识)
每个对象都是唯一的:对象具有可变的状态,而且对象的状态只能通过它们的成员谓词观察到,因而
对象只与它自己是同一的。这就是说,即使有两个对象的状态是一样的,它们也不是同一的,因为我们可
以改变一个对象的状态而不影响另一个对象的状态。
我们无法直接访问一个对象的状态,而总是通过对象的引用来访问对象的状态。尽管对象仅与自身是
同一的,但可以有许多对同一对象的引用。因此,一个对象可以由许多不同的引用来访问。
类和接口也是唯一的,用它们的名字来标识。在一个程序中,两个接口或两个类不能用相同的名字,
只有当一个类构造某个接口的对象时,这个类和这个接口才可以用相同的名字。
总之,结构的相同并不意味着同一,对对象、类和接口都是这样的。
内视图
前一节描述了对象、类及接口的外在表现,这一节描述内部情况。这些内部问题更具程序特性,可以
把它们分成声明与实现两个部分来考虑。
从程序的观点,类是核心:代码是包含在类中的。
接口主要地是静态特性,实事上,接口只存在于一个程序的文本表示中,运行时没有一个(直接的)
代表接口的东西。而另一方面,对象主要地是动态特性,它在程序中并不是直接可见的,直到程序实际运
行时它才存在。