首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 计算机考试 > 软件考试 > 复习指导 >

Prolog语言的编译原理:合一算法

2009-01-31 
合一算法

    Prolog是一种基于谓词演算的程序设计语言。Prolog是一种说明性语言,它的基本意思是程序员着重于描述问题而不是指定一组指令来解决问题。Prolog程序是一组子句的集合,每个子句要么是事实要么是规则,子句表示属性或者个体之间的关系。
  Prolog的语法和谓词演算的语法接近。例如,下面是一些事实的例子:
  metal(copper) 铜是一种金属
  likes(john,mary) John喜欢Mary
  between(manchester,london,edinburgh) 曼彻斯特位于伦敦和爱丁堡之间
  以上metal,likes等都叫做谓词。
  Prolog中有常量和变量的区别,常量由小写字母开头,变量由大写字母开头。例如metal(copper)中copper是常量。
  比如:parent(zhangsan,X),即zhangsan是X的双亲,此处zhangsan是常量,X是变量。
  Prolog中有一个很重要的匹配的概念。比如,parent(zhangsan,X)与事实parent(zhangsan,zhangsi)匹配。
  比如,有以下事实:
  likes(john,mary)
  likes(john,meg)
  likes(david,mary)
  而子句likes(john,X)则与上面的likes(john,mary),likes(john,meg)匹配。而likes(X,Y)与上面的四句都匹配,parent(zhangsan,X)与上面的四句都不匹配,因为谓词不同。
  Prolog依靠这种匹配来对知识库中的知识进行搜索,在此基础上推理出新的事实。
  这种匹配用一个专用术语叫做合一。合一有时候情况会比较复杂,比如,p(X,f(Y))与p(a,K)也是匹配的,因为K能与f(Y)匹配,X能与a匹配。path(X,Y)和path(X,Y,Z)不匹配,因为参数个数不同。mother(X,Y)和father(W,Z)不匹配,因为谓词名字不同等等。
  判断两个句子是否匹配,可以做一个函数boolean unify()。在调用时,传递一个堆栈对象进去,堆栈中包含着要匹配的一对子句,返回值是true代表两子句匹配,false代表两子句不匹配。
  在判断两子句匹配时,我们一般还要判断两个子句中,第一个子句中的哪个变量与第二个子句中相应位置的项匹配。例如,parent(zhangsan,X)与事实parent(zhangsan,zhangsi)匹配,则可以知道X与zhangsi匹配。又例如,likes(X,Y)与likes(john,meg)中,X与john匹配,Y与meg匹配。我们在调用unify(),在获得两子句是否匹配的信息时,同时,也将两子句中匹配的项,保存到“合一表”中。“合一表”可以使用list这种数据结构来保存。
  判断匹配的伪代码如下:
  while堆栈中不为空时
  1,获得堆栈中的子句s1和s2
  2,如果s1是变量,那么取得s1变量中的值,再赋给s1
  3,如果s2是变量,那么取得s2变量中的值,再赋给s2
  4,如果s1为null或者s2为null,或者s1和s2都是null,则return true,代表两个子句匹配。
  5,如果s1和s2都是常量,而且s1不等于s2,那么return false,代表两个子句不匹配。
  6,如果s1是变量而且s1与s2不同(这个不同指的是s1与s2不在同一个地址),那么将s1与s2添加进合一表中。
  否则如果s2是变量而且s2与s1不同(这个不同指的是s1与s2不在同一个地址),那么将s1与s2添加进合一表中。
  7,如果s1是一个子句,s2也是一个子句那么
  a,如果s1的谓词不等于s2的谓词,则return false
  b,如果s1的参数个数不等于s2的参数个数,则return false
  将s1,s2中相应位置的参数,一对一对的,依次push进堆栈中.
  end while
  合一算法我是用java实现的,参考了Rob Callan的<人工智能>一书的c语言代码.其中,TestUnify.java是测试类,其他的,UT.java是合一表类,常量,变量,字句都有各自的类,这些项的基类是Exp类。

 

3COME考试频道为您精心整理,希望对您有所帮助,更多信息在http://www.reader8.com/exam/

热点排行