资源描述
人工智能程序设计语言----Prolog
1概述
1970年由法国马赛大学Alain Colmerauer等开发,作为逻辑程序设计的工具。
很多著名的专家系统外壳都用Prolog编写,如ESP/Advisor, APE, X1等。
程序特点:陈述式语言。只要给出必要的事实和规则,Prolog就可以用演绎推理自动求解问题。而过程式语言必须告之求解过程才行。
实例与基本概念:
一个Prolog的实例程序如下:
domains /*领域声明段*/
person,activity=symbol /*域person和activity的声明,symbol为标准域*/
predicates /*谓词格式说明段*/
likes(person,activity) /*likes为谓词名,表示某人person喜欢activity活动*/
clauses /*子句段*/
likes(ellen,tennis). /*事实:ellen喜欢tennis*/
likes(john,football).
likes(tom,baseball).
likes(eric,swimming).
likes(mark,tennis).
likes(bill,X):-likes(tom,X). /*规则:tom喜欢的,bill也喜欢*/
goal /*目标段*/
likes(bill,football). /*考察bill是否喜欢football*/
变量:以大写字母开头,后跟若干数字、下划线、字母组成的符号名称。是在满足目标时,其值未知的量。例如:likes(X_Persons,tennis).中的X。
对象与关系:谓词表示一个或多个对象之间的某种关系。例如:likes(mark,tennis).中的likes谓词表示某人喜欢某类活动。其中,mark和和tennis分别是关系likes中的对象。
又如:owns(susan,horse).
eats(jill,meat).
valuable(gold). /*黄金是值钱的*/
注:对象名和关系名都必须以小写字母开头。
领域与谓词:谓词是用语描述事实和关系的。但与此相关的谓词之涉及对象的领域范围必须明确。因此,在Prolog中,需要对关系中的对象的域进行声明。例如:likes(person,activity).表明,谓词likes中第一个参数为person域,第二个为activuty域。如果目标中输入likes(12,x),系统将给出一个领域类型错的信息。因为,第一个参数不属于person域,此处即symbol域。
复合目标:由多个子目标构成的问题目标描述。例如:likes(tom,X) and likes(erric,X)。
无名变量:即谓词参数中以下划线表示时,该变量称为无名变量。表示此时该变量的值无关紧要。例如:likes(_,baseball) and likes(ellen,tennis).表示只要有人喜欢baseball,ellen就喜欢tennis。car(_,_,Age,_,Cost) and Cost<27000.表示查找价格在27000$以下的车,并给出其使用年限和价格。
无名变量用于事实时,表示任意或全部都成立。例如:owns(_,shirt).表示人人都有一件衬衣。washface(_).表示人人都洗脸。
回溯:当子目标匹配或搜索失败时,回到最近的成功点继续进行余下的事实或规则的匹配的过程。以如下程序为例:
domains
child=symbol
age=integer
predicates
pupil(child,age)
clauses
pupil(peter,9).
pupil(chris,9).
pupil(paul,10).
pupil(susan,9).
问题:安排一次班级上9岁同学的乒乓球比赛,每对运动员赛两场。则目标子句可描述pupil(P1,9) and pupil(P2,9) and P1<>P2.的执行过程如下:
子目标1
子目标2
子目标3
结果
说明
peter
peter
peter<>peter
失败
回溯到第二子目标
chris
peter<>chris
成功
回溯到第二子目标继续寻找下一组解
susan
peter<>susan
成功
子目标2已搜索完毕,回溯到子目标1
chris
peter
chris<>peter
成功
回溯到第二子目标继续寻找下一组解
chris
chirs<>chris
失败
回溯到第二子目标
susan
chris<>susan
成功
子目标2已搜索完毕,回溯到子目标1
susan
peter
susan<>peter
成功
回溯到第二子目标继续寻找下一组解
chris
susan<>chris
成功
回溯到第二子目标继续寻找下一组解
susan
susan<>susan
失败
全部搜索完毕
not的用法:表示谓词或规则的否定。例如:likes(X,baseball) and not(likes(X,tennis)).表示喜欢baseball但不喜欢tennis的人。
注释问题:Prolog中的注释用/**/方法。
其它符号约定: “if”çè “:-”; “,”çè “and”; “;”çè “or”
2 Visual Prolog简介
2-1 程序的整体结构
2-1-1 编译器导向(置于程序文本的开头)
bgidriver----(BGI-Borland Graphics Interface)。如果程序需要BGI图形模式,则可加此导向语句。(只对DOS版用!)
用法:bgidriver "_CGA_driver_far"
bgifont----与bgidriver类似。
用法:bgifont "_gothic_font_far"
nowarnings----不再显示警告信息。
nobreak----程序执行时不能中断,只有启动机器才能终止执行。
(其它见help)
2-1-2 常量声明段
用于声明和使用一些在程序中将使用到的符号常量。其关键词是CONSTANTS,后跟对符号常量的声明。其符号常量的声明语法格式如下:
<Id>=<Macro definition>
例如:
CONSTANTS
zero = 0
one = 1
two = 2
hundred = (10*(10-1)+10)
pi = 3.141592653
ega = 3
slash_fill = 4
red = 4
注:在编译程序之前,Visual Prolog将用符号常量全部替换程序中对应的符号串(与C语言中的宏替换相似!)
对符号常量使用过程中的约束如下:
1) 符号常量声明时,系统并不区分符号常量的大小写。因此,在CLAUSES部分,为了和变量名区分开来,符号常量名的首字符必须小写。
例如:
CONSTANTS
two = 2
GOAL
A=two, write(A).
2) 符号常量定义中不能自己定义自己
例如:my_number = 2*my_number
3) 程序中可以有多个CONSTANTS区,但必须遵循先声明,后使用原则
4) 常量的有效范围从声明处开始,直到源文件的末尾,包含程序文件的包含情形在内。
5) 常量标识符只能声明一次
2-1-3 变量、约束变量与自由变量
变量:其值在程序执行过程中可以发生改变的量。
变量的表示:大写字母开头的符号串。
变量的两种状态:值不定时为自由变量,值已知时为约束变量。
例如:
DOMAINS
person,hobby=symbol
PREDICATES
likes(person,hobby)
CLAUSES
likes(ellen,reading).
likes(john,computers).
likes(john,badminton).
likes(leonard,badminton).
likes(eric,swimming).
likes(eric,reading).
GOAL
likes(X,reading) and likes(X,swimming).
分析:目标有两个子目标。Prolog试图从左到右逐一满足。在搜索过程中,likes(X,reading)没有被满足之前,其X的值没有确定,此时称X为自由变量。当用likes(ellen,reading)匹配第一子目标后,X被约束为ellen值,此时称X为约束变量。此后,对第二子目标likes(X,swimming)进行匹配时,X是约束变量。
2-1-4 事实数据库段
Visual prolog程序是事实和规则的集合。在程序运行期间,对程序操纵的事实的更新、改变、移动及增加、减少等,因此,属于动态库(dynamic database)或内部库(internal database)。Visual prolog包含了一个专门用来说明属于动态库的事实的部分,即FACTS部分。
FACTS的一般声明格式如下:
[GLOBAL] {FACTS | DATABASE} [- databasename]
[nocopy][{nondeterm|determ|single}] fact_1[([ArgsList_1])] ...
[nocopy][{single|determ|nondeterm}] fact_N[([ArgsList_N])]
...
其中,“{}”表示多选一,且必选一,“[]”表示可有可无,“*”表示任意多次重复(包含0次)。
GLOBAL----表明事实部分是否是全局的。
nocopy----事实匹配时不进行复制。
nondeterm----默认情形是事实fact_N的任意多个实例可以存在(即不确定的)。
determ----任何时候,一个fact_N的实例不超过1个。
single----任何时候,事实fact_N的实例有且只能有一个。
fact_N----事实或谓词。
argsList_N ----事实或谓词中的参数表。其形式为:
[ Domain_1 Name_1 [ , Domain_2 Name_2 ]* ]
例如:
FACTS
person(STRING Name, STRING Address, INTEGER Age)
determ counter(integer CounterValue)
single singleFact(STRING)
single my_font(font_list)
2-1-5 域段
用于声明任何Visual Prolog标准域以外的域。类似于C语言中的数据类型定义typedef的功能。
2-1-5-1符号约定及说明
dom----领域名。
reference表示允许有非约束变量作为输入参数。其声明的方法是在域声明右边加一关键字reference。例如:
DOMAINS
reflist = reference refint*
refint = reference integer
term = reference int(refint); symb(refsymb)
refsymb = reference symbol
当一个复合域被声明为一个reference域时,其所有的子域自动成为reference的。然而,应该在域段中明确指出要成为reference域的域。如果子域是标准域,如integer,string,则整个程序中的标准域都将成为reference域。
注:不应该将标准域作为reference域。在纯粹的Prolog中,这将显著地增加系统的负担。在含C调用的工程中,还将导致不正确的参数传递甚至保护性错误。
例如:用reference域进行排序的实例。
DOMAINS
tree = reference t(val, tree, tree) /*tree是一个reference域*/
val = integer
list = integer*
PREDICATES
insert(integer,tree)
instree(list,tree)
nondeterm treemembers(integer,tree)
sort(list,list)
CLAUSES
insert(Val,t(Val,_,_)):-!.
insert(Val,t(Val1,Tree,_)):-Val<Val1,!,insert(Val,Tree).
insert(Val,t(_,_,Tree)):-insert(Val,Tree).
instree([],_).
instree([H|T],Tree):-insert(H,Tree),instree(T,Tree).
treemembers(_,T):-free(T),!,fail.
treemembers(X,t(_,L,_)):-treemembers(X,L).
treemembers(X,t(Refstr,_,_)):-X = Refstr.
treemembers(X,t(_,_,R)):-treemembers(X,R).
sort(L,L1):-instree(L,Tree),findall(X,treemembers(X,Tree),L1).
GOAL
sort([3,6,1,4,5],L),write("L=",L),nl.
[align {byte|word|dword}]内存分配与使用方法指定。对标准Prolog内存的处理是自动进行的。(详细情形及例子见Help)
declaration_1 [;declaration_2]* 可选择的复合对象声明部分。其格式为:functor([sub_1 [, sub_2]* ])。
2-1-5-2用标准领域进行声明
标准领域类型:integer, char, real, string, symbol, word, byte, short, unsigned, long, ulong, ushort, binary等。其定义如下:
integer:-32768~32767之间的整数。
char:单引号引起来的单个字符,如‘a’。其中,‘\n’, ‘\t’, ‘\b’等为转义字符。
real:+/-1.0e-307之间的实数。
string:双引号引起来的任意多个字符构成。可以是空串。
symbol:有两种格式,一是以小写字母开头,后跟若干字母、数字和下划线组成的符号串,一是由双引号引起来的一串字符。后者主要用于含空格字符或起始字符不是小写的时候。
byte, word, short, ushort, signed, unsigned, long, ulong, binary:表示不同的数据类型。
注1:符号和串可以交替使用,但在机器内部的处理过程是不同的。对符号串,内部是用表存放的,能加速匹配过程。其缺点是占用专门的存储空间,且搜索需要花费一定时间。
注2:如果程序中谓词说明都用标准领域,则领域段可以省略。
基本域的说明格式:dom [, dom1] = [reference] <basicdom>
例如:
DOMAINS
brand, color = symbol
age, price = integer
mileage = real
PREDICATES
car(brand, mileage, age, color, price)
CLAUSES
car(chrysler,130000,3,red,12000).
car(ford,90000,4,gray,25000).
car(datsun,8000,1,red,30000).
GOALS
car(Make,Odometer,Years_on_road,Body,25000); //查找价格为25000车
car(Make,Odometer,Years_on_road,Body,Cost) and Cost<25000. //或查找25000以下的车
特殊域的说明格式:dom [,dom1] = [reference] [signed | unsigned] {byte | word | dword}
2-1-5-3复合对象及其领域的声明
复合对象:对象中含对象时,该对象称为复合对象。
例如:复合对象实例。
owns(john,book(“From Here to Eternity”, “James Jones”)).和owns(john,horse(blacky)).分别表示John拥有James Jones写的《从现在到未来》的书,以及John拥有一匹黑马的事实。而用owns(john,“From Here to Eternity”).和owns(john,blacky).是不能表达以上两个事实的。
复合对象的构成:由函数子及属于此函数子的子对象构成,即functor(obj1,obj2,…,objN)。没有子对象的函数子表示为functor()或functor,用于区分不同的对象,如前面的book和horse。
复合对象的领域说明:
其完整格式如下:
[GLOBAL] DOMAINS
dom [,dom_1] = [reference] [align {byte|word|dword}] declaration_1 [;declaration_2]*
例如:复合对象域的声明实例。
DOMAINS
title,author,name = symbol
articles = book(title,author);horse(name) /*各选择域之间用分号分隔*/
符合对象的层次结构表示特征:
书
作者
书名
姓
名
复合对象域的树结构示意图
DOMAINS
articles = book(title,author);…
author = author(firstname,surname)
title, firstname, surname = symbol
注:一个领域语句一次仅能描述一层树结构,而不能描述整棵树。
例如:articles=book(title,author(name,surname))作为领域说明是不行的。必须分别如上例所示进行描述。
没有函数子的复合对象(单选择的复合对象):
一般格式:dom [, dom_1] = struct [align {byte | word | dword}] obj_declaration
例如:BOOKS = struct book(SYMBOL Author_Name, SYMBOL Title)
注:域的右边不能再有其它可选择域!
2-1-5-4列表及其领域的声明
表是Prolog程序中的基本数据结构,与Pascal和C等面向过程程序设计语言的数组结构相当。
列表域声明的一般格式:mylist [, mylist1]= [reference] elementDom*
注1:其中的星号表示可有0个或多个元素。
注2:表中元素必须具有相同领域,如果不为标准领域范围,则必须有一个关于对象的声明。
注3:表中元素可以是任何对象类型,也包含表类型本身。其一般定义格式如下:
DOMAINS
objectlist=objects*
objects=…
例如:
DOMAINS
integerlist=integer*
namelist=name*
name=symbol
表的表示方法:以[]扩住的,其间由多个元素构成,元素和元素之间由逗号分隔。
例如:[1,2,3]
[dog, cat, canary]
[“valerie”, “jonathan”, “Michael”]等。
表的基本结构与操作:
Prolog将表分成表头(head)和表尾(tail)两部分。表头是表中的第一个元素,表尾是除去表头元素后剩下的部分。表头和表尾可用竖线(“|”)分隔。(其表示与基本操作可以参见数据结构中广义表结构的讨论)
注:空表的表头和表尾均无定义。
例如:表及其表头、表尾实例。
[a,b,c]的表头为a,表尾为[b,c]。可以表示为[a|[b,c]]。
[1]的表头为1,表尾为[]。可以表示为[a|[]]。
[]的表头无定义,表尾也无定义。
[[1,2,3],[2,3,4],[]]的表头为[1,2,3],表尾为[[2,3,4],[]]。可以表示为[[1,2,3]|[[2,3,4],[]]。
例如:表头表尾的匹配实例。
[X,Y,Z]与[egbert, eats, icecream]匹配结果为:X= egbert,Y= eats,Z= icecream。
[7]与[X|Y]匹配的结果为:X=7,Y=[]。
[1,2,3,4]与[X,Y|Z]的匹配结果为:X=1,Y=2,Z=[3,4]。
[1,2]与[3|X]匹配失败。
例如:有关表头、表尾操作的程序实例。
DOMAINS
namelist=name*
name=symbol
PREDICATES
member(name,namelist).
CLAUSES
member(Name,[Name|_]). /*下划线表示子句匹配时不感兴趣*/
member(Name,[_|Tail]) if member(Name,Tail). /*判定Name是否表中成员*/
write_a_list([]). /*表空时停止(此时匹配成功)*/
write_a_list([Head|Tail]):-write(Head),nl,write_a_list(Tail).
(3) 特殊的预定义对象(略)
(4) 谓词域的声明(略)
(5) 对象谓词域的声明(略)
(6) 引用域的声明(略)
(7) 目标域的声明(略)
2-1-6 谓词段
用于声明谓词、函数或谓词之值的地方。
谓词、函数的声明形式:
[GLOBAL] PREDICATES
[PredicateMode] [ReturnDomain] predicateName[(arglist)]
[- [flowpatterns]] [language] [namespec]
GLOBAL----表示该谓词定义为全局的。
PredicateMode----谓词模式,定义为{procedure | determ | nondeterm | failure | erroneous | multi}。用于定义谓词的执行方式,因为 ,Visual Prolog是强制类型执行系统,它强迫程序员指定谓词的两种行为的确定:一是谓词的调用是否要失败,一个谓词可以产生的解答个数。其中:
multi----定义非确定性谓词,可以回溯产生多解。这种谓词总是成功的,因此,至少有一个解。(never fail!)
procedure----定义被称之为过程的谓词。过程总是成功的,但不回溯。过程有且仅有一个解。运行时可能有错误产生!编译器将总是检查并给出过程中的非确定性子句的警告。如果不能保证一个过程不绝失败的话,编译器将给出595或596错误。
erroneous----不应产生一个解,且永远不失败。(相当于一个运行时错误,可以用于设置陷阱的处理)
failure----不产生一个解,但可以失败。用于强迫程序回溯到最近的回溯点,或者与运行时错误一样,起中断程序执行的作用。例如内建谓词fail。编译器总是检查并对含不确定子句的谓词进行警告。
determ----定义确定性谓词。该类谓词可以成功,也可以失败,但绝不回溯。即该类谓词不会多于一个解。编译器总是检查并对谓词中含不确定性子句的进行警告。注:determ也用于事实的声明中。
nondeterm----定义能够进行回溯并产生多解的非确定性谓词。可以失败,此时,不产生任何解。注:determ也用于事实的声明中。
ReturnDomain----声明一个函数时的返回域。返回值从函数子句的最后一个参数获得,但该参数在谓词声明时不必出现。
例如:
PREDICATES
INTEGER /*Return*/ cube(INTEGER In) /*代入一整型参数,返回一整型结果*/
CLAUSES
cube(In,Return):- Return = In*In*In. /*函数cub()的子句表示!*/
predicateName----谓词名(或函数名)由字母开头(最好小写),后跟字母、数字、下画线的符号串组成,最长不超过250个。名字中间不能出现减号、空格、星号等字符。
- [flowpatterns] ----形如( flow [ , flow ]* )。其中,flow即{ i | o | functor flowpattern | listflow } ,flowpattern指明每一个参数如何使用:i表示输入流,o表示输出流,functor and flowpattern是指一个复合项的输入流和输出流情形。
例如:输入流、输出流的控制流分析实例。
diagnostics %should be placed before the start of the program text
PREDICATES
nondeterm plus(integer, integer, integer)
nondeterm num(integer)
CLAUSES
plus(X,Y,Z):- /*X+Y=?----X加Y的结果是什么*/
bound(X),bound(Y),!,Z=X+Y. /* (i,i,o) */
plus(X,Y,Z):- /*?+Y=Z----什么加Y等于Z*/
bound(Y),bound(Z),!,X=Z-Y. /* (o,i,i) */
plus(X,Y,Z):- /*X+?=Z----X加什么等于Z*/
bound(X),bound(Z),!,Y=Z-X. /* (i,o,i) */
plus(X,Y,Z):- /*?+?=Z----加起来的结果为Z的有哪些*/
free(X),free(Y),bound(Z),num(X),Y=Z-X. /* (o,o,i) */
plus(X,Y,Z):- /*?+Y=?----加数为Y的有哪些*/
free(X),free(Z),bound(Y),num(X),Z=X+Y. /* (o,i,o) */
plus(X,Y,Z):- /*X+?=?----被加数为X的有哪些*/
free(Y),free(Z),bound(X),num(Y),Z=X+Y. /* (i,o,o) */
plus(X,Y,Z):- /*?+?=?----加法有哪些*/
free(X),free(Y),free(Z),num(X),num(Y),Z=X+Y. /* (o,o,o) */
% Generator of numbers starting from 0
num(0).
num(X):-
num(A),
X = A+1.
为方便,一般可以在谓词声明时,为其指定输入输出流的可能使用情形。尤其是谓词流模式不是所有模式都有效时,可以帮助Prolog的流分析器分析子句所属流。
例如:指定谓词流模式的实例。
PREDICATES
procedure plus(integer, integer, integer) - (i,i,o),(i,o,i),(o,i,i)
此例中,流模式的指定告诉系统,谓词必须有两个输入值,一个输出值。由此可以避免其它模式的分析与匹配。
language----用于指定转换用的编译器,当声明的域要被传送到其它语言子程序时用,默认的是Prolog。language { asm | c | pascal | prolog | stdcall | syscall }。
namespec----用于指定目标代码的扩展名字。(主要用于与其它语言接口时)
注1:对全局谓词,必须说明其输入、输出流模式。否则,Prolog将把所有参数都作为默认的流处理,即输入流。
例如:
GLOBAL PREDICATES
my_converter(STRING, INTEGER)
等价于
my_converter(STRING, INTEGER)- (i,i)
注2:每个谓词的流模式可以有多个。
注3:对每一种流模式,都可以分别指定一个谓词模式。
例如:
PREDICATES
procedure append(ILIST,ILIST,ILIST) -
(i,i,o)
determ (i,i,i)
nondeterm (o,o,i)
注4:谓词允许有多重说明。要求对同一谓词的重复说明必须一个接一个连续给出,且要求谓词的参数个数必须一致,但领域可以不同。
例如:要定义一个实数加法和整数加法时,谓词声明如下:
add(integer,integer,integer)
add(real,real,real)
谓词值的声明形式:
[GLOBAL] PREDICATES
predicateName : predicateDomain [namespec]
例如:(略)
函数与返回值:
例如:
PREDICATES
UNSIGNED /*Return*/ triple(UNSIGNED In)
CLAUSES
triple(In, Return):- Return = In * 3.
GOAL
ReturnTripleVal = triple(6),
write(ReturnTripleVal).
无参函数的声明与调用:如果函数无任何参数,其声明的谓词名后的括号对不能省略,否则,程序出错,或不能当函数使用。
例如:
PREDICATES
unsigned hour()
CLAUSES
hour(H):- time(H,_,_,_).
其调用形式为:Hour = hour(),不能为Hour = hour。
函数与尾递归(tail recursion):当一个谓词被声明为一个有返回值的函数时,不能按常规谓词的调用方法调用之(即在参数表的最后给出输出参数的方法),而是要用函数的方法进行调用。原因在于函数将返回值存到了寄存器中去了,即编译之前和函数调用之后的代码与常规的谓词谓词调用是不同的。因此,调用其自身的函数不是尾递归的。
例如:
DOMAINS
ilist = integer*
PREDICATES
ilist neg(ilist)
CLAUSES
neg([],[]).
neg([Head|Tail],[NHead|NTail]):-
NHead = -Head,
NTail = neg(Tail). /*不是尾递归的!*/
GOAL
X=neg([1,2,3,4]). /*neg([1,2,3,4],X)调用时,系统将告之参数个数不对*/
以下代码是尾递归的:
DOMAINS
ilist = integer*
PREDICATES
neg(ilist,ilist)
CLAUSES
neg([],[]).
neg([Head|Tail],[NHead|NTail]):-
NHead = -Head,
neg(Tail,NTail). /*此子句形式是尾递归的!*/
GOAL
neg([1,2,3,4],X). /* Y=neg([1,2,3,4],X).要出错,即目标类型错*/
2-1-7 问题目标段
是程序的内建目标段,一个Prolog程序必须有一个目标段,且只有一个目标段。跟规则体一样,由一个或多个子目标构成。但与规则体之区别在于:目标后面不跟“:-”。程序启动后,将自动执行目标。
复合目标:由两个以上的子目标构成的目标。
子目标:复合目标中的任一目标。
两个子目标之间是联合关系时,用逗号分隔。Prolog尽量满足目标中体,一旦所有子目标都成功,程序成功结束。否则,失败。
两个子目标之间是“或”关系时,用分号分隔。执行时依次满足子目标,一旦子目标被满足,则成功结束,否则,将满足下一子目标。直到所有子目标都不满足时,失败退出。
例如:
car(Make,Odometer,Years_on_road,Body,Cost),Cost<25000.//小于25000的车
car(ford,Odometer,Years_on_road,Body,Cost) ;Cost<25000.//ford车或小于25000的车
外部目标与内部目标:在文本模式下的Prolog对话窗口中给定测试目标时,称为外部目标(Visual Prolog中已经没有了)。在程序中给定目标称为内部目标。
注:在Visual Prolog中实施以前外部目标的调试功能,可以借助于系统提供的测试目标功能(Test Goal)。
2-1-8 子句部分
Prolog是基于谓词逻辑形式系统的一个子集,即Horn子句。一个Prolog程序由两种子句构成:事实和规则。一个程序可以有多个子句段,每个子句段都由CLAUSES开头。
事实:已知为真的关系或性质。如:likes(bill, cindy).
规则:相互依赖的关系。允许Prolog从一类信息推出另外的信息。如果给定的条件为真,则规则为真。
规则由两部分构成:一是规则头,一是规则体。规则头和规则体之间用“:-”分隔。规则头又称结论(conclusion)或依赖关系(dependent relation)。规则体是一些必须为真的条件或事实,它们将由Prolog去证明。
注1:“:-”可用“if”代替。
注2:一个谓词的子句应该放在一起。
注3:定义一个谓词的子句序列被成为过程(procedure)。
注4:规则体中的事实或条件之间有连接词“and”/“or”或“,”/“;”分隔。
注5:每一子句以点“.”结束。
注6:Prolog试图满足一个目标时,按子句出现的先后顺序进行。
例如:如前述各例及后面所有相关例子所示。
2-2 Prolog内建函数(Built-in functions)简介
2-2-1 算术函数与谓词
X mode Y X div Y abs(X) exp(X) ln(X) log(X) sqrt(X)
round(X) trunc(X) val(domain,X)
cos(X) sin(X) tan(X) arctan(X)
random(X)----之间的随机实数。random(X,Y)----之间的随机整数。
randominit(X)----初始化随机数产生器。
2-2-2 控制谓词
bound(Variable)----测试变量是否被约束。
free(Variable)----测试变量是否自由变量。
fail()----强迫失败,以引起回溯。
not(Atom)----对子目标结果的否定。
true()----总是成功。可以作为陷阱函数的参数使用。
findall(X, predicateName(_,_,X,_,…,_), VarList)----汇集非确定性谓词调用的所有求解结果到值域表中去。其中,要求谓词具有nond
展开阅读全文